找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机串口程序调试问题,请大神们帮忙 按键让他发一条,它发9条

[复制链接]
跳转到指定楼层
楼主
#include <reg51.h>
#include "string.h"

#define uchar unsigned char
#define uint unsigned  int


sbit S1=P1^0;
sbit S2=P1^1;
sbit S3=P1^2;
sbit S4=P1^3;
void uart_init(void)
{
     TMOD = 0x20;
    SCON = 0x50;
    TH1 = 0xFA;
    TL1 = TH1;
    PCON = 0x00;
    EA = 1;
    ES = 1;
    TR1 = 1;

}
//

void uart_tx_byte(uchar dat)
{
   SBUF=dat;
   while(!TI);
   TI=0;



}

void uart_tx_string(uchar *P)
{
    while(*P)
           {
             uart_tx_byte(*P);
         P++;
           }
  }
void main()
{
   uart_init();


   while(1)
   {
      if(S1==0)    //按键S1按下
          {
            
                 uart_tx_string("EF 09 73 00 01 02 96 \n\r");
        
        
        
               
          }
          if(S2==0)   //按键S2按下
          {
            
                 uart_tx_string("EF 09 73 00 02 01 96 \n\r");

                        

          }
          if(S3==0)   //按键S3按下
          {
            
                 uart_tx_string("EF 09 66 03 00 00 83 \n\r");

                 
          }
          if (S4==0)
             uart_tx_string("EF 09 73 01 00 00 94 \n\r");
               
               
                 
          {
               
          }
            
   }

}


给位大神帮我看看哪里错了,每按一下按键让他发一条,它发9条。初学者,别笑话。

0.png (53.06 KB, 下载次数: 152)

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

使用道具 举报

沙发
ID:161164 发表于 2022-1-5 17:45 | 只看该作者
加个消抖延时就可以了
  1. void main()
  2. {
  3.         uart_init();

  4.         while(1)
  5.         {static unsigned char delay;
  6.                 if(S1==0 || S2==0 || S3==0 || S4==0)//有键按下
  7.                 {
  8.                         if(delay<0xFF)delay++;//消抖延时
  9.                         if(delay == 250)
  10.                         {
  11.                                 if(S1==0)    //按键S1按下
  12.                                 {
  13.                                         uart_tx_string("EF 09 73 00 01 02 96 \n\r");
  14.                                 }
  15.                                 if(S2==0)   //按键S2按下
  16.                                 {
  17.                                         uart_tx_string("EF 09 73 00 02 01 96 \n\r");
  18.                                 }
  19.                                 if(S3==0)   //按键S3按下
  20.                                 {
  21.                                         uart_tx_string("EF 09 66 03 00 00 83 \n\r");
  22.                                 }
  23.                                 if (S4==0)
  24.                                 {
  25.                                         uart_tx_string("EF 09 73 01 00 00 94 \n\r");
  26.                                 }                               
  27.                         }
  28.                 }else{
  29.                         delay = 0;
  30.                 }
  31.         }
  32. }
复制代码




回复

使用道具 举报

板凳
ID:139866 发表于 2022-1-5 17:51 | 只看该作者
发9条多吗,你这程序不发几十条算少的了
你理顺一下程序逻辑,看看你按下去按键的时候if判断走了多少次
回复

使用道具 举报

地板
ID:761175 发表于 2022-1-5 17:55 来自手机 | 只看该作者
天ノ忆 发表于 2022-1-5 17:51
发9条多吗,你这程序不发几十条算少的了
你理顺一下程序逻辑,看看你按下去按键的时候if判断走了多少次

谢了,跟盆友学写了个蹩脚程序,望多指教
回复

使用道具 举报

5#
ID:761175 发表于 2022-1-5 17:55 来自手机 | 只看该作者
lkc8210 发表于 2022-1-5 17:45
加个消抖延时就可以了

十分感谢,我试试
回复

使用道具 举报

6#
ID:761175 发表于 2022-1-5 18:03 | 只看该作者
lkc8210 发表于 2022-1-5 17:45
加个消抖延时就可以了

十分感谢,用你的程序好了。
回复

使用道具 举报

