一、stm32 按键输入控制LED灯
volatile是一个特征修饰符(type specifier).
volatile的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略,
且要求每次直接读值
输出寄存器:ODR BSRR BRR
输入寄存器:IDR(0 低电平)
#define __I volatile
#define __I volatile const
#define __O volatile
#define __IO volatile
二、编程思路
bsp_key.c
创建函数void ···(KEY)_GPIO_Config() //端口gpio初始化
{
1、结构体变量
2、时钟
3、结构体成员(输入模式 不用速度)
4、结构体成员放到寄存器
}
函数写完放到头文件
//按键(读取IDR输入寄存器)检测按键被按下(函数)
(不是void类型) unit8_t KEY_Scan(GPIO_TypeDef *GPIOx【端口】,uint16_t GPIO_Pin【具体引脚号】)(传输两个形参)
{
//if括号内函数 GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
if (读取电平函数)(等于1位高电平)【GPIO_ReadInputDataBit(GPIOA,GPIO_PIN_1)==1】 // IDR寄存器的值为高电平(需要读取高电平的函数)(读一个IO口/16个IO口)
{
//松手检测
while(GPIO_ReadInputDataBit(GPIOA,GPIO_PIN_1)==1)
return 1;(1通常宏定义为on)
}
else
return 0;(0通常宏定义为off)
}
函数写完放到头文件
三、编程结果
bsp_key.c
#ifndef __BSP_KEY_H
#define __BSP_KEY_H
#include "bsp_key.h"
#endif
void KEY_GPIO_Config(void)
{
GPIO_InitTypeDef Structure;//结构体
RCC_APB2PeriphClockCmd(KEY1_GPIO_CLK, ENABLE);//时钟
RCC_APB2PeriphClockCmd(KEY2_GPIO_CLK, ENABLE);
Structure.GPIO_Pin = KEY2_GPIO_PIN;
Structure.GPIO_Pin = KEY1_GPIO_PIN;
Structure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入(未知上下拉)
//Structure.GPIO_Speed = GPIO_Speed_50MHz; 输入模式不用
GPIO_Init(KEY1_GPIO_PORT, &Structure);//将结构体成员放到寄存器
GPIO_Init(KEY2_GPIO_PORT, &Structure);//将结构体成员放到寄存器
}
uint8_t KEY_Scan(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) //
{
/*检测是否有按键按下 */
if(GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == 1)
{
/*等待按键释放 */
while(GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == 1);
return on;
}
else
return off;
}
bsp_key.h
#ifndef _BSP_LED_H//__或_
#define _BSP_LED_H
#include "stm32f10x.h"
#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 KEY_GPIO_Config(void);
uint8_t KEY_Scan(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
#define on 1
#define off 0
#define LED(a) if(a)GPIO_SetBits(GPIOA,GPIO_Pin_0);else GPIO_ResetBits(GPIOA,GPIO_Pin_0)
#endif
bsp_led.c
#include "bsp_led.h"
void LED_GPIO_Config(void) //初始化GPIO端口
{
GPIO_InitTypeDef Structure;//结构体
RCC_APB2PeriphClockCmd(LED_GPIO_CLK, ENABLE);//时钟
Structure.GPIO_Pin = LED_GPIO_PIN;
Structure.GPIO_Mode = GPIO_Mode_Out_PP;
Structure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(LED_GPIO_PORT, &Structure);//将结构体成员放到寄存器
}
bsp_led.h
#ifndef __BSP_LED_H
#define __BSP_LED_H
#include "stm32f10x.h"
#define LED_GPIO_PIN GPIO_Pin_0
#define LED_GPIO_PORT GPIOB
#define LED_GPIO_CLK RCC_APB2Periph_GPIOB
void LED_GPIO_Config(void);
#define on 1
#define off 0
#define LED(a) if(a)GPIO_SetBits(GPIOB,GPIO_Pin_0);else GPIO_ResetBits(GPIOB,GPIO_Pin_0)
// ^ 异或 c语言一个二进制运算符
// 与1异或改变 与0异或不变
#define LED_TOGGLE {LED_GPIO_PORT ->ODR ^= LED_GPIO_PIN;}
#endif
main.c
#include "stm32f10x.h"
//#include "bsp_led.h"
#include "bsp_key.h"
#include "bsp_led.h"
void Delay(uint32_t count)
{
for(;count!=0;count--);
}
int main(void)
{
LED_GPIO_Config();//初始化LED的GPIO(端口)
KEY_GPIO_Config();//初始化按键
//while(1)
//{
//LED(on);
GPIO_SetBits(GPIOB,GPIO_Pin_0);
//Delay(0XFFFFF); 控制灯泡亮灭
//LED(off);
GPIO_ResetBits(GPIOB,GPIO_Pin_0);
//Delay(0XFFFFF);
//}
/* 轮询按键状态,若按键按下则反转 LED */
while(1)
{
if(KEY_Scan(KEY1_GPIO_PORT,KEY1_GPIO_PIN) == 1)
LED_TOGGLE; /*LED1 反转*/ 输出高低电平
if(KEY_Scan(KEY2_GPIO_PORT,KEY2_GPIO_PIN) == 1)
LED_TOGGLE; /*LED1 反转*/
}
}