完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
`还是郭老师的那个题目:以16进制发送一个0-65536之间的任一数,当单片机收到后在数码管上动态显示出来,波特率自定。我的问题是,我在串口助手上输入任何数,五个数码管只显示11366,代码如下: #include #define uchar unsigned char uchar flag; int a,ge,shi,bai,qian,wan; //个位、十位、百位、千位、万位 ***it dula=P2^6; ***it wela=P2^7; uchar code table[]={ 0x06,0x5b,0x4f, 0x66,0x6d,0x7d}; void init() { EA=1; ES=1; TMOD=0x20;//定时器1工作方式2 TH1=0xfd; TL1=0xfd; TR1=1; REN=1; SM0=0; SM1=1; dula=0; } void delay(uchar y) { uchar i,j; for(i=y;i>0;i--) for(j=118;j>0;j--); } void display(int x) { wan=x/10000; qian=x%10000/1000; bai=x%10000%1000/100; shi=x%100/10; ge=x%10; //从左到右,第1个数码管 dula=1; P0=table[wan]; dula=0; P0=0xff; wela=1; P0=0xfe; wela=0; delay(5); dula=1; //第2个数码管 P0=table[qian]; dula=0; P0=0xff; wela=1; P0=0xfd; wela=0; delay(5); //第3 个数码管 dula=1; P0=table[bai]; dula=0; P0=0xff; wela=1; P0=0xfb; wela=0; delay(5); dula=1; P0=table[shi]; dula=0; P0=0xff; wela=1; P0=0xf7; wela=0; delay(5); dula=1; P0=table[ge]; dula=0; P0=0xff; wela=1; P0=0xef; wela=0; delay(5); } void main() { init(); while(1) { if(flag==1) { ES=0 ; SBUF=a; //向PC端返回要显示的值 while(!ti); TI=0; display(a); ES=1; } } } void serial() interrupt 4 { RI=0; a=SBUF; //将接受到的值给a flag=1; } @一抹阳光 @爱我别走 麻烦你们了 ` ![]() |
|
相关推荐
7个回答
|
|
纠正你几个错误。
其一:变量分配问题,flag只用到了0,1两个状态51可以定义成bit型节省空间,ge、shi……应该放在display()函数中定义成局部变量。 其二:段码数组不完整。0~9显示码不管共阴共阳有10个的(0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07共阴) 其三:flag变量赋值以后没有清零,main函数不断执行if(flag)条件下的语句块。失去flag的意义了。display函数正常应该放在while(1)第一层下只做显示用。 其四:串口信息帧中,一次接受、发送一个字符。怎么能赋值给5位数呢?思路:定义一个接收缓冲区,buf[5]类似的,开拓出5个字节的空间保存你的5位数数据。当然你也可以简单的一个变量用算法把接受的二进制数据组合到两个字节的int型中。 其五:串口助手发送字符一般用字符型发送,接收的时候,buf=SBUF&0X0F;去低位,例如:发送2,数据形式为0x32;取低位,为2保存在缓存中,再进行处理。 有问题再交流。先解决以上的。 |
|
|
|
|
|
|
|
本帖最后由 一抹阳光 于 2013-7-3 10:04 编辑
在尽量保证你原有程序结构不变的情况下,对你的程序进行了改正,所有存在问题隐患,或错误的语句前均加有注释并已修改,可以对照你原有程序查看,如有疑问可以继续交流。 另外对于串口调试助手,你在发送数据的时候,如果选择的是16进制发送就应该输入十六进制的数,比如你要发送65534的时候就输入FF FE,而不是65534,如果你输入的是"65534",并以16进制发送,实际单片机收到的是0X65 0x53,这不符合你的初衷,对于此程序如果你需要让数码管显示65535,那么必须在串口调试助手输入对应的16进制数FF FF再以16进制形式发送,否则出错,同理其他数字先应转换为16进制,而如果你以字符型发送那么单片机收到的则是每个字符对应的ASCII值,比如你已字符型发送123,实际发出的则是0x31 0x32 0x33,这样的数据与我定的数据格式不符,因而也无法正常显示,当然你如果想输入字符数字,数码管直接显示,这也是可以做到的,需要另外定义数据格式,更改程序,或者对上位机串口助手进行修改。但对于你们这道作业题实际上题意是让发送16进制数而不是字符。 这里我将串口接收数据的格式定为:两个字节为一段数据,前者为高8位,无数据校验。
|
|
|
|
首先,很感谢@一抹阳光 耐心地给我修改冗长的代码,通过你的注释,我对串口通信又多了一些理解.接下来就讲一下一个细节问题吧,我用你改好的的代码测试的时候,发现,如果我第一次发送"ff",数码管显示"255",但第二次发送"ff"时,数码管却显示"65535",所以,我就修改了一下串口接受中断: /*这里我定义了两个全局变量 i 和 j ,根据版主的的说法,我也定义了 uint buf[2] 作为缓存*/ void serial() interrupt 4 { //变量i计数收到数据的个数,j作为标志 if(RI==1) { RI=0; if(j==2) //第三次发送的数据,放到高8位 j=0; buf[j]=SBUF; i++; j++; if(i==3) i=1; //第三个字节做为第一个字节处理 } if(i==1) a=buf[0]; if(i==2) a=buf[0]*256+buf[1]; flag=1 ; } 一开始,我是在中断中对 i,j 清零的,但是这样做还是有问题,所以我就将其改在main中进行: void main() { init(); while(1) { display(a); if(flag==1) { flag=0; ES=0; SBUF=a/256; while(!TI); TI=0; SBUF=a%256; while(!TI); TI=0; ES=1; i=0;j=0; //发送结束后,对i,j清零 } } } |
|
|
|
谢谢版主的建议,我已经做了修改,问题基本解决 |
|
|
|
|
|
|
|
受益匪浅,谢谢大神解析
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
龙芯中科胡伟武:3B6600 八核桌面 CPU 性能将达到英特尔中高端酷睿 12~13 代水平
425 浏览 0 评论
树莓派Pico 2发布,搭载RP2350双核RISC-V和Arm Cortex-M33微控制器!
413 浏览 0 评论
嵌入式学习-搭建自己的ubuntu系统之VMware Tools安装
373 浏览 0 评论
嵌入式学习-搭建自己的ubuntu系统之ubuntu系统安装
590 浏览 0 评论
国产芯上运行TinyMaxi轻量级的神经网络推理库-米尔基于芯驰D9国产商显板
648 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
10655 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-8-14 10:18 , Processed in 0.886504 second(s), Total 85, Slave 66 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191