7#
ID:761175 发表于 2022-1-6 14:30 来自手机 | 只看该作者
稻草人008 发表于 2022-1-5 18:03
十分感谢,用你的程序好了。

大神你好现在又遇到新问题了,我在仿真上数据正常,烧到单片机里通过485转出来在串口助手上显示的数据不对。我改了下头文件,stc12c5410ad的

IMG_20220106_142618.jpg (1.28 MB, 下载次数: 131)

IMG_20220106_142618.jpg
回复

使用道具 举报

8#
ID:161164 发表于 2022-1-6 14:45 | 只看该作者
如果你现实用的是stc12c5410ad
要把定时器设为12分频
void UartInit(void)                //9600bps@22.1184MHz
{
        PCON &= 0x7F;                //波特率不倍速
        SCON = 0x50;                //8位数据,可变波特率
        AUXR &= 0xBF;                //定时器时钟12T模式
        AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
        TMOD &= 0x0F;                //设置定时器模式
        TMOD |= 0x20;                //设置定时器模式
        TL1 = 0xFA;                //设置定时初始值
        TH1 = 0xFA;                //设置定时重载值
        ET1 = 0;                //禁止定时器%d中断
        TR1 = 1;                //定时器1开始计时
        ES = 1;
        EA = 1;
}
回复

使用道具 举报

9#
ID:450849 发表于 2022-1-6 15:36 | 只看该作者
阻塞试延时是单片机程序设计最大的忌讳,
回复

使用道具 举报

10#
ID:761175 发表于 2022-1-6 18:31 来自手机 | 只看该作者
boboxuexi 发表于 2022-1-6 15:36
阻塞试延时是单片机程序设计最大的忌讳,

十分感谢,等忙完试试。
回复

使用道具 举报

11#
ID:908826 发表于 2022-1-6 19:45 | 只看该作者
正点原子论坛有个按键扫描程序,里面有个 静态变量的用法,你可以了解一下,有个对你有帮助。
回复

使用道具 举报

12#
ID:761175 发表于 2022-1-6 22:00 来自手机 | 只看该作者
13205495918 发表于 2022-1-6 19:45
正点原子论坛有个按键扫描程序,里面有个 静态变量的用法,你可以了解一下,有个对你有帮助。

好的谢了,我去看看
回复

使用道具 举报

13#
ID:761175 发表于 2022-1-7 15:08 | 只看该作者
lkc8210 发表于 2022-1-6 14:45
如果你现实用的是stc12c5410ad
要把定时器设为12分频
void UartInit(void)                //9600bps@22.1184MHz

高手,你好,现在都调出来了,
但是我发的EF 09 73 00 01 02 96这字符在串口上读出来的是ASCII正确,16进制45 46 20 30 39 20 37 33 20 30 30 20 30 32 20 30 31 20 39 36 20 0A 0D 。但是我要的是16位进制的。是不是需要转码
回复

使用道具 举报

14#
ID:161164 发表于 2022-1-7 15:21 | 只看该作者
稻草人008 发表于 2022-1-7 15:08
高手,你好,现在都调出来了,
但是我发的EF 09 73 00 01 02 96这字符在串口上读出来的是ASCII正确,16 ...

如果你要的是0xEF 0x09 0x73...就要转码
回复

使用道具 举报

15#
ID:761175 发表于 2022-1-7 18:35 来自手机 | 只看该作者
lkc8210 发表于 2022-1-7 15:21
如果你要的是0xEF 0x09 0x73...就要转码

我要的是16进制下的EF 09 73 00 01 02 96
回复

使用道具 举报

16#
ID:161164 发表于 2022-1-7 18:40 来自手机 | 只看该作者
稻草人008 发表于 2022-1-7 18:35
我要的是16进制下的EF 09 73 00 01 02 96

就是45 46 20 30 39 20 37 33 20 30 30 20 30 32 20 30 31 20 39 36 20 0A 0D吗?
那就不用转
回复

使用道具 举报

17#
ID:761175 发表于 2022-1-7 19:02 来自手机 | 只看该作者
lkc8210 发表于 2022-1-7 18:40
就是45 46 20 30 39 20 37 33 20 30 30 20 30 32 20 30 31 20 39 36 20 0A 0D吗?
那就不用转

