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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

請教單片機串口通信方面的問題,希望做過這一方面的大佬能解答一下

[復制鏈接]
跳轉到指定樓層
樓主
最近正在用51單片機做串口通信,已經完成了基本的發送接收。想做更深入一點:1.對接收到的數據能進行解析,比如串口助手發送了一組電壓電流數據:V1012A0022,要把它還原成電壓1.012伏,電路0.022A,用兩數碼管顯示出來。
2.發送數據能不用中斷嗎?現在用的是interrupt 0(外部中斷0),能不能不用中斷,用單片機上任意的一個口控制發送。

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:303383 發表于 2018-4-23 17:28 | 只看該作者
提示: 作者被禁止或刪除 內容自動屏蔽
回復

使用道具 舉報

板凳
ID:213173 發表于 2018-4-23 19:37 | 只看該作者
你可以自定義通訊協議,比如:數據頭0xff,電壓整數0x01,電壓小數0x0c,電流整數0x00,電流小數0x16,數據尾為有效數據和0x23,0xff 0x01 0x0c 0x00 0x16 0x23,由6組8位數據組成一個數據串,下位機收到數據串后保存在緩存中,根據數據頭尾判斷數據傳輸正確后對有效數據解析,提供給顯示模塊。
回復

使用道具 舉報

地板
ID:308816 發表于 2018-4-23 19:58 | 只看該作者
發數據不需要中斷接收需要
回復

使用道具 舉報

5#
ID:304431 發表于 2018-4-24 12:11 | 只看該作者
wulin 發表于 2018-4-23 19:37
你可以自定義通訊協議,比如:數據頭0xff,電壓整數0x01,電壓小數0x0c,電流整數0x00,電流小數0x16,數據 ...

通過狀態機實現么?能否給一個大概的代碼框架么,因為剛接觸這方面,個人編程也不熟練,沒法直接根據您提供的思路搭建出來。
回復

使用道具 舉報

6#
ID:213173 發表于 2018-4-24 14:41 | 只看該作者
mdzzlsf 發表于 2018-4-24 12:11
通過狀態機實現么?能否給一個大概的代碼框架么,因為剛接觸這方面,個人編程也不熟練,沒法直接根據您提 ...

沒有你想的那么復雜,給你寫一個示例程序參考,經TX-1C實驗板與串口助手驗證無誤。
#include <reg51.h>
#define uint unsigned int
#define uchar unsigned char
sbit dula=P2^6;                        //段選
sbit wela=P2^7;                        //位選
uchar code table[]={                //共陰數碼管0~F、U數組
        0x3f,0x06,0x5b,0x4f,
        0x66,0x6d,0x7d,0x07,
        0x7f,0x6f,0x77,0x7c,
        0x39,0x5e,0x79,0x71,0x3e};
