功能简介
使用库函数基于STM32F103c8t6实现对5个按键动作的检测和4个LED指示灯的控制。所要实现的效果为:
- 程序开始运行时,开发平台上的4 个LED 全部是熄灭状态;
- 按下某个按键时,对应的LED点亮,其它LED熄灭,再次按下改键时,对应的LED也熄灭;
- 其它按键也具备这样的功能;
- 而第五个按键则对应这4个led的流水状态;
功能实现
按键控制led
代码编程流程图
软件代码
按键部分:key.c(key.h声明一下头函数即可)
/*按键初始化*/
void Key_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;//根据仿真接线选择下拉输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1| GPIO_Pin_3| GPIO_Pin_4| GPIO_Pin_11;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/*按键扫描返回键值*/
uint8_t Key_GetNum(void)//按键按下为1,松开为0
{
uint8_t KeyNum = 0;
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 1)
{
Delay_ms(20);//延时消抖
while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 1);
Delay_ms(20);
KeyNum = 1;
}
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 1)
{
Delay_ms(20);
while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 1);
Delay_ms(20);
KeyNum = 2;
}
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_3) == 1)
{
Delay_ms(20);
while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_3) == 1);
Delay_ms(20);
KeyNum = 3;
}
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_4) == 1)
{
Delay_ms(20);
while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_4) == 1);
Delay_ms(20);
KeyNum = 4;
}
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 1)
{
Delay_ms(20);
while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 1);
Delay_ms(20);
KeyNum = 5;
}
return KeyNum;
}
LED部分:
/*LED初始化*/
void LED_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化为低电平
GPIO_SetBits(GPIOA, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3);//需使其都为高电平
}
/*LED代码*/
/*说白了就是灯状态的封装,想要灯怎么亮封装引用即可,以下使用简单的封装*/
void LED1_Turn(void) //电平反转
{
if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_0) == 0)
{
GPIO_SetBits(GPIOA, GPIO_Pin_0);
}
else
{
GPIO_ResetBits(GPIOA, GPIO_Pin_0);
}
}
void LED2_Turn(void)
{
if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_1) == 0)
{
GPIO_SetBits(GPIOA, GPIO_Pin_1);
}
else
{
GPIO_ResetBits(GPIOA, GPIO_Pin_1);
}
}
void LED3_Turn(void)
{
if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_2) == 0)
{
GPIO_SetBits(GPIOA, GPIO_Pin_2);
}
else
{
GPIO_ResetBits(GPIOA, GPIO_Pin_2);
}
}
void LED4_Turn(void)
{
if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_3) == 0)
{
GPIO_SetBits(GPIOA, GPIO_Pin_3);
}
else
{
GPIO_ResetBits(GPIOA, GPIO_Pin_3);
}
}
void LED5_ON(void)
{
GPIO_ResetBits(GPIOA, GPIO_Pin_0);
Delay_ms(100);
GPIO_ResetBits(GPIOA, GPIO_Pin_1);
Delay_ms(100);
GPIO_ResetBits(GPIOA, GPIO_Pin_2);
Delay_ms(100);
GPIO_ResetBits(GPIOA, GPIO_Pin_3);
Delay_ms(100);
}
void LED5_OFF(void)
{
GPIO_SetBits(GPIOA, GPIO_Pin_0);
Delay_ms(100);
GPIO_SetBits(GPIOA, GPIO_Pin_1);
Delay_ms(100);
GPIO_SetBits(GPIOA, GPIO_Pin_2);
Delay_ms(100);
GPIO_SetBits(GPIOA, GPIO_Pin_3);
Delay_ms(100);
}
/**
* @brief 微秒级延时
* @param xus 延时时长,范围:0~233015
* @retval 无
*/
void Delay_us(uint32_t xus)
{
SysTick->LOAD = 72 * xus; //设置定时器重装值
SysTick->VAL = 0x00; //清空当前计数值
SysTick->CTRL = 0x00000005; //设置时钟源为HCLK,启动定时器
while(!(SysTick->CTRL & 0x00010000)); //等待计数到0
SysTick->CTRL = 0x00000004; //关闭定时器
}
/**
* @brief 毫秒级延时
* @param xms 延时时长,范围:0~4294967295
* @retval 无
*/
void Delay_ms(uint32_t xms)
{
while(xms--)
{
Delay_us(1000);
}
}
主函数main:
uint8_t KeyNum;
int main(void)
{
LED_Init();
Key_Init();
while (1)
{
KeyNum = Key_GetNum();
if (KeyNum == 1)
{
LED1_Turn();
}
if (KeyNum == 2)
{
LED2_Turn();
}
if (KeyNum == 3)
{
LED3_Turn();
}
if (KeyNum == 4)
{
LED4_Turn();
}
if (KeyNum == 5)
{
while(1)
{
KeyNum =Key_GetNum();
LED5_ON();
KeyNum =Key_GetNum();
LED5_OFF();
}
}
}
}