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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

請教單片機如何避免串口接收數據丟失?

  [復制鏈接]
跳轉到指定樓層
樓主
ID:734017 發表于 2021-10-13 00:17 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
單片機與觸控屏通信  按下屏幕下發 AA 79 ** ** 33 cc c3 3c  抬起屏幕下發 AA 78 ** ** 33 cc c3 3c  中間兩個字節用戶定義相同指令
以下部分代碼
uchar buf[16];      //接收緩存區     這里因為上電握手最大長度,所以給了16  下面程序只用到8個字節
uchar rp = 0;       //緩存區地址

void interrupt_uart() interrupt 4 //using 3   //串口接收,定時器2 115200
{
                if (RI)  
                        {  
                        RI = 0 ;               
                        buf[ rp++ ] = SBUF;
                        if(SBUF==0X3C)                      //接收到尾 地址復位
                                rp=0;               
                        }
        }



void key_service()                //放在大循環        while(1) 里一直調用                                                
{        
switch(buf[1])                         //對應該按下 指令 79后進行比較                                       
                        {
                                case 0X79:
                                
                                if(        buf[3]==0x01 && buf[7]==0x3c)             //buf[3]==0x01 是用戶指令01 只判定buf[3]                                       
                                 {
                                        memset(buf, 0, 16)
                                       **********此處省略**********
                                }
                                if(        buf[3]==0x02 && buf[7]==0x3c)                                                
                                {
                                           memset(buf, 0, 16)
                                        **********此處省略**********        
                                }
                                if(        buf[3]==0x03 && buf[7]==0x3c)                                                
                                {        
                                          memset(buf, 0, 16)
                                        **********此處省略**********
                                }
                                if(        buf[3]==0x04 && buf[7]==0x3c)                                                               
                                {
                                          memset(buf, 0, 16)
                                      **********此處省略**********
                                }
                                
                                ......................        
                               總共15個IF判斷
                        
                                break;        
                        
                        case 0X78:             //對應該抬起 指令 78后進行比較        
               
                                if(buf[0]==0xAA && buf[7]==0x3c)               //   接收完成
                        {        
                                for(i=0;i<16;i++)                                   //清空緩存區
                                {
                                        buf[ i]=0;
                                }
                                                               
                                //memset(buf, 0, 16)                              //清空緩存區   感覺這個函數比較費時,所以沒用 ,求指教
                        }
                                
                                  break;  
                                default:break;
                        }
}


目前程序運行正常。
請問,如果數據接收慢,當case 0X79: 跑完了,用戶指令才來,或者我要比較指令01 。但可能跑到03去比較了。這時候 01 才到。那么這一次不執行。退出 case 0X79: 這時候緩存區未被清空,(此處為單次點擊)
當抬起屏幕的時候指令78來了,會覆蓋緩存區 ,然后 switch(buf[1]) 在while(1) 里一直調用。直到清空
(正常操作點擊屏幕按下抬起不作停留 。屏幕下發數據是  AA 79**********   AA 78 ********** 中間有很短的間隔)
這次點擊那就無效了。
如果在case 0X79后面加上while (buf[7]!=0x3c) 防止沒接收完就判斷,會有多大影響。謝謝大家
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:460753 發表于 2021-10-13 07:45 | 只看該作者
參考宋老師的串口接收部份。百度金沙灘工作室
回復

使用道具 舉報

板凳
ID:236035 發表于 2021-10-13 08:00 | 只看該作者
再加緩存,就不怕buf[]的變化了。當一幀數據接收完畢,置標志位,放入緩存,再進行數據處理。
回復

使用道具 舉報

地板
ID:57657 發表于 2021-10-13 08:09 | 只看該作者
請提供下波特率和晶振頻率確定是否為誤碼率高。
回復

使用道具 舉報

5#
ID:554500 發表于 2021-10-13 08:21 | 只看該作者
如果你的單片機處理速度比較慢,那就降低波特率。或者采用閉環控制的方式。
回復

使用道具 舉報

6#
ID:94031 發表于 2021-10-13 08:35 | 只看該作者
應該是一幀數據接收完設置標志,再進行判斷,不應該收一個判斷一個。
回復

使用道具 舉報

7#
ID:734017 發表于 2021-10-13 09:51 | 只看該作者
npn 發表于 2021-10-13 08:09
請提供下波特率和晶振頻率確定是否為誤碼率高。

24M 1T  115200
回復

使用道具 舉報

8#
ID:429003 發表于 2021-10-13 10:16 | 只看該作者
總體思路:中斷僅緩存接收數據,接收完畢喚醒任務處理數據。
使用一個定時器,每次串口中斷接收到一個字節,緩存數據后更新定時器延后一段時間產生定時器超時中斷,只要串口連續接收到數據,超時中斷不會產生,反之只要定時器發生超時中斷,則判定為一幀連續數據接收完畢。
整個串口數據接收過程,全部由串口和定時器中斷完成,無需任務參與,任務只需要在接收完畢后由定時器中斷喚醒后做數據幀解析處理。
如果其它功能應用對中斷占用時間不敏感,可以直接在定時器超時中斷里面處理數據幀。全程任務完全無需參與了。
回復

使用道具 舉報

9#
ID:57657 發表于 2021-10-13 11:00 | 只看該作者

串口需要用 22.1184Mhz 或 33.1776Mhz 才可以的。
回復

使用道具 舉報

10#
ID:971661 發表于 2021-10-13 11:50 | 只看該作者
增加數據緩存是比較好的方法,可以的話最好做個環形隊列,先進先出。
回復

使用道具 舉報

11#
ID:158375 發表于 2021-10-13 14:12 | 只看該作者
建議改變整個程序結構,那樣更簡單,更有效。
回復

使用道具 舉報

12#
ID:123289 發表于 2021-10-13 17:10 | 只看該作者
所有的中斷程序處理時間,不大于1個字節的串行拼裝時間,你能做到就可以。
回復

使用道具 舉報

13#
ID:971769 發表于 2021-10-13 17:17 | 只看該作者
加緩存, 數據接收完畢,設置標志位,放入緩存后再進行數據處理
回復

使用道具 舉報

14#
ID:624769 發表于 2021-10-13 20:46 | 只看該作者
做緩沖池,比如你一個指令8個字節,你做一個128字節的緩沖池,最多保存16個指令,那么,應該就沒啥問題了。
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 一区二区在线不卡 | 99精品99 | 精品国产99| 国产成人免费视频网站高清观看视频 | 一区二区av | 成人日韩 | 国产成人精品一区二区三区在线观看 | 久久国产欧美日韩精品 | 日本一区二区三区视频在线 | 欧美天堂在线 | 久久精品色欧美aⅴ一区二区 | 国产一区二区欧美 | 在线成人 | 中文字幕日韩av | 91精品国产91久久久久久密臀 | 亚洲精品一区在线观看 | 欧美淫片 | 精品自拍视频 | 欧美日韩一区二区在线观看 | 欧美一级二级视频 | 亚洲一区二区三区久久 | 好好的日在线视频 | 亚洲一区二区视频在线播放 | 欧美一级特黄aaa大片在线观看 | 97国产在线观看 | 在线a视频网站 | 欧美精品久久久久 | 青青草在线视频免费观看 | 天天激情综合 | 福利视频网 | 亚洲精品成人网 | 欧美成人精品一区二区男人看 | 国产精品一区二区三区免费观看 | 日本中文字幕视频 | avhd101在线成人播放 | 成人免费视频网站在线观看 | 国产精品久久久久久久久久久久 | 精品一区二区在线观看 | www.日本三级 | 狠狠干美女| 久久免费观看视频 |