MSP432速成教程(看这一篇就够了)

avatar
作者
筋斗云
阅读量:0

文章目录

MSP432P401R基础使用

一、GPIO输出 点灯 跑马灯

(一)GPIO输出

打开芯片数据手册(msp432p401r)第17页的表详细描述了对应引脚的GPIO功能

1.库函数
  • 配置GPIO模式:
GPIO_setAOutputPin(Port,pin)//设置GPIO为输出模式 
  • 设置高低电平
GPIO_setOutputHoghOnPin(Port,Pin)//设置GPIO为高电平 GPIO_setOutputLowOnPin(Port,Pin)//设置GPIO为低电平 GPIO_toggleOutputOnPin(Port,Pin)//翻转GPIO引脚电平 
  • 配置驱动强度

只有P2.0、P2.1、P2.2、P2.3引脚可以配置为高驱动程度

This I/O can be configured for high drive operation with up to 20-mA drive capability.

此I/O可配置为高达20 mA驱动能力的高驱动操作。

GPIO_setDriveStrengthHigh(Port,Pin)//强驱动 GPIO_setDriveStrengthLow(Port,Pin)//弱驱动(无特殊要求,一般不用设置) //几乎不用,需要使用时自行查看参数、返回值等详细信息 
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>  int main(void) {     // 初始化 MSP432P401R 微控制器     MAP_WDT_A_holdTimer();      // 配置 P1.0 引脚为输出模式     MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);      // 设置 P1.0 引脚的驱动强度为高级别     MAP_GPIO_setDriveStrengthHigh(GPIO_PORT_P1, GPIO_PIN0);      while (1)     {         // 在 P1.0 引脚输出高电平         MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN0);          // 延时约一秒钟         MAP_PCM_gotoLPM0();     } } 

(二)点亮LED灯

1.硬件连接

可以打开评估版手册(MSP432开发板手册/slau597f)37页原理图

在这里插入图片描述

共阴极连接,高电平亮,低电平熄灭

2.代码

led.h

#ifndef __LED_H #define __LED_H #include <ti/devices/msp432p4xx/driverlib/driverlib.h>  // 位带操作 #define LED_RED BITBAND_PERI(P1OUT,0) #define LED_R BITBAND_PERI(P2OUT,0) #define LED_G BITBAND_PERI(P2OUT,1) #define LED_B BITBAND_PERI(P2OUT,2)  void LED_Init(void);//LED初始化函数  void LED_RED_On(void);//打开LED1 void LED_RED_Off(void);//关闭LED1 void LED_RED_Tog(void);//翻转LED1  void LED_Y_On(void);//打开黄色RGB灯 void LED_C_On(void);//打开青色RGB灯 void LED_P_On(void);//打开品红RGB灯  void LED_R_On(void);//红色RGB灯 void LED_G_On(void);//绿色RGB灯 void LED_B_On(void);//蓝色RGB灯  void LED_R_Off(void); void LED_G_Off(void); void LED_B_Off(void);  void LED_R_Tog(void); void LED_G_Tog(void); void LED_B_Tog(void);  void LED_W_On(void);//白色RGB灯 void LED_W_Off(void); void LED_W_Tog(void);  #endif 

led.c

#include "led.h"  void LED_Init(void) {     MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);//设置GPIO为输出模式     MAP_GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN0 + GPIO_PIN1 + GPIO_PIN2);      LED_RED_Off();     LED_R_Off();     LED_G_Off();     LED_B_Off(); } void LED_RED_On(void) { LED_RED = 1; } void LED_RED_Off(void) { LED_RED = 0; } void LED_RED_Tog(void) { LED_RED ^= 1; }  void LED_R_Off(void) { LED_R = 0;} void LED_G_Off(void) { LED_G = 0;} void LED_B_Off(void) { LED_B = 0; }  void LED_R_On(void) { LED_R = 1; } void LED_G_On(void) { LED_G = 1;  } void LED_B_On(void) { LED_B = 1;  }  void LED_R_Tog(void) { LED_R ^= 1; } void LED_G_Tog(void) { LED_G ^= 1; } void LED_B_Tog(void) { LED_B ^= 1; }  //白色 White void LED_W_On(void) {     LED_R_On();     LED_G_On();     LED_B_On(); } //白色 White void LED_W_Off(void) {     LED_R_Off();     LED_G_Off();     LED_B_Off(); } //白色 White void LED_W_Tog(void) {     LED_R_Tog();     LED_G_Tog();     LED_B_Tog(); } //黄色 Yellow void LED_Y_On(void) {     LED_R_On();     LED_G_On();     LED_B_Off(); } //品红 Pinkish red void LED_P_On(void) {     LED_R_On();     LED_G_Off();     LED_B_On(); } //青色 Cyan void LED_C_On(void) {     LED_R_Off();     LED_G_On();     LED_B_On(); } 

main.c

#include <ti/devices/msp432p4xx/driverlib/driverlib.h>  /* Standard Includes */ #include <stdint.h> #include <stdbool.h>  #include "led.h"  int main(void) {     uint32_t i;      /* Stop Watchdog  */     MAP_WDT_A_holdTimer();//关闭看门狗      LED_Init();//LED初始化          while (1)     {         LED_RED_On();         for (i = 0; i < 500000; i++);         LED_RED_Off();          LED_R_On();         for (i = 0; i < 500000; i++);         LED_R_Off();          LED_G_On();         for (i = 0; i < 500000; i++);         LED_G_Off();          LED_B_On();         for (i = 0; i < 500000; i++);         LED_B_Off(); 		 		LED_C_On();         for (i = 0; i < 500000; i++); 		 		LED_P_On();         for (i = 0; i < 500000; i++); 		 		LED_Y_On();         for (i = 0; i < 500000; i++); 		 		LED_W_On();         for (i = 0; i < 500000; i++);         LED_W_Off();     } } 

二、GPIO做输入 按键输入

(一)GPIO做输入

1.库函数

配置GPIO模式:

GPIO_setAslnputPin(Port,Pin);//设置为浮空输入 GPIO_setAslnputWithPullUpResistor(Port,Pin);//设置为上拉输入模式 GPIO_setAslnputWithPullDownResistor(Port,Pin);//设置为下拉输入模式 

获取电平状态:

GPIO_getlnputPinValue(Port,Pin); 

(二)按键输入

1.硬件连接

可以打开评估版手册(MSP432开发板手册/slau597f)37页原理图

在这里插入图片描述

可以看到按下后被拉低为低电平,所以我们应该把引脚配置为上拉输入

2.代码

key.h

#ifndef __KEY_H #define __KEY_H	  	  #include "driverlib.h"  #define KEY1 BITBAND_PERI(P1IN, 1) //读取按键1 #define KEY2 BITBAND_PERI(P1IN, 4) //读取按键2   #define KEY1_PRES 	1	//KEY0按下 #define KEY2_PRES	  2	//KEY1按下   void KEY_Init(void);//IO初始化 uint8_t KEY_Scan(uint8_t);  	//按键扫描函数					     #endif  

key.c

#include "driverlib.h" #include "key.h" 								     //按键初始化函数 void KEY_Init(void) //IO初始化 { 	GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1 | GPIO_PIN4); }  //按键处理函数 //返回按键值 //mode:0,不支持连续按;1,支持连续按; //0,没有任何按键按下 //1,KEY0按下 //2,KEY1按下 //3,KEY3按下 WK_UP //注意此函数有响应优先级,KEY0>KEY1>KEY_UP!! uint8_t KEY_Scan(uint8_t mode) { 	uint16_t i; 	static uint8_t key_up = 1; //按键按松开标志 	if (mode) 		key_up = 1; //支持连按	 	if (key_up && (KEY2 == 0 || KEY1 == 0)) 	{ 		for (i = 0; i < 5000; i++) 			; //去抖动 		key_up = 0; 		if (KEY1 == 0) 			return KEY1_PRES; 		else if (KEY2 == 0) 			return KEY2_PRES; 	} 	else if (KEY2 == 1 && KEY1 == 1) 		key_up = 1; 	return 0;// 无按键按下 }  

main.c

#include "driverlib.h"  /* Standard Includes */ #include <stdint.h> #include <stdbool.h>  #include "led.h" #include "key.h"  int main(void) {     		uint8_t key; 	     /* Stop Watchdog  */     MAP_WDT_A_holdTimer();      LED_Init();     KEY_Init(); 	     while (1)     { 				key = KEY_Scan(0);//不支持连按  				if (key == KEY1_PRES) 						LED_RED_On();//打开LED1 				else if (key == KEY2_PRES) 						LED_RED_Off();//关闭LED1 					     } }  

三、外部中断

MSP432P401R并不是每一个IO口都可以中断,必须参考msp432p401r第17页

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JWUQ1klo-1690345264992)(D:\Typora\图片\image-20230721141203189.png)]

port interrupt:端口中断

只有P1到P7所以IO口可以做外部中断

(一)库函数

1.gpio.h
  • (1)开启外部中断
GPIO_enableInterrupt(GPIO_PORT_Px,GPIO_PINx); 
  • 配置触发方式
GPIO_interruptEdgeSelect(GPIO_PORT_P1,GPIO_PIN4,Edge); 

Edge有效值:

