Cortex-M4板子 UART中断实验思考
程序员文章站
2022-04-01 22:05:35
...
实验任务:
1. PC 端发来绝对对时命令,如 SET12:56:03 或 12-56-03,自动将当前时间同步到12:56:03,并回之以当前时间
下文中命令采用SET12:56:03(超过8位)
解决方式:
利用UARTHANDLER即UART中断实现非阻塞性赋值
遇到问题:
1. 输出时间为乱码
首先确认时间显示代码段正确
if (light_cnt == 60)
{
light_cnt = 0;
light_cnt1++;
}
if (light_cnt1 == 60)
{
light_cnt1 = 0;
light_cnt2++;
}
if (light_cnt2 == 60)
{
light_cnt2 = 0;
}
非常典型的秒针分针时针的显示方式,数码管输出时分别整除和取模
中断代码如下:
while (UARTCharsAvail(UART0_BASE)) // Loop while there are characters in the receive FIFO.
{
///Read the next character from the UART and write it back to the UART.
uart_receive_char[controlbit] = UARTCharGetNonBlocking(UART0_BASE);
controlbit++;
}
输出:
light_cnt = (uart_receive_char[10]-'0') + (uart_receive_char[9]-'0') * 10;
light_cnt1 = (uart_receive_char[7]-'0') + (uart_receive_char[6]-'0') * 10;
light_cnt2 = (uart_receive_char[4]-'0') + (uart_receive_char[3]-'0') * 10;
此时,看似一切正常,但是输出为乱码
尝试了一下Debug中的单步执行,通过Watch发现参数正常,显示也正常,此时真是丈二和尚摸不着头脑。
于是思考:究竟遗漏了什么点导致了乱码,在翻看ppt时候发现了这张图
数据位最多为8位,此程序设置的为8位,而读入的长度为11位
此时怀疑是否进入了两次中断,于是在中断中添加输出测试,证实。而每次中断的时候会初始化读入数组位controlbit置为0,所以会覆盖。
覆盖后的字符数组如下
本来应该位于[5][6][7]的:11被放到了[0][1][2]将原本的时针覆盖了
解决过程:
方法1. 将controlbit置为全局变量,并且设置读取信息的轮次
if (equal1 && Uartround == 2)//equal1为不相干变量
{
Uartround = 0;
light_cnt = (uart_receive_char[10]-'0') + (uart_receive_char[9]-'0') * 10;
light_cnt1 = (uart_receive_char[7]-'0') + (uart_receive_char[6]-'0') * 10;
light_cnt2 = (uart_receive_char[4]-'0') + (uart_receive_char[3]-'0') * 10;
controlbit = 0;
}
方法2. 增加Delay延时程序
while (UARTCharsAvail(UART0_BASE)) // Loop while there are characters in the receive FIFO.
{
uart_receive_char[controlbit] = UARTCharGetNonBlocking(UART0_BASE);
controlbit++;
Delay(1000);
}
原理:
方法1其实只是一种强行的解决方法,方法2是根据硬件性质解决的
因为UART一次传输8位的原因,中间还有停止符开始符之类,导致前8位和后8或者小于8位的数据中间有间隔,而读取的函数是一个while循环,中间几乎没有间隔,所以在传完8位之后判断是否有数据的函数UARTCharsAvail()返回为假,因此退出了while循环,而其后的数据即使不满8位也会因为超时中断而再次进入循环,就出现了上面的问题,而Delay()函数能很好的解决这个问题。
附上老师的解释:
同学们,在实验三中UART中断中读取FIFO中的数据时,一般情况下要进行适当延时,也就是读取一个字节后要延时一点时间。为什么?因为接收FIFO中的数据是通过RxD端串转并而来,速度比较慢。比如,外设(ONE BUS虚拟串口软件)传9个字节到主板芯片,按照默认中断触发深度,第8个字节传输完毕即触发UART接收中断,此时如果中断读取这8个字节太快,以至于第9个字节还没有传好,此时中断接收8个字节后即退出中断,留下第9个字节在FIFO中,它将会产生接收超时中断。这意味着产生了2次中断。如果中断中读字节的速度慢一些,则在读取前8个字节的时候,第9个字节也能及时传到FIFO中,供中断继续读取。