目录:
1.MM32F0020简介
2.初始化MM32F0020 UART1和NVIC中断
3.编写MM32F0020 UART1使能中断发送函数
4.编写MM32F0020 UART1中断接收和中断发送函数
5.编写MM32F0020 UART1处理中断接收和UART1使能中断发送函数
6.MM32F0020 UART1中断发送UART1中断接收到的数据到上位机串口助手
提要:
学习MM32F0020 UART1中断接收和UART1中断发送数据,通过上位机串口助手发送8字节的十六进制数据:0xAA,0x01,0x02,0x03,0x04,0x05,0x06,0x55;下位机MM32F0020的UART1中断接收到一帧:0xAA,0x01,0x02,0x03,0x04,0x05,0x06,0x55 共8字节数据后,通过UART1中断发送函数,把UART1中断接收到的数据原样发送到串口助手显示出来。
内容:
1、MM32F0020简介:
(1)MM32F0020微控制器是基于Arm® Cortex®-M0内核,最高工作频率可达48MHz;
(2)供电电压支持:2.0V - 5.5V;
(3)多达32KB的Flash,2KB的SRAM;
(4)1个I2C;
(5)2个UART;
(6)1个12位的共8通道的ADC;
(7)1个I2C或I2S;
(8)1个16位高级定时,1个16位通用定时器,1个16位基本定时器;
(9)1个IWDG和一个WWDG看门狗。
2.初始化MM32F0020 UART1和NVIC中断:
MM32F0020 UART1的GPIO初始化,根据MM32F0020的DS数据手册选择PA12:UART1_TX,PA3:UART1_RX做为UART1的发送和接收数据的引脚,具体配置步骤,及其初始化如下所示:
(1)使能GPIOA外设时钟;
(2)配置IO管脚GPIO_AFx复用为UART1功能;
(3)配置UARTx IO的管脚;
(4)配置GPIO的输出速度;
(5)配置IO管脚的工作模式;
(6)根据GPIOA配置的参数整体初始化GPIO各管脚的成员参数。
void Bsp_UART1_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE); //UART initialset GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_1); GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_1); //UART1_TX GPIOA.12 GPIO_StructInit(&GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStruct); //UART1_RX GPIOA.3 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOA, &GPIO_InitStruct); }
MM32F0020 UART1和NVIC中断优先级初始化,具体配置步骤,及其初始化如下所示:
(1)使能UART1外设时钟;
(2)调用之前配置的UART1GPIO初始化函数;
(3)调配置UART1通信波特率为115200;
(4)配置UART1字长为8位;
(5)配置UART1收发数据为1位停止位;
(6)配置UART1收发数据为无奇偶校验位;
(7)配置UART1允许串口收发数据;
(8)根据以上配置参数初始化UART1结构体成员;
(9)使能UART1中断接收功能;
(10)配置UART1的NVIC中断优先级为0,并使能和初始化NVIC中断(优先级为0-3均可,参数越小优先级越高)。
根据以上配置参数,初始化UART1并使能UART1,则UART1初始化代码如下所示:
void Bsp_UART1_NVIC_Init(u32 baudrate) { UART_InitTypeDef UART_InitStruct; NVIC_InitTypeDef NVIC_InitStruct; RCC_APB1PeriphClockCmd(RCC_APB1ENR_UART1, ENABLE); Bsp_UART1_GPIO_Init(); UART_StructInit(&UART_InitStruct); UART_InitStruct.BaudRate = baudrate; //The word length is in 8-bit data format. UART_InitStruct.WordLength = UART_WordLength_8b; UART_InitStruct.StopBits = UART_StopBits_1; //No even check bit. UART_InitStruct.Parity = UART_Parity_No; //No hardware data flow control. UART_InitStruct.HWFlowControl = UART_HWFlowControl_None; UART_InitStruct.Mode = UART_Mode_Rx | UART_Mode_Tx; UART_Init(UART1, &UART_InitStruct); UART_ITConfig( UART1,UART_IT_RXIEN, ENABLE); //UART1 NVIC NVIC_InitStruct.NVIC_IRQChannel = UART1_IRQn; //UART1 Priority NVIC_InitStruct.NVIC_IRQChannelPriority = 0; //Enable UART1_IRQn NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(& NVIC_InitStruct); UART_Cmd(UART1, ENABLE); }
3.编写MM32F0020 UART1使能中断发送函数
(1)定义与UART1中断发送相关的缓存、变量,代码如下所示:
//UART1 Tx Buffer u8 gUART1_Tx_Buf[UART1_TXD_LEN] = {0x00}; //UART1 Tx Lenth u8 gUART1_Tx_Lenth = 0; //UART1 Tx Count u8 gUART1_Tx_Real_Cnt = 0; //UART1 Tx OK Flag u8 gUART1_Tx_OK_Flag = 0;
(2)根据以上步骤(1)中定义,编写MM32F0020 UART1使能中断发送函数,代码如下所示:
void Bsp_UART1_Interrupt_Send_Data(UART_TypeDef* Uart, u8 *pBuf,u8 data_lenth) { gUART1_Tx_Real_Cnt = 0; gUART1_Tx_Lenth = data_lenth; memcpy(gUART1_Tx_Buf,pBuf,data_lenth); //Enable UART Interrupt send UART_ITConfig(Uart, UART_IT_TXIEN, ENABLE ); }
4.编写MM32F0020 UART1中断接收和中断发送函数:
MM32F0020 UART1中断接收和中断发送函数代码如下所示,当UART1中断发送完数据后需失能中断发送,当UART1中断发送数据时再次使能中断发送即可。
void UART1_IRQHandler(void) { u8 Recv; //Check receive status if(UART_GetITStatus(UART1, UART_IT_RXIEN) == SET) { UART_ClearITPendingBit(UART1, UART_IT_RXIEN); Recv = UART_ReceiveData(UART1); gUART1_Rx_Buf[gUART1_Rx_Cnt] = Recv; if(gUART1_Rx_Cnt < UART1_RXD_LEN-1) { gUART1_Rx_Cnt++; } else { gUART1_Rx_Cnt = 0; } if(gUART1_Rx_Cnt >= 8) { gUART1_Rx_Flag = true; } } if(UART_GetITStatus(UART1, UART_IT_TXIEN) != RESET) { UART_ClearITPendingBit(UART1, UART_IT_TXIEN); if(gUART1_Tx_Real_Cnt < gUART1_Tx_Lenth) { UART_SendData(UART1,(u8)gUART1_Tx_Buf[gUART1_Tx_Real_Cnt]); gUART1_Tx_Real_Cnt++; } else { UART_ITConfig(UART1, UART_IT_TXIEN,DISABLE); gUART1_Tx_OK_Flag = 1; } } }
5.编写MM32F0020 UART1处理中断接收和UART1使能中断发送函数:
MM32F0020 UART1处理中断接收和使能中断发送数据函数如下所示,当上位机串口助手发送8字节的十六进制数据:0xAA,0x01,0x02,0x03,0x04,0x05,0x06,0x55;下位机MM32F0020的UART1中断接收到一帧:0xAA,0x01,0x02,0x03,0x04,0x05,0x06,0x55 共8字节数据后,通过UART1使能中断发送函数,原样发送UART1中断接收到的数据到串口助手,代码如下所示:
void Bsp_UART1_Recv_Task(void) { //UART1 Rx Flag if(gUART1_Rx_Flag == true) { gUART1_Rx_Flag = false; if((gUART1_Rx_Buf[0] == 0xAA) && (gUART1_Rx_Buf[1] == 0x01) && (gUART1_Rx_Buf[2] == 0x02) && (gUART1_Rx_Buf[3] == 0x03) && \ (gUART1_Rx_Buf[4] == 0x04) && (gUART1_Rx_Buf[5] == 0x05) && (gUART1_Rx_Buf[6] == 0x06) && (gUART1_Rx_Buf[7] == 0x55)) { LED4_TOGGLE(); Bsp_UART1_Interrupt_Send_Data(UART1,gUART1_Rx_Buf,gUART1_Rx_Cnt); } gUART1_Rx_Cnt = 0; memset(gUART1_Rx_Buf,0,sizeof(gUART1_Rx_Buf)); } }
6.MM32F0020 UART1中断发送UART1中断接收到的数据到上位机串口助手:
当上位机串口助手发送8字节的十六进制数据:0xAA,0x01,0x02,0x03,0x04,0x05,0x06,0x55;下位机MM32F0020的UART1中断接收到一帧:0xAA,0x01,0x02,0x03,0x04,0x05,0x06,0x55 共8字节数据后,通过UART1使能中断发送函数,采用UART1中断发送函数原样发送UART1中断接收到的数据到串口助手显示。
(1)在main函数中调用UART1 NVIC初始化函数;
(2)在main函数的while(1)主循环中调用UART1处理中断接收到的数据函数,循环检测UART1的接收中断是否接收到上位机串口助手下发的数据,如有收到就调用UART1使能中断发送函数,原样发送UART1中断接收到的数据到上位机串口助手上显示出来,代码如下所示,串口助手发送和接收数据如下图1所示:
int main(void) { //UART1 NVIC Init Baudrate 115200 Bsp_UART1_NVIC_Init(UART1_BAUDRATE); while(1) { //Process UART1 Recv Task Bsp_UART1_Recv_Task(); } }
图1
总结:
学习MM32F0020 UART1中断接收和UART1中断发送数据,通过上位机串口助手发送8字节的十六进制数据:0xAA,0x01,0x02,0x03,0x04,0x05,0x06,0x55;下位机MM32F0020的UART1中断接收到一帧:0xAA,0x01,0x02,0x03,0x04,0x05,0x06,0x55 共8字节数据后,通过UART1中断发送函数,把UART1中断接收到的数据原样发送到串口助手显示出来。数据发送和接收的数据帧长度用户可根据实际应用自行编写应用逻辑。
注意事项:
(1)MM32F0020每个外设都有自己独立的时钟,需使能UART1 发送和接收引脚的GPIO时钟;
(2)使能UART1外设时钟;
(3)配置GPIOA的 PA12和PA3复用成UART1功能
(4)使能UART1接收中断;
(5)使能UART1 NVIC中断;
(6)使用UART1中断发送时,需使能UART1中断发送,数据发送完成需失能UART1中断发送,表示一帧数据发送完成,当UART1需再次中断发送数据时使能UART1中断发送即可。
(7)UART2的操作方法与UART1的方法一样,可参考以上UART1的中断接收和中断发送,把对应的UART1参数改成UART2,使能相应外设时钟和中断即可。