是不是我发的被我指定为文本了,然后它在转了一遍
回复

使用道具 举报

18#
ID:761175 发表于 2022-1-7 19:07 来自手机 | 只看该作者
稻草人008 发表于 2022-1-7 19:02
是不是我发的被我指定为文本了,然后它在转了一遍

"EF 09 73 00 01 02 96这串数就是16进制的,在ascll上显示正常,在16进制下就被转了一下。是不是这样。
回复

使用道具 举报

19#
ID:761175 发表于 2022-1-7 19:16 来自手机 | 只看该作者
lkc8210 发表于 2022-1-7 18:40
就是45 46 20 30 39 20 37 33 20 30 30 20 30 32 20 30 31 20 39 36 20 0A 0D吗?
那就不用转

EF 09 73 00 01 02 96这串数就是16进制的,在ascll上显示正常,在16进制下就被转了一下。是不是这样。
回复

使用道具 举报

20#
ID:517466 发表于 2022-1-7 19:49 | 只看该作者
对于接收方,它不知道来的是什么数据,是ASCII还是十六进制数据,它都统一按照16进制收取。所以发送方即使发的是ASCII码,接收方会按照16进制收取ASCII码对应的16进制数据。实际上,无论收发,走在线路上的数据都是二进制数据0和1的组合而已。所以才有协议一说,接收方按照发射方的意图去解析数据。
回复

使用道具 举报

21#
ID:761175 发表于 2022-1-7 20:03 来自手机 | 只看该作者
suncat0504 发表于 2022-1-7 19:49
对于接收方,它不知道来的是什么数据,是ASCII还是十六进制数据,它都统一按照16进制收取。所以发送方即使 ...

但是我要的数据它在ASCII里传送正常,在16进制里就被编了一次,设备不认
回复

使用道具 举报

22#
ID:761175 发表于 2022-1-8 01:05 来自手机 | 只看该作者
lkc8210 发表于 2022-1-6 14:45
如果你现实用的是stc12c5410ad
要把定时器设为12分频
void UartInit(void)                //9600bps@22.1184MHz

大神你好,还是要请你帮忙。EF 09 73 00 01 02 96这串数就是16进制的,在ascll上显示正常,在16进制下就被从编了一遍。是不是这样。要怎么改。
回复

使用道具 举报

23#
ID:161164 发表于 2022-1-8 09:15 | 只看该作者
稻草人008 发表于 2022-1-7 19:02
是不是我发的被我指定为文本了,然后它在转了一遍

对~
所以你要以16进数组来发
char table_s1[] = {0xEF, 0x09, 0x73, 0x00, 0x02, 0x01, 0x96};
char table_s2[] = {0xEF, ...};
char table_s3[] = {0xEF, ...};
char table_s4[] = {0xEF, ...};

                                if(S1==0)    //按键S1按下
                                {
                                        uart_tx_string(table_s1);
                                }
                                if(S2==0)    //按键S2按下
                                {
                                        uart_tx_string(table_s2);
                                }
回复

使用道具 举报

24#
ID:761175 发表于 2022-1-8 10:42 来自手机 | 只看该作者
lkc8210 发表于 2022-1-8 09:15
对~
所以你要以16进数组来发
char table_s1[] = {0xEF, 0x09, 0x73, 0x00, 0x02, 0x01, 0x96};

谢谢,我是搞硬件的,对软件只知道点皮毛。。再次谢谢你的指点。
回复

使用道具 举报

25#
ID:517466 发表于 2022-1-8 11:09 | 只看该作者
稻草人008 发表于 2022-1-7 20:03
但是我要的数据它在ASCII里传送正常,在16进制里就被编了一次,设备不认

