標(biāo)題: 利用串口接收ASCLL碼作為單片機(jī)定時器定時值 [打印本頁]

作者: LAW1100    時間: 2023-6-13 14:43
標(biāo)題: 利用串口接收ASCLL碼作為單片機(jī)定時器定時值
在串口助手上發(fā)送ascll碼,單片機(jī)接收后將ascll碼值賦給定時值(如控制字符是大寫A,ASCLL值是65,定時值就是65分鐘或小時),但接收到的數(shù)據(jù)由于進(jìn)制不同,需轉(zhuǎn)換成整數(shù)類型,是否要制作通訊協(xié)議?有那位大佬指點(diǎn)下?謝謝!

作者: yzwzfyz    時間: 2023-6-13 16:07
串口接收到了任何數(shù),都認(rèn)為二進(jìn)制BIN碼,其它一蓋不論。
例如:串口現(xiàn)在收到一個字節(jié)是:01000001B,你可以將它解釋為任意一個意思,比如:12345,65,ABCD……,天馬行空,你可以任意相像!這取決于接收程序?qū)Α?1000001B】是如何定義(解釋)的。而不取決于發(fā)送方的定義!
所以:你只要在接收程序中,定義好所收到的每一個字節(jié),及其組合,是什么意思就可以了。
例如:收到【00110001B】(31H),你可以認(rèn)為是49,也可以認(rèn)為是1,或其它什么的,都可以!
如果你用ASCII碼系統(tǒng)對它做解釋,就是字符“1”;
如果你用二進(jìn)制數(shù)來解釋,它就是49;
當(dāng)然你也可以認(rèn)為它是一個亮燈信號。于是你就點(diǎn)亮P1.3接口上的燈。
作者: 不要黑    時間: 2023-6-13 16:14
不是做通信使用,何不直接十六進(jìn)制理解
作者: xuyaqi    時間: 2023-6-13 16:17
通信雙方肯定要有協(xié)議,否則無法理解對方意思,只能靠猜。
作者: LaoYuTou    時間: 2023-6-13 16:36
可以使用標(biāo)準(zhǔn)協(xié)議,也可以自定義協(xié)議,雙方約定好即可,在程序中處理。
作者: wufa1986    時間: 2023-6-13 16:44
協(xié)議是肯定要的,串口本身就是不可靠的,人體碰一下線就有可能感應(yīng)出字符
作者: LAW1100    時間: 2023-6-13 16:50
yzwzfyz 發(fā)表于 2023-6-13 16:07
串口接收到了任何數(shù),都認(rèn)為二進(jìn)制BIN碼,其它一蓋不論。
例如:串口現(xiàn)在收到一個字節(jié)是:01000001B,你可 ...

ascll碼有128或256個字符,如果接收每個字符都進(jìn)行判別計算轉(zhuǎn)換,豈不是很麻煩?
作者: LAW1100    時間: 2023-6-13 16:53
建立通訊協(xié)議這么多字符需要識別估計也頭大,有沒有簡便的方法?
作者: 123156fsadf    時間: 2023-6-13 17:07
LAW1100 發(fā)表于 2023-6-13 16:53
建立通訊協(xié)議這么多字符需要識別估計也頭大,有沒有簡便的方法?

比如串口發(fā) Time:265 你可以接收到以后放入數(shù)組,如unsigned char ReceiveBuf[15];
定義一個int 類型變量,int time;接收完一幀數(shù)據(jù)后,調(diào)用下面那行代碼,
time = atoi(ReceiveBuf);
這樣time這個變量的值就變成265了
作者: LAW1100    時間: 2023-6-13 17:19
123156fsadf 發(fā)表于 2023-6-13 17:07
比如串口發(fā) Time:265 你可以接收到以后放入數(shù)組,如unsigned char ReceiveBuf[15];
定義一個int 類型變 ...