GPIO_HIGH_TO_LOW_TRANSITION//下降沿(从高到低) GPIO_LOW_TO_HIGH_TRANSITION//上升沿(从低到高) 
  • 获取GPIO中断状态
GPIO_getEnabledInterruptStatus(GPIO_PORT_Px); 
  • 清除GPIO中断标志位
GPIO_clearInterruptFlag(GPIO_PORT_Px,GPIO_PINx); 

配合使用

status=GPIO_getEnabledInterruptStatus(GPIO_PORT_Px); GPIO_clearInterruptFlag(GPIO_PORT_Px,status); 
2.interrupt.h
  • 开启总中断
Interrupt_enableMaster(void); 
  • 开启端口中断
Interrupt_enableInterrupt(interruptNumber); 

interruptNumber有效值:

INT_PORT1 INT_PORT2 INT_PORT3 INT_PORT4 INT_PORT5 INT_PORT6 

(二)一般配置步骤

  1. 配置GPIO输入

    GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1); //P1.1 GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN4); //P1.4 
  2. 清除中断标志位

    GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN1); GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN4); 
  3. 配置触发方式

    GPIO_interruptEdgeSelect(GPIO_PORT_P1, GPIO_PIN1, GPIO_HIGH_TO_LOW_TRANSITION); GPIO_interruptEdgeSelect(GPIO_PORT_P1, GPIO_PIN4, GPIO_HIGH_TO_LOW_TRANSITION); 
  4. 开启外部中断

    GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN1); GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN4); 
  5. 开启端口中断

    Interrupt_enableInterrupt(INT_PORT1); 
  6. 开启总中断

    Interrupt_enableMaster(); 
  7. 编写中断服务函数

void PORT1_IRQHandler(void) { 	uint16_t status; 	 	status = GPIO_getEnabledInterruptStatus(GPIO_PORT_P1); 	GPIO_clearInterruptFlag(GPIO_PORT_P1, status); 	delay_ms(10);//按键消抖 	 	if (status & GPIO_PIN1) //对应P1.1 	{ 		if (KEY1 == 0) 		{ 			LED_RED_On(); //点亮红灯 			 		} 	} 	if (status & GPIO_PIN4) //对应P1.4 	{ 		if (KEY2 == 0) 		{ 			LED_RED_Tog();//翻转红灯 			 		} 	} } 

(三)中断优先级管理

详情见技术手册(slau356)82页

  • 等级越低,中断优先级越高,也就是说等级0的优先级最高。

  • 支持动态调整优先级

  • 将优先级分为组优先级和子优先级,组优先级高的是可以打断组优先级低的,组优先级一样时就不会被打断,如果发生了两个组优先级一样的中断,则子优先级高的会先执行,另一个挂起

  • 注意,这里的子优先级是硬件优先级,是已经设置好了的,不能更改

详情见msp432p401r第117页,中断号(NVIC INTERRUPT INPUT)越小,子优先级越高

例子:

​ 系统有两个中断,中断A和中断B,中断号分别为1和2。
​ 当不进行中断优先级配置时,组优先级一致,中断号即为中断优先级,中断号小的中断优先级高,所以中断优先级为A>B。假如此时系统正在执行中断B,而中断A发生了,系统会如何处理呢?因为它们组优先级一样,故中断A不能打断中断B,系统会先挂起中断A,待中断B执行完后,再执行中断A;
​ 倘若将中断A的组优先级设置为1,中断B的组优先级设置为2,此时系统正在执行中断B,而中断A发生了,系统会如何处理呢?因为组优先级小的优先级高,所以中断优先级是A>B,故系统打断中断B,执行中断A,待中断A执行完后,再继续执行中断B。

总结:

  • 组优先级高的能打断组优先级低的
  • 在组优先级一样的情况下,子优先级高的不能打断子优先级低的
1.代码
  • 设置组优先级
Interrupt_setPriority(interruptNuber,level); 

level:x<<5,x∈[0,7]

只使用高3位,配置时左移5位。

(四)外部中断实验

exti.h

#ifndef __EXTI_H #define __EXIT_H	  #include "driverlib.h"    	  void EXTIX_Init(void);//外部中断初始化   #endif  

exti.c

#include "driverlib.h" #include "exti.h"   void EXTIX_Init(void) { 	//1.配置GPIO输入 	GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1); //P1.1 	GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN4); //P1.4  	//2.清除中断标志位 	GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN1); 	GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN4);  	//3.配置触发方式 	GPIO_interruptEdgeSelect(GPIO_PORT_P1, GPIO_PIN1, GPIO_HIGH_TO_LOW_TRANSITION); 	GPIO_interruptEdgeSelect(GPIO_PORT_P1, GPIO_PIN4, GPIO_HIGH_TO_LOW_TRANSITION);  	//4.5 配置组优先级 	Interrupt_setPriority(INT_PORT1, 1 << 5); 	Interrupt_setPriority(INT_PORT1, 2 << 5);  	//4.开启外部中断 	GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN1); 	GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN4);  	//5.开启端口中断 	Interrupt_enableInterrupt(INT_PORT1);  	//6.开启总中断 	Interrupt_enableMaster(); }  

main.h

#include "driverlib.h"  /* Standard Includes */ #include <stdint.h> #include <stdbool.h>  #include "led.h" #include "key.h" #include "delay.h" #include "exti.h"  int main(void) { 	     /* Stop Watchdog  */     MAP_WDT_A_holdTimer();      LED_Init();     EXTIX_Init(); 		delay_init();     while (1)     {     } }  //7.编写中断服务函数 void PORT1_IRQHandler(void) { 	uint16_t status; 	 	status = GPIO_getEnabledInterruptStatus(GPIO_PORT_P1); 	GPIO_clearInterruptFlag(GPIO_PORT_P1, status); 	delay_ms(10);//按键消抖 	 	if (status & GPIO_PIN1) //对应P1.1 	{ 		if (KEY1 == 0) 		{ 			LED_RED_On(); //点亮红灯 			 		} 	} 	if (status & GPIO_PIN4) //对应P1.4 	{ 		if (KEY2 == 0) 		{ 			LED_RED_Tog();//翻转红灯 			 		} 	} }  

四、串口收发

(一)MSP432P401R串口资源+

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wWrtfid0-1690345264992)(D:\Typora\图片\image-20230704220945418.png)]

详见msp432p401r第6页

A0的串口是通过跳线帽连接到调试器上的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wUvcYTeL-1690345264992)(D:\Typora\图片\image-20230704221144484.png)]

开发板手册(slau597f)第38页

(二)UART模式的特性

  • 7/8个数据位、1个奇/偶/无奇偶效验位
  • 独立的发送和接收移位寄存器
  • 独立的发送和接收缓冲寄存器
  • LSP优先/MSB优先的数据发送和接收
  • 为多处理器系统内置空闲线和地址位通信协议
  • 支持分数波特率的可编程调制波特率
  • 用于错误检测和抑制的状态标志
  • 针对地址检测的状态标志
  • 针对接收、发送,起始位接收和发送完成的独立中断能力

数据手册(slau356)第904页

(三)库函数

1.uart.h

  • 初始化串口函数

    UART_initModule(EUSCI_Ax_BASE, &uartConfig); 
  • 使能串口模块

    UART_enableModule(EUSCI_Ax_BASE); 
  • 开启串口相关中断

    UART_enableInterrupt(EUSCI_Ax_BASE, EUSCI_x_INTERRUPT); 
  • 获取数据

    UART_receiveData(EUSCI_Ax_BASE)
  • 发送数据

    UART_transmitData(EUSCI_Ax_BASE,Data_8bit); 
  • 开启串口端口中断

    Interrupt_enableInterrupt(INT_EUSCIAx); 
  • 开启总中断

    Interrupt_enableMaster(void); 

(四)一般配置步骤

  1. 配置时钟
  2. 配置GPIO复用
  3. 配置结构体
  4. 初始化串口
  5. 开启串口
  6. 开启串口相关中断
  7. 开启串口端口中断
  8. 开启总中断
  9. 编写UART ISR

(五)代码

usart.h

/****************************************************/ // MSP432P401R // 串口配置 // Bilibili:m-RNA // E-mail:m-RNA@qq.com /****************************************************/  /******************   版本更新说明   *****************  *   * CCS支持printf  * Keil支持标准C库跟微库  * 用Keil开发终于可以不开微库啦  *   * ? 需要注意:  * ①使用标准C库时,将无法使用scanf。  * 如果需要使用scanf时,请使用微库 MicroLIB  * ①低频时钟频率下,高波特率使得传输时误差过大,  * 比如35768Hz下19200波特率,  * 会使得传输出错,这时可以尝试降低波特率。  * ②baudrate_calculate的问题请去文件内查看。  *   * **************************************************  *   * ? v3.2  2021/10/28  * 简化对CCS支持的printf代码  *  * ? v3.1  2021/10/18  * 添加对CCS的printf支持  *  * ? v3.0  2021/10/15  * 此版本支持使用 标准C库  * 文件正式改名为与正点原子同名的  * usart.c 和 usart.h,方便移植  * 仅支持Keil平台开发  *    * ? v2.1  2021/8/27  * 添加支持固件库v3_21_00_05  * 仅支持 MicroLIB 微库、Keil平台开发  *   * ? v2.0  2021/8/25  * uart_init增添了波特率传入参数,可直接配置波特率。  * 计算UART的代码单独打包为名为  * baudrate_calculate的c文件和h文件  * 仅支持 MicroLIB 微库、Keil平台开发  *   * ? v1.0 2021/7/17  * 仅支持固件库v3_40_01_02  * 配置了SMCLK 48MHz 波特率 115200的初始化代码,  * 对接标准输入输出库,使其能使用printf、scanf函数  * 仅支持 MicroLIB 微库、Keil平台开发  *   ****************************************************/  #ifndef __USART_H #define __USART_H #include "driverlib.h" #include "stdio.h" //1.61328125kb  #ifdef __TI_COMPILER_VERSION__ //CCS平台 #include "stdarg.h" #include "string.h" #define USART0_MAX_SEND_LEN     600                 //最大发送缓存字节数 int printf(const char *str, ...); #endif  void uart_init(uint32_t baudRate);  #endif 

