STM32 GPIO之二——按键例程 学习总结
来源:互联网 发布:美工需要练打字吗 编辑:程序博客网 时间:2024/05/29 03:16
一. GPIO的8种工作模式
1.4种输入模式:
(1)上拉输入模式(GPIO_Mode_IPU):在默认状态下(GPIO引脚无输入),读取得的GPIO引脚数据为1,高电平。
(2)下拉输入模式(GPIO_Mode_IPD):在默认状态下(GPIO引脚无输入),读取得的GPIO引脚数据为0,低电平。
(3)浮空输入模式(GPIO_Mode_IN_FLOATING):一般把这种模式用于标准的通信协议如I²C、USART的接收端。
(4)模拟输入模式(GPIO_Mode_AIN):使用ADC外设时,必须设置为模拟输入模式。
2.4种输出模式:
(1)推挽输出模式(GPIO_Mode_OUT_PP):一般应用在输出电平为0到3.3伏的场合。
(2)开漏输出模式(GPIO_Mode_OUT_OD):一般应用在电平不匹配的场合。
(3)复用推挽输出模式:如GPIO的引脚用作串口的输出。
(4)复用开漏输出模式:如在IC、SMBUS这些需要线与功能的复用场合。
二、开发板原理图如下:
三、测试代码:
实现功能:LED1亮,按下按键时LED1灭,再按下按键时LED1亮,如此循环。
/*led.c*/#include "led.h"/*配置LED用到的I/O口*/void LED_GPIO_Config(void){/*定义一个GPIO_InitTypeDef类型的结构体*/ GPIO_InitTypeDef GPIO_InitStructure;/*开启GPIOC的外设时钟*/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);/*选择要控制的GPIO引脚*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_6 | GPIO_Pin_5;/*设置引脚模式为通用推挽输出*/ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;/*设置引脚速率为50MHz*/ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;/*调用库函数,初始化GPIOB、GPIOD*/ GPIO_Init(GPIOB,&GPIO_InitStructure); GPIO_Init(GPIOD,&GPIO_InitStructure);/*关闭所有LED灯*/ GPIO_SetBits(GPIOB,GPIO_Pin_5);//3、6、5引脚输出高电平,关闭三盏LED灯 GPIO_SetBits(GPIOD,GPIO_Pin_3|GPIO_Pin_6); }
/*led.h*/#ifndef __LED_H#define __LED_H#include "stm32f10x.h"#define ON 0#define OFF 1#define LED1(a) if(a) \ GPIO_SetBits(GPIOD,GPIO_Pin_3);\ else \ GPIO_ResetBits(GPIOD,GPIO_Pin_3) #define LED2(a) if(a) \ GPIO_SetBits(GPIOD,GPIO_Pin_6);\ else \ GPIO_ResetBits(GPIOD,GPIO_Pin_6) #define LED3(a) if(a) \ GPIO_SetBits(GPIOB,GPIO_Pin_5);\ else \ GPIO_ResetBits(GPIOB,GPIO_Pin_5)void LED_GPIO_Config(void);#endif /*__LED_H*/
/*key.c*/#include "key.h"void Delay(u16 time){ u16 i=0; while(time--) { i=10; //自己定义 while(i--) ; }}/**函数名:Key_GPIO_Config*描述 :配置按键用到的I/O口*输入 :无*输出 :无*/void Key_GPIO_Config(void){ GPIO_InitTypeDef GPIO_InitStructure; /*开启按键端口(PE5)的时钟*/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_MHZ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOC,&GPIO_InitStructure);}/**函数名:Key_Scan(GPIO_TypeDef* GPIOx,u16 GPIO_Pin)*描述 :检测是否有按键按下*输入 :GPIOx:x 可以是A,B,C,D或者E* GPIO_Pin:待读取的端口位*输出 :KEY_OFF(没按下按键)、KEY_ON(按下按键)*/u8 Key_Scan(GPIO_TypeDef* GPIOx,u16 GPIO_Pin){ /*检测是否有键按下*/if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON ){ /*延时消抖*/ Delay(10000); if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON ){ /*等待按键释放*/while(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON); return KEY_ON; }else return KEY_OFF; } else return KEY_OFF;}
/*key.h*/#ifndef __KEY_H#define __KEY_H#include "stm32f10x.h"#define KEY_ON 0#define KEY_OFF 1void Key_GPIO_Config(void);u8 Key_Scan(GPIO_TypeDef* GPIOx,u16 GPIO_Pin);void Delay(u16 time);#endif /*__LED_H*/
/*main.c*/#include "stm32f10x.h"#include "led.h"#include "key.h" int main (void){ LED_GPIO_Config(); LED1( ON ); Key_GPIO_Config(); while(1){ if( Key_Scan(GPIOC,GPIO_Pin_5) == KEY_ON ){/*LED反转*/ GPIO_WriteBit(GPIOB, GPIO_Pin_5,(BitAction)((1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_5)))); } }}
四、范例
/*stm32v5_led.c*/#include "stm32v5_led.h"static led_gpio_t leds_gpio[MAX_LED] ={{LED1, GPIOB, GPIO_Pin_5}, /* LED1 用的GPB5 */{LED2, GPIOD, GPIO_Pin_6}, /* LED2 用的GPD6 */{LED3, GPIOD, GPIO_Pin_3}, /* LED3 用的GPD3 */};void init_led_gpio(void){int i;GPIO_InitTypeDef GPIO_InitStructure;/* 使能PB和PD组 GPIO的时钟 */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOD , ENABLE);/*设置 PB5(LED1), PD6(LED2), PD3(LED3)为 GPIO 输出推免模式,口线翻转速度为50MHz */for(i=0; i<MAX_LED; i++){/*设置 PB5(LED1)为 GPIO 输出推免模式,口线翻转速度为50MHz */GPIO_InitStructure.GPIO_Pin = leds_gpio[i].pin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(leds_gpio[i].group, &GPIO_InitStructure); }}void turn_led(int which, int cmd){ if(which<0 || which> MAX_LED ) return; if(OFF == cmd) GPIO_ResetBits(leds_gpio[which].group, leds_gpio[which].pin); else GPIO_SetBits(leds_gpio[which].group, leds_gpio[which].pin);}
/*stm32v5_led.h*/#ifndef __STM32V5_LED_H#define __STM32V5_LED_H#include"stm32f10x.h"#define ON 1#define OFF 0enum { LED1 = 0,LED2,LED3,MAX_LED,};typedef struct led_gpio_s{int num; /* LED编号 */GPIO_TypeDef *group; /* LED使用的GPIO在哪一组: GPIOB or GPIOD */ uint16_t pin; /* LED使用的GPIO组中的那一个pin: GPIO_Pin_x */} led_gpio_t;extern void init_led_gpio(void);extern void turn_led(int which, int cmd);#endif
/*stm32v5_key.c*/#include "stm32f10x.h"#include "stm32f10x_exti.h"#include "stm32f10x_rcc.h"#include "misc.h"#include "stm32v5_led.h"#include "stm32v5_key.h"#define DEFINE_PIN_EXTI(group, pin, IRQn, SubPriority) \void init_P##group##pin##_as_EXTI(void) \{ \GPIO_InitTypeDef GPIO_InitStructure; \EXTI_InitTypeDef EXTI_InitStructure; \NVIC_InitTypeDef NVIC_InitStructure; \\RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIO##group|RCC_APB2Periph_AFIO, ENABLE); \\ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_##pin;\ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; \ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; \ GPIO_Init(GPIO##group, &GPIO_InitStructure); \\GPIO_EXTILineConfig(GPIO_PortSourceGPIO##group, GPIO_PinSource##pin); \ EXTI_InitStructure.EXTI_Line = EXTI_Line##pin; \ EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; \ EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; \ EXTI_InitStructure.EXTI_LineCmd = ENABLE; \ EXTI_Init(&EXTI_InitStructure);\\NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); \ NVIC_InitStructure.NVIC_IRQChannel = IRQn;\ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; \ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; \ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;\ NVIC_Init(&NVIC_InitStructure); \} /* Key1(PC5) configured as EXTI5, SubPriority as 1 */DEFINE_PIN_EXTI(C, 5, EXTI9_5_IRQn, 1)/* Key2(PC2) configured as EXTI2, SubPriority as 2 */DEFINE_PIN_EXTI(C, 2, EXTI2_IRQn, 2)/* Key3(PC3) configured as EXTI3, SubPriority as 3 */DEFINE_PIN_EXTI(C, 3, EXTI3_IRQn, 3)/* PC5 Key1 interrupt handler */void EXTI9_5_IRQHandler(void){static uint8_t led1_status = OFF;if(EXTI_GetITStatus(EXTI_Line5) != RESET){led1_status ^= 1;turn_led(LED1, led1_status);//EXTI_ClearITPendingBit(EXTI_Line5); }}/* PC2 Key2 interrupt handler */void EXTI2_IRQHandler(void){static uint8_t led2_status = OFF;if(EXTI_GetITStatus(EXTI_Line2) != RESET){led2_status ^= 1;turn_led(LED2, led2_status);EXTI_ClearITPendingBit(EXTI_Line2); }}/* PC3 Key3 interrupt handler */void EXTI3_IRQHandler(void){static uint8_t led3_status = OFF;if(EXTI_GetITStatus(EXTI_Line3) != RESET){led3_status ^= 1;turn_led(LED3, led3_status);EXTI_ClearITPendingBit(EXTI_Line3); }}void init_keys_interrupt(void){init_PC5_as_EXTI();init_PC2_as_EXTI();init_PC3_as_EXTI();}
/*stm32v5_key.h*/#ifndef __STM32V5_KEY_H#define __STM32V5_KEY_Hextern void init_keys_interrupt(void);#endif
/*main.c*/#include "stm32f10x.h"#include "stm32v5_led.h"#include "stm32v5_key.h"int main(void){init_led_gpio();init_keys_interrupt(); while(1) {; }}
阅读全文
0 0
- STM32 GPIO之二——按键例程 学习总结
- STM32 GPIO——流水灯例程 学习总结
- STM32之GPIO按键实验
- STM32(二)之GPIO操作(2)——通过按键控制LED灯的开关
- STM32之GPIO推挽输出例程
- STM32之GPIO浮空输入例程
- STM32之GPIO推挽输出例程
- STM32之GPIO浮空输入例程
- stm32 GPIO 操作例程
- 嵌入式系统学习——STM32之GPIO
- STM32学习笔记 — 之GPIO端口篇
- STM32学习笔记 — 之GPIO端口篇
- STM32学习笔记 — 之GPIO端口篇
- STM32学习笔记 — 之GPIO端口篇
- STM32学习笔记 — 之GPIO端口篇
- STM32学习笔记 — 之GPIO端口篇
- 嵌入式系统学习——STM32之按键输入
- STM32学习系列----STM32之GPIO
- 乐观锁与悲观锁的实现
- Java 类设计----Java类的继承
- cocos2dx 项目总结(陆续更新)
- 几个经典的动态规划算法
- 14期9月自荐
- STM32 GPIO之二——按键例程 学习总结
- Ubuntu pip使用国内镜像,加速安装
- laravel admin快速入门
- jquery的deferred对象
- Java入门知识准备(*随笔*)
- 欢迎使用CSDN-markdown编辑器
- [转]linux 的产生和发展(非常详细的历史)
- ARM Linux 3.x的设备树(Device Tree)
- 2017年8月5日 Ubuntu 14.04 修复日志