//功能:串口助手每次发送数据格式:@0000&
// 第二个字节控制LED1亮灭
// 第三个字节控制LED2亮灭
// 第四个字节控制LED3亮灭
// 第无个字节控制LED4亮灭
//要求:代码能够一直运行,能够接收多字节数据
上节讲了串口的基本发送接收数据,本节应用一下。
以上功能可写成这样:发送和接收数据的解析函数:
void DataAnaly(void)
{
if(usart1flag == 1)
{
if(Usart1buff[0]== '@' && Usart1buff[Usart1len-1]== '&')
{
if(Usart1buff[1]=='1')
LED1(1);
else
LED1(0);
if(Usart1buff[2]=='1')
LED2(1);
else
LED2(0);
if(Usart1buff[3]=='1')
LED3(1);
else
LED3(0);
if(Usart1buff[4]=='1')
LED4(1);
else
LED4(0);
memset(Usart1buff,0,10);
Usart1len=0;
usart1flag=0;
}
else
{
memset(Usart1buff,0,10);
Usart1len=0;
usart1flag=0;
}
}
}
因为功能要求代码能够一直运行,所以一般会想到把上面这个功能函数写在while(1)循环里,但是如果写在while(1)循环中,只有发数据,while循环才会跑起来,不发的话,程序会一直卡死在接收数据这里,while循环里的其他数据就不能运行了,所以要使用中断。因为在接受数据这导致其他数据不能运行,所以要使用接收中断。
1,在上节的usart.c中的void Usart_Init(void){ }函数里加一行代码,开启接收函数中断源
//开启串口1接收中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
2,在usart.c写中断服务函数
uint8_t Usart1buff[10] = {0};
uint16_t Usart1len = 0;
uint8_t usart1flag = 0;
//中断服务函数按键1 不用在.h中声明 不用在main函数中调用了
void USART1_IRQHandler(void)
{
//检查指定usart中断(接收中断)发生与否
if(USART_GetITStatus(USART1,USART_IT_RXNE) == SET)
{
//将接收到的数据保存在Usart1buff[10]数组中
Usart1buff[Usart1len] = USART_ReceiveData(USART1);
if(Usart1buff[Usart1len] == '&')
{
//判断数据是否接受完毕
usart1flag=1;
}
//只要接收到数据就会发生中断
//因为中断一直在发生,所以数据要往后偏移
Usart1len++;
//清除 USARTx 的中断待处理位
USART_ClearITPendingBit(USART1,USART_IT_RXNE);
}
}
3,在usart.c写解析函数,然后在usart.h中声明函数(省略)
void DataAnaly(void)
{
//如果数据接收正确,执行对应程序
if(usart1flag == 1)
{
if(Usart1buff[0]== '@' && Usart1buff[Usart1len-1]== '&')
{
if(Usart1buff[1]=='1')
LED1(1);
else
LED1(0);
if(Usart1buff[2]=='1')
LED2(1);
else
LED2(0);
if(Usart1buff[3]=='1')
LED3(1);
else
LED3(0);
if(Usart1buff[4]=='1')
LED4(1);
else
LED4(0);
//将Usart1buff所指向的内存区域的前10个字节设置为0,清除
memset(Usart1buff,0,10);
Usart1len=0;
usart1flag=0;
}
//如果数据接收不正确,清除接收输入的数据的数组,数组长度和标志位清零
else
{
memset(Usart1buff,0,10);
Usart1len=0;
usart1flag=0;
}
}
}