usart.c

/****************************************************/ // MSP432P401R // 串口配置 // Bilibili:m-RNA // E-mail:m-RNA@qq.com /****************************************************/  /******************   版本更新说明   *****************  *   * CCS支持printf  * Keil支持标准C库跟微库  * 用Keil开发终于可以不开微库啦  *   * ? 需要注意:  * ①使用标准C库时,将无法使用scanf。  * 如果需要使用scanf时,请使用微库 MicroLIB  * ①低频时钟频率下,高波特率使得传输时误差过大,  * 比如35768Hz下19200波特率,  * 会使得传输出错,这时可以尝试降低波特率。  * ②baudrate_calculate的问题请去文件内查看。  *   * **************************************************  *   * ? v3.2  2021/10/28  * 简化对CCS支持的printf代码  *  * ? v3.1  2021/10/18  * 添加对CCS的printf支持  *  * ? v3.0  2021/10/15  * 此版本支持使用 标准C库  * 文件正式改名为与正点原子同名的  * usart.c 和 usart.h,方便移植  * 仅支持Keil平台开发  *    * ? v2.1  2021/8/27  * 添加支持固件库v3_21_00_05  * 仅支持 MicroLIB 微库、Keil平台开发  *   * ? v2.0  2021/8/25  * uart_init增添了波特率传入参数,可直接配置波特率。  * 计算UART的代码单独打包为名为  * baudrate_calculate的c文件和h文件  * 仅支持 MicroLIB 微库、Keil平台开发  *   * ? v1.0 2021/7/17  * 仅支持固件库v3_40_01_02  * 配置了SMCLK 48MHz 波特率 115200的初始化代码,  * 对接标准输入输出库,使其能使用printf、scanf函数  * 仅支持 MicroLIB 微库、Keil平台开发  *   ****************************************************/  #include "usart.h" #include "baudrate_calculate.h"  #ifdef __TI_COMPILER_VERSION__ //CCS平台 uint8_t  USART0_TX_BUF[USART0_MAX_SEND_LEN];             //发送缓冲,最大USART3_MAX_SEND_LEN字节 int printf(const char *str, ...) {     uint16_t i,j;     va_list ap;     va_start(ap,str);     vsprintf((char*)USART0_TX_BUF,str,ap);     va_end(ap);     i=strlen((const char*)USART0_TX_BUF);       //此次发送数据的长度     for(j=0;j<i;j++)                            //循环发送数据     {       //while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕         UART_transmitData(EUSCI_A0_BASE, USART0_TX_BUF[j]);     }     return 0; } /*****************   函数说明   *****************  *  * 函数:int printf(const char *str, ...);  * 源码来自@正点原子  * 稍作改动适配CCS工程,在此也表感谢正点原子。  *  *****************   说明结束   *****************/  #else //Keil支持标准C库跟微库 //预编译 //if 1 使用标准C库 如果报错就使用微库 //if 0 使用微库 得去勾选魔术棒里的 Use MicroLIB #if 1 #pragma import(__use_no_semihosting) //标准库需要的支持函数 struct __FILE {   int handle; }; FILE __stdout; //定义_sys_exit()以避免使用半主机模式 void _sys_exit(int x) {   x = x; } #else int fgetc(FILE *f) {   while (EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG !=          UART_getInterruptStatus(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG))     ;   return UART_receiveData(EUSCI_A0_BASE); } #endif int fputc(int ch, FILE *f) {   UART_transmitData(EUSCI_A0_BASE, ch & 0xFF);   return ch; } /*****************   函数说明   *****************  *  * 以上两条对接标准输入输出库的函数:  * int fputc(int ch, FILE *f);  * int fgetc(FILE *f);  * 源码为BiliBili平台UP主 “CloudBoyStudio” 编写  * 本人RNA,不是作者  * 在此也表感谢  *  *****************   说明结束   *****************/ #endif  void uart_init(uint32_t baudRate) { #ifdef EUSCI_A_UART_7_BIT_LEN   //固件库v3_40_01_02   //默认SMCLK 48MHz 比特率 115200   const eUSCI_UART_ConfigV1 uartConfig =       {           EUSCI_A_UART_CLOCKSOURCE_SMCLK,                // SMCLK Clock Source           26,                                            // BRDIV = 26           0,                                             // UCxBRF = 0           111,                                           // UCxBRS = 111           EUSCI_A_UART_NO_PARITY,                        // No Parity           EUSCI_A_UART_LSB_FIRST,                        // MSB First           EUSCI_A_UART_ONE_STOP_BIT,                     // One stop bit           EUSCI_A_UART_MODE,                             // UART mode           EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION, // Oversampling           EUSCI_A_UART_8_BIT_LEN                         // 8 bit data length       };   eusci_calcBaudDividers((eUSCI_UART_ConfigV1 *)&uartConfig, baudRate); //配置波特率 #else   //固件库v3_21_00_05   //默认SMCLK 48MHz 比特率 115200   const eUSCI_UART_Config uartConfig =       {           EUSCI_A_UART_CLOCKSOURCE_SMCLK,                // SMCLK Clock Source           26,                                            // BRDIV = 26           0,                                             // UCxBRF = 0           111,                                           // UCxBRS = 111           EUSCI_A_UART_NO_PARITY,                        // No Parity           EUSCI_A_UART_LSB_FIRST,                        // MSB First           EUSCI_A_UART_ONE_STOP_BIT,                     // One stop bit           EUSCI_A_UART_MODE,                             // UART mode           EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION, // Oversampling       };   eusci_calcBaudDividers((eUSCI_UART_Config *)&uartConfig, baudRate); //配置波特率 #endif    MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P1, GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);//2.配置GPIO复用   MAP_UART_initModule(EUSCI_A0_BASE, &uartConfig);//3.初始化串口   MAP_UART_enableModule(EUSCI_A0_BASE);//4.开启串口模块 	UART_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);//5.开启串口相关中断 	Interrupt_enableInterrupt(INT_EUSCIA0);//6.开启串口端口中断 	Interrupt_enableMaster();//7.开启总中断 }  //8.编写UART ISR void EUSCIA0_IRQHandler(void) {     uint32_t status = UART_getEnabledInterruptStatus(EUSCI_A0_BASE);      if(status & EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG) //接收中断     {         UART_transmitData(EUSCI_A0_BASE, MAP_UART_receiveData(EUSCI_A0_BASE)); //发送数据     }  } 

sysinit.h

