找回密码
 立即注册

QQ登录

只需一步,快速开始

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

求教编程思路 用独立按键控制流水灯的方向,按一下流水灯从亮的地方反向流转

  [复制链接]
跳转到指定楼层
楼主
      刚学单片机,学长布置的题,用独立按键控制流水灯的方向,按一下流水灯从亮的地方反向流转,求教思路,想了很久还没解决,谢谢好心人了

评分

参与人数 1黑币 +5 收起 理由
649459021 + 5 很给力!

查看全部评分

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

使用道具 举报

沙发
ID:65425 发表于 2017-1-9 09:14 | 只看该作者
八位数码管采用共阳极接法(所有阳极接一起接Vcc,阴极接P0口)
按键分别接P2.0  P2.1  P2.2(低电平有效)

#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit key1 =P2^0; //按键1
sbit key2 =P2^1; //按键2
sbit key3 =P2^2; //按键3
uchar flag1=0,flag2=0,flag3=0;
void delay_ms(uint z)
{
     uint i,j;
     for(i=0;i<z;i++)
     for(j=0;j<110;j++);
}
void O_to_E() //1,3,5,7与2,4,6,8交替闪烁
{
     P0=0Xaa;
     delay_ms(200);
     P0=~0Xaa;
     delay_ms(200);
}
void key_scan()    //键盘扫描
{
     if(!key1)
     {
          delay_ms(10); //延时消抖
          if(!key1)
          flag1=1;
     }
     if(!key2)
     {
          delay_ms(10); //延时消抖
          if(!key2)
           flag2=1;
         }
     if(!key3)
     {
          delay_ms(10); //延时消抖
          if(!key3)
           flag3=1;
     }
}
void main()
{
     uchar i;
     while(1)
     {
            key_scan();
            if(flag1)                               //按键一按下?               
            {
                   for(i=0;i<8;i++)            //从左至右亮,每次一盏            
                   {
                            P0=~(0x80>>i);
                            delay_ms(100);
                            key_scan();                 //按键扫描   
                            if(flag2||flag3){flag1=0;break;}        //如果有其它按键按下响应其它按键
                   }
             }
             if(flag2)                                //按键一按下?                  
             {
                    for(i=0;i<8;i++)             //从右至左亮,每次一盏  
                   {
                            P0=~(0x01<<i);
                            delay_ms(100);
                            key_scan();
                            if(flag1||flag3){flag2=0;break;}
                   }
             }
              if(flag3)
             {
                   O_to_E();                             //奇偶交替闪烁
                   key_scan();
                   if(flag1||flag2)flag3=0;
              }
        }
}
回复

使用道具 举报

板凳
ID:149988 发表于 2017-1-9 09:21 | 只看该作者

RE: 求教编程思路 用独立按键控制流水灯的方向,按一下流水灯从亮的地方反向流转

我写过这样一个程序,发给你参考一下。

单键控制循环灯移动样式.zip

33.52 KB, 下载次数: 991

回复

使用道具 举报

地板
ID:150865 发表于 2017-1-9 23:22 | 只看该作者
本帖最后由 espopoi 于 2017-1-9 23:24 编辑

这个程序能差不多满足要求,就有一点,精度不高,不能在按下的瞬间就从亮的地方返回,他有时候会先按原来的顺序亮一个灯,再按相反的顺序亮,希望有大神能改进,

模拟.rar

33.65 KB, 下载次数: 348

评分

参与人数 1黑币 +50 收起 理由
admin + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

5#
ID:71584 发表于 2017-1-10 00:16 | 只看该作者
弄清高低位就好了
回复

使用道具 举报

6#
ID:160860 发表于 2017-1-10 06:53 | 只看该作者
不倒翁.WZT 发表于 2017-1-9 09:21
我写过这样一个程序,发给你参考一下。

嗯嗯,谢谢了。
回复

使用道具 举报

7#
ID:160860 发表于 2017-1-10 06:57 | 只看该作者
espopoi 发表于 2017-1-9 23:22
这个程序能差不多满足要求,就有一点,精度不高,不能在按下的瞬间就从亮的地方返回,他有时候会先按原来的 ...

嗯嗯,谢谢啦
回复

使用道具 举报

8#
ID:161074 发表于 2017-1-10 10:24 | 只看该作者
加一个键盘检测程序,然后里面写左右循环

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

