久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2157|回復: 9
打印 上一主題 下一主題
收起左側

C51單片機執行串口中斷怎樣不阻礙主程序?

[復制鏈接]
跳轉到指定樓層
樓主
ID:1064961 發表于 2023-3-14 21:58 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
C51執行串口中斷怎樣不阻礙主程序執行串口接收中斷時while中主程序卡住有什么方法可以既可以執行主程序也能接收串口出來的數據
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:883242 發表于 2023-3-14 22:48 | 只看該作者
串口中斷一定要快進快出給個信號量semaphore通知主程序已經發生串口接收事件就趕緊退出千萬不要猶豫否則一定會耽誤主程序的執行在中斷里面加延遲更是大忌
回復

使用道具 舉報

板凳
ID:878061 發表于 2023-3-14 22:54 | 只看該作者
定義一個串口緩存區,每次串口中斷只處理一個數據判斷正確先放到緩存,緩存到指定數量就再處理
回復

使用道具 舉報

地板
ID:161164 發表于 2023-3-14 23:17 | 只看該作者
加個發送數組
把數據放進數組
在中斷內一個一個的發
回復

使用道具 舉報

5#
ID:101869 發表于 2023-3-15 08:53 來自手機 | 只看該作者
降低串口中斷的優先等級,切勿在串口中斷加阻塞延時
回復

使用道具 舉報

6#
ID:1064961 發表于 2023-3-15 09:01 | 只看該作者
各位有具體代碼實現步驟嗎,利用數組存儲數據,數組滿后執行還是不可
回復

使用道具 舉報

7#
ID:1045628 發表于 2023-3-15 10:42 | 只看該作者
單片機是單線程,所以中斷一定會阻礙主程序執行,只能通過快進快出來降低影響,快進不用你管,快出就盡量減少中斷中的代碼,delay等強制等待更是不要;
串口接收的話,定一個協議,當出現連續的幾個數,則認為是串口發起,比如我認為,當收到的前兩個數據為0x7F,0x55 ,這是正常通信發起,那接下來繼續接收,直到收到我需要的長度,再對收到的數據進行校驗即可
回復

使用道具 舉報

8#
ID:277550 發表于 2023-3-15 12:16 | 只看該作者

單線程,不影響是不可能的,使用緩沖,可以減少影響
回復

使用道具 舉報

9#
ID:155507 發表于 2023-3-15 13:06 | 只看該作者
111111yfyf 發表于 2023-3-15 09:01
各位有具體代碼實現步驟嗎,利用數組存儲數據,數組滿后執行還是不可