/* --COPYRIGHT--,BSD  * Copyright (c) 2017, Texas Instruments Incorporated  * All rights reserved.  *  * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  *  * *  Redistributions of source code must retain the above copyright  *    notice, this list of conditions and the following disclaimer.  *  * *  Redistributions in binary form must reproduce the above copyright  *    notice, this list of conditions and the following disclaimer in the  *    documentation and/or other materials provided with the distribution.  *  * *  Neither the name of Texas Instruments Incorporated nor the names of  *    its contributors may be used to endorse or promote products derived  *    from this software without specific prior written permission.  *  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  * --/COPYRIGHT--*/ #ifndef __SYSCTL_H__ #define __SYSCTL_H__  #include <stdint.h> #include "driverlib.h"  /* Define to ensure that our current MSP432 has the SYSCTL module. This     definition is included in the device specific header file */ #ifdef __MCU_HAS_SYSCTL__  //***************************************************************************** // //! \addtogroup sysctl_api //! @{ // //*****************************************************************************  //***************************************************************************** // // If building with a C++ compiler, make all of the definitions in this header // have a C binding. // //***************************************************************************** #ifdef __cplusplus extern "C" { #endif  //***************************************************************************** // // Control specific variables // //***************************************************************************** #define SYSCTL_SRAM_BANK7 SYSCTL_SRAM_BANKEN_BNK7_EN #define SYSCTL_SRAM_BANK6 SYSCTL_SRAM_BANKEN_BNK6_EN #define SYSCTL_SRAM_BANK5 SYSCTL_SRAM_BANKEN_BNK5_EN #define SYSCTL_SRAM_BANK4 SYSCTL_SRAM_BANKEN_BNK4_EN #define SYSCTL_SRAM_BANK3 SYSCTL_SRAM_BANKEN_BNK3_EN #define SYSCTL_SRAM_BANK2 SYSCTL_SRAM_BANKEN_BNK2_EN #define SYSCTL_SRAM_BANK1 SYSCTL_SRAM_BANKEN_BNK1_EN  #define SYSCTL_HARD_RESET 1 #define SYSCTL_SOFT_RESET 0  #define SYSCTL_PERIPH_DMA SYSCTL_PERIHALT_CTL_HALT_DMA #define SYSCTL_PERIPH_WDT SYSCTL_PERIHALT_CTL_HALT_WDT #define SYSCTL_PERIPH_ADC SYSCTL_PERIHALT_CTL_HALT_ADC #define SYSCTL_PERIPH_EUSCIB3 SYSCTL_PERIHALT_CTL_HALT_EUB3 #define SYSCTL_PERIPH_EUSCIB2 SYSCTL_PERIHALT_CTL_HALT_EUB2 #define SYSCTL_PERIPH_EUSCIB1 SYSCTL_PERIHALT_CTL_HALT_EUB1 #define SYSCTL_PERIPH_EUSCIB0 SYSCTL_PERIHALT_CTL_HALT_EUB0 #define SYSCTL_PERIPH_EUSCIA3 SYSCTL_PERIHALT_CTL_HALT_EUA3 #define SYSCTL_PERIPH_EUSCIA2 SYSCTL_PERIHALT_CTL_HALT_EUA2 #define SYSCTL_PERIPH_EUSCIA1 SYSCTL_PERIHALT_CTL_HALT_EUA1 #define SYSCTL_PERIPH_EUSCIA0 SYSCTL_PERIHALT_CTL_HALT_EUA0 #define SYSCTL_PERIPH_TIMER32_0_MODULE SYSCTL_PERIHALT_CTL_HALT_T32_0 #define SYSCTL_PERIPH_TIMER16_3 SYSCTL_PERIHALT_CTL_HALT_T16_3 #define SYSCTL_PERIPH_TIMER16_2 SYSCTL_PERIHALT_CTL_HALT_T16_2 #define SYSCTL_PERIPH_TIMER16_1 SYSCTL_PERIHALT_CTL_HALT_T16_1 #define SYSCTL_PERIPH_TIMER16_0 SYSCTL_PERIHALT_CTL_HALT_T16_0  #define SYSCTL_NMIPIN_SRC SYSCTL_NMI_CTLSTAT_PIN_SRC #define SYSCTL_PCM_SRC SYSCTL_NMI_CTLSTAT_PCM_SRC #define SYSCTL_PSS_SRC SYSCTL_NMI_CTLSTAT_PSS_SRC #define SYSCTL_CS_SRC SYSCTL_NMI_CTLSTAT_CS_SRC  #define SYSCTL_REBOOT_KEY   0x6900  #define SYSCTL_1_2V_REF        (uint32_t)&TLV->ADC14_REF1P2V_TS30C - (uint32_t)TLV_BASE #define SYSCTL_1_45V_REF       (uint32_t)&TLV->ADC14_REF1P45V_TS30C - (uint32_t)TLV_BASE #define SYSCTL_2_5V_REF        (uint32_t)&TLV->ADC14_REF2P5V_TS30C - (uint32_t)TLV_BASE  #define SYSCTL_85_DEGREES_C    4 #define SYSCTL_30_DEGREES_C    0   #define TLV_START               0x00201004 #define TLV_TAG_RESERVED1      1 #define TLV_TAG_RESERVED2      2 #define TLV_TAG_CS             3 #define TLV_TAG_FLASHCTL       4 #define TLV_TAG_ADC14          5 #define TLV_TAG_RESERVED6      6 #define TLV_TAG_RESERVED7      7 #define TLV_TAG_REF            8 #define TLV_TAG_RESERVED9      9 #define TLV_TAG_RESERVED10     10 #define TLV_TAG_DEVINFO        11 #define TLV_TAG_DIEREC         12 #define TLV_TAG_RANDNUM        13 #define TLV_TAG_RESERVED14     14 #define TLV_TAG_BSL            15 #define TLV_TAGEND             0x0BD0E11D  //***************************************************************************** // // Structures for TLV definitions // //***************************************************************************** typedef struct {     uint32_t    maxProgramPulses;     uint32_t    maxErasePulses; } SysCtl_FlashTLV_Info;  typedef struct {     uint32_t rDCOIR_FCAL_RSEL04;     uint32_t rDCOIR_FCAL_RSEL5;     uint32_t rDCOIR_MAXPOSTUNE_RSEL04;     uint32_t rDCOIR_MAXNEGTUNE_RSEL04;     uint32_t rDCOIR_MAXPOSTUNE_RSEL5;     uint32_t rDCOIR_MAXNEGTUNE_RSEL5;     uint32_t rDCOIR_CONSTK_RSEL04;     uint32_t rDCOIR_CONSTK_RSEL5;     uint32_t rDCOER_FCAL_RSEL04;     uint32_t rDCOER_FCAL_RSEL5;     uint32_t rDCOER_MAXPOSTUNE_RSEL04;     uint32_t rDCOER_MAXNEGTUNE_RSEL04;     uint32_t rDCOER_MAXPOSTUNE_RSEL5;     uint32_t rDCOER_MAXNEGTUNE_RSEL5;     uint32_t rDCOER_CONSTK_RSEL04;     uint32_t rDCOER_CONSTK_RSEL5;  } SysCtl_CSCalTLV_Info;  //***************************************************************************** // // Prototypes for the APIs. // //*****************************************************************************  //***************************************************************************** // //! Gets the size of the SRAM. //! //! \return The total number of bytes of SRAM. // //***************************************************************************** extern uint_least32_t SysCtl_getSRAMSize(void);  //***************************************************************************** // //! Gets the size of the flash. //! //! \return The total number of bytes of flash. // //***************************************************************************** extern uint_least32_t SysCtl_getFlashSize(void);  //***************************************************************************** // //! Reboots the device and causes the device to re-initialize itself. //! //! \return This function does not return. // //***************************************************************************** extern void SysCtl_rebootDevice(void);  //***************************************************************************** // //! The TLV structure uses a tag or base address to identify segments of the //! table where information is stored. Some examples of TLV tags are Peripheral //! Descriptor, Interrupts, Info Block and Die Record. This function retrieves //! the value of a tag and the length of the tag. //! //! \param tag represents the tag for which the information needs to be //!        retrieved. //!        Valid values are: //!        - \b TLV_TAG_RESERVED1 //!        - \b TLV_TAG_RESERVED2 //!        - \b TLV_TAG_CS //!        - \b TLV_TAG_FLASHCTL //!        - \b TLV_TAG_ADC14 //!        - \b TLV_TAG_RESERVED6 //!        - \b TLV_TAG_RESERVED7 //!        - \b TLV_TAG_REF //!        - \b TLV_TAG_RESERVED9 //!        - \b TLV_TAG_RESERVED10 //!        - \b TLV_TAG_DEVINFO //!        - \b TLV_TAG_DIEREC //!        - \b TLV_TAG_RANDNUM //!        - \b TLV_TAG_RESERVED14 //! \param instance In some cases a specific tag may have more than one //!        instance. For example there may be multiple instances of timer //!        calibration data present under a single Timer Cal tag. This variable //!        specifies the instance for which information is to be retrieved (0, //!        1, etc.). When only one instance exists; 0 is passed. //! \param length Acts as a return through indirect reference. The function //!        retrieves the value of the TLV tag length. This value is pointed to //!        by *length and can be used by the application level once the //!        function is called. If the specified tag is not found then the //!        pointer is null 0. //! \param data_address acts as a return through indirect reference. Once the //!        function is called data_address points to the pointer that holds the //!        value retrieved from the specified TLV tag. If the specified tag is //!        not found then the pointer is null 0. //! //! \return None // //***************************************************************************** extern void SysCtl_getTLVInfo(uint_fast8_t tag, uint_fast8_t instance,         uint_fast8_t *length, uint32_t **data_address);  //***************************************************************************** // //! Enables a set of banks in the SRAM. This can be used to optimize power //! consumption when every SRAM bank isn't needed. It is important to note //! that when a  higher bank is enabled, all of the SRAM banks below that bank //! are also enabled. For example, if the user enables SYSCTL_SRAM_BANK7, //! the banks SYSCTL_SRAM_BANK1 through SYSCTL_SRAM_BANK7 will be enabled //! (SRAM_BANK0 is reserved and always enabled). //! //! \param sramBank The SRAM bank tier to enable. //!        Must be only one of the following values: //!                 - \b SYSCTL_SRAM_BANK1, //!                 - \b SYSCTL_SRAM_BANK2, //!                 - \b SYSCTL_SRAM_BANK3, //!                 - \b SYSCTL_SRAM_BANK4, //!                 - \b SYSCTL_SRAM_BANK5, //!                 - \b SYSCTL_SRAM_BANK6, //!                 - \b SYSCTL_SRAM_BANK7 //! //! \note \b SYSCTL_SRAM_BANK0 is reserved and always enabled. //! //! \return None. // //***************************************************************************** extern void SysCtl_enableSRAMBank(uint_fast8_t sramBank);  //***************************************************************************** // //! Disables a set of banks in the SRAM. This can be used to optimize power //! consumption when every SRAM bank isn't needed. It is important to note //! that when a  higher bank is disabled, all of the SRAM banks above that bank //! are also disabled. For example, if the user disables SYSCTL_SRAM_BANK5, //! the banks SYSCTL_SRAM_BANK6 through SYSCTL_SRAM_BANK7 will be disabled. //! //! \param sramBank The SRAM bank tier to disable. //!        Must be only one of the following values: //!                 - \b SYSCTL_SRAM_BANK1, //!                 - \b SYSCTL_SRAM_BANK2, //!                 - \b SYSCTL_SRAM_BANK3, //!                 - \b SYSCTL_SRAM_BANK4, //!                 - \b SYSCTL_SRAM_BANK5, //!                 - \b SYSCTL_SRAM_BANK6, //!                 - \b SYSCTL_SRAM_BANK7 //! //! \note \b SYSCTL_SRAM_BANK0 is reserved and always enabled. //! //! \return None. // //***************************************************************************** extern void SysCtl_disableSRAMBank(uint_fast8_t sramBank);  //***************************************************************************** // //! Enables retention of the specified SRAM bank register when the device goes //! into LPM3 mode. When the system is placed in LPM3 mode, the SRAM //! banks specified with this function will be placed into retention mode. By //! default, retention of every SRAM bank except SYSCTL_SRAM_BANK0 (reserved) is //! disabled. Retention of individual banks can be set without the restrictions //! of the enable/disable functions. //! //! \param sramBank The SRAM banks to enable retention //!        Can be a bitwise OR of the following values: //!                 - \b SYSCTL_SRAM_BANK1, //!                 - \b SYSCTL_SRAM_BANK2, //!                 - \b SYSCTL_SRAM_BANK3, //!                 - \b SYSCTL_SRAM_BANK4, //!                 - \b SYSCTL_SRAM_BANK5, //!                 - \b SYSCTL_SRAM_BANK6, //!                 - \b SYSCTL_SRAM_BANK7 //! \note  \b SYSCTL_SRAM_BANK0 is reserved and retention is always enabled. //! //! //! \return None. // //***************************************************************************** extern void SysCtl_enableSRAMBankRetention(uint_fast8_t sramBank);  //***************************************************************************** // //! Disables retention of the specified SRAM bank register when the device goes //! into LPM3 mode. When the system is placed in LPM3 mode, the SRAM //! banks specified with this function will not be placed into retention mode. //! By default, retention of every SRAM bank except SYSCTL_SRAM_BANK0 (reserved) //! is disabled. Retention of individual banks can be set without the //! restrictions of the enable/disable SRAM bank functions. //! //! \param sramBank The SRAM banks to disable retention //!        Can be a bitwise OR of the following values: //!                 - \b SYSCTL_SRAM_BANK1, //!                 - \b SYSCTL_SRAM_BANK2, //!                 - \b SYSCTL_SRAM_BANK3, //!                 - \b SYSCTL_SRAM_BANK4, //!                 - \b SYSCTL_SRAM_BANK5, //!                 - \b SYSCTL_SRAM_BANK6, //!                 - \b SYSCTL_SRAM_BANK7 //! \note  \b SYSCTL_SRAM_BANK0 is reserved and retention is always enabled. //! //! \return None. // // //***************************************************************************** extern void SysCtl_disableSRAMBankRetention(uint_fast8_t sramBank);  //***************************************************************************** // //! Makes it so that the provided peripherals will either halt execution after //! a CPU HALT. Parameters in this function can be combined to account for //! multiple peripherals. By default, all peripherals keep running after a //! CPU HALT. //! //! \param devices The peripherals to continue running after a CPU HALT //!         This can be a bitwise OR of the following values: //!                 - \b SYSCTL_PERIPH_DMA, //!                 - \b SYSCTL_PERIPH_WDT, //!                 - \b SYSCTL_PERIPH_ADC, //!                 - \b SYSCTL_PERIPH_EUSCIB3, //!                 - \b SYSCTL_PERIPH_EUSCIB2, //!                 - \b SYSCTL_PERIPH_EUSCIB1 //!                 - \b SYSCTL_PERIPH_EUSCIB0, //!                 - \b SYSCTL_PERIPH_EUSCIA3, //!                 - \b SYSCTL_PERIPH_EUSCIA2 //!                 - \b SYSCTL_PERIPH_EUSCIA1, //!                 - \b SYSCTL_PERIPH_EUSCIA0, //!                 - \b SYSCTL_PERIPH_TIMER32_0_MODULE, //!                 - \b SYSCTL_PERIPH_TIMER16_3, //!                 - \b SYSCTL_PERIPH_TIMER16_2, //!                 - \b SYSCTL_PERIPH_TIMER16_1, //!                 - \b SYSCTL_PERIPH_TIMER16_0 //! //! \return None. // // //***************************************************************************** extern void SysCtl_enablePeripheralAtCPUHalt(uint_fast16_t devices);  //***************************************************************************** // //! Makes it so that the provided peripherals will either halt execution after //! a CPU HALT. Parameters in this function can be combined to account for //! multiple peripherals. By default, all peripherals keep running after a //! CPU HALT. //! //! \param devices The peripherals to disable after a CPU HALT //! //! The \e devices parameter can be a bitwise OR of the following values: //!         This can be a bitwise OR of the following values: //!                 - \b SYSCTL_PERIPH_DMA, //!                 - \b SYSCTL_PERIPH_WDT, //!                 - \b SYSCTL_PERIPH_ADC, //!                 - \b SYSCTL_PERIPH_EUSCIB3, //!                 - \b SYSCTL_PERIPH_EUSCIB2, //!                 - \b SYSCTL_PERIPH_EUSCIB1 //!                 - \b SYSCTL_PERIPH_EUSCIB0, //!                 - \b SYSCTL_PERIPH_EUSCIA3, //!                 - \b SYSCTL_PERIPH_EUSCIA2 //!                 - \b SYSCTL_PERIPH_EUSCIA1, //!                 - \b SYSCTL_PERIPH_EUSCIA0, //!                 - \b SYSCTL_PERIPH_TIMER32_0_MODULE, //!                 - \b SYSCTL_PERIPH_TIMER16_3, //!                 - \b SYSCTL_PERIPH_TIMER16_2, //!                 - \b SYSCTL_PERIPH_TIMER16_1, //!                 - \b SYSCTL_PERIPH_TIMER16_0 //! //! \return None. // // //***************************************************************************** extern void SysCtl_disablePeripheralAtCPUHalt(uint_fast16_t devices);  //***************************************************************************** // //! Sets the type of RESET that happens when a watchdog timeout occurs. //! //! \param resetType The type of reset to set //! //! The \e resetType parameter must be only one of the following values: //!         - \b SYSCTL_HARD_RESET, //!         - \b SYSCTL_SOFT_RESET //! //! \return None. // // //***************************************************************************** extern void SysCtl_setWDTTimeoutResetType(uint_fast8_t resetType);  //***************************************************************************** // //! Sets the type of RESET that happens when a watchdog password violation //! occurs. //! //! \param resetType The type of reset to set //! //! The \e resetType parameter must be only one of the following values: //!         - \b SYSCTL_HARD_RESET, //!         - \b SYSCTL_SOFT_RESET //! //! \return None. // // //***************************************************************************** extern void SysCtl_setWDTPasswordViolationResetType(uint_fast8_t resetType);  //***************************************************************************** // //! Disables NMIs for the provided modules. When disabled, a NMI flag will not //! occur when a fault condition comes from the corresponding modules. //! //! \param flags The NMI sources to disable //! Can be a bitwise OR of the following parameters: //!         - \b SYSCTL_NMIPIN_SRC, //!         - \b SYSCTL_PCM_SRC, //!         - \b SYSCTL_PSS_SRC, //!         - \b SYSCTL_CS_SRC //! // //***************************************************************************** extern void SysCtl_disableNMISource(uint_fast8_t flags);  //***************************************************************************** // //! Enables NMIs for the provided modules. When enabled, a NMI flag will //! occur when a fault condition comes from the corresponding modules. //! //! \param flags The NMI sources to enable //! Can be a bitwise OR of the following parameters: //!         - \b SYSCTL_NMIPIN_SRC, //!         - \b SYSCTL_PCM_SRC, //!         - \b SYSCTL_PSS_SRC, //!         - \b SYSCTL_CS_SRC //! // //***************************************************************************** extern void SysCtl_enableNMISource(uint_fast8_t flags);  //***************************************************************************** // //! Returns the current sources of NMIs that are enabled //! //! \return Bitwise OR of NMI flags that are enabled // //***************************************************************************** extern uint_fast8_t SysCtl_getNMISourceStatus(void);  //***************************************************************************** // //! Enables glitch suppression on the reset pin of the device. Refer to the //! device data sheet for specific information about glitch suppression //! //! \return None. // // //***************************************************************************** extern void SysCtl_enableGlitchFilter(void);  //***************************************************************************** // //! Disables glitch suppression on the reset pin of the device. Refer to the //! device data sheet for specific information about glitch suppression //! //! \return None. // // //***************************************************************************** extern void SysCtl_disableGlitchFilter(void);  //***************************************************************************** // //! Retrieves the calibration constant of the temperature sensor to be used //! in temperature calculation. //! //! \param refVoltage Reference voltage being used. //! //! The \e refVoltage parameter must be only one of the following values: //!         - \b SYSCTL_1_2V_REF //!         - \b SYSCTL_1_45V_REF //!         - \b SYSCTL_2_5V_REF //! //! \param temperature is the calibration temperature that the user wants to be //!     returned. //! //! The \e temperature parameter must be only one of the following values: //!         - \b SYSCTL_30_DEGREES_C //!         - \b SYSCTL_85_DEGREES_C //! //! \return None. // // //***************************************************************************** extern uint_fast16_t SysCtl_getTempCalibrationConstant(uint32_t refVoltage,         uint32_t temperature);  //***************************************************************************** // // Mark the end of the C bindings section for C++ compilers. // //***************************************************************************** #ifdef __cplusplus } #endif  //***************************************************************************** // // Close the Doxygen group. //! @} // //*****************************************************************************  #endif /* __MCU_HAS_SYSCTL__ */  #endif // __SYSCTL_H__ 

