找回密码
 立即注册

QQ登录

只需一步,快速开始

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

为什么不能实现流水等功能,单片机代码编译没有问题,可以串口发送指令,请各位帮忙...

[复制链接]
跳转到指定楼层
楼主
ID:858009 发表于 2021-5-6 11:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include<reg51.h>    //包含51单片机寄存器定义的头文件
unsigned char keyval;  //储存按键值
//unsigned char keyval2;  //储存按键值
#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;
keyval2=0;
/*************************************************
函数功能:流水灯延时
**************************************************/
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位自动重载模式, 用于产生波特率


  TL1  = 0xfd;
  TH1  = 0xfd;           //波特率9600
  TR1  = 1;
  EA   = 1;
  ES   = 1;              //允许串口中断
  while(1);        
}
/*************************************************
函数功能:定时器T0的中断服务子程序
**************************************************/
void  serial() interrupt 4
{
   ES = 0;                //关闭串行中断
   RI = 0;                //清除串行接受标志位
   keyval = SBUF;         //从串口缓冲区取得数据
   if(keyval==0);

         {
                 keyval=keyval2;
         }
   keyval2=keyval;         
   switch(keyval)
   {
      case 1:forward();break;
      case 2:backward();break;
      case 3:stop();break;
      case 4:flash();break;
   }

        
  ES = 1;    //允许串口中断
}

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

使用道具 举报

沙发
ID:913577 发表于 2021-5-6 13:03 | 只看该作者
debug看一下,能走到这几个case里吗?
回复

使用道具 举报

板凳
ID:546568 发表于 2021-5-6 13:45 | 只看该作者
本帖最后由 dhz0105 于 2021-5-6 13:52 编辑

你的那些函数有在main里调用吗?
回复

使用道具 举报

地板
ID:367369 发表于 2021-5-6 15:21 | 只看该作者
你把延时时间调大一点看看20ms可能太短肉眼识别不出来,看起来就是直接就亮了最后一个灯
还有就是把这段放到main函数的while(1)里面
if(keyval==0);

         {
                 keyval=keyval2;
         }
   keyval2=keyval;         
   switch(keyval)
   {
      case 1:forward();break;
      case 2:backward();break;
      case 3:stop();break;
      case 4:flash();break;
   }
回复

使用道具 举报

5#
ID:392485 发表于 2021-5-6 16:29 | 只看该作者
不要在中断函数内处理太多的东西,把switch判断的语句都放到主函数里就可以了。同时流水灯的延时时间要长一些,太短了看不出来。
回复

使用道具 举报

6#
ID:858009 发表于 2021-5-6 16:37 | 只看该作者
sync763 发表于 2021-5-6 16:29
不要在中断函数内处理太多的东西,把switch判断的语句都放到主函数里就可以了。同时流水灯的延时时间要长一 ...

原来代码发送对应指令没有反应
回复

使用道具 举报

7#
ID:858009 发表于 2021-5-6 16:37 | 只看该作者
game灬boy 发表于 2021-5-6 15:21
你把延时时间调大一点看看20ms可能太短肉眼识别不出来,看起来就是直接就亮了最后一个灯
还有就是把这段放 ...

是一个都没有亮
回复

使用道具 举报

8#
ID:858009 发表于 2021-5-6 16:38 | 只看该作者
game灬boy 发表于 2021-5-6 15:21
你把延时时间调大一点看看20ms可能太短肉眼识别不出来,看起来就是直接就亮了最后一个灯
还有就是把这段放 ...

不是亮一个
回复

使用道具 举报

9#
ID:867005 发表于 2021-5-6 18:44 | 只看该作者
可以加一个循环试试
回复

使用道具 举报

10#
ID:889094 发表于 2021-5-6 22:01 | 只看该作者
1、串口处理程序里一般不要放太多东西,中断处理要尽量快
2、要确认你收到的数据是你想要的,你这里是要的1,2,3,那么收到的是不是数字1,2,3,还是字符1,2,3,调试程序时要确认一下,可以让串口把收到的再发回去,在上位机确认一下
3、程序合理的缩进结构有助于自己检查程序,求助别人也能让人容易看懂,乱了就别人就不想看了,哪有那么多时间去琢磨别人是怎么想的呀
回复

使用道具 举报

