标题: 单片机串口程序调试问题,请大神们帮忙 按键让他发一条,它发9条 [打印本页]

作者: 稻草人008    时间: 2022-1-5 16:56
标题: 单片机串口程序调试问题,请大神们帮忙 按键让他发一条,它发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");
               
               
                 
          {
               
          }
            
   }

}

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

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

0.png

作者: lkc8210    时间: 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. }
复制代码





作者: 天ノ忆    时间: 2022-1-5 17:51
发9条多吗,你这程序不发几十条算少的了
你理顺一下程序逻辑,看看你按下去按键的时候if判断走了多少次
作者: 稻草人008    时间: 2022-1-5 17:55
天ノ忆 发表于 2022-1-5 17:51
发9条多吗,你这程序不发几十条算少的了
你理顺一下程序逻辑,看看你按下去按键的时候if判断走了多少次

谢了,跟盆友学写了个蹩脚程序,望多指教
作者: 稻草人008    时间: 2022-1-5 17:55
lkc8210 发表于 2022-1-5 17:45
加个消抖延时就可以了

十分感谢,我试试
作者: 稻草人008    时间: 2022-1-5 18:03
lkc8210 发表于 2022-1-5 17:45
加个消抖延时就可以了

十分感谢,用你的程序好了。
作者: 稻草人008    时间: 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

作者: lkc8210    时间: 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;
}

作者: boboxuexi    时间: 2022-1-6 15:36
阻塞试延时是单片机程序设计最大的忌讳,
作者: 稻草人008    时间: 2022-1-6 18:31
boboxuexi 发表于 2022-1-6 15:36
阻塞试延时是单片机程序设计最大的忌讳,

十分感谢,等忙完试试。
作者: 13205495918    时间: 2022-1-6 19:45
正点原子论坛有个按键扫描程序,里面有个 静态变量的用法,你可以了解一下,有个对你有帮助。
作者: 稻草人008    时间: 2022-1-6 22:00
13205495918 发表于 2022-1-6 19:45
正点原子论坛有个按键扫描程序,里面有个 静态变量的用法,你可以了解一下,有个对你有帮助。

好的谢了,我去看看
作者: 稻草人008    时间: 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位进制的。是不是需要转码
作者: lkc8210    时间: 2022-1-7 15:21
稻草人008 发表于 2022-1-7 15:08
高手,你好,现在都调出来了,
但是我发的EF 09 73 00 01 02 96这字符在串口上读出来的是ASCII正确,16 ...

如果你要的是0xEF 0x09 0x73...就要转码
作者: 稻草人008    时间: 2022-1-7 18:35
lkc8210 发表于 2022-1-7 15:21
如果你要的是0xEF 0x09 0x73...就要转码

我要的是16进制下的EF 09 73 00 01 02 96
作者: lkc8210    时间: 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吗?
那就不用转
作者: 稻草人008    时间: 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吗?
那就不用转

是不是我发的被我指定为文本了,然后它在转了一遍
作者: 稻草人008    时间: 2022-1-7 19:07
稻草人008 发表于 2022-1-7 19:02
是不是我发的被我指定为文本了,然后它在转了一遍

"EF 09 73 00 01 02 96这串数就是16进制的,在ascll上显示正常,在16进制下就被转了一下。是不是这样。
作者: 稻草人008    时间: 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进制下就被转了一下。是不是这样。
作者: suncat0504    时间: 2022-1-7 19:49
对于接收方,它不知道来的是什么数据,是ASCII还是十六进制数据,它都统一按照16进制收取。所以发送方即使发的是ASCII码,接收方会按照16进制收取ASCII码对应的16进制数据。实际上,无论收发,走在线路上的数据都是二进制数据0和1的组合而已。所以才有协议一说,接收方按照发射方的意图去解析数据。
作者: 稻草人008    时间: 2022-1-7 20:03
suncat0504 发表于 2022-1-7 19:49
对于接收方,它不知道来的是什么数据,是ASCII还是十六进制数据,它都统一按照16进制收取。所以发送方即使 ...

但是我要的数据它在ASCII里传送正常,在16进制里就被编了一次,设备不认
作者: 稻草人008    时间: 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进制下就被从编了一遍。是不是这样。要怎么改。
作者: lkc8210    时间: 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);
                                }
作者: 稻草人008    时间: 2022-1-8 10:42
lkc8210 发表于 2022-1-8 09:15
对~
所以你要以16进数组来发
char table_s1[] = {0xEF, 0x09, 0x73, 0x00, 0x02, 0x01, 0x96};

谢谢,我是搞硬件的,对软件只知道点皮毛。。再次谢谢你的指点。
作者: suncat0504    时间: 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);
作者: 稻草人008    时间: 2022-1-8 11:30
suncat0504 发表于 2022-1-8 11:09
楼主,我觉得你应该抽点时间,看看串口通讯在芯片、线路上是怎么实现的。这个是基础,学明白了,如何解决 ...

谢谢指点,要好好学习学习一下
作者: 稻草人008    时间: 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







欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1