sysinit.c

/****************************************************/ //MSP432P401R //时钟配置 //Bilibili:m-RNA //E-mail:m-RNA@qq.com //创建日期:2021/8/11 /****************************************************/  #include "sysinit.h"  //High:48MHz  Low:32768Hz //MCLK=48MHz  SMCLK=48MHz void SysInit(void) {     WDTCTL = WDTPW | WDTHOLD; // 停用看门狗      /* 第一步需要配置我们的时钟引脚,这里的高速时钟使用的是外部晶振*/     //低速时钟初始化比较慢     MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_PJ, GPIO_PIN3 | GPIO_PIN2, GPIO_PRIMARY_MODULE_FUNCTION); //High     MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_PJ, GPIO_PIN0 | GPIO_PIN1, GPIO_PRIMARY_MODULE_FUNCTION); //Low     CS_setExternalClockSourceFrequency(32768, 48000000);      /* Starting HFXT in non-bypass mode without a timeout. Before we start      * we have to change VCORE to 1 to support the 48MHz frequency */     MAP_PCM_setCoreVoltageLevel(PCM_VCORE1);      /* 更改闪存控制器使用的等待状态数用于读取操作。     当改变时钟的频率范围时,必须使用此函数以允许可读闪存     通俗来讲就是CPU跑太快了,Flash跟不上,让CPU等等它 */     MAP_FlashCtl_setWaitState(FLASH_BANK0, 1);     MAP_FlashCtl_setWaitState(FLASH_BANK1, 1);      CS_startHFXT(false);          //这是晶体 需要驱动     CS_startLFXT(CS_LFXT_DRIVE3); //驱动等级3      MAP_CS_initClockSignal(CS_MCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);  //48MHz   16分频时,滴答延时可达到最长     MAP_CS_initClockSignal(CS_SMCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_1); //48MHz }  

