找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2090|回复: 22
打印 上一主题 下一主题
收起左侧

利用串口接收ASCLL码作为单片机定时器定时值

[复制链接]
跳转到指定楼层
楼主
ID:322939 发表于 2023-6-13 14:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在串口助手上发送ascll码,单片机接收后将ascll码值赋给定时值(如控制字符是大写A,ASCLL值是65,定时值就是65分钟或小时),但接收到的数据由于进制不同,需转换成整数类型,是否要制作通讯协议?有那位大佬指点下?谢谢!
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:123289 发表于 2023-6-13 16:07 | 只看该作者
串口接收到了任何数,都认为二进制BIN码,其它一盖不论。
例如:串口现在收到一个字节是:01000001B,你可以将它解释为任意一个意思,比如:12345,65,ABCD……,天马行空,你可以任意相像!这取决于接收程序对【01000001B】是如何定义(解释)的。而不取决于发送方的定义!
所以:你只要在接收程序中,定义好所收到的每一个字节,及其组合,是什么意思就可以了。
例如:收到【00110001B】(31H),你可以认为是49,也可以认为是1,或其它什么的,都可以!
如果你用ASCII码系统对它做解释,就是字符“1”;
如果你用二进制数来解释,它就是49;
当然你也可以认为它是一个亮灯信号。于是你就点亮P1.3接口上的灯。
回复

使用道具 举报

板凳
ID:789121 发表于 2023-6-13 16:14 | 只看该作者
不是做通信使用,何不直接十六进制理解
回复

使用道具 举报

地板
ID:94031 发表于 2023-6-13 16:17 | 只看该作者
通信双方肯定要有协议,否则无法理解对方意思,只能靠猜。
回复

使用道具 举报

5#
ID:1080935 发表于 2023-6-13 16:36 | 只看该作者
可以使用标准协议,也可以自定义协议,双方约定好即可,在程序中处理。
回复

使用道具 举报

6#
ID:879348 发表于 2023-6-13 16:44 | 只看该作者
协议是肯定要的,串口本身就是不可靠的,人体碰一下线就有可能感应出字符
回复

使用道具 举报

7#
ID:322939 发表于 2023-6-13 16:50 | 只看该作者
yzwzfyz 发表于 2023-6-13 16:07
串口接收到了任何数,都认为二进制BIN码,其它一盖不论。
例如:串口现在收到一个字节是:01000001B,你可 ...

ascll码有128或256个字符,如果接收每个字符都进行判别计算转换,岂不是很麻烦?
回复

使用道具 举报

8#
ID:322939 发表于 2023-6-13 16:53 | 只看该作者
建立通讯协议这么多字符需要识别估计也头大,有没有简便的方法?
回复

使用道具 举报

9#
ID:744809 发表于 2023-6-13 17:07 | 只看该作者
LAW1100 发表于 2023-6-13 16:53
建立通讯协议这么多字符需要识别估计也头大,有没有简便的方法?

比如串口发 Time:265 你可以接收到以后放入数组,如unsigned char ReceiveBuf[15];
定义一个int 类型变量,int time;接收完一帧数据后,调用下面那行代码,
time = atoi(ReceiveBuf);
这样time这个变量的值就变成265了
回复

使用道具 举报

10#
ID:322939 发表于 2023-6-13 17:19 | 只看该作者
123156fsadf 发表于 2023-6-13 17:07
比如串口发 Time:265 你可以接收到以后放入数组,如unsigned char ReceiveBuf[15];
定义一个int 类型变 ...

多谢!我尝试下。
回复

使用道具 举报

11#
ID:883242 发表于 2023-6-13 18:45 | 只看该作者
A的ASCII码是65,你接受以后不需要任何转换。
回复

使用道具 举报

12#
ID:123289 发表于 2023-6-14 16:04 | 只看该作者
标准ASCII码就是个表格,不是256个,而是128个,从0000000-1111111。
你只要做一个,下次再用时,查表就可以了。
回复

使用道具 举报

13#
ID:883242 发表于 2023-6-14 17:07 | 只看该作者
yzwzfyz 发表于 2023-6-14 16:04
标准ASCII码就是个表格,不是256个,而是128个,从0000000-1111111。
你只要做一个,下次再用时,查表就可 ...

查什么表???

楼主接收到‘A’,就是65,延迟65秒,需要什么样的表?你给编一个。
回复

使用道具 举报

14#
ID:322939 发表于 2023-6-14 19:00 | 只看该作者
Hephaestus 发表于 2023-6-13 18:45
A的ASCII码是65,你接受以后不需要任何转换。

试过了,赋给定时值没反应,计时一直走时下去
回复

使用道具 举报

15#
ID:322939 发表于 2023-6-14 19:14 | 只看该作者
Hephaestus 发表于 2023-6-14 17:07
查什么表???