9#
ID:156580 发表于 2017-1-10 10:33 | 只看该作者
espopoi 发表于 2017-1-9 23:22
这个程序能差不多满足要求,就有一点,精度不高,不能在按下的瞬间就从亮的地方返回,他有时候会先按原来的 ...

应该是采用了空循环做延时,改用定时器做延时就好了

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

10#
ID:153041 发表于 2017-1-10 21:12 | 只看该作者
提供思路仅供参考:
1、流水灯左右循环通过循环左移、循环右移;弄个变量标志方向,每次移动判断一下是左还是右。
2、如果不用定时器和中断,那就把你的延时函数做成 循环检测按键,检测到按键就把方向变量反一下。
3、追求精确的延时用定时器方便。
4、如果用空循环等待,把按键接到中断,用中断方式读按键也行得通。

评分

参与人数 1黑币 +50 收起 理由
admin + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

11#
ID:140489 发表于 2017-1-11 14:01 | 只看该作者
#include <REG51.h> //51头文件

/*********************************************************************************************/

#define DY_PORT                P1 //设置LED连接的I/O组
#define DY_SPEED        100 //设置每一个明亮级的停留时间(值域:0~65535)

/*********************************************************************************************

bit [自定义名] ; //定义一个位(位的值只能是0或1)例:bit LED
#define [代替名]        [原名]  //用代替名代替原名(可以方便修改常改或调试的值)例:#define LED P1
sbit  [自定义名] = [系统位名] ; //自定义系统位名。例:sbit Add_Key = P3 ^ 1;
unsigned char [自定义名] ; //定义一个0~255的整数变量.例:unsigned char a;
unsigned int [自定义名] ; //定义一个0~65535的整数变量

/*********************************************************************************************/
void delay (unsigned int a){ // 1ms延时程序
        unsigned int i;
        while( --a != 0){
                for(i = 0; i < 600; i++);//STC单片机在外部晶振为12MHz时i值上限为600  
        }                                                       //AT89C51单片机在外部晶振为12MHz时i值上限为125
}
/*********************************************************************************************/
void main(void){
        unsigned int i;
        unsigned int temp;
        while(1){
            temp=0x01;
            for(i=0;i<8;i++){ //8个流水灯逐个闪动
                     DY_PORT=~temp;
                     delay(DY_SPEED);   //调用延时函数
                     temp<<=1;
            }
                temp=0x80;
                for(i=0;i<8;i++){ //8个流水灯反向逐个闪动
                    DY_PORT=~temp;
                    delay(DY_SPEED);   //调用延时函数
                    temp>>=1;
                   }
            temp=0xFE;
                for(i=0;i<8;i++){ //8个流水灯依次全部点亮
                     DY_PORT=temp;
                     delay(DY_SPEED);   //调用延时函数
                     temp<<=1;
            }
                   temp=0x7F;
                   for(i=0;i<8;i++){ //8个流水灯依次反向全部点亮
                     DY_PORT=temp;
                     delay(DY_SPEED);   //调用延时函数
                     temp>>=1;
            }
        }
}

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

12#
ID:161286 发表于 2017-1-11 14:04 | 只看该作者
功能顺序理清楚就行了。。。
回复

使用道具 举报

13#
ID:161477 发表于 2017-1-12 16:20 | 只看该作者
按键做个标志,然后取反
回复

使用道具 举报

14#
ID:153199 发表于 2017-2-3 11:48 | 只看该作者
不错的分享,值得收藏
回复

使用道具 举报

15#
ID:186719 发表于 2017-5-5 15:32 | 只看该作者
AVR的好不
回复

使用道具 举报

16#
ID:110456 发表于 2017-5-5 23:13 | 只看该作者
第一,需要用一个IO口来控制按键,需要进行延时消抖,第二需要让流水灯做来回点亮构成死循环

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

17#
ID:110456 发表于 2017-5-5 23:14 | 只看该作者
#include <reg52.h> #include <intrins.h> #define uchar unsigned char #define uint unsigned int  void DelayMS(uint x) {          uchar i;         while(x--)         {                  for(i=200;i>0;i--);         } }  void Move_LED() {          if((P1 &= 0x10)==0)        P0 = _cror_(P0,1);         else if((P1 &= 0x20)==0)        P0 = _crol_(P0,1);         else if((P1 &= 0x40)==0)        P2 = _cror_(P2,1);         else if((P1 &= 0x80)==0)        P2 = _crol_(P2,1); }  void main() {          uchar Recent_Key=0xff;         P0=0xfe;         P1=0xfe;         P2=0xfe;         while(1)         {                  if(Recent_Key != P1)                 {                          Recent_Key=P1;                         Move_LED();                         DelayMS(10);                 }         } }
回复

