串口1接收任意长度数据以回车换行符为结束标志。使用Atmel Studio 创建工程,添加外设串口1(因为串口1与调试器的虚拟串口相连接,直接接根USB线即可);
对USART1进行如下配置:
别忘了开全局中断:
生成代码:
对usart1的接收中断函数进行修改(在usart_base.h和usart_base.c):
将usart_base.h里面添加2个外部变量声明
extern uint8_t USART_0_rxbuf[USART_0_RX_BUFFER_SIZE];
extern volatile uint16_t USART_0_rx_elements;
对usart_base.c进行如下修改:
对下面2个变量,去掉static标志
uint8_t USART_0_rxbuf[USART_0_RX_BUFFER_SIZE];
volatile uint16_t USART_0_rx_elements;
void USART_0_default_rx_isr_cb(void)
{
uint8_t data;
/* Read the received data */
data = USART1.RXDATAL;
/* Calculate buffer index */
if((USART_0_rx_elements & 0x8000) == 0) //接收未完成
{
if(USART_0_rx_elements & 0x4000) //接收到了0x0d
{
if(data != 0x0a)USART_0_rx_elements = 0; //接收错误,重新开始
else USART_0_rx_elements |= 0x8000; //接收完成了
}
else //还没收到0X0D
{
if(data == 0x0d)USART_0_rx_elements |= 0x4000;
else
{
USART_0_rxbuf[USART_0_rx_elements & 0X3FFF] = data ;
USART_0_rx_elements++;
if(USART_0_rx_elements > (USART_0_RX_BUFFER_SIZE - 1))USART_0_rx_elements = 0; //接收数据错误,重新开始接收
}
}
}
}
在main.c的while里面添加执行语句:
头文件包含:
#include "util\delay.h"
#include "stdio.h"
#include "string.h"
添加3变量:
uint16_t t=0;
uint16_t len;
uint16_t times=0;
while里面添加:
while(1)
{
if(USART_0_rx_elements&0x8000)
{
len=USART_0_rx_elements&0x3fff;//得到此次接收到的数据长度
printf("\r\n您发送的消息为:\r\n");
for(t=0;t<len;t++)
{
USART_0_write(USART_0_rxbuf[t]);
}
printf("\r\n");//插入换行
USART_0_rx_elements=0;
//串口解析指令控制相应任务--TEST
if (strstr((const char *) USART_0_rxbuf,(const char *) "LED1ON"))
{
printf("LED1打开了\r\n");
//实际操作代码
//...
}
if (strstr((const char *) USART_0_rxbuf,(const char *) "LED1OFF"))
{
printf("LED1关闭了\r\n");
//实际操作代码
//...
}
}else
{
times++;
if(times%5000==0)
{
printf("\r\nAVR128DA48 串口实验\r\n");
printf("2020-08-25\r\n\r\n");
}
if(times%200==0)printf("请输入数据,以回车键结束\n");
if(times%30==0)PORTC_toggle_pin_level(6);//闪烁LED,提示系统正在运行.
_delay_ms(10);
}
}
自动生成的代码还是有点小BUG,譬如我明明定义的USART1图,它还是给我定义这种usart_0_xx的变量,不过不影响使用,强迫症可以自己修改下。
本代码参考正点原子STM32的串口处理函数,觉得很好用,就参考修改了下。
执行如下:
|