baudrate_calculate.h

/****************************************************/ // MSP432P401R // 串口波特率计算 // Bilibili:m-RNA // E-mail:m-RNA@qq.com /****************************************************/  /******************************    说明    ******************************  *  * 源码为TI官方编写,本人只是将JS程序移植到了C语言平台,仅作为学习使用。源码出处为:  * http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSP430BaudRateConverter/index.html  *   * ? 已知问题:  * 调试时发现某些情况下,C语言的小数的大小与JS的相差较大,  * 导致了算出的UCSx(即secondModReg)不一样,  * 这时如果出现不能准确传输时,请换一个波特率。  *  * ? 需要注意:  * 波特率不能大于时钟频率,否则会退出函数  *   * *****************************   版本说明   ******************************  *   * ? v1.2 2021/8/29  * 注释掉了闪烁灯的代码  *   * ? v1.1  2021/8/27  * 添加支持固件库v3_21_00_05   *   * ? v1.0  2021/8/25  * 仅支持固件库v3_40_01_02  *   * *******************************   结束    *******************************/    #ifndef __RNA_BAUDRATE_CALCULATE_H #define __RNA_BAUDRATE_CALCULATE_H #include "driverlib.h"  //错误指示灯宏定义 方便移植使用 //MSP432P401R 有两个红灯P1.0 P2.0 //#define WARN_LED_1_PORT GPIO_PORT_P1 //#define WARN_LED_2_PORT GPIO_PORT_P2 //#define WARN_LED_1_PIN GPIO_PIN0 //#define WARN_LED_2_PIN GPIO_PIN0 //#define WARN_LED_INIT MAP_GPIO_setAsOutputPin //#define WARN_LED_ON MAP_GPIO_setOutputHighOnPin //#define WARN_LED_OFF MAP_GPIO_setOutputLowOnPin  #ifdef EUSCI_A_UART_7_BIT_LEN void eusci_calcBaudDividers(eUSCI_UART_ConfigV1 *uart_config, uint32_t baudRate); //固件库v3_40_01_02 #else void eusci_calcBaudDividers(eUSCI_UART_Config *uart_config, uint32_t baudRate); //固件库v3_21_00_05 #endif  #endif  

baudrate_calculate.c

/****************************************************/ // MSP432P401R // 串口波特率计算 // Bilibili:m-RNA // E-mail:m-RNA@qq.com /****************************************************/  /******************************    说明    ******************************  *  * 源码为TI官方编写,本人只是将JS程序移植到了C语言平台,仅作为学习使用。源码出处为:  * http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSP430BaudRateConverter/index.html  *  * ? 已知问题:  * 调试时发现某些情况下,C语言的小数的大小与JS的相差较大,  * 导致了算出的UCSx(即secondModReg)不一样,  * 这时如果出现不能准确传输时,请换一个波特率。  *  * ? 需要注意:  * 波特率不能大于时钟频率,否则会退出函数  *  * *****************************   版本说明   ******************************  *  * ? v1.2 2021/8/29  * 注释掉了闪烁灯的代码  *   * ? v1.1  2021/8/27  * 添加支持固件库v3_21_00_05  *  * ? v1.0  2021/8/25  * 仅支持固件库v3_40_01_02  *  * *******************************   结束    *******************************/  #include "baudrate_calculate.h"  //void uart_warning_led(void);  /*  *  ======== bitPosition ========  *  return 1(0) if the specified bit position in value is set(clear)  */ bool bitPosition(uint16_t value, uint16_t position) {     if ((value & (1 << position)))         return 1;     return 0; }  /*  *  ======== eusci_calcBaudDividers ========  *  computes the eUSCI_UART register settings for a given clock and baud rate  *  *      UCOS16:      the oversampling bit (0 or 1)  *      UCBRx:       the Baud Rate Control Word  *      UCFx:        the First modulation stage select (UCBRFx)  *      UCSx:        the Second modulation stage select (UCBRSx)  *      maxAbsError: the maximum TX error for the register setting above  *  *  The first four field names match the names used in Table 18-5,  *  "Recommended Settings for Typical Crystals and Baudrates", of the  *  MSP430FR57xx Family User's Guide (SLAU272A).  */ #ifdef EUSCI_A_UART_7_BIT_LEN void eusci_calcBaudDividers(eUSCI_UART_ConfigV1 *uart_config, uint32_t baudRate) //固件库v3_40_01_02 #else void eusci_calcBaudDividers(eUSCI_UART_Config *uart_config, uint32_t baudRate) //固件库v3_21_00_05 #endif {     float maxAbsErrorInByte;     float minAbsError;     float error;     uint8_t ii;     uint16_t jj;     uint16_t NN;     uint32_t count;     uint32_t clockRate;      if (!uart_config || !baudRate) //传参错误 退出函数     {         //uart_warning_led(); //闪烁错误指示灯10次         return;     }      if (uart_config->selectClockSource == EUSCI_A_UART_CLOCKSOURCE_SMCLK)         clockRate = MAP_CS_getSMCLK();     else if (uart_config->selectClockSource == EUSCI_A_UART_CLOCKSOURCE_ACLK)         clockRate = MAP_CS_getACLK();     else     {         uart_config->selectClockSource = EUSCI_A_UART_CLOCKSOURCE_SMCLK;         clockRate = MAP_CS_getSMCLK();     }     if (baudRate > clockRate) //判断波特率是否大于时钟频率 是则退出函数     {         //uart_warning_led(); //闪烁错误指示灯10次         return;     }     //var result = {UCOS16 : 0, UCBRx : 0, UCFx : 0, UCSx : 0, maxAbsError : 0};      NN = (uint16_t)((float)clockRate / (float)baudRate); //应该是不需要floor      minAbsError = 100000;     for (jj = 0; jj <= 255; jj++)     {          maxAbsErrorInByte = 0;         count = 0;         for (ii = 0; ii <= 10; ii++)         {             count += NN + bitPosition(jj, 7 - (ii % 8));              //error = (ii + 1) * baudPeriod - count * clockPeriod;             error = (ii + 1) / (float)baudRate - count / (float)clockRate; //为了减少变量,改为此代码              if (error < 0)                 error = -error;              if (error > maxAbsErrorInByte)                 maxAbsErrorInByte = error;         }         if (maxAbsErrorInByte - minAbsError < -7.3e-12f) //这里就是“已知问题”         {             minAbsError = maxAbsErrorInByte;             uart_config->secondModReg = jj;         }     }      if (NN < 20)     {         uart_config->overSampling = 0;         uart_config->clockPrescalar = NN;         uart_config->firstModReg = 0;     }     else     {         uart_config->overSampling = 1;         uart_config->clockPrescalar = (uint16_t)((float)NN / 16.0f); //应该是不需要floor         uart_config->firstModReg = NN - (uart_config->clockPrescalar * 16);     }     //return minAbsError * baudRate * 100; }  闪烁错误指示灯10次 //void uart_warning_led(void) //{ //    uint8_t ii; //    uint32_t jj; //    WARN_LED_INIT(WARN_LED_1_PORT, WARN_LED_1_PIN); //    WARN_LED_INIT(WARN_LED_2_PORT, WARN_LED_2_PIN); //    for (ii = 0; ii < 10; ii++) //    { //        WARN_LED_ON(WARN_LED_1_PORT, WARN_LED_1_PIN); //        WARN_LED_OFF(WARN_LED_2_PORT, WARN_LED_2_PIN); //        for (jj = 0; jj < 100000; jj++) //            ; //        WARN_LED_OFF(WARN_LED_1_PORT, WARN_LED_1_PIN); //        WARN_LED_ON(WARN_LED_2_PORT, WARN_LED_2_PIN); //        for (jj = 0; jj < 100000; jj++) //            ; //    } //} 

