OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 14273|回复: 12

STM32F103系列的单片机怎么实现一个按键控制一个LED,第一次按下常亮,再次按下闪烁,第三次按下熄灭?

[复制链接]

3

主题

16

帖子

0

精华

新手入门

积分
18
金钱
18
注册时间
2018-11-16
在线时间
7 小时
发表于 2019-1-15 12:24:43 | 显示全部楼层 |阅读模式
3金钱

最佳答案

查看完整内容[请看2#楼]

void Key_Num(void) { static u8 StatNum=0; if (Key_Scan(GPIOC,GPIO_Pin_2) == KEY_ON) { Delay_MS(1000);//延时1s消抖 StatNum++; } switch(StatNum) { case 1: //长亮函数;break; case 2: //闪烁函数;break; case 3: //关灯函数;StatNum=0;break; } } 按你的写法是这样做成单独函数的....但是这样真的好蠢...... 你把按键挂外部中断线上,按一次按键消抖标志位++;这个函数就只检测标 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

7

主题

143

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
438
金钱
438
注册时间
2017-8-21
在线时间
76 小时
发表于 2019-1-15 12:24:44 | 显示全部楼层
void Key_Num(void)
{
        static u8 StatNum=0;
        if (Key_Scan(GPIOC,GPIO_Pin_2) == KEY_ON)
        {
                Delay_MS(1000);//延时1s消抖
                StatNum++;
        }
       
        switch(StatNum)
        {
                case 1: //长亮函数;break;
                case 2: //闪烁函数;break;
                case 3: //关灯函数;StatNum=0;break;
        }
}

按你的写法是这样做成单独函数的....但是这样真的好蠢......
你把按键挂外部中断线上,按一次按键消抖标志位++;这个函数就只检测标志位是什么值,你这样在函数里检测KeyScanf有点奇怪。。。。
回复

使用道具 举报

3

主题

16

帖子

0

精华

新手入门

积分
18
金钱
18
注册时间
2018-11-16
在线时间
7 小时
 楼主| 发表于 2019-1-15 12:38:04 | 显示全部楼层
                        if (GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2) == KEY_ON)
                                {status=status+1;
                                }               
                                        if(status>3)
                                        {
                                                status=0;
                                        }
                                                switch(status){
                                                                                                                case 1:{GPIO_SetBits(GPIOC, GPIO_Pin_1);}
                                                                                                                case 2:{GPIO_ResetBits(GPIOC, GPIO_Pin_1);
                                                                                                                                                Delay(500000);
                                                                                                                             GPIO_SetBits(GPIOC, GPIO_Pin_1);
                                                                                                                                                Delay(500000);
                                                                                                                                                }
                                                                                                          case 3:{ GPIO_ResetBits(GPIOC, GPIO_Pin_1);}
                                                                                                                      }
一上电LED就亮,按下就一直在闪烁,关不掉
回复

使用道具 举报

57

主题

1680

帖子

3

精华

资深版主

Rank: 8Rank: 8

积分
4307
金钱
4307
注册时间
2018-6-30
在线时间
808 小时
发表于 2019-1-15 12:38:09 | 显示全部楼层
每按一次计数count加一
再用if(count&&按键)
判断执行相应的语句就行
业精于勤荒于嬉;行成于思毁于随!
回复

使用道具 举报

46

主题

200

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1128
金钱
1128
注册时间
2016-3-25
在线时间
365 小时
发表于 2019-1-15 12:42:24 | 显示全部楼层
用状态机制
回复

使用道具 举报

3

主题

16

帖子

0

精华

新手入门

积分
18
金钱
18
注册时间
2018-11-16
在线时间
7 小时
 楼主| 发表于 2019-1-15 15:27:29 | 显示全部楼层
我试过了,用计数的方式是可以解决了但需要把
   if (GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2) == KEY_ON)
给改掉
用着个结构给先处理下端口的取值问题
        u8 Key_Scan(GPIO_TypeDef* GPIOx,u16 GPIO_Pin)
{                       
                /*¼ì2aêÇ·ñóD°′¼ü°′Ï */
           if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON )
          {          
                  /*Ñóê±Ïû¶¶*/
                  Delay(50000);               
                           if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON )  
                                        {         
                                                /*μè′y°′¼üêí·Å */
                                                while(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON);   
                                                 return         KEY_ON;         
                                        }
                        else
                                        return KEY_OFF;
                }
        else
                return KEY_OFF;
}
改为
if (Key_Scan(GPIOC,GPIO_Pin_2) == KEY_ON)
最终是这个主程序
//                                if (Key_Scan(GPIOC,GPIO_Pin_2) == KEY_ON)
//                                {
//                                        Delay(1000000);
//                                        status=status+1;
//                                }               
//                                        if(status>2)
//                                        {
//                                                status=0;
//                                        }
//                                                if (status==0)
//                                                {

