一个基于stm32f103的按键控制小灯程序:PA0为按键端(配置为浮空输入),PB0为输出端用于点亮小灯,实现:按下每次按键后PB0的输出状态反转并保持
法一(为何在proteus中无法实现------PA0端口无法控制PB0端口):
while(1)
{
if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==1){
Toggle_LED();
// 延时去抖动
for (uint32_t i = 0; i < 50000; i++);
}
}
法二(在proteus仿真中可以实现效果):
uint8_t Read_Key(void)
{
// 读取PA0的状态
if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 1)
{
// 按键未被按下
return 0;
}
else
{
// 按键被按下
return 1;
}
}
int main(void)
{
// 初始化GPIO
GPIO_Config();
while (1)
{
// 读取按键状态
if (Read_Key() == 1)
{
// 按键被按下,反转LED状态
Toggle_LED();
// 延时去抖动
for (uint32_t i = 0; i < 50000; i++);
}
}
}
仿真图:
在仿真中还发现若延时消抖时间过短,PB0端口控制的小灯会一直不受控制的闪烁
完整代码:
#include "stm32f10x.h"
void GPIO_Config(void);
uint8_t Read_Key(void);
void Toggle_LED(void);
int main(void)
{
// 初始化GPIO
GPIO_Config();
while (1)
{
// 读取按键状态
if (Read_Key() == 1)
{
// 按键被按下,反转LED状态
Toggle_LED();
// 延时去抖动
for (uint32_t i = 0; i < 50000; i++);
}
}
}
void GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
// 启用GPIOA和GPIOB的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
// 配置PA0为浮空输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置PB0为推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
uint8_t Read_Key(void)
{
// 读取PA0的状态
if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 1)
{
// 按键被按下
return 0;
}
else
{
// 按键未被按下
return 1;
}
}
void Toggle_LED(void)
{
// 反转PB0的状态
if (GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_0) == 1)
{
GPIO_ResetBits(GPIOB, GPIO_Pin_0); // 关闭LED
}
else
{
GPIO_SetBits(GPIOB, GPIO_Pin_0); // 打开LED
}
}