main.c

#include "driverlib.h"  /* Standard Includes */ #include <stdint.h> #include <stdbool.h>  #include "sysinit.h" #include "usart.h" #include "baudrate_calculate.h"  int main(void) { 	SysInit();		 //1.配置时钟 	uart_init(115200); //包含了2.配置GPIO复用   3.初始化串口   4.开启串口模块 	 	printf("MSP432\r\n"); 	printf("2021/8/24\r\n\r\n");  	char c = '!'; 	char *s = "printf test"; 	int i = -12345; 	unsigned u = 4321; 	long int l = -123456780; 	unsigned long n = 1098765432; 	unsigned x = 0x89AB;  	printf("Char           %c\r\n", c); 	printf("String         %s\r\n", s); 	printf("Integer        %d\r\n", i); 	printf("Unsigned       %u\r\n", u); 	printf("Long           %d\r\n", l); 	printf("Unsigned long  %u\r\n", n); 	printf("HEX            %X\r\n", x);  	while (1) 	{ //		 使用微库则可支持 scanf //		 char a[100]; //		 scanf("%s", a); //		 printf("%s\r\n", a); 	} }  

注意:未知原因scanf用不了,勾选了微库也无法解决

五、定时器A中断

(一)MSP432P401R定时器A资源

MSP432P401R共有4个定时器A,每一个定时器A共有5个通道

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rHAWOoWn-1690345264993)(D:\Typora\图片\image-20230705150356304.png)]

Timer_A的特性包括

  • 具有4种操作模式的异步16位定时/计数器;
  • 可选择和可配置的时钟源;
  • 最多达7个可配置的捕获/比较模块;
  • 具有PWM 功能的可配置输出;
  • 异步输入和输出锁存。

详见技术手册第783页

(二)计数模式

  • 连续计数模式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vk2F64ZP-1690345264994)(D:\Typora\图片\image-20230705152737087.png)]

从0开始计数,直到计数到216(65535),然后又从0计数,不断循环,可用于定时器捕获

  • 增计数模式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-54uIKhSp-1690345264994)(D:\Typora\图片\image-20230705152852465.png)]

需要设置CCR0比较值寄存器0,CCR0确定定时器周期,可以将CCR0理解为STM32的ARR自动重装载值,定时器中断周期的计算公式也是通用的:Ttimer_a= C l k D i v × ( C C R 0 + 1 ) f   c l k   \quad {ClkDiv×(CCR0+1)\over f~clk~} f clk ClkDiv×(CCR0+1)【时钟分频乘以计数值(CCR0+1)的和除以时钟频率】

==ClkDiv ∈ [1, 8] ∪ {10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 64 };==这里与STM32不同,是固定的

  • 增减计数模式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mbgfEyFo-1690345264994)(D:\Typora\图片\image-20230705152949119.png)]

从0开始计数到CCR0递减为0

(三)库函数

1.初始化定时器模块

Timer_A_configureUpMode(TIMER_Ax_BASE, &upConfig); 

2.选择模式开始计数

Timer_A_startCounter(TIMER_Ax_BASE, TIMER_A_UP_MODE); 

3.清除比较中断标志位

Timer_A_clearCaptureCompareInterrupt(TIMER_Ax, REGISTER_0); 

4.开启定时器A端口中断

Interrupt_enableInterrupt(INT_TAx_0); 

5.开启总中断

Interrupt_enableMaster(void); 

(四)定时器中断的一般配置

  1. 配置时钟
  2. 配置结构体
  3. 初始化定时器A
  4. 选择模式开始计数
  5. 清除比较中断标志位
  6. 开启定时器端口中断
  7. 开启总中断
  8. 编写TIMA ISR

(五)TIMER_A0定时0.5秒闪灯

timA.h

#ifndef __RNA_TIMA_H #define __RNA_TIMA_H #include <ti/devices/msp432p4xx/driverlib/driverlib.h>  void TimA0_Int_Init(uint16_t ccr0, uint16_t psc);  #endif 

timA.c

#include "timA.h"  void TimA0_Int_Init(uint16_t ccr0, uint16_t psc) {     // 1.增计数模式初始化     Timer_A_UpModeConfig upConfig;     upConfig.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;                                      //时钟源     upConfig.clockSourceDivider = psc;                                                     //时钟分频 范围1-64     upConfig.timerPeriod = ccr0;                                                           //自动重装载值(ARR)     upConfig.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE;                   //禁用 tim溢出中断     upConfig.captureCompareInterruptEnable_CCR0_CCIE = TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE; //启用 ccr0更新中断     upConfig.timerClear = TIMER_A_DO_CLEAR;                                                // Clear value      // 2.初始化定时器A     MAP_Timer_A_configureUpMode(TIMER_A0_BASE, &upConfig);      // 3.选择模式开始计数     MAP_Timer_A_startCounter(TIMER_A0_BASE, TIMER_A_UP_MODE);      // 4.清除比较中断标志位     MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_0);      // 5.开启串口端口中断     MAP_Interrupt_enableInterrupt(INT_TA0_0); }  // 6.编写TIMA ISR void TA0_0_IRQHandler(void) {     MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_0);      /*开始填充用户代码*/      MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);      /*结束填充用户代码*/ } /*********************************************************************************************************/  

main.c

#include "sysinit.h" #include "usart.h" #include "timA.h" #include "usart.h" #include "led.h"  #define CLKDIV 64   //时钟源分频 #define CCR0 37499  // 比较值0  /*  * 定时器中断周期:  *  * T_timer_a = CLKDIV * (CCR0 + 1) / f_clk   *           = 64 * 37500 / 48000000   *           = 0.05s = 20Hz  */   int main(void) {     SysInit();  			     // 第3讲 时钟配置 	LED_Init();					 // 第2讲 GPIO输出 	TimA0_Int_Init(CCR0,CLKDIV); // 第8讲 TIMA中断          MAP_Interrupt_enableMaster(); // 开启总中断     while (1)     {     } } 

六、定时器A PWM模式

(一)计数模式

  • 增计数模式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ntdCf3QU-1690345264994)(D:\Typora\图片\image-20230705152852465.png)]

需要设置CCR0比较值寄存器0,CCR0确定定时器周期,可以将CCR0理解为STM32的ARR自动重装载值,定时器中断周期的计算公式也是通用的:Ttimer_a= C l k D i v × ( C C R 0 + 1 ) f   c l k   \quad {ClkDiv×(CCR0+1)\over f~clk~} f clk ClkDiv×(CCR0+1)【时钟分频乘以计数值(CCR0+1)的和除以时钟频率】

==ClkDiv ∈ [1, 8] ∪ {10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 64 };==这里与STM32不同,是固定的

  • 增减计数模式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HARZl8qg-1690345264995)(D:\Typora\图片\image-20230705152949119.png)]

从0开始计数到CCR0递减为0

(二)输出模式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LshlM5Dw-1690345264995)(D:\Typora\图片\image-20230705212358007.png)]

​ 增计数模式 增减计数模式

定时器A有7种输出模式,但常用的只有两种

  • Output Mode 2:Toggle/Reset

    当计时器计数到TAxCCRn值时,输出切换。当计时器计数到TAxCCR0值时,它被重置

  • Output Mode 6:Toggle/Set

    当计时器计数到TAxCCRn值时,输出切换。当计时器计数到TAxCCR0值时设置

详见msp432p401r第791页

1.增计数模式:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BBU0QtDf-1690345264995)(D:\Typora\图片\image-20230705212755577.png)]

定时器A从0计数到比较值1(CCR1)时,模式6输出高电平,之后比较值1计数到比较值0(CCR0)时,输出为低电平

比较值0是确定了整个定时器的周期

当选择输出模式2时,可以看到输出是相反的。

2.增减计数模式:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yfjr1MLN-1690345264996)(D:\Typora\图片\image-20230705213922999.png)]

模式2和模式6配合后能生成带死区的互补PWM

一个定时器A能生成2路的带死区的互补PWM

(三)定时器A输出通道资源

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cg0ljXQt-1690345264996)(D:\Typora\图片\image-20230705214540751.png)]

带有PM是支持端口重映射的意思

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KtpaNgDP-1690345264996)(D:\Typora\图片\image-20230705214714199.png)]

