STM32入门项目:使用按键控制LED灯亮灭
创作时间:
作者:
@小白创作中心
STM32入门项目:使用按键控制LED灯亮灭
引用
CSDN
1.
https://blog.csdn.net/Aronbattle/article/details/142906194
本文将介绍如何使用STM32微控制器实现一个简单的按键控制LED灯亮灭的项目。通过这个项目,读者可以了解按键和LED的工作原理,以及如何使用STM32的GPIO端口进行输入输出操作。
按键工作原理
- 下拉接法:
- 当K1按下时,PA0与GND之间联通,此时读取PA0的电压是低电平。
- 当松开K1时,PA0被悬空,会导致引脚的电压不确定。因此,STM32内部应该设置上拉输入模式,以避免引脚电压不确定的错误现象。
- 如果PA0是上拉输入模式,上拉电阻连接VDD,保证引脚悬空时,PA0为高电平。
- 所以此时按下按键为引脚为低电平,抬起按键引脚为高电平。
- 上拉接法:
- 此时,PA0外接了一个上拉电阻。松开K1时,引脚由于上拉作用,保持为高电平。
- 按下按键K1时,由于GND此时下部电阻无穷大,上拉电阻无法对抗下部电阻,此时引脚电压为低电平。
- 这种状况不可能出现悬空状态,故此时PA可以配置为浮空输入或上拉输入。
- 如果为上拉输入,由于有两个上拉电阻,且都联通电源电压,这两个上拉电阻为并联状态,此时高电平更强,更稳定。但引脚被强行拉低,损耗也更大。
上述两种接法都是按下为低电平,松开为高电平。
LED电路分析
此为低电平驱动电路:LED正极接在3.3V电压上,负极通过一个限流电阻接到PA0上。
- 当PA0输出低电平时,LED两端会产生电压差,就会形成正向导通电流,LED被点亮。
- 当PA0输出高电压时,LED两端电压均为3.3V,无电势差,不会产生电流,LED不会亮。
限流电阻的作用:
- 防止LED因为电流过大被烧毁
- 可以调节LED的亮度
GPIO在推挽输出模式下,高低电平均有较强的驱动能力,但因为单片机,通常使用高电平弱驱动,低电平强驱动(可以避免高低电平打架)。
接线图
LED1接PA1,LED2接PA2;按键1接PB1,按键2接PB11
代码实现
LED驱动程序
#include "stm32f10x.h"//头文件
void LED_Init(void)//LED初始化函数
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启时钟
GPIO_InitTypeDef GPIO_InitStructure;//定义GPIO结构体,方便配置端口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//将控制LED的引脚设置为推挽输出模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;//LED对应的引脚为PA1和PA2
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //将端口速度设置为50MHz
GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化端口,指向结构体
GPIO_SetBits(GPIOA,GPIO_Pin_1 | GPIO_Pin_2);//将LED设置为默认关闭状态
}
//配置LED开启或关闭的函数
void LED1_ON(void)
{
GPIO_ResetBits(GPIOA,GPIO_Pin_1);
}
void LED1_OFF(void)
{
GPIO_SetBits(GPIOA,GPIO_Pin_1);
}
void LED2_ON(void)
{
GPIO_ResetBits(GPIOA,GPIO_Pin_2);
}
void LED2_OFF(void)
{
GPIO_SetBits(GPIOA,GPIO_Pin_2);
}
按键驱动程序
按键抖动:按键内部是机械机构使用的是机械式弹簧片来进行通断的,所以在按下或松手的一瞬间都会伴随一连串的抖动,持续时间约5-10ms
假设没按下为高电平,按下为低电平;当按下的一瞬间,高电平变为低电平,会来回抖动几下,但对于运行中的单片机5-10ms还是很漫长,所以需要对抖动进行过滤,否则会出现按下按键单片机反应了很多次,所以需要设置按键延时函数
void Key_Init(void)//初始化所接GPIO端口配置函数
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//打开时钟
GPIO_InitTypeDef GPiO_Initstructure;//定义结构体变量
GPiO_Initstructure.GPIO_Mode = GPIO_Mode_IPU;//将GPIO端口设置为上拉输入模式
//因为根据上述电路分析,都是上拉输入高电平,下拉输入低电平
GPiO_Initstructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_11;//选择引脚1和11
GPiO_Initstructure.GPIO_Speed = GPIO_Speed_50MHz;//设置端口速度为50MHz
GPIO_Init(GPIOB,&GPiO_Initstructure);//初始化结构体变量
}
uint8_t Key_Getnum(void)//调用此函数,就会返回按下按键的键码,返回值为uint8_t
{
uint8_t Key_num = 0; //将此变量作为返回值
/*
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
此函数是读取输入数据寄存器某一端口的输入值,参数是GPIOx,GPIO_Pin用于指定端口,返回值uint8_t代表端口的高低电平
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
对比上面函数少了Bit,所以是用来读取整个输入寄存器的输入值
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
此函数用于读取输出寄存器某一端口的输出值
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
此函数用于读取输出寄存器所有端口的输出值
*/
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0)//此函数的返回值是输入寄存器PB1的值
{
Delay_ms(20);//因为按下后有抖动所以要延时
while((GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0))//用于判断是否结束按压
{
Delay_ms(20);
}
Key_num = 1;//将此变量将按键1的值传递出去
}
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0) //同理为PB11的的配置
{
Delay_ms(20);
while((GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0))
{
Delay_ms(20);
}
Key_num = 2;//将此变量将按键2的值传递出去
}
return Key_num;
}
主函数配置
int main(void)
{
LED_Init();//初始化LED端口
Key_Init();//初始化KEY端口
while(1)
{
KeyNum = Key_Getnum();
if(KeyNum == 1)//如果按键1按下LED1亮
{
LED1_ON();
}
if(KeyNum == 2)//如果按键2按下LED1灭
{
LED1_OFF();
}
}
}
热门推荐
《曹全碑》:隶书的巅峰之作
隶书在现代设计中的独特魅力
秋冬防腹泻,老年人必看!
四川省农村居民如何预防长期腹泻?
慢性腹泻的科学诊断方法揭秘!
癌症患者腹泻如何科学补营养?
马齿苋:夏日止泻的天然良药
华强动漫揭秘《熊出没之夺宝熊兵》创作灵感
阿莫西林和阿莫西林克拉维酸钾有何不同?
宋朝文武官职大揭秘:谁才是真正的权力玩家?
中国古代武官体系的演变历程
《1699·桃花扇》:古典文学的现代演绎
江苏省演艺集团《桃花扇》:创新演绎让经典永流传
秋冬打卡赣州古城墙和八境台,感受千年宋城魅力!
嵌入式冰箱选购指南:零嵌、全嵌、平嵌哪种最适合你?
《桃花扇》:一段乱世爱情的BE美学
《桃花扇》:乱世中的爱情与家国情怀
如何理解和应用货币基金的运作机制?这些机制有哪些实际效果和局限性?
11张图,了解债券基金(风险篇)
货币基金收益越来越低!闲钱理财又该如何参与?8大类助阵!
如何安全稳健地进行基金投资?这种投资有哪些策略?
如何正确进行货币基金的买卖操作?货币基金买卖的策略如何计算?
如何选择低风险的投资策略?这些策略有哪些实际应用?
骨关节疾病患者可以补充这些营养素
什么投资风险小?低风险投资的种类有哪些及如何选择?
什么投资风险小?低风险投资的种类有哪些及如何选择?
投资计划书模板:从初学到精通的完整指南
银行基金投资的风险分散方法?
新手投资者在股票市场应该注意哪些事项?
如何避免在投资中陷入误区?这种避免误区的方法对投资收益有何影响?