uchar table0[] ="OK\n";        //用于串口助手返回驗證
uchar table1[]="ERROR\n";//用于串口助手返回驗證
uchar rec_buf[6];                        //緩存
uint swan,wan,qian,bai,shi,ge;//數碼管顯示位
bit flag=0;                                        //接收完成標
/*************初始化串口**************/
void InitUART()                //9600bps@11.0592MHz
{
        PCON &= 0x7F;                //波特率不倍速
        SCON = 0x50;                //8位數據,可變波特率
        TMOD= 0x20;                        //設定定時器1為8位自動重裝方式
        TL1 = 0xFD;                        //設定定時初值
        TH1 = 0xFD;                        //設定定時器重裝值
        ET1 = 0;                                //禁止定時器1中斷
        TR1 = 1;                                //啟動定時器1
        EA = 1;                                //開總中斷
        ES = 1;                                //開串口中斷
}
/**********串口發送函數*************/
void SendOneByte(uchar c)
{
    SBUF = c;                //發送數據
    while(!TI);        //等待發送完成
    TI = 0;                        //發送中斷請求標志位清0
}
/************數據解析函數*************/
void analysis()
{
        uchar i;                        //臨時變量
        if(flag==1)                //一幀數據串接收完成
        {
                ES=0;                        //關串口中斷
                flag=0;                //接收完成標志清0
                if(rec_buf[5]==rec_buf[1]+rec_buf[2]+rec_buf[3]+rec_buf[4])//驗證數據和,超出8位溢出舍棄
                {
                        for(i=0;i<3;i++)
                        SendOneByte(table0);//返回OK
                }
                else
                {
                        for(i=0;i<6;i++)
                                SendOneByte(table1);//返回ERROR
                        rec_buf[0]=rec_buf[1]=rec_buf[2]=rec_buf[3]=rec_buf[4]=rec_buf[5]=0;//清除緩存數據
                }
                ES=1;                //開串口中斷
        }
}
/*************數據分解***************/
void Transformation()
{
        static uint i=0;
        static bit j=0;
        i++;
        if(i==7500)                //計數延時切換顯示內容
        {
                i=0;
                j=~j;
        }
        if(j==0)                        //換算電壓
        {
                swan = rec_buf[1]%100/10;                        // 十萬位
                wan  = rec_buf[1]%10;                                // 萬位
                qian = rec_buf[2]%1000/100;                // 千位
                bai  = rec_buf[2]%100/10;                        // 百位
                shi  = rec_buf[2]%10;                                // 十位
                ge   = 16;                                                                // 個位"V"
        }
        else                        //換算電流
        {
                swan = rec_buf[3]%100/10;                        // 十萬位
                wan  = rec_buf[3]%10;                                // 萬位
                qian = rec_buf[4]%1000/100;                // 千位
                bai  = rec_buf[4]%100/10;                        // 百位
                shi  = rec_buf[4]%10;                                // 十位
                ge   = 10;                                                                // 個位"A"
        }
}
/**********6位數碼管顯示程序************/
void display()
{
        static uchar k=0;                        //分時顯示變量
        switch(k)
        {
                case 0:
                   dula=0;
                   P0=table[swan];                //顯示十萬位段碼
                   dula=1;
                   dula=0;
               
                   wela=0;
                   P0=0x7e;                                                //顯示十萬位碼
                   wela=1;
                   wela=0;
                        k++;
                 break;       

                case 1:
                   dula=0;
                   P0=table[wan]|0x80;                //顯示萬位段碼+小數點
                   dula=1;
                   dula=0;
               
                   wela=0;
                   P0=0x7d;                                                //顯示萬位位碼
                   wela=1;
                   wela=0;
                        k++;
                 break;       

                case 2:
                   P0=table[qian];                        //顯示千位段碼
                   dula=1;
                   dula=0;
               
                   P0=0x7b;                                                //顯示千位位碼
                   wela=1;
                   wela=0;
                        k++;
                 break;       

                case 3:
                   P0=table[bai];                        //顯示百位段碼
                   dula=1;
                   dula=0;
               
                   P0=0x77;                                                //顯示百位位碼
                   wela=1;
                   wela=0;
                        k++;
                 break;       

                case 4:
                   P0=table[shi];                        //顯示十位段碼
                   dula=1;
                   dula=0;
               
                   P0=0xef;                                                //顯示十位位碼
                   wela=1;
                   wela=0;
                        k++;
                 break;       

                case 5:
                   P0=table[ge];                        //顯示個位段碼
                   dula=1;
                   dula=0;
               
                   P0=0xdf;                                                //顯示個位位碼
                   wela=1;
                   wela=0;
                        k=0;
                 break;       
        }
}
/**************主程序**************/
void main()
{
        InitUART();                //初始化串口
        while(1)
        {
                analysis();        //數據解析
                Transformation();//數據分解
                display();        //數碼管顯示
        }
}
/*********串口中斷服務程序**********/
void UARTInterrupt() interrupt 4
{
        static uchar num=0;        //靜態計數變量
        RI=0;                                                //接收中斷請求標志位清0
        rec_buf[num]=SBUF;        //接收到的數據串保存在緩存數組
        if(rec_buf[0]==0xff)        //驗證數據頭(起始位)
        {
                num++;
                if(num>=6)
                {
                        flag=1;                        //接收完成標志置1
                        num=0;                        //計數變量清0
                }
        }
}
//0xff 0x01 0x0c 0x00 0x16 0x23


評分

參與人數 1黑幣 +5 收起 理由
mdzzlsf + 5 很給力!

查看全部評分

回復

使用道具 舉報

7#
ID:266627 發表于 2018-4-24 16:16 | 只看該作者
接收要用中斷,因為接收緩沖區只有一個字節,不停下手頭的事去接收,SBUF會被下一個字節改變。
發送不用中斷。

將發送的數據包裝成一個個的數據幀,加上幀頭和校驗,一般還是很可靠的。
回復

使用道具 舉報

8#
ID:304431 發表于 2018-4-25 11:40 | 只看該作者
wulin 發表于 2018-4-24 14:41
沒有你想的那么復雜,給你寫一個示例程序參考,經TX-1C實驗板與串口助手驗證無誤。
#include
#define  ...

謝謝您的解答!
回復

使用道具 舉報

9#
ID:451441 發表于 2019-9-5 10:36 | 只看該作者
謝謝LZ分享,借鑒下
回復

使用道具 舉報

10#
ID:438771 發表于 2019-9-7 20:17 來自手機 | 只看該作者
緒爺 發表于 2018-4-23 19:58
發數據不需要中斷接收需要

請教一下怎么發送?我每次發送數據都上位機都亂碼了
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产无套一区二区三区久久 | 色毛片 | 密乳av| 国产精品一区二区三级 | 日韩av免费看 | 日本人麻豆 | 亚洲成人中文字幕 | 国产一区二区激情视频 | 成人免费视频7777777 | 中文字幕国产视频 | 真人女人一级毛片免费播放 | 国产午夜精品一区二区三区四区 | 久久婷婷国产麻豆91 | 黑人巨大精品欧美一区二区免费 | 久久高清 | 偷派自拍| 成人一区二区三区在线观看 | 国产精品视频网 | 欧美中文字幕一区二区三区 | 黄色大片在线 | 91精品久久久久久久久久 | 久久国产成人 | 狠狠涩| 日韩在线不卡视频 | 国产精品一区二区三区四区 | 亚洲日本一区二区三区四区 | 国产成人短视频在线观看 | 欧美日本一区二区 | 日韩一区二区在线播放 | 日韩视频在线观看中文字幕 | 欧美在线视频a | 成人在线免费观看视频 | 午夜免费福利电影 | 欧美一级高潮片免费的 | 国产一区二区久久 | 中文字幕精品一区二区三区精品 | 日韩中文字幕av | 成人精品在线观看 | 久久久女女女女999久久 | 日本一区二区三区四区 | 精品国产一区二区在线 |