日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > 單片機(jī) > 單片機(jī)
[導(dǎo)讀] 今天在使用USART模塊,遇到了一些問題并解決了,于是發(fā)貼共享。問題描述:在使用USART做串口通訊時(shí),我只把接收中斷打開,并設(shè)置搶占優(yōu)先級為最低一個(gè)級別,而接收中斷上一個(gè)優(yōu)先級處理事情比較多,可能

 

今天在使用USART模塊,遇到了一些問題并解決了,于是發(fā)貼共享。

問題描述:
在使用USART做串口通訊時(shí),我只把接收中斷打開,并設(shè)置搶占優(yōu)先級為最低一個(gè)級別,而接收中斷上一個(gè)優(yōu)先級處理事情比較多,可能占用了2ms時(shí)間。當(dāng)我使用9600波特率往下位機(jī)發(fā)送數(shù)據(jù),速度非??欤褪且恢卑椿剀嚢l(fā)!問題就出來,不到1分鐘時(shí)間,通訊沒有反應(yīng)了。USART配置代碼如下:

 

  1. voiduart_config(void)

  2. {

  3. USART_InitTypeDefUSART_InitStructure;

  4. USART_InitStructure.USART_BaudRate=UART_GetBaud(BaudRate);

  5. USART_InitStructure.USART_WordLength=USART_WordLength_8b;

  6. USART_InitStructure.USART_StopBits=USART_StopBits_1;

  7. USART_InitStructure.USART_Parity=USART_Parity_No;

  8. USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;

  9. USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;

  10. USART_InitStructure.USART_Clock=USART_Clock_Disable;

  11. USART_InitStructure.USART_CPOL=USART_CPOL_Low;

  12. USART_InitStructure.USART_CPHA=USART_CPHA_2Edge;

  13. USART_InitStructure.USART_LastBit=USART_LastBit_Enable;

  14. /*ConfigureUSART1*/

  15. USART_Init(USART1,&USART_InitStructure);

  16. /*EnableUSART1receiveinterrupt*/

  17. USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);

  18. /*EnabletheUSART1*/

  19. USART_Cmd(USART1,ENABLE);

  20. }


分析問題:

1.為什么沒有通訊了?
通過仿真器仿真,發(fā)現(xiàn)程序一直進(jìn)入接收中斷中,由于我沒有使用中斷發(fā)送,于是程序就死在了接收中斷,也就沒有數(shù)據(jù)發(fā)送到電腦上來。接收中斷代碼如下:

 

  1. voidUART_Receive(void)

  2. {

  3. //正在處理上一條通訊,接收到數(shù)據(jù)不處理

  4. if(bRecieveOK)

  5. {

  6. if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)

  7. USART_ClearITPendingBit(USART1,USART_IT_RXNE);

  8. return;//processingreceivedata,don'treceiveagain

  9. }

  10. if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)

  11. {

  12. if(MoudBusExpir==0)

  13. {

  14. ucRcePtr=0;

  15. MoudBusExpir=20;//50ms

  16. }

  17. else

  18. MoudBusExpir=20;

  19. /*Readonebytefromthereceivedataregister*/

  20. ucRS485Buff[ucRcePtr++]=USART_ReceiveData(USART1);

  21. /*CleartheUSART1Receiveinterrupt*/

  22. USART_ClearITPendingBit(USART1,USART_IT_RXNE);

  23. }


