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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2838|回復: 9
打印 上一主題 下一主題
收起左側(cè)

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

[復制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:304431 發(fā)表于 2018-4-23 15:47 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
最近正在用51單片機做串口通信,已經(jīng)完成了基本的發(fā)送接收。想做更深入一點:1.對接收到的數(shù)據(jù)能進行解析,比如串口助手發(fā)送了一組電壓電流數(shù)據(jù):V1012A0022,要把它還原成電壓1.012伏,電路0.022A,用兩數(shù)碼管顯示出來。
2.發(fā)送數(shù)據(jù)能不用中斷嗎?現(xiàn)在用的是interrupt 0(外部中斷0),能不能不用中斷,用單片機上任意的一個口控制發(fā)送。

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

使用道具 舉報

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

使用道具 舉報

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

使用道具 舉報

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

使用道具 舉報

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

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

使用道具 舉報

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

沒有你想的那么復雜,給你寫一個示例程序參考,經(jīng)TX-1C實驗板與串口助手驗證無誤。
#include <reg51.h>
#define uint unsigned int
#define uchar unsigned char
sbit dula=P2^6;                        //段選
sbit wela=P2^7;                        //位選
uchar code table[]={                //共陰數(shù)碼管0~F、U數(shù)組
        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;//數(shù)碼管顯示位
bit flag=0;                                        //接收完成標
/*************初始化串口**************/
void InitUART()                //9600bps@11.0592MHz
{
        PCON &= 0x7F;                //波特率不倍速
        SCON = 0x50;                //8位數(shù)據(jù),可變波特率
        TMOD= 0x20;                        //設(shè)定定時器1為8位自動重裝方式
        TL1 = 0xFD;                        //設(shè)定定時初值
        TH1 = 0xFD;                        //設(shè)定定時器重裝值
        ET1 = 0;                                //禁止定時器1中斷
        TR1 = 1;                                //啟動定時器1
        EA = 1;                                //開總中斷
        ES = 1;                                //開串口中斷
}
/**********串口發(fā)送函數(shù)*************/
void SendOneByte(uchar c)
{
    SBUF = c;                //發(fā)送數(shù)據(jù)
    while(!TI);        //等待發(fā)送完成
    TI = 0;                        //發(fā)送中斷請求標志位清0
}
/************數(shù)據(jù)解析函數(shù)*************/
void analysis()
{
        uchar i;                        //臨時變量
        if(flag==1)                //一幀數(shù)據(jù)串接收完成
        {
                ES=0;                        //關(guān)串口中斷
                flag=0;                //接收完成標志清0
                if(rec_buf[5]==rec_buf[1]+rec_buf[2]+rec_buf[3]+rec_buf[4])//驗證數(shù)據(jù)和,超出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;//清除緩存數(shù)據(jù)
                }
                ES=1;                //開串口中斷
        }
}
/*************數(shù)據(jù)分解***************/
void Transformation()
{
        static uint i=0;
        static bit j=0;
        i++;
        if(i==7500)                //計數(shù)延時切換顯示內(nèi)容
        {
                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位數(shù)碼管顯示程序************/
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;                //顯示萬位段碼+小數(shù)點
                   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();        //數(shù)據(jù)解析
                Transformation();//數(shù)據(jù)分解
                display();        //數(shù)碼管顯示
        }
}
/*********串口中斷服務(wù)程序**********/
void UARTInterrupt() interrupt 4
{
        static uchar num=0;        //靜態(tài)計數(shù)變量
        RI=0;                                                //接收中斷請求標志位清0
        rec_buf[num]=SBUF;        //接收到的數(shù)據(jù)串保存在緩存數(shù)組
        if(rec_buf[0]==0xff)        //驗證數(shù)據(jù)頭(起始位)
        {
                num++;
                if(num>=6)
                {
                        flag=1;                        //接收完成標志置1
                        num=0;                        //計數(shù)變量清0
                }
        }
}
//0xff 0x01 0x0c 0x00 0x16 0x23


評分

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

查看全部評分

回復

使用道具 舉報

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

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

使用道具 舉報

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

謝謝您的解答!
回復

使用道具 舉報

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

使用道具 舉報

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

請教一下怎么發(fā)送?我每次發(fā)送數(shù)據(jù)都上位機都亂碼了
回復

使用道具 舉報

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

本版積分規(guī)則

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

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲国产成人精品女人久久久野战 | 国产精品久久久久久妇女6080 | 国产精品成人一区二区三区夜夜夜 | 久久久久无码国产精品一区 | 亚洲午夜精品视频 | 久久99精品久久久水蜜桃 | 久久亚洲一区 | 99久久久久久99国产精品免 | av色站| 久草视频2 | 成年人网站免费视频 | 天天插天天搞 | 欧美午夜影院 | 国产精品乱码一区二区三区 | 欧美一区二区在线观看 | 亚州国产| 一级黄色毛片免费 | 国产欧美精品一区二区三区 | 国产免费观看视频 | 精品久久久久久一区二区 | 国产乱码精品一区二区三区av | 一区二区三区四区在线 | 亚洲精品中文字幕 | 91精品国产乱码久久久久久久久 | 在线日韩中文字幕 | 成年视频在线观看福利资源 | 一区二区在线不卡 | 国产成人精品免费 | 国产一区在线免费观看视频 | 国产精品永久免费视频 | www.国产一区 | 天堂一区| 久久久久国产精品一区二区 | 国产成人福利在线 | 日韩视频在线播放 | 人人爽人人爽人人片av | 中文字幕第一页在线 | 日韩在线免费观看视频 | 国产伦一区二区三区四区 | 91偷拍精品一区二区三区 | 国产精品黄 |