多謝!我嘗試下。
作者: Hephaestus    時間: 2023-6-13 18:45
A的ASCII碼是65,你接受以后不需要任何轉(zhuǎn)換。
作者: yzwzfyz    時間: 2023-6-14 16:04
標(biāo)準(zhǔn)ASCII碼就是個表格,不是256個,而是128個,從0000000-1111111。
你只要做一個,下次再用時,查表就可以了。
作者: Hephaestus    時間: 2023-6-14 17:07
yzwzfyz 發(fā)表于 2023-6-14 16:04
標(biāo)準(zhǔn)ASCII碼就是個表格,不是256個,而是128個,從0000000-1111111。
你只要做一個,下次再用時,查表就可 ...

查什么表???

樓主接收到‘A’,就是65,延遲65秒,需要什么樣的表?你給編一個。
作者: LAW1100    時間: 2023-6-14 19:00
Hephaestus 發(fā)表于 2023-6-13 18:45
A的ASCII碼是65,你接受以后不需要任何轉(zhuǎn)換。

試過了,賦給定時值沒反應(yīng),計時一直走時下去
作者: LAW1100    時間: 2023-6-14 19:14
Hephaestus 發(fā)表于 2023-6-14 17:07
查什么表???

樓主接收到‘A’,就是65,延遲65秒,需要什么樣的表?你給編一個。

我試過在串口助手發(fā)“a",接收后賦給定時值,計時卻一直走下去,沒作用。
unsigned  char   Recv_dat;
unsigned  char   Time_dat;
bit flag=0;
void T0_ver(void)  interrupt 1//設(shè)置1ms
{
  t++;
      if(t>=1000)//1秒
        {
                t=0;
                min++;
               
        }
        if(min>59)
        {
                min=0;
                hour++;
               
        }
        if(hour>=Time_dat)
        {
                hour=0;
               LED5=1;
              TR0=0;
    }
}
/***********串口初始化*************/
void UartInit()
{
  SCON = 0x50;                //8???,?????
        AUXR &= 0xBF;                //?????12T??
        AUXR &= 0xFE;                //??1?????1???????
        TMOD &= 0x0F;                //???????
        TL1 = 0x40;                //???????
        TH1 = 0xFF;                //???????
        ET1 = 0;                //?????%d??
        TR1 = 1;                //???1????
        ES=1;
        EA=1;
}
/************串口中斷*****************/
void UartIsr() interrupt 4
{
    if (TI)
    {
        TI = 0;
        busy = 0;
    }
    if (RI)
    {
        RI = 0;
         flag=1;
       Recv_dat = SBUF;
     
    }
}
void SendByte(char dat)//發(fā)送
{   
    SBUF = dat;
          while(!TI);
          TI=0;
}
void main(void)

   Timer_Init();
          UartInit();
while(1)
{

   if(flag==1)
   {
        flag=0;
   Time_dat=Recv_dat;
SendByte(Recv_dat);
}

作者: Hephaestus    時間: 2023-6-14 19:29
LAW1100 發(fā)表于 2023-6-14 19:14
我試過在串口助手發(fā)“a",接收后賦給定時值,計時卻一直走下去,沒作用。
unsigned  char   Recv_dat;
...

1)串口助手接收到返回的'a'了么?

2)在T0中斷里面加個IO口翻轉(zhuǎn),用示波器看下時間是不是1ms。
作者: xuyaqi    時間: 2023-6-14 19:31
單片機(jī)接收后將值賦給定時器,直接發(fā)8位2進(jìn)制數(shù)簡單,方便,雙方都不用轉(zhuǎn)換,為什么要發(fā)ASCII碼呢。
作者: LAW1100    時間: 2023-6-14 20:50
Hephaestus 發(fā)表于 2023-6-14 19:29
1)串口助手接收到返回的'a'了么?

2)在T0中斷里面加個IO口翻轉(zhuǎn),用示波器看下時間是不是1ms。

串口助手可以接收數(shù)據(jù),通信沒問題
作者: LAW1100    時間: 2023-6-14 20:54
Hephaestus 發(fā)表于 2023-6-14 19:29
1)串口助手接收到返回的'a'了么?

2)在T0中斷里面加個IO口翻轉(zhuǎn),用示波器看下時間是不是1ms。

