你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32F103入门2——按键点灯

[复制链接]
STMCU小助手 发布时间:2022-8-22 17:48
1:按键不带锁存
不带锁存的意思就是 比如你按下按键灯亮,但是你一旦松手了灯就熄灭了,所以你想这个灯一直亮,那么你就一直按着按键不松手。

1.1例程

key.c

  1. /*========================key.c=========================*/
  2. #include "stm32f10x.h"
  3. #include "key.h"

  4. /*按键初始化函数*/
  5. void KEY_Init(void)
  6. {
  7.         //1.打开控制GPIOA的时钟(APB2)
  8.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  9.                
  10.         //2.配置结构体        
  11.         GPIO_InitTypeDef key_init;
  12.         key_init.GPIO_Pin   = GPIO_Pin_5;              //GPIOC A5引脚
  13.         key_init.GPIO_Mode  = GPIO_Mode_IPU;         //上拉输入        
  14.         //led_init.GPIO_Speed = GPIO_Speed_10MHz; //10MHz
  15.         
  16.         //3.对成员进行初始化
  17.         GPIO_Init(GPIOA, &key_init);
  18. }
复制代码

led.c

  1. #include "stm32f10x.h"
  2. #include "led.h"

  3. void LED_Init(void)
  4. {        
  5.         //1.打开控制GPIOC的时钟(APB2)
  6.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
  7.         
  8.         //2.配置结构体        
  9.         GPIO_InitTypeDef led_init;
  10.         led_init.GPIO_Pin   = GPIO_Pin_13;      //GPIOC13引脚
  11.         led_init.GPIO_Mode  = GPIO_Mode_Out_PP; //推挽输出        
  12.         led_init.GPIO_Speed = GPIO_Speed_10MHz; //10MHz
  13.         
  14.         //3.对成员进行初始化
  15.         GPIO_Init(GPIOC, &led_init);
  16. }
复制代码

main.c

  1. #include "stm32f10x.h"
  2. #include "led.h"
  3. #include "key.h"
  4. #include "delay.h"

  5. int  main()
  6. {
  7.         LED_Init(); //LED初始化
  8.         KEY_Init(); //按键初始化
  9.         GPIO_SetBits(GPIOC,LED);        //LED设置高电平
  10.         GPIO_SetBits(GPIOA,KEY);        //按键设置高电平
  11.         
  12.         while(1)
  13.         {
  14.                 #if 0
  15.                 /*示例1:无锁存*/
  16.                 if(GPIO_ReadInputDataBit(GPIOA, KEY) == 0)         //读取按键是否被按下         
  17.                 {               
  18.                         GPIO_ResetBits(GPIOC, LED);         //LED点亮               
  19.                 }
  20.                 else
  21.                 {
  22.                         GPIO_SetBits(GPIOC,LED);                //LED熄灭
  23.                 }
  24.                 #endif
  25.                
  26.                 /*示例2:无锁存*/
  27.                 GPIO_WriteBit(GPIOC, LED, (BitAction)(GPIO_ReadInputDataBit(GPIOA, KEY)));                                
  28.         }

  29. }
复制代码

2:按键带锁存
锁存的意思就是 比如你按下按键灯亮,但是你一旦松手了灯还是亮的,跟不带锁存相反。

2.1例程
key.c 和 led.c 和上面的不带锁存是一样的代码

  1. #include "stm32f10x.h"
  2. #include "led.h"
  3. #include "key.h"
  4. #include "delay.h"

  5. int  main()
  6. {
  7.         LED_Init(); //LED初始化
  8.         KEY_Init(); //按键初始化
  9.         GPIO_SetBits(GPIOC,LED);        //LED设置高电平
  10.         GPIO_SetBits(GPIOA,KEY);        //按键设置高电平
  11.         
  12.         while(1)
  13.         {
  14.                 /*示例3:有锁存 每按一次 灯取反*/
  15.                 if(GPIO_ReadInputDataBit(GPIOA, KEY) == 0)         //读取按键是否被按下
  16.                 {
  17.                         delay_ms(20); //消抖再次判断是否按下
  18.                         if(GPIO_ReadInputDataBit(GPIOA, KEY) == 0)         //读取按键还是被按下
  19.                         {
  20.                                 GPIO_WriteBit(GPIOC, LED, (BitAction)(1-GPIO_ReadOutputDataBit(GPIOC, LED)));
  21.                         }
  22.                         while(!GPIO_ReadInputDataBit(GPIOA, KEY)); //等待按键松开
  23.                 }
  24.                
  25.         }


  26. }