11#
ID:213173 发表于 2021-5-7 06:52 | 只看该作者
串口中断里不要放与串口功能无直接关系的语句,更不能含有较长时间的阻滞型延时,这会导致通信响应缓慢甚至无效。程序要简洁,给你屏蔽了所有不必要的语句,你试试。
  1. #include<reg51.h>    //包含51单片机寄存器定义的头文件
  2. unsigned char keyval;  //储存按键值
  3. //unsigned char keyval2;  //储存按键值
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. unsigned char code tabup[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
  7. //code tabdown[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
  8. uint x,y;
  9. //keyval2=0;
  10. /*************************************************
  11. 函数功能:流水灯延时
  12. **************************************************/
  13. void led_delay(unsigned int t)
  14. {
  15.         unsigned int i,j;
  16.         for(i=0;i<t;i++)
  17.                 for(j=0;j<120;j++);
  18. }
  19. /*************************************************
  20. 函数功能:软件消抖延时
  21. **************************************************/
  22. /*
  23. void delay20ms(void)
  24. {
  25.         unsigned char i,j;
  26.         for(i=0;i<100;i++)
  27.                 for(j=0;j<60;j++);
  28. }*/
  29. /*************************************************
  30. 函数功能:正向流水点亮LED
  31. **************************************************/
  32. void forward(void)
  33. {                              //不能加while(1),会循环这一函数,其他按键控制无效
  34. //        for(x=0;x<8;x++)        
  35. //        {
  36.                 P1=tabup[x];
  37. //                led_delay();
  38. //        }               
  39. }
  40. /*************************************************
  41. 函数功能:反向流水点亮LED
  42. **************************************************/
  43. void backward(void)
  44. {                          //不能加while(1),会循环这一函数,其他按键控制无效
  45. //        for(y=0;y<8;y++)
  46. //        {
  47. //                P1=tabdown[x];
  48.                 P1=tabup[7-(x%8)];
  49. //                led_delay();
  50. //        }
  51. }
  52. /*************************************************
  53. 函数功能:关闭所有LED
  54. **************************************************/
  55. void stop(void)
  56. {
  57.         P1=0xff;    //关闭8个LED
  58. }
  59. /*************************************************
  60. 函数功能:闪烁点亮LED
  61. **************************************************/
  62. void flash(void)
  63. {
  64.         P1=0x00;      //点亮8个LED
  65. //        led_delay();
  66. }
  67. /*************************************************
  68. 函数功能:主函数
  69. **************************************************/
  70. void main(void)           //主函数
  71. {
  72.         SCON = 0x50;           //设定串口工作方式
  73.         PCON = 0x00;           //波特率不倍增        
  74.         TMOD = 0x20;           //定时器1工作于8位自动重载模式, 用于产生波特率
  75.         TL1  = 0xfd;
  76.         TH1  = 0xfd;           //波特率9600
  77.         TR1  = 1;
  78.         EA   = 1;
  79.         ES   = 1;              //允许串口中断
  80.         while(1)   
  81.         {
  82.                 switch(keyval)
  83.                 {
  84.                         case 1:forward();break;
  85.                         case 2:backward();break;
  86.                         case 3:stop();break;
  87.                         case 4:flash();break;
  88. //                        这样写更简洁
  89. //                        case 1:P1=tabup[x];break;//正向流水灯
  90. //                        case 2:P1=tabup[7-(x%8)];break;//反向流水灯
  91. //                        case 3:P1=0xff;break;//全熄
  92. //                        case 4:P1=0x00;break;//全亮
  93.                 }
  94.                 led_delay(500);//延时约0.5秒
  95.                 x=++x%8;//循环计数
  96.         }
  97. }

  98. /*************************************************
  99. 函数功能:定时器T0的中断服务子程序
  100. **************************************************/
  101. void  serial() interrupt 4
  102. {
  103. //        ES = 0;                //关闭串行中断
  104.         RI = 0;                //清除串行接受标志位
  105.         keyval = SBUF;         //从串口缓冲区取得数据
  106. /*        if(keyval==0);
  107.         {
  108.                 keyval=keyval2;
  109.         }
  110.         keyval2=keyval;         

  111.         ES = 1;*/    //允许串口中断
  112. }

复制代码


回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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