专家您好,我遇到这样一个问题,这是我的代码出现问题的两个函数(放到了提问的最下面),这是一个蓝桥杯嵌入式省赛会考的知识点,是检测串口传输数据内容是否正确的一个问题,首先我在回调函数里写了flag,每次接收数据后将tim4的cnt归零,并且把接收到的数据放到一个数组里面。然后我在void Usart_Proc(void)里面写了,当flag生效且tim4的计数大于15次(波特率为9600,系统频率为80MHZ,tim4的PSC为8000-1,所以计数15下大概为1.5ms,大于了传输一个字节的时间)的时候说明数据传输完毕,开始对if的内容进行判断,函数的功能是这样的
遇到的问题是:
问题1:你可以看到,我在回调函数里面写了这样两行代码:
sprintf(str,"%c\n",rx_buffer);
HAL_UART_Transmit(&huart1, (uint8_t *)str, strlen(str), 50); //检测数据是否输入正常
这两行代码的意思是串口每接收到一个数据就将其传输出来,我平时需要在串口传输助手里面对其反复调试,这里出现的问题,我如果不开fifo的话,我在串口传输助手里面输入10个字符,程序只能检测出2~3个,而且存储进数组的顺序也经常混乱,于是我试着把这两行代码去掉让回调函数更简洁高效,然后就正常实现功能了,或者我打开fifo模式的情况下加上这两行代码也依然正常。请问这是为什么,是因为不加fifo的情况下,回调函数比较占用时间的时候会导致数据丢失吗??
问题2:你可以注意到,我的代码里用来判断数据传输完成的方法是人造了一个空闲中断,用TIM计数来实现的,理论上只需要计数11次后数据就传输完毕了,所以我设置的阈值是计数15次。但是我在实际操作过程中,我试着将判断数据是否传输完毕这里的TIM -> CNT > 15这里将15改成10甚至是0,那么按理说理想情况应该是由于人造空闲中断计数不够,导致函数无法判断串口的数据是否传输完毕,我在从串口调试助手里面输入“abc”时,它应该先error两次,然后再success对吧,但实际上测试发现,实际效果是大部分情况直接success,小概率情况会出现仅仅一次error,请问这是什么原因导致的呢?是计数器不够精准的原因,还是串口数据传输的中断优先级比主函数while里的函数void Usart_Proc(void)循环优先级高呢还是while循坏的不够快呢?
真心求问,如果有需要的话我可以提供源代码文件
下面的是我写的两个代码和相关变量声明
//串口显示专用变量
uint8_t str[21];
uint8_t rx_buffer=0;
uint8_t rx_val[10000];
int rx_flag=0;
int count_flag = 0;
void Usart_Proc(void)
{
if(rx_flag == 1 && TIM4->CNT >15) //判断数据是否传输完毕
{
if(rx_val[0] == 'a'&&rx_val[1] == 'b'&&rx_val[2] == 'c')
{
sprintf(str,"success\n");
HAL_UART_Transmit(&huart1, (uint8_t *)str, strlen(str), 50); //成功
}
else
{
sprintf(str,"error!\n");
HAL_UART_Transmit(&huart1, (uint8_t *)str, strlen(str), 50); //失败
}
rx_flag = 0;
for(int j = 0;j<=count_flag;j++) //清空数组
{
rx_val[j] = 0;
}
count_flag=0;
}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
TIM4->CNT = 0; //计数器归零
rx_flag=1; //flag
rx_val[count_flag] = rx_buffer; //数据存入数组中保存
count_flag++;
sprintf(str,"%c\n",rx_buffer);
HAL_UART_Transmit(&huart1, (uint8_t *)str, strlen(str), 50); //检测数据是否输入正常
HAL_UART_Receive_IT(&huart1,&rx_buffer,1);
}