复制代码

3:按键用外部中断来做
正常如何程序比较多的话,我们有时候按键是需要及时处理的,如果通过循环检测其实不太理想的,所以我们可以把按键设置为中断来做。这样就可以更有效率,能及时处理。

步骤:

1.配置GPIO(配置结构体的相关东西)
  1. //1.打开控制GPIOA的时钟(APB2)
  2. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

  3. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);         //我们设置复用 用作外部中断
  4. GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource5); //设置A5引脚为 外部中断引脚

  5. //2.配置结构体        
  6. GPIO_InitTypeDef key_init;
  7. key_init.GPIO_Pin   = GPIO_Pin_5;              //GPIO A5引脚
  8. key_init.GPIO_Mode  = GPIO_Mode_IPU;         //上拉输入        
  9. //led_init.GPIO_Speed = GPIO_Speed_10MHz; //10MHz

  10. //3.对成员进行初始化
  11. GPIO_Init(GPIOA, &key_init);
复制代码

2.设置EXTI (触发方式:上升沿、下降沿、上下都触发)。

EXTI_Line: 中断线(一共20条)
EXTI_Mode: EXTI 中断的模式/产生的事件
EXTI_Trigger: EXTI()触发方式 上升沿 下降沿 上下都触发)
EXTI_LineCmd: 控制是否使能EXTI线,使能EXTI线或禁用

  1. //4.配置EXTI外部中断结构体
  2. EXTI_InitTypeDef exti_init;

  3. exti_init.EXTI_Line = EXTI_Line5;                 //A5引脚 所以是line5
  4. exti_init.EXTI_Mode = EXTI_Mode_Interrupt;         //中断模式
  5. exti_init.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
  6. exti_init.EXTI_LineCmd = ENABLE;                         //打开外部中断开关

  7. //对成员进行初始化
  8. EXTI_Init(&exti_init);
复制代码

3.设置NVIC(中断优先级)
  1. //5.配置NVIC优先级结构体
  2. NVIC_InitTypeDef nvic_init;
  3. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); //配置第四组

  4. nvic_init.NVIC_IRQChannel = EXTI9_5_IRQn; //A5引脚嘛 选择通道5
  5. nvic_init.NVIC_IRQChannelPreemptionPriority = 0; //设置抢占优先级 0级
  6. nvic_init.NVIC_IRQChannelSubPriority = 0; //设置子优先级 0级
  7. nvic_init.NVIC_IRQChannelCmd = ENABLE; //打开NVIC优先级开关

  8. //对成员进行初始化
  9. NVIC_Init(&nvic_init);
复制代码

4.编写中断服务函数

当按键从高电平变成低电平,也就是下降沿的时候,会触发中断,然后会进入中断服务函数。然后我们在服务函数里面点灯即可。
  1. void EXTI9_5_IRQHandler(void)
  2. {
  3.         if(EXTI_GetITStatus(EXTI_Line5) != RESET) //如果发生外部中断
  4.         {
  5.                 GPIO_ResetBits(GPIOC,GPIO_Pin_13);        //开灯        LED设置低电平
  6.                 delay_ms(1000);                                                //亮灯1秒
  7.                 GPIO_SetBits(GPIOC,GPIO_Pin_13);        //关灯        LED设置高电平
  8.         }
  9.         
  10.         EXTI_ClearFlag(EXTI_Line5); //清除标志位
  11. }
复制代码