//                                                        {GPIO_SetBits(GPIOC, GPIO_Pin_1);}
//                                                }
//                                                if (status==1)
//                                                {
//                                                        {GPIO_ResetBits(GPIOC, GPIO_Pin_1);}
//                                                }
//                                                if (status==2)
//                                                {
//                                                        {GPIO_ResetBits(GPIOC, GPIO_Pin_1);
//                                                                                                                                                Delay(1000000);
//                                                         GPIO_SetBits(GPIOC, GPIO_Pin_1);
//                                                                                                                                                Delay(500000);}                                                       
//                                                }
但现在我想把这写东西给做成一个可调用的形式
只需要把输入端口一写,然后进行计数的判断。
改成主函数如下
//                                                if (任意端口==0)
//                                                {

//                                                        {GPIO_SetBits(GPIOC, GPIO_Pin_1);}
//                                                }
//                                                if (任意端口==1)
//                                                {
//                                                        {GPIO_ResetBits(GPIOC, GPIO_Pin_1);}
//                                                }
//                                                if (任意端口==2)
//                                                {
//                                                        {GPIO_ResetBits(GPIOC, GPIO_Pin_1);
//                                                                                                                                                Delay(1000000);
//                                                         GPIO_SetBits(GPIOC, GPIO_Pin_1);
//                                                                                                                                                Delay(500000);}                                                       
//                                                }
回复

使用道具 举报

3

主题

16

帖子

0

精华

新手入门

积分
18
金钱
18
注册时间
2018-11-16
在线时间
7 小时
 楼主| 发表于 2019-1-15 15:29:14 | 显示全部楼层
要不然我要是多个按键控制多个led岂不是写起来要麻烦死了。
回复

使用道具 举报

7

主题

143

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
438
金钱
438
注册时间
2017-8-21
在线时间
76 小时
发表于 2019-1-15 15:42:29 | 显示全部楼层
按一下+1,判断等于1的时候LED长亮,等于2的时候闪烁,等于3的时候标志位置0,并且关灯。就这么简单....
回复

使用道具 举报

3

主题

16

帖子

0

精华

新手入门

积分
18
金钱
18
注册时间
2018-11-16
在线时间
7 小时
 楼主| 发表于 2019-1-15 15:47:46 | 显示全部楼层
路人曦 发表于 2019-1-15 15:42
按一下+1,判断等于1的时候LED长亮,等于2的时候闪烁,等于3的时候标志位置0,并且关灯。就这么简单....

是啊,我实现了。我现在想把这些功能写成一个结构的形式。
回复

使用道具 举报

3

主题

16

帖子

0

精华

新手入门

积分
18
金钱
18
注册时间
2018-11-16
在线时间
7 小时
 楼主| 发表于 2019-1-15 15:49:55 | 显示全部楼层
路人曦 发表于 2019-1-15 15:42
按一下+1,判断等于1的时候LED长亮,等于2的时候闪烁,等于3的时候标志位置0,并且关灯。就这么简单....

//                                if (Key_Scan(GPIOC,GPIO_Pin_2) == KEY_ON)
//                                {
//                                        Delay(1000000);
//                                        status=status+1;
//                                }               
//                                        if(status>2)
//                                        {
//                                                status=0;
//                                        }
就是这些也给它做成一个可调用的形式
不用在主函数里写了。
回复

使用道具 举报

7

主题

143

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
438
金钱
438
注册时间
2017-8-21
在线时间
76 小时
发表于 2019-1-15 15:51:52 | 显示全部楼层
尹默然 发表于 2019-1-15 15:49
//                                if (Key_Scan(GPIOC,GPIO_Pin_2) == KEY_ON)
//                    ...

...你在下面写个函数,调用这个不就好啦....把函数放到 while里面...
回复

使用道具 举报

20

主题

76

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1028
金钱
1028
注册时间
2019-5-27
在线时间
142 小时
发表于 2019-8-25 20:41:46 | 显示全部楼层
卧槽,终于找到了
回复

使用道具 举报

0

主题

5

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2019-10-16
在线时间
8 小时
发表于 2020-12-22 11:21:15 | 显示全部楼层
1111111111111
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-24 04:03

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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