定時器設(shè)置沒問題,接收到ascll作為定時值,時間到了就停止計時歸零
作者: LAW1100    時間: 2023-6-14 20:59
xuyaqi 發(fā)表于 2023-6-14 19:31
單片機(jī)接收后將值賦給定時器,直接發(fā)8位2進(jìn)制數(shù)簡單,方便,雙方都不用轉(zhuǎn)換,為什么要發(fā)ASCII碼呢。

如果以后遇到項目要求是發(fā)送ascll碼這種條件那就不會了,客人不懂其它進(jìn)制,只懂標(biāo)準(zhǔn)編碼表
作者: Y_G_G    時間: 2023-6-18 18:13
控制不應(yīng)該是電腦串口發(fā)送個類似"SET"的ASCLL碼,然后,單片機(jī)識別到"SET"就進(jìn)行設(shè)置這樣的操作嗎?
你發(fā)個A,定時器就是65,這好像一點(diǎn)關(guān)聯(lián)都沒有呀
單片機(jī)與串口通訊是要有協(xié)議的,串口很容易有干擾的我這有一段是單片機(jī)和串口屏之間的通訊協(xié)議,協(xié)議是我自己定的
以 # 為開始,以3個 0xff為結(jié)束
只有符合這個格式的,才判定為有效的命令
在串口中斷中接收,在主函數(shù)中查找
數(shù)據(jù)的聲明和定時器設(shè)定你自己搞定,這里的代碼給你一個思路
void Uart1_Isr() interrupt 4                                                                //串口1中斷函數(shù)
{
        static u8 RX_Count = 0x00, end_str = 0x00;                                //RX_Count接收數(shù)據(jù)數(shù)量,end_str結(jié)束符數(shù)量
        u8 temp;//
        if(TI)                                                                                                          //如果是發(fā)送中斷觸發(fā),就處理發(fā)送中斷
        {                          
                TI = CLR;                                                                                           //發(fā)送中斷
                busy1 = CLR;                          
        }
        if(RI)
        {
                RI = CLR;                                                                                        //清除中斷接收標(biāo)示位
                temp = SBUF;                                                                                //讀取接收到的數(shù)據(jù)
                Suart_re0.Uart_Re[RX_Count] = temp;                                        //接收到的數(shù)據(jù)保存到緩沖池中
                if(temp == 0xff)end_str++;                                                         //檢測結(jié)束符,接收到0xff就加1
                else if (end_str > 0)end_str--;                                                //否則減1
                if(Suart_re0.Uart_Re[RX_Count] == '#')RX_Count = 0;        //檢測開始接收到"#",所有命令要以'#'開頭,重新開始接收                                                                                                     
                RX_Count++;                                                                                        //
                if(RX_Count >= 30)RX_Count = 0;                                                //防止數(shù)組溢出
                if(end_str >= 3)                                                                        //檢測接收到3個0xff結(jié)束符
                {                       
                                end_str = 0;
                                RX_Count = 0;       
                                Suart_re1 = Suart_re0;                                                //接收到的數(shù)據(jù)轉(zhuǎn)移
                                memset(&Suart_re0, 0, sizeof(Suart_re0));        //原有串口接收數(shù)據(jù)清除       
                }                                                                                                                           
        }                                                       
}


查找命令會用到strstr函數(shù)

        char *p;
        p = strstr(Suart_re1.Uart_Re,"#MODE_CH");//進(jìn)入充電模式
        if(NULL != p)
        {
        指針返回值不是空的,就說明有這個        #MODE_CH
        }

作者: coody_sz    時間: 2023-6-18 20:39
非常簡單:收到ASCII的65,放在data0、data1,則 (data0-'0')*10+data1-'0'。
作者: Hephaestus    時間: 2023-6-20 11:04
coody_sz 發(fā)表于 2023-6-18 20:39
非常簡單:收到ASCII的65,放在data0、data1,則 (data0-'0')*10+data1-'0'。

不用轉(zhuǎn),他收到的是65,不是你以為的字符串“65”。






歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1