在使用环接收串口数据时,在中断中向环区写入数据,在主程序中从环区读出数据。(测试芯片为雅特丽AT32F413)
上边做法经常出现环中数据没有完全读出时ringbuff1.length已经变为0的情况,并且出错一次有1个字节数据未读出。
猜测:
全局变量ringbuff1.length内存原始数据为1,此时程序运行到while中的U1ReadOneFrameData;函数中,处理器在使用ringbuff1.length的值进行连续的运算操作时,这个变量的值将在第一次操作时被复制到中间临时变量中,则紧接其后的其它操作将有可能直接从临时变量中取数以提高运行效率,即处理器从内存中读出ringbuff1.length的值1存入中间临时变量,此时中断条件到达进入中断处理函数void USART2_IRQHandler(void);
中断函数运行完成后ringbuff1.length变为2写入内存,内存中ringbuff1.length值变为2,并且返回while,然后while中的ringbuff1.length经过编译器优化实际为中间临时变量值--,即1-1为0,最后值写入内存,内存中全局变量ringbuff1.length值为0。
但是理想情况下ringbuff1.length值先经过++,在经过--,最后理想值为1。与实际情况不一致所以出错。
修改方法:
避免使用在中断中++,在主函数中--的全局变量ringbuff1.length,即不适用在中断和主函数同时进行了写操作的全局变量,改用只在中断中写的
ringbuff1.tail和在主函数中进行写操作的ringbuff1.head,通过二者判断环中数据是否为空。