(四)库函数

  • 初始化定时器为PWM模式
Timer_A_generatePWM(TIMER_Ax_BASE, &TimAx_PWMConfig); 
  • 改变比较值(占空比/周期)
Timer_A_setCompareValue(TIMER_Ax, COMPARE_REGISTER_x, CCR); 

(五)一般配置步骤

  1. 配置时钟
  2. 配置GPIO复用
  3. 配置结构体
  4. 初始化定时器

(六)PWM驱动舵机

timA.h

#ifndef __RNA_TIMA_H #define __RNA_TIMA_H #include <ti/devices/msp432p4xx/driverlib/driverlib.h>  void TimA1_PWM_Init(uint16_t ccr0, uint16_t psc);   #endif 

timA.c

#include "timA.h"  void TimA1_PWM_Init(uint16_t ccr0, uint16_t psc) {     /*初始化引脚*/     MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P7, GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION);      Timer_A_PWMConfig TimA1_PWMConfig;     /*定时器PWM初始化*/     TimA1_PWMConfig.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;             //时钟源     TimA1_PWMConfig.clockSourceDivider = psc;                            //时钟分频 范围1-64     TimA1_PWMConfig.timerPeriod = ccr0;                                  //自动重装载值(ARR)     TimA1_PWMConfig.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_1; //通道一 (引脚定义)     TimA1_PWMConfig.compareOutputMode = TIMER_A_OUTPUTMODE_TOGGLE_SET;   //输出模式     TimA1_PWMConfig.dutyCycle = ccr0;                                    //这里是改变占空比的地方 默认100%      MAP_Timer_A_generatePWM(TIMER_A1_BASE, &TimA1_PWMConfig); /* 初始化比较寄存器以产生 PWM1 */ } 

main.c

#include "sysinit.h" #include "usart.h" #include "delay.h" #include "timA.h"  /*  * 定时器PWM周期:  *`     * T_timer_a = CLKDIV * (CCR0 + 1) / f_clk  *           = 48 * (19999 + 1) / 48000000  *           = 0.02s = 50Hz  */  #define CLKDIV 48     // 时钟源分频 #define CCR0 19999    // 比较值0 #define CCR1_MIN 499  // ( 499 + 1) / (19999 + 1) =  500 / 20000 =  2.5% #define CCR1_MAX 2499 // (2499 + 1) / (19999 + 1) = 2500 / 20000 = 12.5%  int main(void) {     bool dir = 1;     uint16_t i = CCR1_MIN;      SysInit();    //第3讲 时钟配置     delay_init(); //第4讲 滴答延时 	     TimA1_PWM_Init(CCR0, CLKDIV); //第8讲 定时器A PWM     while (1)     {         if (dir)             i++;         else             i--;          if (i == CCR1_MAX)         {             dir = 0;             delay_ms(50);         }         else if (i == CCR1_MIN)         {             dir = 1;             delay_ms(50);         }         MAP_Timer_A_setCompareValue(TIMER_A1_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_1, i);         delay_us(600);     } }  

七、定时器32

(一)定时器32介绍

Timer32的主要特性包括:

  • 两个独立的计数器,每个都可配置成32位递减或16位计数器;
  • 每个计数器具有3种不同的定时器模式;
  • 每个计数器都可独立产生中断,而且两个计数器可生成一个组合中断。
  • 输入时钟可预分频为1、1/16或1/256;(MCLK)

中断向量:

  • INT_T32_INT1(定时器32_0)
  • INT_T32_INT2(定时器32_1)
  • INT_T32_INTC (Combine 结合)

定时器时钟使能由分频单元产生,并使能由计数器创建的具有下列条件之一的定时时钟:

  • MCLK #define TIMER32_PRESCALER_1 0x00

  • 由4位预分频产生的16分频MCLK #define TIMER32_PRESCALER_16 0x04

  • 由总共8位预分频产生的256分频MCLK #define TIMER32_PRESCALER_256 0x08

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sl5XiQQ6-1690345264996)(D:\Typora\图片\image-20230706151006407.png)]

详见技术手册第756、766页

(二)Timer32的计数模式

  • 自由运行模式: 计数器在递减到0后,继续从最大值递减。这是默认模式
  • 周期定时器模式:需要设置ARR(自动重装载值),ARR确定定时器32的周期,然后计数器以恒定的间隔生成一个中断,在递减到0后重新加载原始值(ARR)。常用
  • 单次定时器模式:计数器产生一次中断。当计数器达到零时,它会停止,直到被用户重新编程。

定时器周期计算:

Ttimer_a= C l k D i v × ( A R R + 1 ) f   c l k   \quad {ClkDiv×(ARR+1)\over f~clk~} f clk ClkDiv×(ARR+1)【时钟分频乘以计数值(CCR0+1)的和除以时钟频率】

ClkDiv ∈ {1, 16, 256 };

例 1s= 1 (不分频) × ( A R R + 1 ) 48000000 \quad {1(不分频)×(ARR+1)\over 48000000} 480000001(不分频)×(ARR+1)

得出ARR+1=48000000

(三)库函数

  • 初始化定时器
 MAP_Timer32_initModule(TIMER32_0_BASE, psc, TIMER32_32BIT, TIMER32_PERIODIC_MODE); 
  • 设置ARR重装载值
MAP_Timer32_setCount(TIMER32_0_BASE, aar); 
  • 配置定时器32开始连续计数 false
MAP_Timer32_startTimer(TIMER32_0_BASE, false); //连续计数模式 false 
  • 清除中断标志位
MAP_Timer32_clearInterruptFlag(TIMER32_0_BASE); 
  • 使能定时器32中断
MAP_Timer32_enableInterrupt(TIMER32_0_BASE); 
  • 开启定时器32端口中断
MAP_Interrupt_enableInterrupt(INT_T32_INT1); 

(四)一般配置步骤

配置时钟

  • 初始化为32位周期计数模式
  • 设置ARR自动重装载值
  • 清除中断标志位
  • 使能定时器32中断
  • 配置定时器32开始连续计数
  • 开启定时器32端口中断
  • 开启总中断
  • 编写TIM32 ISR

(五)打印一个自增的数值

tim32.h

#ifndef __RNA_TIM32_H #define __RNA_TIM32_H #include <ti/devices/msp432p4xx/driverlib/driverlib.h>  void Tim32_0_Int_Init(uint32_t aar, uint8_t psc);  #endif 

tim32.c

#include "tim32.h" #include "usart.h"  void Tim32_0_Int_Init(uint32_t aar, uint8_t psc) {     MAP_Timer32_initModule(TIMER32_0_BASE, psc, TIMER32_32BIT, TIMER32_PERIODIC_MODE);      MAP_Timer32_setCount(TIMER32_0_BASE, aar);      MAP_Timer32_enableInterrupt(TIMER32_0_BASE);      MAP_Timer32_startTimer(TIMER32_0_BASE, false); //连续计数模式 false      MAP_Interrupt_enableInterrupt(INT_T32_INT1); }  /* Timer32 ISR */ void T32_INT1_IRQHandler(void) {     MAP_Timer32_clearInterruptFlag(TIMER32_0_BASE);      /*开始填充用户代码*/     static uint8_t timer_second = 0;      //一般在频率较高的中断不常用 这个printf比较费时间 这里只是演示     printf("%d秒过去了\r\n\r\n", ++timer_second);      /*结束填充用户代码*/ }  

main.c

#include "sysinit.h" #include "usart.h" #include "led.h" #include "tim32.h"  /*  * 定时器中断周期:  *  * T_timer_32 = CLKDIV * (ARR + 1) / f_clk   *            = 1 * 48000000 / 48000000   *            = 1s = 1Hz  */  #define CLKDIV TIMER32_PRESCALER_1 // 时钟源分频 #define ARR 47999999               // 自动重装载值  int main(void) {     SysInit();                     // 第3讲 时钟配置     uart_init(115200);             // 第7讲 串口配置 	     Tim32_0_Int_Init(ARR, CLKDIV); // 第9讲 TIM32中断 	 	printf("砸瓦鲁多\r\n\r\n");      MAP_Interrupt_enableMaster(); // 开启总中断      while (1)     {     } } 

八、GPIO复用

(一)库函数

  • 配置GPIO模式:
GPIO_setAsPeripheralModuleFunctionInputPin(Port, Pin,mode);//复用输入 GPIO_setAsPeripheralModuleFunctionOutputPin(Port, Pin,mode);//复用输出 
  • mode参数有效值
GPIO_PRIMARY_MODULE_FUNCTION     //主功能 GPIO_SECONDARY_MODULE_FUNCTION   //第二功能 GPIO_TERTIARY_MODULE_FUNCTION    //第三功能 

功能详见msp432o401r第138页

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eKLnMSwk-1690345264997)(D:\Typora\图片\image-20230706170948920.png)]

看P1SEL1.x+P1SEL0.x:

  • 0 1:主功能
  • 1 0:第二功能
  • 1 1:第三功能

P1DIR.x:方向寄存器

1为输出

0为输入

x表示无需关心。例:使用串口时GPIO的输入输出是由模块接管的,所以配置为复用输入或复用输出都可

需要完整工程代码的点赞加关注,评论留下邮箱我发你

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!