給你一個示例參考

  1. /*------------------------------------------------------------------*/
  2. /* --- STC MCU International Limited -------------------------------*/
  3. /* --- STC 1T Series MCU RC Demo -----------------------------------*/
  4. /* If you want to use the program or the program referenced in the  */
  5. /* article, please specify in which data and procedures from STC    */
  6. /*------------------------------------------------------------------*/


  7. /*********************************************************/
  8. //        #define MAIN_Fosc                24000000L        //定義主時鐘
  9. //        #define MAIN_Fosc                22118400L        //定義主時鐘
  10.         #define MAIN_Fosc                11059200L        //定義主時鐘

  11. #include        "..\..\STC8Gxxx.h"


  12. /*************        功能說明        **************

  13. 請先別修改程序, 直接下載"06-串口1-串口2-同時中斷收發-C語言"里的"UART1-UART2.hex"測試,主頻選擇11.0592MHZ.  測試正常后再修改移植.

  14. 2個串口(串口1 串口2)全雙工中斷方式收發通訊程序。

  15. 通過PC向MCU發送數據, MCU收到后通過串口把收到的數據原樣返回.

  16. 默認參數:
  17. 所有串口均設置均為 1位起始位, 8位數據位, 1位停止位, 無校驗.
  18. 每個串口可以使用不同的波特率.
  19. 串口1(P3.0 P3.1): 115200bps.
  20. 串口2(P1.0 P1.1):  57600bps.


  21. ******************************************/

  22. /*************        本地常量聲明        **************/
  23. #define        RX1_Length        128                /* 接收緩沖長度 */
  24. #define        RX2_Length        128                /* 接收緩沖長度 */


  25. /*************        本地變量聲明        **************/
  26. u8        xdata        RX1_Buffer[RX1_Length];        //接收緩沖
  27. u8        xdata        RX2_Buffer[RX2_Length];        //接收緩沖

  28. u8        TX1_read,RX1_write;        //讀寫索引(指針).
  29. u8        TX2_read,RX2_write;        //讀寫索引(指針).

  30. bit        B_TX1_Busy,B_TX2_Busy;        // 發送忙標志


  31. /*************        本地函數聲明        **************/
  32. void        UART1_config(u32 brt, u8 timer, u8 io);        // brt: 通信波特率,  timer=2: 波特率使用定時器2, 其它值: 使用Timer1做波特率. io=0: 串口1切換到P3.0 P3.1,  =1: 切換到P3.6 P3.7, =2: 切換到P1.6 P1.7,  =3: 切換到P4.3 P4.4.
  33. void        UART2_config(u32 brt, u8 timer, u8 io);        // brt: 通信波特率,  timer=任意值: 波特率使用定時器2. io=0: 串口2切換到P1.0 P1.1, =1: 切換到P4.6 P4.7.
  34. void         UART1_PrintString(u8 *puts);
  35. void         UART2_PrintString(u8 *puts);




  36. //========================================================================
  37. // 函數: void main(void)
  38. // 描述: 主函數
  39. // 參數: none.
  40. // 返回: none.
  41. // 版本: VER1.0
  42. // 日期: 2018-4-2
  43. // 備注:
  44. //========================================================================
  45. void main(void)
  46. {
  47.         u8        i;

  48.         EAXRAM();

  49.         UART1_config(115200UL, 1, 0);        // brt: 通信波特率,  timer=2: 波特率使用定時器2, 其它值: 使用Timer1做波特率. io=0: 串口1切換到P3.0 P3.1,  =1: 切換到P3.6 P3.7, =2: 切換到P1.6 P1.7,  =3: 切換到P4.3 P4.4.
  50.         UART2_config( 57600UL, 2, 0);        // brt: 通信波特率,  timer=任意值: 波特率使用定時器2. io=0: 串口2切換到P1.0 P1.1, =1: 切換到P4.6 P4.7.

  51.         EA = 1;

  52.         for(i=0; i<RX1_Length; i++)                RX1_Buffer[i] = 0;
  53.         B_TX1_Busy  = 0;
  54.         TX1_read    = 0;
  55.         RX1_write   = 0;

  56.         for(i=0; i<RX2_Length; i++)                RX2_Buffer[i] = 0;
  57.         B_TX2_Busy  = 0;
  58.         TX2_read    = 0;
  59.         RX2_write   = 0;
  60.         
  61.         UART1_PrintString("STC8G系列 UART1 Test!\r\n");
  62.         UART2_PrintString("STC8G系列 UART2 Test!\r\n");


  63.         while (1)
  64.         {

  65.                 if((TX1_read != RX1_write) && !B_TX1_Busy)        //收到過數據, 并且發送空閑
  66.                 {
  67.                         B_TX1_Busy = 1;                //標志發送忙
  68.                         SBUF = RX1_Buffer[TX1_read];        //發一個字節
  69.                         if(++TX1_read >= RX1_Length)        TX1_read = 0;        //避免溢出處理
  70.                 }

  71.                 if((TX2_read != RX2_write) && !B_TX2_Busy)        //收到過數據, 并且發送空閑
  72.                 {
  73.                         B_TX2_Busy = 1;                //標志發送忙
  74.                         S2BUF = RX2_Buffer[TX2_read];        //發一個字節
  75.                         if(++TX2_read >= RX2_Length)        TX2_read = 0;        //避免溢出處理
  76.                 }
  77.         }
  78. }


  79. //========================================================================
  80. // 函數: SetTimer2Baudraye(u16 dat)
  81. // 描述: 設置Timer2做波特率發生器。
  82. // 參數: dat: Timer2的重裝值.
  83. // 返回: none.
  84. // 版本: VER1.0
  85. // 日期: 2018-4-2
  86. // 備注:
  87. //========================================================================
  88. void        SetTimer2Baudrate(u16 dat)        // 選擇波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
  89. {
  90.         AUXR &= ~(1<<4);        //Timer stop
  91.         AUXR &= ~(1<<3);        //Timer2 set As Timer
  92.         AUXR |=  (1<<2);        //Timer2 set as 1T mode
  93.         TH2 = (u8)(dat >> 8);
  94.         TL2 = (u8)dat;
  95.         IE2  &= ~(1<<2);        //禁止中斷
  96.         AUXR |=  (1<<4);        //Timer run enable
  97. }


  98. //========================================================================
  99. // 函數: void        UART1_config(u32 brt, u8 timer, u8 io)
  100. // 描述: UART1初始化函數。
  101. // 參數:   brt: 通信波特率.
  102. //       timer: 波特率使用的定時器, timer=2: 波特率使用定時器2, 其它值: 使用Timer1做波特率.
  103. //          io: 串口1切換到的IO,  io=0: 串口1切換到P3.0 P3.1,  =1: 切換到P3.6 P3.7, =2: 切換到P1.6 P1.7,  =3: 切換到P4.3 P4.4.
  104. // 返回: none.
  105. // 版本: VER1.0
  106. // 日期: 2018-4-2
  107. // 備注:
  108. //========================================================================
  109. void        UART1_config(u32 brt, u8 timer, u8 io)        // brt: 通信波特率,  timer=2: 波特率使用定時器2, 其它值: 使用Timer1做波特率. io=0: 串口1切換到P3.0 P3.1,  =1: 切換到P3.6 P3.7, =2: 切換到P1.6 P1.7,  =3: 切換到P4.3 P4.4.
  110. {
  111.         brt = 65536UL - (MAIN_Fosc / 4) / brt;
  112.         if(timer == 2)        //波特率使用定時器2
  113.         {
  114.                 AUXR |= 0x01;                //S1 BRT Use Timer2;
  115.                 SetTimer2Baudrate((u16)brt);
  116.         }

  117.         else                //波特率使用定時器1
  118.         {
  119.                 TR1 = 0;
  120.                 AUXR &= ~0x01;                //S1 BRT Use Timer1;
  121.                 AUXR |=  (1<<6);        //Timer1 set as 1T mode
  122.                 TMOD &= ~(1<<6);        //Timer1 set As Timer
  123.                 TMOD &= ~0x30;                //Timer1_16bitAutoReload;
  124.                 TH1 = (u8)(brt >> 8);
  125.                 TL1 = (u8)brt;
  126.                 ET1 = 0;                        // 禁止Timer1中斷
  127.                 INT_CLKO &= ~0x02;        // Timer1不輸出高速時鐘
  128.                 TR1  = 1;                        // 運行Timer1
  129.         }

  130. //                 if(io == 1)        {S1_USE_P32P33();        P3n_standard(0x0c);}        //切換到 P3.2 P3.3        用于8腳MCU
  131. //        else if(io == 2)        {S1_USE_P54P53();        P5n_standard(0x18);}        //切換到 P5.4 P5.3        用于8腳MCU
  132.                  if(io == 1)        {S1_USE_P36P37();        P3n_standard(0xc0);}        //切換到 P3.6 P3.7
  133.         else if(io == 2)        {S1_USE_P16P17();        P1n_standard(0xc0);}        //切換到 P1.6 P1.7
  134.         else if(io == 3)        {S1_USE_P43P44();        P4n_standard(0x18);}        //切換到 P4.3 P4.4
  135.         else                                {S1_USE_P30P31();        P3n_standard(0x03);}        //切換到 P3.0 P3.1

  136.         SCON = (SCON & 0x3f) | (1<<6);        // 8位數據, 1位起始位, 1位停止位, 無校驗
  137. //        PS  = 1;        //高優先級中斷
  138.         ES  = 1;        //允許中斷
  139.         REN = 1;        //允許接收
  140. }


  141. //========================================================================
  142. // 函數: void        UART2_config(u32 brt, u8 timer, u8 io)
  143. // 描述: UART2初始化函數。
  144. // 參數:   brt: 通信波特率.
  145. //       timer: 波特率使用的定時器, timer=任意值: 波特率使用定時器2.
  146. //          io: 串口2切換到的IO,  io=0: 串口2切換到P1.0 P1.1, =1: 切換到P4.6 P4.7.
  147. // 返回: none.
  148. // 版本: VER1.0
  149. // 日期: 2018-4-2
  150. // 備注:
  151. //========================================================================
  152. void        UART2_config(u32 brt, u8 timer, u8 io)        // brt: 通信波特率,  timer=任意值: 波特率使用定時器2. io=0: 串口2切換到P1.0 P1.1, =1: 切換到P4.6 P4.7.
  153. {
  154.         brt = 65536UL - (MAIN_Fosc / 4) / brt;
  155.         if(timer == 2)        SetTimer2Baudrate((u16)brt);        //波特率使用定時器2
  156.         else                        SetTimer2Baudrate((u16)brt);        //波特率使用定時器2                兩個條件都使用Timer2, 是為了跟另外串口函數兼容

  157.         S2CON &= ~(1<<7);        // 8位數據, 1位起始位, 1位停止位, 無校驗
  158.         IE2   |= 1;                        //允許中斷
  159.         S2CON |= (1<<4);        //允許接收
  160.         if(io == 1)        {        P_SW2 |=  1;        P4n_standard(0xc0);}        //切換到 P4.6 P4.7
  161.         else                {        P_SW2 &= ~1;        P1n_standard(0x03);}        //切換到 P1.0 P1.1
  162. }


  163. //========================================================================
  164. // 函數: void UART1_PrintString(u8 *puts)
  165. // 描述: 串口1字符串打印函數
  166. // 參數: puts: 字符串指針.
  167. // 返回: none.
  168. // 版本: VER1.0
  169. // 日期: 2018-4-2
  170. // 備注:
  171. //========================================================================
  172. void UART1_PrintString(u8 *puts)
  173. {
  174.     for (; *puts != 0;        puts++)
  175.         {
  176.                 B_TX1_Busy = 1;                //標志發送忙
  177.                 SBUF = *puts;                //發一個字節
  178.                 while(B_TX1_Busy);        //等待發送完成
  179.         }
  180. }

  181. //========================================================================
  182. // 函數: void UART2_PrintString(u8 *puts)
  183. // 描述: 串口2字符串打印函數
  184. // 參數: puts: 字符串指針.
  185. // 返回: none.
  186. // 版本: VER1.0
  187. // 日期: 2018-4-2
  188. // 備注:
  189. //========================================================================
  190. void UART2_PrintString(u8 *puts)
  191. {
  192.     for (; *puts != 0;        puts++)
  193.         {
  194.                 B_TX2_Busy = 1;                //標志發送忙
  195.                 S2BUF = *puts;                //發一個字節
  196.                 while(B_TX2_Busy);        //等待發送完成
  197.         }
  198. }


  199. //========================================================================
  200. // 函數: void UART1_int (void) interrupt UART1_VECTOR
  201. // 描述: 串口1中斷函數
  202. // 參數: none.
  203. // 返回: none.
  204. // 版本: VER1.0
  205. // 日期: 2018-4-2
  206. // 備注:
  207. //========================================================================
  208. void UART1_int (void) interrupt UART1_VECTOR
  209. {
  210.         if(RI)
  211.         {
  212.                 RI = 0;
  213.                 RX1_Buffer[RX1_write] = SBUF;
  214.                 if(++RX1_write >= RX1_Length)        RX1_write = 0;
  215.         }

  216.         if(TI)
  217.         {
  218.                 TI = 0;
  219.                 B_TX1_Busy = 0;
  220.         }
  221. }

  222. //========================================================================
  223. // 函數: void UART2_int (void) interrupt UART2_VECTOR
  224. // 描述: 串口2中斷函數
  225. // 參數: none.
  226. // 返回: none.
  227. // 版本: VER1.0
  228. // 日期: 2018-4-2
  229. // 備注:
  230. //========================================================================
  231. void UART2_int (void) interrupt UART2_VECTOR
  232. {
  233.         if(RI2)
  234.         {
  235.                 CLR_RI2();
  236.                 RX2_Buffer[RX2_write] = S2BUF;
  237.                 if(++RX2_write >= RX2_Length)        RX2_write = 0;
  238.         }

  239.         if(TI2)
  240.         {
  241.                 CLR_TI2();
  242.                 B_TX2_Busy = 0;
  243.         }

  244. }

