1.正点原子例程里面的串口中断接收打印的方法仅仅适用于接收单个数据,发送接收到的数据,多个数据的原理是不断接收发送,接收多少个字符便会触发多少次中断;所以当需要接收一组数据再处理数据个个位的时候,就变得棘手起来,但stm32还提供了另外一种方法,可以完美解决这个问题,那就是空闲中断;
以下代码是一个串口初始化程序,与常规的相比,仅多了一句,开启空闲中断USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);
/*******************************************************************************
* 函 数 名 : usart_init
* 函数功能 : 串口初始化程序
* 作 者 : Yy.Fu
*******************************************************************************/
void usart1_init()
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; // TX
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 19200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_ClearFlag(USART1, USART_FLAG_TC);
USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);
/* Configure NVIC */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); // Set NVIC priority group to group 1
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; // Enable USART2 global interrupt
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // Set preemption priority to 0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // Set sub priority to 0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // Enable the interrupt channel
NVIC_Init(&NVIC_InitStructure); // Initialize NVIC
}
一个可以接收一组数据的串口初始化就完成了,这时候就继续编写中断以及处理函数;
中断函数:currentIndex1_flag是接受完成的标志位,currentIndex1是数组的索引,中断函数最好不要添加发送处理等相关耗时长的函数,可能会导致数据丢失;所以我把后续处理数组的放在主函数执行;
/*******************************************************************************
* 函 数 名 : USART1/2/3_IRQHandler
* 函数功能 : 串口中断程序
* 输 入 : USART_ReceiveData
* 作 者 : Yy.Fu
*******************************************************************************/
u16 receivedData1[16];
u16 currentIndex1 = 0;
u8 currentIndex1_flag = 0;
void USART1_IRQHandler(void)
{
if (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != RESET)
{
USART_ClearFlag(USART1, USART_FLAG_RXNE);
receivedData1[currentIndex1] = USART_ReceiveData(USART1);
currentIndex1++;
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
if (USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)
{
USART_ReceiveData(USART1);
receivedData1[currentIndex1] = USART_ReceiveData(USART1);
currentIndex1_flag = 1;
}
}
处理函数:我把它放在了别的文件,所以需要用到extern(额外变量)
extern u16 receivedData1[16];
extern u16 currentIndex1;
extern u8 currentIndex1_flag;
static void usart1_send()
{
if (currentIndex1_flag == 1)
{
if (receivedData1[3] == 3)
{
USART_SendData(USART1, 0xff);
}
currentIndex1 = 0;
currentIndex1_flag = 0;
}
}
最后,把usart1_send放在主函数循环执行即可,就可以看到usart1打印接收到的数组了;