- void PLATFORM_Init(void)
- {
- PLATFORM_InitDelay();
- //PLATFORM_InitConsole(115200);
- PLATFORM_InitLED();
- //PLATFORM_PrintInfo();
- }
3、增加个uart_demo.c负责uart相关处理
1)USART初始化
使用USART1,TX:PB6,RX:PB7,
使用USART1的原因是USART1和板载调试器已相连,不用外接串口工具
USART1配置为双向收发
USART_IT_PE、USART_IT_ERR、USART_IT_IDLE、USART_IT_RXNE中断使能
USART_IT_IDLE使能用于实现接收不定长UART消息
- void USART_Configure(uint32_t Baudrate)
- {
- GPIO_InitTypeDef GPIO_InitStruct;
- NVIC_InitTypeDef NVIC_InitStruct;
- USART_InitTypeDef USART_InitStruct;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
- USART_StructInit(&USART_InitStruct);
- USART_InitStruct.USART_BaudRate = Baudrate;
- USART_InitStruct.USART_WordLength = USART_WordLength_8b;
- USART_InitStruct.USART_StopBits = USART_StopBits_1;
- USART_InitStruct.USART_Parity = USART_Parity_No;
- USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
- USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
- USART_Init(USART1, &USART_InitStruct);
-
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
- GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_0);
- GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_0);
- GPIO_StructInit(&GPIO_InitStruct);
- GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOB, &GPIO_InitStruct);
- GPIO_StructInit(&GPIO_InitStruct);
- GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7;
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_FLOATING;
- GPIO_Init(GPIOB, &GPIO_InitStruct);
- NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
- NVIC_InitStruct.NVIC_IRQChannelPriority = 0;
- NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStruct);
- USART_ITConfig(USART1, USART_IT_PE, DISABLE);
- USART_ITConfig(USART1, USART_IT_ERR, DISABLE);
-
- USART_ITConfig(USART1, USART_IT_CTS, DISABLE);
- USART_ITConfig(USART1, USART_IT_TC, DISABLE);
- USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);
- USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
-
- USART_Cmd(USART1, ENABLE);
- }
2)定义收发数据处理数据结构
typedef struct
{
uint8_t Buffer[255];//缓冲
uint8_t Length; //最大长度
uint8_t CurrentCount; //当前缓冲指针位置
uint8_t CompleteFlag; //完成标志
} USART_RxTx_TypeDef;
volatile USART_RxTx_TypeDef USART_RxStruct;
volatile USART_RxTx_TypeDef USART_TxStruct;
3)USART接收处理函数
函数中Length参数为要接收数据的长度,此函数对USART_RxStruct进行了初始化,然后通过
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);使能接收中断
- void USART_RxData_Interrupt(uint8_t Length)
- {
- uint8_t i = 0;
- for (i = 0; i < Length; i++)
- {
- USART_RxStruct.Buffer[i] = 0;
- }
- USART_RxStruct.Length = Length;
- USART_RxStruct.CurrentCount = 0;
- USART_RxStruct.CompleteFlag = 0;
- USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
- }
4)USART发送处理函数
Buffer发送数据指针,Length为发送数据长度
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);使能发送中断
- void USART_TxData_Interrupt(uint8_t *Buffer, uint8_t Length)
- {
- uint8_t i = 0;
- for (i = 0; i < Length; i++)
- {
- USART_TxStruct.Buffer[i] = Buffer[i];
- }
- USART_TxStruct.Length = Length;
- USART_TxStruct.CurrentCount = 0;
- USART_TxStruct.CompleteFlag = 0;
- USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
- }
4、中断处理函数(mm32f0120_it.c)
- void USART1_IRQHandler(void)
- {
- uint8_t RxData = 0;
-
- if ((RESET != USART_GetITStatus(USART1, USART_IT_PE)) ||
- (RESET != USART_GetITStatus(USART1, USART_IT_ERR)))
- {
- USART_ReceiveData(USART1);
- }
-
- if (RESET != USART_GetITStatus(USART1, USART_IT_RXNE))
- {
- RxData = USART_ReceiveData(USART1);
- if (0 == USART_RxStruct.CompleteFlag)
- {
-
- USART_RxStruct.Buffer[USART_RxStruct.CurrentCount++] = RxData;
- PLATFORM_LED_Toggle(LED2);
-
- }
-
- }
-
- if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)
- {
-
- // 检测到空闲中断,表示一帧数据接收完成
- USART_ReceiveData(USART1); // 读取数据寄存器清除中断
- USART_ClearITPendingBit(USART1, USART_IT_IDLE);
-
- // 处理接收到的完整消息
- // ...
- if(USART_RxStruct.CurrentCount>0){
- USART_ITConfig(USART1, USART_IT_IDLE, DISABLE);
- USART_RxStruct.CompleteFlag = 1;
- PLATFORM_LED_Toggle(LED1);
- USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
- }
- }
-
- if (RESET != USART_GetITStatus(USART1, USART_IT_TXE))
- {
- if (0 == USART_TxStruct.CompleteFlag)
- {
- USART_SendData(USART1, USART_TxStruct.Buffer[USART_TxStruct.CurrentCount++]);
- if (USART_TxStruct.CurrentCount == USART_TxStruct.Length)
- {
- USART_TxStruct.CompleteFlag = 1;
- USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
- }
- }
- }
- }
通过前面定义可知USART_IT_PE、USART_IT_ERR、USART_IT_IDLE、USART_IT_RXNE、USART_IT_TXE都会导致进入中断
1、USART_IT_PE (奇偶校验错误中断)、USART_IT_ERR (错误中断)
这两个中断主要处理一些错误情况。
2、USART_IT_RXNE处理接收数据,每接收一个字节,保存在缓冲的CurrentCount所指位置
3、USART_IT_TXE处理发送数据,在USART_IT_TXE使能并且CompleteFlag标识为发送完成情况下,按字节发送缓冲中的数据,当达到Length长度时,设置发送完成标识,设置USART_IT_TXE失能。
4、USART_IT_IDLE (空闲中断)
当检测到总线空闲(接收到一帧数据后,总线保持高电平超过一个完整数据帧时间)触发。
先清除中断标识:
USART_ReceiveData(USART1); // 读取数据寄存器清除中断
USART_ClearITPendingBit(USART1, USART_IT_IDLE);
没有接收到数据时也会进入USART_IT_IDLE中断,所以先判断一下USART_RxStruct.CurrentCount>0,保证是在USART_IT_RXNE中断之后触发的USART_IT_IDLE中断。
实行失能USART_IT_IDLE中断,设置接收数据完成标志CompleteFlag,失能USART_IT_RXNE
if(USART_RxStruct.CurrentCount>0){
USART_ITConfig(USART1, USART_IT_IDLE, DISABLE);
USART_RxStruct.CompleteFlag = 1;
PLATFORM_LED_Toggle(LED1);
USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
}
5、写个DEMO运行一下
因为在platform.c以及对USART1做了printf重定义所以可以直接用printf
- void Welcome_Info(void)
- {
- printf("请输入你的选择:\r\n");
- printf("=========================\r\n");
- printf("【1】:显示Hello 5次\r\n");
- printf("【2】:显示不定长UART接收\r\n");
- printf("【help】:显示本内容\r\n");
- printf("【其他输入】:输入内容串口回显\r\n");
- }
回显函数Echo_Back:就是在接收到非命令的RX串口数据后,将原数据通过TX发送回去,使用中断方式,通过USART_TxStruct.CompleteFlag判断是否完成:
- void Echo_Back(void)
- {
- USART_TxData_Interrupt((uint8_t *)USART_RxStruct.Buffer, USART_RxStruct.CurrentCount);
- while(USART_TxStruct.CompleteFlag!=1){};
- }
RX接收后处理函数:
收到1,显示5次“Hello 21ic, Hello MM32F0121”
收到2,显示“输入2显示:这是不定长UART接收DEMO”
收到help,显示Welcome_Info()打印内容
收到其他,原数据回显
- void Process_Input(void)
- {
- int i;
- if(USART_RxStruct.CurrentCount==3){
- if(USART_RxStruct.Buffer[0]=='1'){
- printf("输入1显示hello信息:\r\n");
- for(i=0;i<5;i++)
- {
- USART_TxData_Interrupt((uint8_t *)"Hello 21ic, Hello MM32F0121\r\n",29);
- PLATFORM_DelayMS(500);
- }
-
- }else if(USART_RxStruct.Buffer[0]=='2'){
- USART_TxData_Interrupt((uint8_t *)"输入2显示:这是不定长UART接收DEMO\r\n",35);
- }else{
- Echo_Back();
- }
-
- }else if(strstr((char*)USART_RxStruct.Buffer,"help"))
- {
- Welcome_Info();
- }else{
- Echo_Back();
- }
- USART_RxData_Interrupt(255);
- USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);
- }
UART_Sample
- void UART_Sample(void)
- {
-
- USART_RxStruct.CompleteFlag = 0;
- USART_TxStruct.CompleteFlag = 1;
- USART_Configure(115200);
-
- printf("【MM32F0121开发板评测】2、串口打印\r\n");
- Welcome_Info();
-
- USART_RxData_Interrupt(255);
- while(1)
- {
-
- if (1== USART_RxStruct.CompleteFlag&&USART_RxStruct.CurrentCount>0)
- {
- USART_RxStruct.CompleteFlag=0;
- Process_Input();
- }
- }
- }
6、运行