2.為什么會一直跑到接收中斷?
斷點(diǎn)之后發(fā)現(xiàn)(USART_GetITStatus(USART1, USART_IT_RXNE)==RESET的,也就是說沒有數(shù)據(jù)接收到也進(jìn)了中斷,而且在USART配置中我也只打開了接收中斷!沒有數(shù)據(jù)送過來應(yīng)該是不可能進(jìn)入中斷的!

3.響應(yīng)了什么中斷?
我想通過函數(shù)(USART_GetITStatus()把所有中斷狀態(tài)都讀出來,但失敗了,USART_IT_XXX所有中斷狀態(tài)都是RESET!也就是說沒有中斷也進(jìn)入到這個(gè)中斷服務(wù)程序來了!?

4.找資料
STM32F10x微控制器參考手冊(2009年12月第10版)P541發(fā)現(xiàn)如下說明:

也就是說只要接收中斷打開,即RXNEIE設(shè)置為1,那么ORE中斷也自動打開了。
可是USART_GetITStatus(USART1, USART_IT_ORE )== RESET!!!!
找到USART_GetITStatus(USART1, USART_IT_RXNE)函數(shù),發(fā)現(xiàn)只有當(dāng)USART_IT_ERR中斷使能時(shí),才能讀到ORE中斷。
在這里要指出這個(gè)BUG:產(chǎn)生ORE中斷了,但使用USART_GetITStatus()函數(shù)卻無法讀到這個(gè)中斷被SET起來!

5.把ORE中斷標(biāo)志位清除
既然找到了是什么中斷,那么把相應(yīng)的中斷標(biāo)志位清除,就應(yīng)該可以了吧?
USART_ClearITPendingBit(USART1, USART_IT_ORE);
但是,結(jié)果是沒有任何效果!清除之后,馬上讀ORE中斷狀態(tài),USART_GetITStatus(USART1, USART_IT_ORE)==RESET.程序仍然跑死在接收中斷。再使用另一個(gè)函數(shù)USART_GetFlagStatus(USART1, USART_FLAG_ORE) = SET,原來ORE標(biāo)志位還沒有清除。

6.問題解決
為什么清除不掉?頭疼了,再找找資料,有發(fā)現(xiàn),在P523頁如下圖:

接收中斷程序改為(注意這一句://注意!不能使用if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)來判斷):

 

  1. voidUART_Receive(void)

  2. {

  3. if(USART_GetFlagStatus(USART1,USART_FLAG_ORE)!=RESET)//注意!不能使用if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)來判斷

  4. {

  5. USART_ReceiveData(USART1);

  6. }

  7. //正在處理上一條通訊,接收到數(shù)據(jù)不處理

  8. if(bRecieveOK)

  9. {

  10. if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)

  11. USART_ClearITPendingBit(USART1,USART_IT_RXNE);

  12. return;//processingreceivedata,don'treceiveagain

  13. }

  14. if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)

  15. {

  16. if(MoudBusExpir==0)

  17. {

  18. ucRcePtr=0;

  19. MoudBusExpir=20;//50ms

  20. }

  21. else

  22. MoudBusExpir=20;

  23. /*Readonebytefromthereceivedataregister*/

  24. ucRS485Buff[ucRcePtr++]=USART_ReceiveData(USART1);

  25. /*CleartheUSART1Receiveinterrupt*/

  26. USART_ClearITPendingBit(USART1,USART_IT_RXNE);

  27. }


總結(jié):
注意問題:1.USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);使能了接收中斷,那么ORE中斷也同時(shí)被開啟了。
2.ORE中斷只能使用USART_GetFlagStatus(USART1, USART_FLAG_ORE) 讀到(沒有使能USART_IT_ERR中斷時(shí))
BUG建議:1.在STM32庫中,能不能修改USART_GetITStatus()函數(shù)對USART_IT_ORE中斷的處理?也就是我只要打開了接收中斷,那么有ORE中斷時(shí),我也能使用USART_GetITStatus(USART1,USART_IT_ORE)讀到.
其它:在找資料的同時(shí),發(fā)現(xiàn)STM32F10x微控制器參考手冊(2009年12月第10版)中文翻譯P538有錯(cuò)誤,如下圖:

 

英文P696如下圖:

 

 

 

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時(shí)聯(lián)系本站刪除( 郵箱:macysun@21ic.com )。
換一批
延伸閱讀
關(guān)閉