找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

大家新年好,請教一個單片機串口通信問題

[復制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:269508 發(fā)表于 2018-2-19 18:20 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
我現(xiàn)在寫出來一個,單片機接收1個字符,用串口調(diào)試助手軟件通過串口向單片機發(fā)送數(shù)據(jù)。當發(fā)送的數(shù)據(jù)為1到8時,P1口分別對應點亮相應的發(fā)光二極管。發(fā)送其他數(shù)據(jù),蜂鳴器會響。 注意:波特率9600 。
1,現(xiàn)在我是想,如果我要一次接收3個字符,分別對應控制P0-P2口的LED燈。如何寫呢?10位通信,只能有8個位是數(shù)據(jù)。是串口通信,只能一個10位接一個10位的發(fā)。怎么區(qū)分第二個是對應P1口,第三個是對應P2口呢?
2,這個一次只能點亮1個LED燈,如果我想同時點亮多個LED燈,那該怎么寫呢?
最后祝大家,新年快樂,恭喜發(fā)財,萬事如意。

這個是我寫的代碼
#include <reg52.h>
        
#define uchar  unsigned char
#define uint   unsigned int

uchar buf;

sbit beep=P2^3;

void main(void)
{
    SCON=0x50;           //設定串口工作方式
    PCON=0x00;           //波特率不倍增
                        
    TMOD=0x20;           //定時器1工作于8位自動重載模式, 用于產(chǎn)生波特率
    EA=1;
    ES = 1;              //允許串口中斷
    TL1=0xfd;
    TH1=0xfd;             //波特率9600
    TR1=1;
    while(1);        
}
/*********************************************************

  串行中斷服務函數(shù)

*********************************************************/
void  serial() interrupt 4
{
   ES = 0;                //關閉串行中斷
   RI = 0;                //清除串行接受標志位
   buf = SBUF;            //從串口緩沖區(qū)取得數(shù)據(jù)
  switch(buf)
   {
      case 0x31:  P1=0xfe;beep=1;break;  //接受到1,第一個LED亮         
      case 0x32:  P1=0xfd;beep=1;break;  //接受到2,第二個LED亮        
      case 0x33:  P1=0xfb;beep=1;break;  //接受到3,第三個LED亮        
      case 0x34:  P1=0xf7;beep=1;break;  //接受到4,第四個LED亮      
      case 0x35:  P1=0xef;beep=1;break;  //接受到5,第五個LED亮            
      case 0x36:  P1=0xdf;beep=1;break;  //接受到5,第六個LED亮                  
      case 0x37:  P1=0xbf;beep=1;break;  //接受到5,第七個LED亮
          case 0x38:  P1=0x7f;beep=1;break;  //接受到5,第八個LED亮
          default:    beep=0;P1=0xff;break;  //接受到其它數(shù)據(jù),蜂鳴器響         
   }
   ES = 1;    //允許串口中斷
}

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

使用道具 舉報

沙發(fā)
ID:213173 發(fā)表于 2018-2-20 14:56 | 只看該作者
//利用串口傳輸控制信號不是簡單的發(fā)送一幀數(shù)據(jù),而是需要多功能的數(shù)據(jù)串,也不要把控制程序放在中斷里。
//以下是依你的程序和要求改為串口信號多功能控制,供參考。自定義協(xié)議:以此為例 "AA 55 AA 5A 59"共五位數(shù)據(jù)
//AA是數(shù)據(jù)頭,55 AA 5A 是三位有效數(shù)據(jù),59是數(shù)據(jù)尾,是三位有效數(shù)據(jù)和的余數(shù),依此驗證數(shù)據(jù)傳輸是否正確
#include <reg52.h>        
#define uchar  unsigned char
#define uint   unsigned int
uchar table0[] ="OK ";        //用于串口助手返回驗證
uchar table1[]="ERROR ";//用于串口助手返回驗證
uchar rec_buf[5];                        //數(shù)據(jù)緩存
bit flag=0;                                        //接收完成標志
bit sign=0;                                        //數(shù)據(jù)驗證標志
sbit beep=P2^3;

/**********串口發(fā)送函數(shù)*************/
void SendOneByte(uchar k)
{
    SBUF = k;                //發(fā)送數(shù)據(jù)
    while(!TI);        //等待發(fā)送完成
    TI = 0;                        //發(fā)送中斷請求標志位清0
}

void main(void)
{
        uchar i,j;                                //臨時變量
        SCON=0x50;           //設定串口工作方式
        PCON=0x00;           //波特率不倍增                        
        TMOD=0x20;           //定時器1工作于8位自動重載模式, 用于產(chǎn)生波特率
        TL1=0xfd;
        TH1=0xfd;             //波特率9600
        TR1=1;
        EA=1;
        ES = 1;              //允許串口中斷
        while(1)
        {/************數(shù)據(jù)解析*************/
                if(flag==1)                //5位數(shù)據(jù)串接收完成
                {
                        ES=0;                        //關串口中斷
                        flag=0;                //接收完成標志清0
                        j=rec_buf[1]+rec_buf[2]+rec_buf[3];//三位有效數(shù)據(jù)的和,溢出部分舍棄
                        if(rec_buf[4]==j)//驗證數(shù)據(jù)和
                        {
                                for(i=0;i<3;i++)
                                        SendOneByte(table0[i]);//返回串口助手字符"OK"
                                sign=1;                        //數(shù)據(jù)傳輸正確
                        }
                        else
                        {
                                for(i=0;i<6;i++)
                                        SendOneByte(table1[i]);//返回串口助手字符"ERROR"
                                sign=0;                        //數(shù)據(jù)傳輸錯誤
                        }
                        ES=1;                //開串口中斷

        /******控制任務*******/
                        if(sign==1)
                        {
                                P0=rec_buf[1];
                                P1=rec_buf[2];
                                P2=rec_buf[3];
                                beep=1;
                        }
                        else
                        {
                                P0=0xff;
                                P1=0xff;
                                P2=0xff;
                                beep=0;
                        }
                }
        }
}
/*********************************************************
  串口中斷服務函數(shù)
*********************************************************/
void serial() interrupt 4
{
        static uchar num=0;        //靜態(tài)計數(shù)變量
        RI=0;                                                //接收中斷請求標志位清0
        rec_buf[num]=SBUF;        //接收到的數(shù)據(jù)串保存在緩存數(shù)組
        if(rec_buf[0]==0xAA)        //驗證數(shù)據(jù)頭(起始位)
        {
                num++;
                if(num>=5)
                {
                        flag=1;                        //接收完成標志置1
                        num=0;                        //計數(shù)變量清0
                }
        }
}

評分

參與人數(shù) 1黑幣 +8 收起 理由
arthuryu + 8 贊一個!

查看全部評分

回復

使用道具 舉報

板凳
ID:222948 發(fā)表于 2018-2-20 15:12 | 只看該作者
一次接收3個是嗎,也就是說把這個分門別類就行,比如說接收到的數(shù)據(jù)是1,就寫p0=???;如果是2就寫p2=???;用case語句就足夠了

評分

參與人數(shù) 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

地板
ID:250496 發(fā)表于 2018-2-21 17:31 | 只看該作者
如果只是控制兩個端口的16個等的話,而且是可以一次點亮多個,如果是三幀數(shù)據(jù),可以對著三幀數(shù)據(jù)進行編碼,將解碼函數(shù)放在外部,不必放在串口中斷內(nèi),設置一個標志位,接收到數(shù)據(jù)后,標志位置1,主函數(shù)檢測到標志位時,關閉串口中斷以防下一幀數(shù)據(jù)影響到這一幀數(shù)據(jù)的處理,并進行數(shù)據(jù)的解碼以及置位標志位,解碼并執(zhí)行開關完畢后打開串口中斷,準備接收下一幀數(shù)據(jù)。
舉個例子
收到三幀數(shù)據(jù),00 fe 01
串口接收并存入數(shù)據(jù)緩沖區(qū)后,解碼函數(shù)對第一針數(shù)據(jù)解碼,00代表開燈操作,進入開燈的函數(shù),在開燈函數(shù)內(nèi)將收到的數(shù)據(jù)按位與進入P1端口,將第三幀數(shù)據(jù)按位或進入P2口,這時,第二第三針數(shù)據(jù)中對應的0位會使對應位輸出位零,
當收到第一幀數(shù)據(jù)為ff時,進入關燈程序,第二與第三幀要按位與進入對應的端口,否則會使某些燈關不掉。
當?shù)谝粠瑪?shù)據(jù)為其他時,蜂鳴器響。

評分

參與人數(shù) 1黑幣 +80 收起 理由
admin + 80 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

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

本版積分規(guī)則

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

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

快速回復 返回頂部 返回列表