使用道具 举报

18#
ID:162242 发表于 2017-5-6 13:10 | 只看该作者
用独立按键控制流水灯的方向
回复

使用道具 举报

19#
ID:111634 发表于 2017-5-7 17:37 | 只看该作者
本帖最后由 zl2168 于 2017-5-7 17:51 编辑

实例7  键控流水循环灯先Proteus仿真一下,确认有效。
实例7 键控流水循环灯.rar (36.04 KB, 下载次数: 175)

以上摘自张志良编著《80C51单片机Proteus仿真设计实例教程》清华大学出版社ISBN 978-7-302-41682-1仿真电路和Hex文件能在清华出版社网站免费下载,程序源代码只能到书上看了。到图书馆借,或到新华书店翻阅,或到网上书店打折购买。
仿真电路和Hex文件能在清华出版社网站免费下载,程序源代码只能到书上看了。到图书馆借,或到新华书店翻阅,或到网上书店打折购买。


回复

使用道具 举报

20#
ID:197820 发表于 2017-5-7 17:43 | 只看该作者
设置一个全局bit型变量,打开外部中断,用按键产生中断,在中断程序里吧bit型变量取反,然后在主程序里判断bit变量,1就正移动,0就反移动。这样就能实现用按键控制流水灯正反向了

评分

参与人数 1黑币 +50 收起 理由
admin + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

21#
ID:197820 发表于 2017-5-7 17:45 | 只看该作者
设置一个全局的bit变量,在外部中断函数里取反这个变量的值,在主程序判断bit是1还是0来控制流水灯正反。
回复

使用道具 举报

22#
ID:197826 发表于 2017-5-7 17:51 | 只看该作者
不错的分享,值得收藏
回复

使用道具 举报

23#
ID:216258 发表于 2018-3-16 21:14 | 只看该作者
向前看zk 发表于 2017-1-9 09:14
八位数码管采用共阳极接法(所有阳极接一起接Vcc,阴极接P0口)
按键分别接P2.0  P2.1  P2.2(低电平有效 ...

请教一下,此程序要怎么改成按键按下不放执行程序,放开按键不执行程序,每次按下按键重新执行程序,谢谢
回复

使用道具 举报

24#
ID:437955 发表于 2018-12-2 21:30 | 只看该作者
求一个按键流水灯的程序和仿真图
回复

使用道具 举报

25#
ID:438961 发表于 2018-12-4 09:54 | 只看该作者
不要在流水灯程序里延时循环,这样需要等运行完一遍了才能换向。可以用定时器的方式
回复

使用道具 举报

26#
ID:439490 发表于 2018-12-4 20:12 | 只看该作者
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int

void delay(uint z);
void main()
{
        uchar  num,dat1,dat2;
        delay(500);
        P0=0;
        while(1)
        {
                dat1=0xfe;
                dat2=0x7f;
                for(num=0;num<7;num++)
                {
                        P1=dat1;          //初始化赋值
                        dat1=dat1<<1; //右移一位
                        delay(500);   //延时       
                }
                for(num=0;num<7;num++)
                {
                        P1=dat2;          //初始化赋值
                        dat2=dat2>>1; //右移一位
                        delay(500);   //延时       
                }
        }
void delay(uint z)
{
    uchar j;
    for(z;z>0;z--)
        for(j=200;j>0;j--);
回复

使用道具 举报

27#
ID:160860 发表于 2020-12-2 13:40 | 只看该作者
不倒翁.WZT 发表于 2017-1-9 09:21
我写过这样一个程序,发给你参考一下。

好久没上过这个论坛啦,登上来之后看到这么多热心的人,感激不尽
回复

使用道具 举报

28#
ID:160860 发表于 2020-12-2 13:42 | 只看该作者
zl2168 发表于 2017-5-7 17:37
实例7  键控流水循环灯先Proteus仿真一下,确认有效。

刚看到您的评论,好几年了,感谢
回复

使用道具 举报

29#
ID:851329 发表于 2020-12-16 18:46 | 只看该作者
加一个按键控制,用循环和延时就可以
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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