楼主,我觉得你应该抽点时间,看看串口通讯在芯片、线路上是怎么实现的。这个是基础,学明白了,如何解决问题,你会有重新认识。用来实现数据传送的,是芯片中的寄存器,你把数据送进去,通过线路送到接收方的寄存器。收发正常的场合,两边寄存器里的内容是一致的。当你把可显示、打印的ASCII和不可显示、打印的16禁止数据混合传输的时候,比如以下语句(假设printf做个输出转向,转向给串口输出,假设comout是输出16进制数据给串口):
printf("12345"); // 注:这五个字符,对应的6进制数据为:0x31,0x32,0x33,0x34,0x35
unsigned char dat[]={0xF1,0xC1,0x00,0x23};
comout(dat,0,3);  // 像串口发送dat数组中从0号元素开始,到3号元素截止的数据,包含0号元素和3号元素
那么经过这些发送,接收方收到的数据,以16进制表达:0x31,0x32,0x33,0x34,0x35,0xF1,0xC1,0x00,0x23
当你使用APP接收这些数据,如果以文本形式表示出来的时候,因为前五个对应的是可显示打印的数据,所以显示“12345”,但后五个是没法显示的。
上面的发送,是可以用以下形式,一样实现:
unsigned char dat[]={0x31,0x32,0x33,0x34,0x35,0xF1,0xC1,0x00,0x23};
comout(dat, 0, 8);
回复

使用道具 举报

26#
ID:761175 发表于 2022-1-8 11:30 | 只看该作者
suncat0504 发表于 2022-1-8 11:09
楼主,我觉得你应该抽点时间,看看串口通讯在芯片、线路上是怎么实现的。这个是基础,学明白了,如何解决 ...

谢谢指点,要好好学习学习一下
回复

使用道具 举报

27#
ID:761175 发表于 2022-1-8 13:22 | 只看该作者
lkc8210 发表于 2022-1-7 15:21
如果你要的是0xEF 0x09 0x73...就要转码

//发送字符串到串口助手
#include <STC12C5410AD.h>
#include "string.h"

#define uchar unsigned char
#define uint unsigned  int



sbit S1=P1^3;
sbit S2=P1^2;
sbit S3=P1^1;
sbit S4=P1^0;


char table_s1[] = {0xEF, 0x09, 0x73, 0x00, 0x01, 0x02, 0x96};
char table_s2[] = {0xEF, 0x09, 0x73, 0x00, 0x02, 0x01, 0x96};
char table_s3[] = {0xEF, 0x09, 0x66, 0x03, 0x00, 0x00, 0x83};
char table_s4[] = {0xEF, 0x09, 0x73, 0x01, 0x00, 0x00, 0x94};


//初始化
void uart_init(void)               //9600bps@22.1184MHz
{
        PCON &= 0x7F;                //波特率不倍速
        SCON = 0x50;                //8位数据,可变波特率
        AUXR &= 0xBF;                //定时器时钟12T模式
        AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
        TMOD &= 0x0F;                //设置定时器模式
        TMOD |= 0x20;                //设置定时器模式
        TL1 = 0xFA;                //设置定时初始值
        TH1 = 0xFA;                //设置定时重载值
        ET1 = 0;                //禁止定时器%d中断
        TR1 = 1;                //定时器1开始计时
        ES = 1;
        EA = 1;
   
}
//

void uart_tx_byte(uchar dat)
{
   SBUF=dat;
   while(!TI);
   TI=0;



}

void uart_tx_string(uchar *P)
{
    while(*P)
           {
             uart_tx_byte(*P);
         P++;
           }
  }
void main()
     
{
        uart_init();

        while(1)

   
        {static unsigned char delay;
                if(S1==0 || S2==0 || S3==0 || S4==0)//有键按下
              {
                        if(delay<0xFF)delay++;//消抖延时
                        if(delay == 250)
                        {
                                if(S1==0)    //按键S1按下
                                {
                                        uart_tx_string(table_s1);
                                }
                                if(S2==0)   //按键S2按下
                                {
                                        uart_tx_string(table_s2);
                                }
                                if(S3==0)   //按键S3按下
                                {
                                        uart_tx_string(table_s3);
                                }
                                if (S4==0)           //按键S4按下
                                {
                                        uart_tx_string(table_s4);
                                }                              
                        }
                }else{
                 
       delay = 0;
                }
        }
}不全
高手,在帮我看看。怎么数据发不全
发送1:EF 09 73 00 01 02 96
接收1:EF 09 73
发送2:EF 09 66 03 00 00 83
接收2:EF 09 66 03


回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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