找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2583|回复: 13
打印 上一主题 下一主题
收起左侧

单片机编译流水灯蓝牙控制,为什么不可以循环,停在LED8就不动,求解

[复制链接]
跳转到指定楼层
楼主
ID:858009 发表于 2021-5-7 16:38 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include <reg52.h>  //头文件
#define uint unsigned int   //宏定义
#define uchar unsigned char
code tabup[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
code tabdowm[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
void delay(uint z);
int i;
sbit beep=P2^3;
void blue_Init()   //蓝牙串口初始化
{
    TMOD = 0x20;
    TH1  = 0xfd;     //9600
    TL1  = 0xfd;
    SM0  = 0;
    SM1  = 1;               
    REN  = 1;
    TR1  = 1;
}
/**主函数**/
void main()
{
    int a;
    blue_Init();
    P1=0xff;
    while(1)
    {
        if(RI==1)                 
        {  
            a=SBUF;
            RI=0;
            if(a=='1')         //熄灭LED
            {
                P1=0xff;
                                                          beep=0;
                                  delay(100);
                                  beep=1;
            }   
            else if(a=='2')    //点亮LED
            {
                P1=0x00;
                                                          beep=0;
                                  delay(100);
                                  beep=1;
            }
            else if(a=='3')    //顺时针流水灯
            {
                                                        for(i=0;i<8;i++)
                                                        {
                                                                P1=tabup[i];
                                                                delay(2000);
                                                        }
                                                }
                                                else if(a=='4')    //逆时针流水灯
                                                {
                                                        for(i=0;i<8;i++)
                                                        {
                                                                P1=tabdowm[i];
                                                                delay(2000);
                                                        }
                                                }
                       
        }  
    }
}
void delay(uint z)  //延时函数
{
  uchar x,y;  
  for(x=z;x>0;x--)
  for(y=210;y>0;y--);
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:275826 发表于 2021-5-7 20:20 | 只看该作者
你这个程序不循环就对了;要串口发一次,循环一次
回复

使用道具 举报

板凳
ID:858009 发表于 2021-5-8 09:00 | 只看该作者
如果要实现循环怎么修改才可以
回复

使用道具 举报

地板
ID:858009 发表于 2021-5-8 09:01 | 只看该作者
tyrl800 发表于 2021-5-7 20:20
你这个程序不循环就对了;要串口发一次,循环一次

如果要实现循环该怎么修改?求教学或者写一个完整的代码参考一下,十分感谢
回复

使用道具 举报

5#
ID:824490 发表于 2021-5-8 09:14 | 只看该作者
代码结构有问题:不建议你在大循环中处理串口接收中断呢,更不要把中断标志做为运行流水的条件。
回复

使用道具 举报

6#
ID:858009 发表于 2021-5-8 09:27 | 只看该作者
名字不是重点 发表于 2021-5-8 09:14
代码结构有问题:不建议你在大循环中处理串口接收中断呢,更不要把中断标志做为运行流水的条件。

它可以运行工作,就是不能进行循环,我想问一下,怎么用代码蓝牙控制流水灯循环,求解
回复

使用道具 举报

7#
ID:213173 发表于 2021-5-8 09:40 | 只看该作者
持续流水要放在 if(RI==1) 之外,否则只能流水一次。
  1. #include <reg52.h>  //头文件
  2. #define uint unsigned int   //宏定义
  3. #define uchar unsigned char
  4. sbit beep=P2^3;
  5. code tabup[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
  6. code tabdowm[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
  7. void delay(uint z);
  8. uchar i;

  9. void blue_Init()   //蓝牙串口初始化
  10. {
  11.         TMOD = 0x20;
  12.         TH1  = 0xfd;     //9600
  13.         TL1  = 0xfd;
  14.         SM0  = 0;
  15.         SM1  = 1;               
  16.         REN  = 1;
  17.         TR1  = 1;
  18. }
  19. /**主函数**/
  20. void main()
  21. {
  22.         uchar a;
  23.         blue_Init();
  24.         P1=0xff;
  25.         while(1)
  26.         {
  27.                 if(RI==1)                 
  28.                 {  
  29.                         a=SBUF;
  30.                         RI=0;
  31.                 }
  32.                 if(a=='1')         //熄灭LED
  33.                 {
  34.                         P1=0xff;
  35.                         beep=0;
  36.                         delay(100);
  37.                         beep=1;
  38.                         a='0';
  39.                 }   
  40.                 else if(a=='2')    //点亮LED
  41.                 {
  42.                         P1=0x00;
  43.                         beep=0;
  44.                         delay(100);
  45.                         beep=1;
  46.                         a='0';
  47.                 }
  48.                 else if(a=='3')    //顺时针流水灯
  49.                 {
  50.                         for(i=0;i<8;i++)
  51.                         {
  52.                                 P1=tabup[i];
  53.                                 delay(2000);
  54.                         }
  55.                 }
  56.                 else if(a=='4')    //逆时针流水灯
  57.                 {
  58.                         for(i=0;i<8;i++)
  59.                         {
  60.                                 P1=tabdowm[i];
  61.                                 delay(2000);
  62.                         }
  63.                 }
  64.         }
  65. }
  66. void delay(uint z)  //延时函数
  67. {
  68.         uint x,y;  
  69.         for(x=z;x>0;x--)
  70.                 for(y=120;y>0;y--);
  71. }
复制代码
回复

使用道具 举报

8#
ID:429356 发表于 2021-5-8 09:47 | 只看该作者
你最后加哥re返回。或者把主函数放进while里面
回复

使用道具 举报

9#
ID:858009 发表于 2021-5-8 11:36 | 只看该作者
wulin 发表于 2021-5-8 09:40
持续流水要放在 if(RI==1) 之外,否则只能流水一次。

为什么这个也不可以实现你,同样的问题
#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)
{                             
        for(x=0;x<8;x++)       
        {
                P1=tabup[x];
                led_delay();
        }               
}
/*************************************************
函数功能:反向流水点亮LED
**************************************************/
void backward(void)
{                        
        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);
}
/*************************************************
函数功能:定时器T0的中断服务子程序
**************************************************/
void  serial() interrupt 4
{
   ES = 0;                //关闭串行中断
   RI = 0;                //清除串行接受标志位
   keyval = SBUF;            //从串口缓冲区取得数据                       
   switch(keyval)
   {
      case 1:forward();break;
      case 2:backward();break;
      case 3:stop();break;
      case 4:flash();break;
   }                  
  ES = 1;    //允许串口中断
}

回复

使用道具 举报

10#
ID:824490 发表于 2021-5-10 11:04 | 只看该作者
你把中断中的:
switch(keyval)
   {
      case 1:forward();break;
      case 2:backward();break;
      case 3:stop();break;
      case 4:flash();break;
   }                  
这一块移到MAIN的while之下:
while(1)
{
switch(keyval)
   {
      case 1:forward();break;
      case 2:backward();break;
      case 3:stop();break;
      case 4:flash();break;
   }              

}
回复

使用道具 举报

11#
ID:883167 发表于 2021-5-10 11:27 | 只看该作者
名字不是重点 发表于 2021-5-10 11:04
你把中断中的:
switch(keyval)
   {

嗯,这个好像可以的!
回复

使用道具 举报

12#
ID:213173 发表于 2021-5-10 14:44 | 只看该作者
qwettyuio 发表于 2021-5-8 11:36
为什么这个也不可以实现你,同样的问题
#include    //包含51单片机寄存器定义的头文件
unsigned char  ...

你把执行语句放在串口中断里,只有发生中断才能执行一次,当然不可重复循环。除非你在中断刚刚结束再次人为触发串口中断。
回复

使用道具 举报

13#
ID:917199 发表于 2021-5-10 20:46 | 只看该作者
delay(2000);
delay(uint z)
  uchar x
  for(x=z                 char?int?     
回复

使用道具 举报

14#
ID:139866 发表于 2021-5-12 09:57 | 只看该作者
最好就是中断里写标志位,在main函数里实现功能
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

Powered by 单片机教程网

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