找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机串口接收数据,程序不按照定义的模式发送,借助串口助手上显示的也仅仅是发送

[复制链接]
跳转到指定楼层
楼主
51单片机串口接收数据,但是程序不按照定义的模式发送,借助串口助手上显示的也仅仅是发送
#include <reg51.h>
typedef unsigned char u8;
typedef unsigned int u16;
u8 rec_buf[4];
u8 code str1[]={0x23,0x01,0x04,0x00,0x00,0x00,0x01,0x23};  
u8 code str2[]={0x23,0x01,0x04,0x00,0x00,0x00,0x02,0x23};
u8 code str3[]={0x23,0x01,0x04,0x00,0x00,0x00,0x03,0x23};
u8 code str4[]={0x23,0x01,0x04,0x00,0x00,0x00,0x04,0x23};
sbit led1=P0^0;
sbit led2=P0^1;
u16 m=3;
void InitUART(void)
{
    TMOD = 0x20;
    SCON = 0x50;
    TH1 = 0xFA;
    TL1 = TH1;
    PCON = 0x80;
    EA = 1;
    ES = 1;
    TR1 = 1;
}

void SendOneByte(unsigned char c)
{
    SBUF = c;
    while(!TI);
    TI = 0;
}
void main(void)
{
    InitUART();
}

