- 硬件部分
- 软件部分
- 宏定义注意点
- 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_GPIOC
void 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页