Cortex-M4板子 UART中断实验思考

实验任务:

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时候发现了这张图

Cortex-M4板子 UART中断实验思考_第1张图片

数据位最多为8位,此程序设置的为8位,而读入的长度为11位

此时怀疑是否进入了两次中断,于是在中断中添加输出测试,证实。而每次中断的时候会初始化读入数组位controlbit置为0,所以会覆盖。

覆盖后的字符数组如下

本来应该位于[5][6][7]的:11被放到了[0][1][2]将原本的时针覆盖了

Cortex-M4板子 UART中断实验思考_第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中,供中断继续读取。



你可能感兴趣的:(UART,d)