楼主接收到‘A’,就是65,延迟65秒,需要什么样的表?你给编一个。

我试过在串口助手发“a",接收后赋给定时值,计时却一直走下去,没作用。
unsigned  char   Recv_dat;
unsigned  char   Time_dat;
bit flag=0;
void T0_ver(void)  interrupt 1//设置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)//发送
{   
    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);
}
回复

使用道具 举报

16#
ID:883242 发表于 2023-6-14 19:29 | 只看该作者
LAW1100 发表于 2023-6-14 19:14
我试过在串口助手发“a",接收后赋给定时值,计时却一直走下去,没作用。
unsigned  char   Recv_dat;
...

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

2)在T0中断里面加个IO口翻转,用示波器看下时间是不是1ms。
回复

使用道具 举报

17#
ID:94031 发表于 2023-6-14 19:31 | 只看该作者
单片机接收后将值赋给定时器,直接发8位2进制数简单,方便,双方都不用转换,为什么要发ASCII码呢。
回复

使用道具 举报

18#
ID:322939 发表于 2023-6-14 20:50 | 只看该作者
Hephaestus 发表于 2023-6-14 19:29
1)串口助手接收到返回的'a'了么?

2)在T0中断里面加个IO口翻转,用示波器看下时间是不是1ms。

串口助手可以接收数据,通信没问题
回复

使用道具 举报

19#
ID:322939 发表于 2023-6-14 20:54 | 只看该作者
Hephaestus 发表于 2023-6-14 19:29
1)串口助手接收到返回的'a'了么?

2)在T0中断里面加个IO口翻转,用示波器看下时间是不是1ms。

定时器设置没问题,接收到ascll作为定时值,时间到了就停止计时归零
回复

使用道具 举报

20#
ID:322939 发表于 2023-6-14 20:59 | 只看该作者
xuyaqi 发表于 2023-6-14 19:31
单片机接收后将值赋给定时器,直接发8位2进制数简单,方便,双方都不用转换,为什么要发ASCII码呢。

如果以后遇到项目要求是发送ascll码这种条件那就不会了,客人不懂其它进制,只懂标准编码表
回复

使用道具 举报

21#
ID:401564 发表于 2023-6-18 18:13 | 只看该作者
控制不应该是电脑串口发送个类似"SET"的ASCLL码,然后,单片机识别到"SET"就进行设置这样的操作吗?
你发个A,定时器就是65,这好像一点关联都没有呀
单片机与串口通讯是要有协议的,串口很容易有干扰的我这有一段是单片机和串口屏之间的通讯协议,协议是我自己定的
以 # 为开始,以3个 0xff为结束
只有符合这个格式的,才判定为有效的命令
在串口中断中接收,在主函数中查找
数据的声明和定时器设定你自己搞定,这里的代码给你一个思路
void Uart1_Isr() interrupt 4                                                                //串口1中断函数
{
        static u8 RX_Count = 0x00, end_str = 0x00;                                //RX_Count接收数据数量,end_str结束符数量
        u8 temp;//
        if(TI)                                                                                                          //如果是发送中断触发,就处理发送中断
        {                          
                TI = CLR;                                                                                           //发送中断
                busy1 = CLR;                          
        }
        if(RI)
        {
                RI = CLR;                                                                                        //清除中断接收标示位
                temp = SBUF;                                                                                //读取接收到的数据
                Suart_re0.Uart_Re[RX_Count] = temp;                                        //接收到的数据保存到缓冲池中
                if(temp == 0xff)end_str++;                                                         //检测结束符,接收到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;                                                //防止数组溢出
                if(end_str >= 3)                                                                        //检测接收到3个0xff结束符
                {                       
                                end_str = 0;
                                RX_Count = 0;       
                                Suart_re1 = Suart_re0;                                                //接收到的数据转移
                                memset(&Suart_re0, 0, sizeof(Suart_re0));        //原有串口接收数据清除       
                }                                                                                                                           
        }                                                       
}


查找命令会用到strstr函数

        char *p;
        p = strstr(Suart_re1.Uart_Re,"#MODE_CH");//进入充电模式
        if(NULL != p)
        {
        指针返回值不是空的,就说明有这个        #MODE_CH
        }
回复

使用道具 举报

22#
ID:1034262 发表于 2023-6-18 20:39 | 只看该作者
非常简单:收到ASCII的65,放在data0、data1,则 (data0-'0')*10+data1-'0'。
回复

使用道具 举报

23#
ID:883242 发表于 2023-6-20 11:04 | 只看该作者
coody_sz 发表于 2023-6-18 20:39
非常简单:收到ASCII的65,放在data0、data1,则 (data0-'0')*10+data1-'0'。

不用转,他收到的是65,不是你以为的字符串“65”。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表