復制代碼
回復

使用道具 舉報

10#
ID:339654 發表于 2023-3-21 18:29 | 只看該作者
使用緩沖處理,然后中斷里面不要處理太多東西
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 毛片入口 | 国产高清精品在线 | 精品日韩一区二区 | 久久精品亚洲成在人线av网址 | 九九热在线精品视频 | 日韩一区不卡 | 91精品国产91久久综合桃花 | 精品国产成人 | 免费一级欧美在线观看视频 | 免费黄色日本 | 亚洲精品一| 中文字幕在线免费观看 | 国产精品一卡二卡三卡 | 亚洲精品久久久一区二区三区 | 国产高清在线 | 久久久国产精品 | 日韩成人免费av | h视频网站在线观看 | 91激情视频| 91免费观看国产 | 色欧美综合 | 精品无码久久久久久久动漫 | 夜夜骑天天干 | 精品三区 | 一区二区在线观看av | 天天干天天色 | 国产乱肥老妇国产一区二 | 一级片视频免费 | 国产精品久久久久一区二区三区 | 国产精品成人久久久久 | 国产高清免费在线 | 免费一级片 | 国产 日韩 欧美 中文 在线播放 | 中文字幕第三页 | 91香蕉嫩草| 日本高清视频在线播放 | 97视频在线观看网站 | 一区在线观看 | 欧美在线视频观看 | 人人爽人人草 | 亚洲精品黄 |