- 硬件部分
- 软件部分
- 宏定义注意点
- define LED_G_TOGGLE {LED_G_GPIO_PORT->ODR ^= LED_G_GPIO_Pin;} //大括号,括号内有英文分号
- define LED_R(a) if(a) \
GPIO_ResetBits(LED_R_GPIO_PORT, LED_R_GPIO_Pin); \
else GPIO_SetBits(LED_R_GPIO_PORT, LED_R_GPIO_Pin); - define LED_R(a) if(a) GPIO_ResetBits(LED_R_GPIO_PORT, LED_R_GPIO_Pin); \else GPIO_SetBits(LED_R_GPIO_PORT, LED_R_GPIO_Pin);
硬件部分
从按键的原理图可知,这些按键在没有被按下的时候, GPIO 引脚的输入状态为低电平(按键所在的电路不通,引脚接地),当按键按下时, GPIO 引脚的输入状态为高电平(按键所
在的电路导通,引脚接到电源)。只要我们检测引脚的输入电平,即可判断按键是否被按下。 
使用按键时会产生带波纹信号,需要用软件消抖处理滤波,不方便输入检测。本实验板连接的按键带硬件消抖功能,见图 ,它利用电容充放电的延时,消除了波纹,从而简化软件的处理,软件只需要直接检测引脚的电平即可。
从按键的原理图可知,这些按键在没有被按下的时候, GPIO 引脚的输入状态为低电平(按键所在的电路不通,引脚接地),当按键按下时, GPIO 引脚的输入状态为高电平(按键所在的电路导通,引脚接到电源)。只要我们检测引脚的输入电平,即可判断按键是否被按下。
软件部分
新建工程
在工程模板中,uesr文件夹下,新建key文件夹。在其中新建.c 和.h文件
打开程序,在user目录下添加.c文件,并编写#include “bsp_key.h”,魔术棒中添加.h文件,编译。
key.h添加条件编译
#ifndef __BSP_KEY_H#define __BSP_KEY_H#endif /*__BSP_KEY_H */
程序
bsp_led.h
#ifndef __BSP_LED_H#define __BSP_LED_H#include "stm32f10x.h"#define LED_G_GPIO_Pin GPIO_Pin_0#define LED_G_GPIO_PORT GPIOB#define LED_G_GPIO_CLK RCC_APB2Periph_GPIOB#define LED_B_GPIO_Pin GPIO_Pin_1#define LED_B_GPIO_PORT GPIOB#define LED_B_GPIO_CLK RCC_APB2Periph_GPIOB#define LED_R_GPIO_Pin GPIO_Pin_5#define LED_R_GPIO_PORT GPIOB#define LED_R_GPIO_CLK RCC_APB2Periph_GPIOB#define ON 1#define OFF 0#define LED_G(a) if(a) \GPIO_ResetBits(LED_G_GPIO_PORT, LED_G_GPIO_Pin); \else GPIO_SetBits(LED_G_GPIO_PORT, LED_G_GPIO_Pin);#define LED_B(a) if(a) \GPIO_ResetBits(LED_B_GPIO_PORT, LED_B_GPIO_Pin); \else GPIO_SetBits(LED_B_GPIO_PORT, LED_B_GPIO_Pin);#define LED_R(a) if(a) \GPIO_ResetBits(LED_R_GPIO_PORT, LED_R_GPIO_Pin); \else GPIO_SetBits(LED_R_GPIO_PORT, LED_R_GPIO_Pin);#define LED_G_TOGGLE {LED_G_GPIO_PORT->ODR ^= LED_G_GPIO_Pin;}#define LED_B_TOGGLE {LED_B_GPIO_PORT->ODR ^= LED_B_GPIO_Pin;}#define LED_R_TOGGLE {LED_R_GPIO_PORT->ODR ^= LED_R_GPIO_Pin;}void LED_G_GPIO_Config(void);void LED_B_GPIO_Config(void);void LED_R_GPIO_Config(void);#endif /* __BSP_LED_H */
bsp_key.c
#include "bsp_key.h"void KEY1_GPIO_Config(void){GPIO_InitTypeDef GPIO_InitStruct;RCC_APB2PeriphClockCmd(KEY1_GPIO_CLK , ENABLE);GPIO_InitStruct.GPIO_Pin = KEY1_GPIO_Pin;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStruct);}void KEY2_GPIO_Config(void){GPIO_InitTypeDef GPIO_InitStruct;RCC_APB2PeriphClockCmd(KEY2_GPIO_CLK , ENABLE);GPIO_InitStruct.GPIO_Pin = KEY2_GPIO_Pin;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(KEY2_GPIO_PORT, &GPIO_InitStruct);}uint8_t Key_Scan(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin){if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON){//松手检测while(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON);return KEY_ON;}else return KEY_OFF;}
bsp_key.h
#ifndef __BSP_KEY_H#define __BSP_KEY_H#include "stm32f10x.h"#define KEY_ON 1#define KEY_OFF 0#define KEY1_GPIO_Pin GPIO_Pin_0#define KEY1_GPIO_PORT GPIOA#define KEY1_GPIO_CLK RCC_APB2Periph_GPIOA#define KEY2_GPIO_Pin GPIO_Pin_13#define KEY2_GPIO_PORT GPIOC#define KEY2_GPIO_CLK RCC_APB2Periph_GPIOCvoid KEY1_GPIO_Config(void);void KEY2_GPIO_Config(void);uint8_t Key_Scan(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin);#endif /*__BSP_KEY_H */
bsp_led.c
//bsp:board support package#include "bsp_led.h"void LED_G_GPIO_Config(void){GPIO_InitTypeDef GPIO_InitStruct;RCC_APB2PeriphClockCmd(LED_G_GPIO_CLK , ENABLE);GPIO_InitStruct.GPIO_Pin = LED_G_GPIO_Pin;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(LED_G_GPIO_PORT, &GPIO_InitStruct);}void LED_B_GPIO_Config(void){GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin = LED_B_GPIO_Pin;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(LED_G_GPIO_PORT, &GPIO_InitStruct);}void LED_R_GPIO_Config(void){GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin = LED_R_GPIO_Pin;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(LED_G_GPIO_PORT, &GPIO_InitStruct);}
main.c
#include "stm32f10x.h"#include "bsp_led.h"#include "bsp_key.h"void Delay( uint32_t count){for(;count != 0;count--);}//void GreenLed(uint32_t t)//{// LED_G(ON);// LED_B(OFF);// LED_R(OFF);// Delay(t);//}//void BlueLed(uint32_t t)//{// LED_G(OFF);// LED_B(ON);// LED_R(OFF);// Delay(t);//}//void RedLed(uint32_t t)//{// LED_G(OFF);// LED_B(OFF);// LED_R(ON);// Delay(t);//}int main(void){LED_G_GPIO_Config();LED_B_GPIO_Config();KEY1_GPIO_Config();KEY2_GPIO_Config();while(1){if(Key_Scan(KEY1_GPIO_PORT,KEY1_GPIO_Pin) == KEY_ON){LED_G_TOGGLE;}if(Key_Scan(KEY2_GPIO_PORT,KEY2_GPIO_Pin) == KEY_ON){LED_B_TOGGLE;}}}
宏定义注意点
定义语句
define LED_G_TOGGLE {LED_G_GPIO_PORT->ODR ^= LED_G_GPIO_Pin;} //大括号,括号内有英文分号
续行符
define LED_R(a) if(a) \
GPIO_ResetBits(LED_R_GPIO_PORT, LED_R_GPIO_Pin); \
else GPIO_SetBits(LED_R_GPIO_PORT, LED_R_GPIO_Pin);
代码中的“\”是 C 语言中的续行符语法,表示续行符的下一行与续行符所在的代码是同一行。代码中因为宏定义关键字“#define”只是对当前行有效,所以我们使用续行符来连接起来,以下的代码是等效的:
define LED_R(a) if(a) GPIO_ResetBits(LED_R_GPIO_PORT, LED_R_GPIO_Pin); \else GPIO_SetBits(LED_R_GPIO_PORT, LED_R_GPIO_Pin);
应用续行符的时候要注意,在“\”后面不能有任何字符(包括注释、空格),只能直接回车。
见玩转stm32第110页