void UARTInterrupt(void) interrupt 4
{
    if(RI)
    {
        RI = 0;
                          rec_buf[4]=SBUF;
                           if(rec_buf[m]==06)
                                         {
                                                 SendOneByte(str1);
           }
          else if(rec_buf[m]==19)
                                         {
                                                 SendOneByte(str2);
           }
            else if(rec_buf[m]==9)
                                         {
                                                 SendOneByte(str3);
           }
                                          else
                                                {
                                                        SendOneByte(str4);
                                                }
    }
    else
        TI = 0;
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:7485 发表于 2017-10-24 20:59 | 只看该作者
“51单片机串口接收数据,但是程序不按照定义的模式发送,借助串口助手上显示的也仅仅是发送”
看不明白,能说得清楚点吗?
回复

使用道具 举报

板凳
ID:237942 发表于 2017-10-25 09:30 | 只看该作者
我定义了4个数组(1,2,3,4)保存协议帧, 另外定义的四个数组(5,6,7,8)保存要使用的数据帧。当单片机接收的协议是(1,2,3,4)这四个数组中的任意一组时,单片机识别到对应的(5,6,7,8)中的任意一组协议,然后输出出来。现在问题是我无论输入什么,串口助手输出的数据都是我输入的数据。 我想是不是程序哪里出问题了, 还麻烦大家帮忙检查一下,给点意见。 谢谢!

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

地板
ID:213173 发表于 2017-10-25 10:40 | 只看该作者
本帖最后由 wulin 于 2017-10-25 11:26 编辑

你定义了缓存数组u8 rec_buf[4];使用范围只能是8位数据0~3,你定义了u16 m=3;,那么if(rec_buf[m]==06),这里数据类型不一致,而且接收到的数据被保存在一个不存在的位置rec_buf[4]=SBUF;。如果要发送数组内全部元素需要用循环
void UARTInterrupt() interrupt 4
{
        u8 i;
        if(RI)
        {
                RI = 0;
                rec_buf[3]=SBUF;
                if(rec_buf[m]==06)
                {
                        for(i=0;i<8;i++)
                        SendOneByte(str1);
                }

          ...........
          ...........

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

5#
ID:237942 发表于 2017-10-25 11:16 | 只看该作者
rec_buf[4]不存在么? 这个不是我定义的可以放4个数的数组么,这一点我觉得没问题。比如我要收的为{0x7E,0x41,0x06,0x0D}  {0x7E,0x41,0x19,0x0D} {0x7E,0x41,0x09,0x0D} {0x7E,0x41,0x03,0x0D},当查询到数组第三个数时,然后对应发送与之对应的数据 {0x23,0x01,0x04,0x00,0x00,0x00,0x01,0x23}   {0x23,0x01,0x04,0x00,0x00,0x00,0x02,0x23}   {0x23,0x01,0x04,0x00,0x00,0x00,0x03,0x23}   {0x23,0x01,0x04,0x00,0x00,0x00,0x04,0x23}  请问一下,具体我应该怎么修改
回复

使用道具 举报

6#
ID:237942 发表于 2017-10-25 11:20 | 只看该作者
还有一点问题,8位数据0~3是指什么? 我的每一个数据都是16进制,应该定义成int类型的么,这4位数能放4个16进制的数么
回复

使用道具 举报

7#
ID:213173 发表于 2017-10-25 11:49 | 只看该作者
本帖最后由 wulin 于 2017-10-25 12:08 编辑
GG276192978 发表于 2017-10-25 11:20
还有一点问题,8位数据0~3是指什么? 我的每一个数据都是16进制,应该定义成int类型的么,这4位数能放4个16 ...

你定义了缓存数组u8 rec_buf[4];就是这个数组有4个元素,使用时只能指定0~3,每个元素是8位2进制数0x00~0xff。如果要同时得到4个8位数字,要分4次中断接收并存入缓存。见楼上回传数据示例。

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

8#
ID:213173 发表于 2017-10-25 11:54 | 只看该作者
GG276192978 发表于 2017-10-25 11:20
还有一点问题,8位数据0~3是指什么? 我的每一个数据都是16进制,应该定义成int类型的么,这4位数能放4个16 ...

这是回传数组str1
回复

使用道具 举报

9#
ID:213173 发表于 2017-10-25 12:17 | 只看该作者
GG276192978 发表于 2017-10-25 11:20
还有一点问题,8位数据0~3是指什么? 我的每一个数据都是16进制,应该定义成int类型的么,这4位数能放4个16 ...

void UARTInterrupt() interrupt 4
{
        RI=0;
        rec_buf[ i]=SBUF;
        i++;
        if(i>=4)
        {
                i=0;        
                flag=1;//接收完成标志置1
                //其他运算放到主程序
        }
}

回复

使用道具 举报

10#
ID:237942 发表于 2017-10-26 15:36 | 只看该作者
wulin 发表于 2017-10-25 12:17
void UARTInterrupt() interrupt 4
{
        RI=0;

你说的逻辑挺对的,我也按照你说的改了,但是修改后的程序的效果并不理想,串口助手接收的数据也没有了。 下面是我按照你所讲的修改的程序
  1. #include <reg51.h>
  2. typedef unsigned char u8;
  3. typedef unsigned int u16;
  4. u16 i;
  5. u8 rec_buf[4]={0,0,0,0};
  6. u8 code str1[]={0x23,0x01,0x04,0x00,0x00,0x00,0x01,0x23};  //¶¨òåËÄ×éμÆ1aD-òé
  7. u8 code str2[]={0x23,0x01,0x04,0x00,0x00,0x00,0x02,0x23};
  8. u8 code str3[]={0x23,0x01,0x04,0x00,0x00,0x00,0x03,0x23};
  9. u8 code str4[]={0x23,0x01,0x04,0x00,0x00,0x00,0x04,0x23};

  10. u8 code table1[4]={0x7E,0x41,0x06,0x0D};       //¶¨òåËÄ×éμã¸èÏμí3D-òé
  11. u8 code table2[4]={0x7E,0x41,0x19,0x0D};
  12. u8 code table3[4]={0x7E,0x41,0x09,0x0D};
  13. u8 code table4[4]={0x7E,0x41,0x03,0x0D};

  14. void InitUART(void)
  15. {
  16.     TMOD = 0x20;  //¶¨ê±Æ÷1¤×÷·½ê½2
  17.     SCON = 0x50; // ′®¿ú1¤×÷·½ê½1£¬ÔêDí½óêÕ
  18.     TH1 = 0xFA;
  19.     TL1 = TH1;
  20.     PCON = 0x80;  //2¨ìØÂ걶Ôö
  21.     EA = 1;
  22.     ES = 1;
  23.     TR1 = 1;
  24. }

  25. void SendOneByte(unsigned char c)
  26. {
  27.     SBUF = c;
  28.     while(!TI);
  29.     TI = 0;
  30. }

  31. void main(void)
  32. {
  33.   InitUART();
  34.         if(rec_buf[4]==table1[4])
  35.                  {
  36.                          for(i=0;str1[i]!='\0';i++)
  37.                                         {
  38.                                                 SendOneByte(str1[i]);
  39.                                                 }
  40.            }
  41.           else if(rec_buf[4]==table2[4])
  42.                                          {
  43.                                                  for(i=0;str2[i]!='\0';i++)
  44.                                                 {
  45.                                                         SendOneByte(str2[i]);
  46.                                                 }
  47.            }
  48.            else if(rec_buf[4]==table3[4])
  49.                                          {
  50.                                                  for(i=0;str3[i]!='\0';i++)
  51.                                                 {
  52.                                                         SendOneByte(str3[i]);
  53.                                                 }
  54.            }
  55.                                           else
  56.                                                 {
  57.                                                         for(i=0;str4[i]!='\0';i++)
  58.                                                         {
  59.                                                         SendOneByte(str4[i]);
  60.                                                         }
  61.             }
  62.         while(1)
  63.         {
  64. }        
  65. }

  66. void UARTInterrupt(void) interrupt 4
  67. {
  68.     int j;
  69.            if(RI)
  70.         {
  71.                                         for(j=0;j<4;j++ )
  72.                              rec_buf[j]=SBUF;
  73.                                                 RI = 0;
  74.     }
  75.     else
  76.         TI = 0;
  77. }
复制代码
回复

使用道具 举报

11#
ID:237942 发表于 2017-10-26 15:57 | 只看该作者
我改好程序但不运行后,在汇编下看到是这个现象。 程序一直在R0和A之间循环
回复

使用道具 举报

12#
ID:237942 发表于 2017-10-26 15:59 | 只看该作者
wulin 发表于 2017-10-25 11:54
这是回传数组str1

回传数组str1? 是翻译成hex文件的6么?
回复

使用道具 举报

13#
ID:213173 发表于 2017-10-26 20:24 | 只看该作者

你的主函数这样写根本就跑不起来,不断重复初始化定时器,怎么能正常呢?
根据你的描述,给你大改动,程序运行正常,是不是完全是你想要的功能不得而知。
用串口助手分别发送4组数字:
7E 41 06 0D
7E 41 19 0D
7E 41 09 0D
7E 41 03 0D
回传接收分别为4组数字:
23 01 04 00 00 00 01 23
23 01 04 00 00 00 02 23
23 01 04 00 00 00 03 23
23 01 04 00 00 00 04 23
  1. /************************************/
  2. #include <reg51.h>
  3. typedef unsigned char u8;
  4. typedef unsigned int u16;
  5. u8 rec_buf[4];
  6. u8 code str1[]={0x23,0x01,0x04,0x00,0x00,0x00,0x01,0x23};  
  7. u8 code str2[]={0x23,0x01,0x04,0x00,0x00,0x00,0x02,0x23};
  8. u8 code str3[]={0x23,0x01,0x04,0x00,0x00,0x00,0x03,0x23};
  9. u8 code str4[]={0x23,0x01,0x04,0x00,0x00,0x00,0x04,0x23};
  10. sbit led1=P0^0;
  11. sbit led2=P0^1;
  12. u8 m=2;
  13. u8 i=0;
  14. bit flag=0;
  15. void InitUART()
  16. {
  17.     TMOD = 0x20;
  18.     SCON = 0x50;
  19.     TH1 = 0xFA;
  20.     TL1 = TH1;
  21.     PCON = 0x80;
  22.     EA = 1;
  23.     ES = 1;
  24.     TR1 = 1;
  25. }

  26. void SendOneByte(u8 c)
  27. {
  28.     SBUF = c;
  29.     while(!TI);
  30.     TI = 0;
  31. }
  32. void main()
  33. {
  34.         u8 i;
  35.         InitUART();
  36.         while(1)
  37.         {
  38.                 if(flag==1)
  39.                 {
  40.                         ES=0;                //关串口中断
  41.                         flag=0;
  42.                         if(rec_buf[m]==6)
  43.                         {
  44.                                 for(i=0;i<8;i++)
  45.                                 SendOneByte(str1[i]);
  46.                         }
  47.                         else if(rec_buf[m]==25)//0x19
  48.                         {
  49.                                 for(i=0;i<8;i++)
  50.                                 SendOneByte(str2[i]);
  51.                         }
  52.                         else if(rec_buf[m]==9)
  53.                         {
  54.                                 for(i=0;i<8;i++)
  55.                                 SendOneByte(str3[i]);
  56.                         }
  57.                         else
  58.                         {
  59.                                 for(i=0;i<8;i++)
  60.                                 SendOneByte(str4[i]);
  61.                         }
  62.                         ES=1;                //开串口中断
  63.                 }
  64.         }
  65. }

  66. void UARTInterrupt() interrupt 4
  67. {
  68.         RI=0;
  69.         rec_buf[i]=SBUF;
  70.         i++;
  71.         if(i>=4)
  72.         {
  73.                 i=0;        
  74.                 flag=1;//接收完成标志置1
  75.                 //其他运算放到主程序
  76.         }
  77. }
复制代码



回复

使用道具 举报

14#
ID:237942 发表于 2017-11-27 09:27 | 只看该作者
多谢大神,我上面的函数怎么会一直在初始化里跳不出来呢 ?
还想问一点,rec_buf[m]==25这里我不是应该写成rec_buf[m]==19么吗
回复

使用道具 举报

15#
ID:213173 发表于 2017-11-27 10:37 | 只看该作者
GG276192978 发表于 2017-11-27 09:27
多谢大神,我上面的函数怎么会一直在初始化里跳不出来呢 ?
还想问一点,rec_buf[m]==25这里我不是应该写 ...

1.你的main函数结构不对。初始化程序要放在主循环外。例如:
void main(void)
{
        InitUART();
        while (1)
        {
                //需要执行的任务
        }
}
2.串口助手发送19是16进制0x19,解析时可以写10进制25或16进制0x19。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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