开发环境
Keil MDK 5.33
proteus 8.9
代码实现
main.c
#include "stm32f10x.h"
#define KEY_ON 1
#define KEY_OFF 0
GPIO_InitTypeDef GPIO_InitStructure;
// 修改延时函数以减少循环次数
void delay_ms(uint32_t ms)
{
uint32_t i_cnt, j_cnt;
for (i_cnt = 0; i_cnt < 3000; i_cnt++);
for (j_cnt = 0; j_cnt < ms; j_cnt++);
}
uint32_t i;
void Key_Configure(void)
{
// 使能时钟:按键使用PB6和PB0
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
// 配置PB6
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// 配置PB0
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void light_on_down()
{
// 依次点亮 GPIOC 上的 LED 并熄灭,形成流动的效果
for (int i = 0; i < 8; i++)
{
/*******注意:延时的时间一定要足够大且在电平设置之前延时,否则肉眼无法很好地观测灯泡明灭*****/
delay_ms(99000); // 增加延时时间
GPIOC->ODR &= ~(1 << i); // 设置第 i 个 LED 为低电平
delay_ms(99000); // 增加延时时间
GPIOC->ODR |= (1 << i); // 设置第 i 个 LED 为高电平
}
}
void light_on_up()
{
// 逆序点亮 GPIOC 上的 LED 并熄灭
for (int i = 7; i >= 0; i--)
{
delay_ms(99000); // 增加延时时间
GPIOC->ODR &= ~(1 << i); // 设置第 i 个 LED 为低电平
delay_ms(99000); // 增加延时时间
GPIOC->ODR |= (1 << i); // 设置第 i 个 LED 为高电平
}
}
int main(void)
{
// 配置按键
Key_Configure();
// 使能GPIOC的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
// 初始化GPIOC的所有引脚作为输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
// 清除GPIOC所有引脚的输出状态
GPIOC->ODR = 0; // 设置所有引脚为低电平
while (1)
{
// 检测按键状态
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_6) == KEY_OFF) // 低电平表示按键按下
{
// 去抖动
delay_ms(50);
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_6) == KEY_OFF)
{
// 等待按键抬起
while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_6) == KEY_OFF)
{
light_on_down(); // 按PB6顺序亮灯
delay_ms(10); // 增加延时,防止重复检测
}
}
}
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == KEY_OFF) // 低电平表示按键按下
{
// 去抖动
delay_ms(50);
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == KEY_OFF)
{
// 等待按键抬起
while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == KEY_OFF)
{
light_on_up(); // 按PB0逆序亮灯
delay_ms(10); // 增加延时,防止重复检测
}
}
}
}
}
运行效果
STM32灯泡控制