大家好,在学习USART通信实验时,看到
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
于是就在中文参考手册中参考了TC的清零方法:
“该位由软件序列清零(读取 USART_SR 寄存器,然后写入USART_DR 寄存器)。TC 位也可以通过向该位写入‘0’来清零”
可见,可以采用先读SR,再写DR的方式清零;或直接向TC位写0.
现在有一个小小的疑问:
例如,USART_RX_BUF数组中有三个数据,123.
当t=0时,通过USART_SendData()发送第一个数据1;接着执行while语句,若没有发送完成,则while等待;若发送完成,此时,
USART_GetFlagStatus()返回SET,这时,TC位为1.
接着执行t=1,通过USART_SendData()发送第二个数据2;接着执行while语言,那么问题来了,t=0时的TC位是怎么清零的呢?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
首先,不读SR,直接写DR也会将SR[TC]清零。
如果按照你自己的解释,那么SR复位值是0x00C0,为什么单片机复位后第一字节发送之前并没有任何读SR,依然正常。
最后,如果你真有疑问,不妨做个小实验来验证一下(自己想)。这,要比我直接告诉你强一万倍。
再最后,我留意到手册里还有一句话不知道你看到没有:
最最后,对这种“小”问题(其实并不小)抱有热心非常值得肯定。
但学习,除了要提出问题,最好还要能解决问题。
您好,非常感谢您的指点。
今天早上按照您的指点在原子哥的程序的基础上写了一个测试,花了一天的时间来理解程序的执行过程,此时终于明白了(但愿理解的是对的),您有空审读一下吗?
对于图1中while(1)内的运行过程是这样的:
当if条件满足后,运行到printf(" The massage: ");时,由于USART_SR寄存器中的TC位在芯片初始化后为1,故在调用该printf时,导致写DR寄存器,这就导致TC位清零。
接着进入for语句,在第二个prinf语句中,先运行USART_GetFlagStatus函数,由于第一个printf函数导致的TC位为0,故在第二个printf函数中,USART_GetFlagStatus返回TC位的值0.即打印出0.
接着执行for语句中的第一个while,直到printf中写DR完成(由fputc实现),完成传输后,TC位置1.这时,运行完该while后,TC为1.
接着执行第三个printf,先执行USART_GetFlagStatus函数,该函数返回1,将1压入堆栈。printf调用参数时,从堆栈中调取1,打印到串口,即打印出1.但是,在打印出1时,由于执行了写DR,故打印完1后,TC位变为0.
接着执行第四个printf,由于此时TC位为0,故打印出0.
接着执行while,执行完while后,TC位为1.
接着执行USART_SendData函数,由于执行了写DR寄存器,故执行完该语句后,TC位为0.
接着执行第五个printf,显然,打印出0.
接着执行while,执行完while后,TC位变为1.
接着执行第六个printf,先调用USART_GetFlagStatus函数,该函数返回TC位的值1,将1压入堆栈,调用printf函数,从堆栈中取出1并打印出来。在调用该printf时,由于执行了写DR寄存器,故本句执行完毕后,TC值为0.
执行第七个printf,显然,打印出0.
例如,若用串口调试助手发送2,则返回如图2所示,返回值与上述分析相符。
建议你跟到USART_GetFlagStatus和USART_SendData这两个函数中去看一眼,GetFlagStatus()这个函数就是在读SR,SendData()这个函数就是在写DR,所以清除TC的序列就满足了,有那么费劲么.
一周热门 更多>