本帖最后由 haokey 于 2021-4-29 09:40 编辑 qwettyuio 发表于 2021-4-28 10:30 我另外有一个建议,把uint x,y弄成局部变量,在forward和backward里面声明变量就可以了。 |
qwettyuio 发表于 2021-4-28 10:30 把流水灯放入主循环后现在是怎样了?如果还是不行有没有检查一下串口发送工具是不是加了换行? |
haokey 发表于 2021-4-28 10:22 流水灯不能循环,每次到第八个led就停了,所以叫了循环,还是不可以,加while1),就不能中断 |
这样写是几个意思? switch(keyval) while(1) { case 1:forward();break; case 2:backward();break; case 3:stop();break; case 4:flash();break; } |
名字不是重点 发表于 2021-4-28 09:52 加入中断代码出错,无法编译 |
名字不是重点 发表于 2021-4-28 09:50 能切换 |
其次,大循环空转,串口能反弹不? |
首先你大循环中,按我给的代码,4种模式能一直切换不? |
名字不是重点 发表于 2021-4-28 09:43 没法实现,通过串口调用数组控制流水等,大佬,求帮忙。 |
qwettyuio 发表于 2021-4-28 09:18 如果中断优先级高的话,死循环中也要触发中断的 |
名字不是重点 发表于 2021-4-27 20:06 进入了死循环,串口输入其它字符无效 |
你先在main()中改一下,加入: while(1) { switch(keyval) { case 1: forward(); break; case 2: backward(); break; case 3: stop(); break; case 4: flash(); break; default: break; } keyval++; if (keyval>4) keyval=1; } 看是不是能从模式1到4 ,一直循环? 确定之后,再在串口中断里改: void serial() interrupt 4 { ES = 0; //关闭串行中断 RI = 0; //清除串行接受标志位 keyval = SBUF; //从串口缓冲区取得数据 SBUF=keyval ;//反弹收到的数据 } 从上位机看看,收到的数据是不是你发出的数据,不丢码? |
tyrl800 发表于 2021-4-27 19:46 用的是开发板,是是11.596晶振 |
把你电路板上12M的晶振换成11.0592M就行了 |
game灬boy 发表于 2021-4-27 18:15 修改了也不可以,串口发送任何字符都没有用 |
建议将流水灯循环放入main函数的while1中 做出以下修改: int keyval_flag = 5 ; //定义标志位,表示流水灯运行方式 初始5为无操作 void main(void) //主函数 { SCON = 0x50; //设定串口工作方式 PCON = 0x00; //波特率不倍增 TMOD = 0x20; //定时器1工作于8位自动重载模式, 用于产生波特率 EA = 1; ES = 1; //允许串口中断 TL1 = 0xfd; TH1 = 0xfd; //波特率9600 TR1 = 1; while(1) { switch(flag) { case 1:forward();break; case 2:backward();break; case 3:stop();break; case 4:flash();break; default: break; } } } /************************************************* 函数功能:定时器T0的中断服务子程序 **************************************************/ void serial() interrupt 4 { ES = 0; //关闭串行中断 RI = 0; //清除串行接受标志位 keyval_flag = SBUF; //从串口缓冲区取得数据 ES = 1; //允许串口中断 } |
啊哈哈123 发表于 2021-4-27 17:38 #include<reg51.h> //包含51单片机寄存器定义的头文件 unsigned char keyval; //储存按键值 #define uchar unsigned char #define uint unsigned int code tabup[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; code tabdown[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe}; uint x,y; /************************************************* 函数功能:流水灯延时 **************************************************/ void led_delay(void) { unsigned char i,j; for(i=0;i<250;i++) for(j=0;j<250;j++); } /************************************************* 函数功能:软件消抖延时 **************************************************/ void delay20ms(void) { unsigned char i,j; for(i=0;i<100;i++) for(j=0;j<60;j++); } /************************************************* 函数功能:正向流水点亮LED **************************************************/ void forward(void) { //不能加while(1),会循环这一函数,其他按键控制无效 for(x=0;x<8;x++) { P1=tabup[x]; led_delay(); } } /************************************************* 函数功能:反向流水点亮LED **************************************************/ void backward(void) { //不能加while(1),会循环这一函数,其他按键控制无效 for(y=0;y<8;y++) { P1=tabdown[y]; led_delay(); } } /************************************************* 函数功能:关闭所有LED **************************************************/ void stop(void) { P1=0xff; //关闭8个LED } /************************************************* 函数功能:闪烁点亮LED **************************************************/ void flash(void) { P1=0x00; //点亮8个LED led_delay(); } void main(void) //主函数 { SCON = 0x50; //设定串口工作方式 PCON = 0x00; //波特率不倍增 TMOD = 0x20; //定时器1工作于8位自动重载模式, 用于产生波特率 EA = 1; ES = 1; //允许串口中断 TL1 = 0xfd; TH1 = 0xfd; //波特率9600 TR1 = 1; while(1); { switch(keyval) { case 1:forward();break; case 2:backward();break; case 3:stop();break; case 4:flash();break; } } } /************************************************* 函数功能:定时器T0的中断服务子程序 **************************************************/ void serial() interrupt 4 { ES = 0; //关闭串行中断 RI = 0; //清除串行接受标志位 keyval = SBUF; //从串口缓冲区取得数据 ES = 1; //允许串口中断 } |
啊哈哈123 发表于 2021-4-27 17:38 #include<reg51.h> //包含51单片机寄存器定义的头文件 unsigned char keyval; //储存按键值 #define uchar unsigned char #define uint unsigned int code tabup[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; code tabdown[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe}; uint x,y; /************************************************* 函数功能:流水灯延时 **************************************************/ void led_delay(void) { unsigned char i,j; for(i=0;i<250;i++) for(j=0;j<250;j++); } /************************************************* 函数功能:软件消抖延时 **************************************************/ void delay20ms(void) { unsigned char i,j; for(i=0;i<100;i++) for(j=0;j<60;j++); } /************************************************* 函数功能:正向流水点亮LED **************************************************/ void forward(void) { //不能加while(1),会循环这一函数,其他按键控制无效 for(x=0;x<8;x++) { P1=tabup[x]; led_delay(); } } /************************************************* 函数功能:反向流水点亮LED **************************************************/ void backward(void) { //不能加while(1),会循环这一函数,其他按键控制无效 for(y=0;y<8;y++) { P1=tabdown[y]; led_delay(); } } /************************************************* 函数功能:关闭所有LED **************************************************/ void stop(void) { P1=0xff; //关闭8个LED } /************************************************* 函数功能:闪烁点亮LED **************************************************/ void flash(void) { P1=0x00; //点亮8个LED led_delay(); } void main(void) //主函数 { SCON = 0x50; //设定串口工作方式 PCON = 0x00; //波特率不倍增 TMOD = 0x20; //定时器1工作于8位自动重载模式, 用于产生波特率 EA = 1; ES = 1; //允许串口中断 TL1 = 0xfd; TH1 = 0xfd; //波特率9600 TR1 = 1; while(1); { switch(keyval) { case 1:forward();break; case 2:backward();break; case 3:stop();break; case 4:flash();break; } } } /************************************************* 函数功能:定时器T0的中断服务子程序 **************************************************/ void serial() interrupt 4 { ES = 0; //关闭串行中断 RI = 0; //清除串行接受标志位 keyval = SBUF; //从串口缓冲区取得数据 ES = 1; //允许串口中断 } |
qwettyuio 发表于 2021-4-27 17:36 你改过的完整代码发出来看看 |
啊哈哈123 发表于 2021-4-27 17:34 没有任何反应 |
啊哈哈123 发表于 2021-4-27 17:34 发送了,一个led都不亮 |
qwettyuio 发表于 2021-4-27 16:58 你向串口发送数据了吗?用hex格式发送1 试试 |
名字不是重点 发表于 2021-4-27 17:24 修改不出来,找不出问题在哪里,小白一个,大佬技术指导一下,感谢 |
你为什么要把流水放在串口中断里动行?你串口没收到数据,就进不了中断‘,又如何能让 switch(keyval)这个有变化?即进了中断,也只能运行一次,除非你不停往串口发送数据。 把你所想的、所做的,画一个流程图,说不定你就能发现是逻辑问题了。。 这种纯属逻辑的代码,建议写代码前先画个流程图,能帮你更快地写出你想要的代码来。 磨刀不误砍柴工哦!!加油 |
啊哈哈123 发表于 2021-4-27 16:36 这样修改不行,没反应,一个led都不亮,原来的不能循环,从一到八,就定在八了 |
你这是通过一点一点问改的啊,挺用心的 你那边这样改应该就行了。 void main(void) //主函数 { SCON = 0x50; //设定串口工作方式 PCON = 0x00; //波特率不倍增 TMOD = 0x20; //定时器1工作于8位自动重载模式, 用于产生波特率 EA = 1; ES = 1; //允许串口中断 TL1 = 0xfd; TH1 = 0xfd; //波特率9600 TR1 = 1; while(1) { switch(keyval) { case 1:forward();break; case 2:backward();break; case 3:stop();break; case 4:flash();break; } } } /************************************************* 函数功能:定时器T0的中断服务子程序 **************************************************/ void serial() interrupt 4 { ES = 0; //关闭串行中断 RI = 0; //清除串行接受标志位 keyval = SBUF; //从串口缓冲区取得数据 ES = 1; //允许串口中断 } |