代码:
key.c
main.c

  1. #include "stm32f10x.h"
  2. #include "led.h"
  3. #include "key.h"
  4. #include "delay.h"
  5. #include "exti.h"

  6. /*主函数入口*/
  7. int  main()
  8. {
  9.         LED_Init(); //LED初始化
  10.         KEY_Init(); //按键初始化
  11.         exti_Init(); //外部中断初始化
  12.         GPIO_SetBits(GPIOC,GPIO_Pin_13);        //LED设置高电平
  13.         GPIO_SetBits(GPIOA,GPIO_Pin_5);                //按键设置高电平
  14.         
  15.         while(1)
  16.         {

  17.         }


  18. }

  19. /*外部中断服务函数*/
  20. void EXTI9_5_IRQHandler(void)
  21. {
  22.         if(EXTI_GetITStatus(EXTI_Line5) != RESET) //如果发生外部中断
  23.         {
  24.                 GPIO_ResetBits(GPIOC,GPIO_Pin_13);        //开灯        LED设置低电平
  25.                 delay_ms(1000);                                                //亮灯1秒
  26.                 GPIO_SetBits(GPIOC,GPIO_Pin_13);        //关灯        LED设置高电平
  27.         }
  28.         
  29.         EXTI_ClearFlag(EXTI_Line5); //清除标志位
  30. }
复制代码
  1. #include "stm32f10x.h"
  2. #include "key.h"

  3. /*按键初始化函数*/
  4. void KEY_Init(void)
  5. {
  6.         //1.打开控制GPIOA的时钟(APB2)
  7.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  8.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);         //复用 用作外部中断
  9.         GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource5); //设置A5引脚为 外部中断引脚
  10.         
  11.         //2.配置结构体        
  12.         GPIO_InitTypeDef key_init;
  13.         key_init.GPIO_Pin   = GPIO_Pin_5;              //GPIOC13引脚
  14.         key_init.GPIO_Mode  = GPIO_Mode_IPU;         //上拉输入        
  15.         //led_init.GPIO_Speed = GPIO_Speed_10MHz; //10MHz
  16.         
  17.         //3.对成员进行初始化
  18.         GPIO_Init(GPIOA, &key_init);
  19. }
复制代码

exti.c
  1. #include "stm32f10x.h"
  2. #include "exti.h"


  3. void exti_Init()
  4. {               
  5.         //4.配置EXTI外部中断结构体
  6.         EXTI_InitTypeDef exti_init;
  7.         
  8.         exti_init.EXTI_Line = EXTI_Line5;                         //A5引脚
  9.         exti_init.EXTI_Mode = EXTI_Mode_Interrupt;         //中断模式
  10.         exti_init.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
  11.         exti_init.EXTI_LineCmd = ENABLE;                         //打开外部中断开关
  12.         
  13.         //对成员进行初始化
  14.         EXTI_Init(&exti_init);
  15.         
  16.         
  17.         //5.配置NVIC优先级结构体
  18.         NVIC_InitTypeDef nvic_init;
  19.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); //配置第四组
  20.         
  21.         
  22.         nvic_init.NVIC_IRQChannel = EXTI9_5_IRQn; //通道5
  23.         nvic_init.NVIC_IRQChannelPreemptionPriority = 0; //设置抢占优先级 0级
  24.         nvic_init.NVIC_IRQChannelSubPriority = 0; //设置子优先级 0级
  25.         nvic_init.NVIC_IRQChannelCmd = ENABLE; //打开NVIC优先级开关
  26.         
  27.         //对成员进行初始化
  28.         NVIC_Init(&nvic_init);
  29. }
复制代码

delay.c
  1. #include "stm32f10x.h"
  2. #include "delay.h"

  3. void delay_ms(uint16_t time)
  4. {
  5.         uint16_t i = 0;
  6.         while(time--)
  7.         {
  8.                 i = 10000;
  9.                 while(i--);
  10.         }
  11. }
复制代码

————————————————
转载:皮卡丘吉尔


收藏 评论0 发布时间:2022-8-22 17:48

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版