找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

为什么单片机流水灯由1到8就停止了。编译没有问题,求解怎么修改代码可以运行

查看数: 2667 | 评论数: 26 | 收藏 0
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2021-4-27 15:48

正文摘要:

本帖最后由 qwettyuio 于 2021-4-28 10:28 编辑 #include<reg51.h>    //包含51单片机寄存器定义的头文件 unsigned char keyval;  //储存按键值 #define uchar unsigned char #define ...

回复

ID:569384 发表于 2021-4-29 09:35
本帖最后由 haokey 于 2021-4-29 09:40 编辑
qwettyuio 发表于 2021-4-28 10:30
流水灯不能循环,每次到第八个led就停了,所以叫了循环,还是不可以,加while1),就不能中断

我另外有一个建议,把uint x,y弄成局部变量,在forward和backward里面声明变量就可以了。
ID:569384 发表于 2021-4-29 09:31
qwettyuio 发表于 2021-4-28 10:30
流水灯不能循环,每次到第八个led就停了,所以叫了循环,还是不可以,加while1),就不能中断

把流水灯放入主循环后现在是怎样了?如果还是不行有没有检查一下串口发送工具是不是加了换行?
ID:858009 发表于 2021-4-28 10:30
haokey 发表于 2021-4-28 10:22
这样写是几个意思?
switch(keyval)
                 while(1)

流水灯不能循环,每次到第八个led就停了,所以叫了循环,还是不可以,加while1),就不能中断
ID:569384 发表于 2021-4-28 10:22
这样写是几个意思?
switch(keyval)
                 while(1)
   {
      case 1:forward();break;
      case 2:backward();break;
      case 3:stop();break;
      case 4:flash();break;
   }
ID:858009 发表于 2021-4-28 09:54
名字不是重点 发表于 2021-4-28 09:52
其次,大循环空转,串口能反弹不?

加入中断代码出错,无法编译
ID:858009 发表于 2021-4-28 09:52
名字不是重点 发表于 2021-4-28 09:50
首先你大循环中,按我给的代码,4种模式能一直切换不?

能切换
ID:824490 发表于 2021-4-28 09:52
其次,大循环空转,串口能反弹不?
ID:824490 发表于 2021-4-28 09:50
首先你大循环中,按我给的代码,4种模式能一直切换不?
ID:858009 发表于 2021-4-28 09:47
名字不是重点 发表于 2021-4-28 09:43
如果中断优先级高的话,死循环中也要触发中断的

没法实现,通过串口调用数组控制流水等,大佬,求帮忙。
ID:824490 发表于 2021-4-28 09:43
qwettyuio 发表于 2021-4-28 09:18
进入了死循环,串口输入其它字符无效

如果中断优先级高的话,死循环中也要触发中断的
ID:858009 发表于 2021-4-28 09:18
名字不是重点 发表于 2021-4-27 20:06
你先在main()中改一下,加入:
       while(1)
{

进入了死循环,串口输入其它字符无效
ID:824490 发表于 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  ;//反弹收到的数据
  
}

从上位机看看,收到的数据是不是你发出的数据,不丢码?

ID:858009 发表于 2021-4-27 20:00
tyrl800 发表于 2021-4-27 19:46
把你电路板上12M的晶振换成11.0592M就行了

用的是开发板,是是11.596晶振
ID:275826 发表于 2021-4-27 19:46
把你电路板上12M的晶振换成11.0592M就行了
ID:858009 发表于 2021-4-27 18:28
game灬boy 发表于 2021-4-27 18:15
建议将流水灯循环放入main函数的while1中
做出以下修改:
int keyval_flag = 5 ;    //定义标志位,表示 ...

修改了也不可以,串口发送任何字符都没有用
ID:367369 发表于 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;    //允许串口中断
}
ID:858009 发表于 2021-4-27 18:06
啊哈哈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;    //允许串口中断
}
ID:858009 发表于 2021-4-27 17:46
啊哈哈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;    //允许串口中断
}
ID:332214 发表于 2021-4-27 17:38
qwettyuio 发表于 2021-4-27 17:36
发送了,一个led都不亮

你改过的完整代码发出来看看
ID:858009 发表于 2021-4-27 17:37
啊哈哈123 发表于 2021-4-27 17:34
你向串口发送数据了吗?用hex格式发送1 试试

没有任何反应
ID:858009 发表于 2021-4-27 17:36
啊哈哈123 发表于 2021-4-27 17:34
你向串口发送数据了吗?用hex格式发送1 试试

发送了,一个led都不亮
ID:332214 发表于 2021-4-27 17:34
qwettyuio 发表于 2021-4-27 16:58
这样修改不行,没反应,一个led都不亮,原来的不能循环,从一到八,就定在八了

你向串口发送数据了吗?用hex格式发送1 试试
ID:858009 发表于 2021-4-27 17:34
名字不是重点 发表于 2021-4-27 17:24
你为什么要把流水放在串口中断里动行?你串口没收到数据,就进不了中断‘,又如何能让 switch(keyval)这个 ...

修改不出来,找不出问题在哪里,小白一个,大佬技术指导一下,感谢
ID:824490 发表于 2021-4-27 17:24
你为什么要把流水放在串口中断里动行?你串口没收到数据,就进不了中断‘,又如何能让 switch(keyval)这个有变化?即进了中断,也只能运行一次,除非你不停往串口发送数据。
把你所想的、所做的,画一个流程图,说不定你就能发现是逻辑问题了。。
这种纯属逻辑的代码,建议写代码前先画个流程图,能帮你更快地写出你想要的代码来。
磨刀不误砍柴工哦!!加油

ID:858009 发表于 2021-4-27 16:58
啊哈哈123 发表于 2021-4-27 16:36
你这是通过一点一点问改的啊,挺用心的 你那边这样改应该就行了。
void main(void)          //主函数
{
...

这样修改不行,没反应,一个led都不亮,原来的不能循环,从一到八,就定在八了
ID:332214 发表于 2021-4-27 16:36
你这是通过一点一点问改的啊,挺用心的 你那边这样改应该就行了。
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;    //允许串口中断
}

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

Powered by 单片机教程网

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