找回密码
 立即注册

QQ登录

只需一步,快速开始

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

有两种单片机流水灯形式,想要加两个按键切换流水灯模式,程序应该怎么改,谢谢

[复制链接]
回帖奖励 50 黑币 回复本帖可获得 5 黑币奖励! 每人限 1 次
跳转到指定楼层
楼主
新手求助:有两种流水灯形式,想加两个按键切换流水灯模式,按键程序搞半天也没整明白,请高人指点,谢谢!按键1执行 void disp0()
按键2执行 void disp1()
请大佬们帮帮忙,万分感谢!
单片机源程序如下:
#include <REGX52.H>
#define        uint        unsigned int
#define        uchar        unsigned char
uchar code table0[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//LED从低位往高位移
uchar code table1[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//LED从高位往低位移
uchar i,j;                //定义循环变量
uint tt=70;                //定义时间指数
void delay(uint time)        //延时函数
{
        uint x,y;
        for(x=time;x>0;x--)
        for(y=110;y>0;y--);
}

void disp0()                        //状态1 LED顺时针转一圈
{
        for(i=0;i<8;i++)
        {
                P2=table1[ i];
                delay(100);
        }
        P2=0xff;

        for(i=0;i<8;i++)
        {
                P0=table0[ i];
                delay(100);
        }
        P0=0xff;
}
void disp1()                        //状态0 所有LED闪烁3次
{
        for(i=0;i<3;i++)
        {
                P0=0x00; P2=0x00;
                delay(300);
                P0=0xff; P2=0xff;
                delay(300);
        }
}
void main()
{        
        while(1)
        {        
         disp0();                //状态1 LED顺时针转一圈
        disp1();                //状态0 所有LED闪烁3次
  }

}



93caf1d444a37d821636c66be211e3c.png (42.97 KB, 下载次数: 18)

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

使用道具 举报

沙发
ID:1080935 发表于 2024-5-21 08:18 | 只看该作者
定义按键端口
sbit key1 =  P1^6;
sbit key2 =  P1^7;
在主循环中while(1)中改为
{
  if(!key1)
  {//可以考虑消抖,仿真中可不用。
    disp0();
    while(!key1);//等待按键释放
  }
  if(!key2)
  {
     disp1();
     while(!key2);//等待按键释放
  }
}
这种方法不是特别推荐,可以额外定义一边量作为状态初始为0,按键按下后状态改变(1或2),根据状态调用对应函数,调用完后变量清零。这相当于只调用一次的任务。
回复

使用道具 举报

板凳
ID:743654 发表于 2024-5-21 08:58 | 只看该作者
先定义两个按键参数sbit k1=P1^6; sbit k2=P1^7;  主函数:        if(k1==0)        //检测按键K1是否按下{delay(1000);   //消除抖动 一般大约10ms  if(k1==0)         //再次判断按键是否按下{disp0();   //模式1}while(!k1);         //检测按键1是否松开              if(k2==0)        //检测按键K2是否按下{delay(1000);   //消除抖动 一般大约10ms  if(k2==0)//再次判断按键是否按下{disp1();   //模式2}while(!k2);         //检测按键2是否松开
回复

使用道具 举报

地板
ID:1109793 发表于 2024-5-21 09:25 | 只看该作者
if(按键1)disp0();
if(按键2)disp1();
回复

使用道具 举报

5#
ID:1105755 发表于 2024-5-23 20:28 | 只看该作者
LaoYuTou 发表于 2024-5-21 08:18
定义按键端口
sbit key1 =  P1^6;
sbit key2 =  P1^7;

谢谢!刚开始弄,研究一下
回复

使用道具 举报

6#
ID:1105755 发表于 2024-5-23 20:29 | 只看该作者
cheney03 发表于 2024-5-21 08:58
先定义两个按键参数sbit k1=P1^6; sbit k2=P1^7;  主函数:        if(k1==0)        //检测按键K1是否按下{delay(1000);  ...

谢谢!我弄一下试试。
回复

使用道具 举报

7#
ID:1105755 发表于 2024-5-23 20:30 | 只看该作者
xiaobendan001 发表于 2024-5-21 09:25
if(按键1)disp0();
if(按键2)disp1();

谢谢!
回复

使用道具 举报

8#
ID:6467 发表于 2025-11-6 21:56 | 只看该作者
你这个程序;容易出现按键响应不灵敏的情况;delay时间越大;约明显;不信你试一试。
回复

使用道具 举报

9#
ID:876947 发表于 2025-12-5 12:26 | 只看该作者
哈哈哈!我竟然为两套流水灯程序在一块板子上整了两块cpu!
回复

使用道具 举报

10#
ID:123917 发表于 2025-12-5 16:36 | 只看该作者
中断应该可以,试试看
回复

使用道具 举报

11#
ID:1156764 发表于 2025-12-5 17:59 | 只看该作者
这是用标识符的方式,
第一步:把disp1() 和disp0() 记作状态1和状态0
第二步:新增定义
   sbit key1 =  P1^6;
   sbit key2 =  P1^7;
   ledstate=0;//默认状态0
第三步:while(1)循环改为
   while(1)
{
    if(ledstate==0)
   {
       disp0();
   }
   else if(ledstate==1)
   {
       disp1();
   }
   if(key1==0)
   {
        ledstate=0;
   }
   else if(key2==0)
   {
         ledstate=1;
   }
}第四现象:
默认上电是状态0,点击key1切换为状态0,点击key2切换为状态1,同时点击key1key2会优先状态0
回复

使用道具 举报

12#
ID:101869 发表于 2025-12-5 19:08 | 只看该作者
#include <REGX52.H>
#define uint unsigned int
#define uchar unsigned char
uchar code table0[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f}; // LED从低位往高位移
uchar code table1[] = {0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe}; // LED从高位往低位移
uchar i, j;                                                             // 定义循环变量
uint tt = 70;                                                           // 定义时间指数
sbit key = P1 ^ 1;
uchar led_mod = 0; // 模式  0=关  1=LED顺时针转一圈 2=所有LED闪烁3次
void key_scan()
{
    static uint key_cnt = 0;
    static bit key_flag = 0;
    if (key)
    {
        key_cnt = 0;
        key_flag = 0;
    }
    else if (!key_flag)
    {
        key_cnt++;
        if (key_cnt >= 1000)
        {
            key_flag = 1;
            led_mod++;
            if (led_mod > 2)
                led_mod = 0;
        }
    }
}
void delay(uint time) // 延时函数
{
    uint x, y;
    for (x = time; x > 0; x--)
        for (y = 110; y > 0; y--)
            ;
}

void disp0() // 状态1 LED顺时针转一圈
{
    for (i = 0; i < 8; i++)
    {
        P2 = table1[i];
        delay(100);
    }
    P2 = 0xff;

    for (i = 0; i < 8; i++)
    {
        P0 = table0[i];
        delay(100);
    }
    P0 = 0xff;
}
void disp1() // 状态0 所有LED闪烁3次
{
    for (i = 0; i < 3; i++)
    {
        P0 = 0x00;
        P2 = 0x00;
        delay(300);
        P0 = 0xff;
        P2 = 0xff;
        delay(300);
    }
}
void main()
{
    while (1)
    {
         key_scan();
        switch (led_mod)
        {
        case 0: // 关闭的代码
            break;
        case 1:
            disp0(); // 状态1 LED顺时针转一圈
            break;
        case 2:
            disp1(); // 状态0 所有LED闪烁3次
            break;
        default:
            break;
        }
    }
}

回复

使用道具 举报

13#
ID:1160531 发表于 2026-1-5 15:31 | 只看该作者
建议使用外部中断的方式,这样的话对按键动作能及时响应,至于哪个按键按下执行什么样的功能逻辑,再分别写两个功能函数进行条件对应即可。功能没通的情况下,可以先少用几个LED,通了之后再控制多个。
回复

使用道具 举报

14#
ID:1160531 发表于 2026-1-5 15:34 | 只看该作者
按键判断程序,供参考while (1)
  {
                                 //正向运动按键 KEY1 判断
                if(!HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1))
                {
                        HAL_Delay(100);
                  if(!HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1))
                        {
                                printf("key1 press down\r\n");
                                if(motor1_dir_flg==zheng)
                                        motor1_dir_flg = fan;
                                else
                                        motor1_dir_flg = zheng;
                        }
                        HAL_Delay(10);                         
                       
                }
               
               
                if(motor1_dir_flg)
                {
                        HAL_GPIO_WritePin(GPIOA,GPIO_PIN_9,GPIO_PIN_RESET);
                        HAL_GPIO_WritePin(GPIOA,GPIO_PIN_10,GPIO_PIN_SET);
                }
                else
                {
                        HAL_GPIO_WritePin(GPIOA,GPIO_PIN_9,GPIO_PIN_SET);
                        HAL_GPIO_WritePin(GPIOA,GPIO_PIN_10,GPIO_PIN_RESET);
                       
                }
               
                 HAL_Delay(10);
               
                //反向运动按键 KEY2 判断
                 if(!HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_2))
                {
                        HAL_Delay(10);
                  if(!HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_2))
                        {
                                printf("key2 press down\r\n");
                                if(motor2_dir_flg==zheng)                                       
                                        motor2_dir_flg=fan;
                                else
                                        motor2_dir_flg=zheng;
                        }
                                HAL_Delay(10);
                }
                       
                        if(motor2_dir_flg)
                        {
                                HAL_GPIO_WritePin(GPIOA,GPIO_PIN_6,GPIO_PIN_RESET);
                                HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_SET);
                        }
                        else
                        {
                               
                                HAL_GPIO_WritePin(GPIOA,GPIO_PIN_6,GPIO_PIN_SET);
                                HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_RESET);
                        }
                       
                        HAL_Delay(10);
                       
                       
                //调速控制按键 KEY3 判断                       
                if(!HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_3))
                {
                        HAL_Delay(10);
                  if(!HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_3))
                        {
                                        if(motor_speed<1000)
                                        {
                                                printf("the current speed: %d\r\n",motor_speed);
                                                motor_speed+=100;
                                                __HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_1,motor_speed);
                                        }
                                        else
                                        {
                                                motor_speed = 100;
                                                __HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_1,motor_speed);
                                                printf("the current speed: %d\r\n",motor_speed);
                                         
                                        }
                                       
                                        HAL_Delay(500);
                       
                        }
               
                }
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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