lkc8210 发表于 2022-1-7 15:21 //发送字符串到串口助手 #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 |
suncat0504 发表于 2022-1-8 11:09 谢谢指点,要好好学习学习一下 |
稻草人008 发表于 2022-1-7 20:03 楼主,我觉得你应该抽点时间,看看串口通讯在芯片、线路上是怎么实现的。这个是基础,学明白了,如何解决问题,你会有重新认识。用来实现数据传送的,是芯片中的寄存器,你把数据送进去,通过线路送到接收方的寄存器。收发正常的场合,两边寄存器里的内容是一致的。当你把可显示、打印的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); |
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); } |
lkc8210 发表于 2022-1-6 14:45 大神你好,还是要请你帮忙。EF 09 73 00 01 02 96这串数就是16进制的,在ascll上显示正常,在16进制下就被从编了一遍。是不是这样。要怎么改。 |
suncat0504 发表于 2022-1-7 19:49 但是我要的数据它在ASCII里传送正常,在16进制里就被编了一次,设备不认 |
对于接收方,它不知道来的是什么数据,是ASCII还是十六进制数据,它都统一按照16进制收取。所以发送方即使发的是ASCII码,接收方会按照16进制收取ASCII码对应的16进制数据。实际上,无论收发,走在线路上的数据都是二进制数据0和1的组合而已。所以才有协议一说,接收方按照发射方的意图去解析数据。 |
lkc8210 发表于 2022-1-7 18:40 EF 09 73 00 01 02 96这串数就是16进制的,在ascll上显示正常,在16进制下就被转了一下。是不是这样。 |
稻草人008 发表于 2022-1-7 19:02 "EF 09 73 00 01 02 96这串数就是16进制的,在ascll上显示正常,在16进制下就被转了一下。是不是这样。 |
lkc8210 发表于 2022-1-7 18:40 是不是我发的被我指定为文本了,然后它在转了一遍 |
稻草人008 发表于 2022-1-7 18:35 就是45 46 20 30 39 20 37 33 20 30 30 20 30 32 20 30 31 20 39 36 20 0A 0D吗? 那就不用转 |
lkc8210 发表于 2022-1-7 15:21 我要的是16进制下的EF 09 73 00 01 02 96 |
稻草人008 发表于 2022-1-7 15:08 如果你要的是0xEF 0x09 0x73...就要转码 |
lkc8210 发表于 2022-1-6 14:45 高手,你好,现在都调出来了, 但是我发的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位进制的。是不是需要转码 |
13205495918 发表于 2022-1-6 19:45 好的谢了,我去看看 |
![]() |
boboxuexi 发表于 2022-1-6 15:36 十分感谢,等忙完试试。 |
阻塞试延时是单片机程序设计最大的忌讳, |
如果你现实用的是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; } |
lkc8210 发表于 2022-1-5 17:45 十分感谢,用你的程序好了。 |
lkc8210 发表于 2022-1-5 17:45 十分感谢,我试试 |
天ノ忆 发表于 2022-1-5 17:51 谢了,跟盆友学写了个蹩脚程序,望多指教 |
发9条多吗,你这程序不发几十条算少的了 你理顺一下程序逻辑,看看你按下去按键的时候if判断走了多少次 |
加个消抖延时就可以了
|