stm32按键控制led频率不用delay
时间: 2025-03-27 10:37:19 浏览: 20
### STM32通过按键控制LED闪烁频率而不使用delay函数
为了实现STM32通过按键控制LED闪烁频率而不使用`delay`函数,可以采用定时器中断的方法来精确控制时间间隔。这种方法不仅提高了程序效率,还使得多任务处理更加容易。
#### 定时器配置
设置一个定时器用于产生周期性的中断事件。每当发生中断时,改变LED的状态。这样就可以避免长时间占用CPU资源的情况[^1]。
```c
// 初始化TIM2定时器,设定溢出时间为5ms
void TIM2_Init(void){
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能定时器2挂载总线时钟
TIM_TimeBaseStructure.TIM_Period = SystemCoreClock / 72000 - 1; //自动重装载寄存器值
TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; //预分频系数
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //不分割APB时钟
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); //允许更新中断
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //选择IRQ通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00; //抢占优先级最高
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; //子优先级最低
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM2, ENABLE); //启动定时器2
}
```
#### 中断服务例程
当定时器触发中断时,切换LED状态并调整下一次点亮的时间长度。这里假设有一个全局变量`count`用来记录当前的闪烁次数,并且每次按压按钮都会增加这个数值从而影响到下一个循环中的延时时长[^3]。
```c
u8 count=0; //定义全局变量存储闪烁速度等级
void TIM2_IRQHandler(void){
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET){ //判断是否为更新中断源
GPIO_ToggleBits(GPIOA,GPIO_Pin_5); //PA5端口电平反转
switch(count%4+1){ //根据不同的档位设置不同长短的脉冲宽度
case 1 : TIM_SetAutoreload(TIM2,SystemCoreClock/72000*1-1);break;
case 2 : TIM_SetAutoreload(TIM2,SystemCoreClock/72000*2-1);break;
case 3 : TIM_SetAutoreload(TIM2,SystemCoreClock/72000*4-1);break;
case 4 : TIM_SetAutoreload(TIM2,SystemCoreClock/72000*8-1);break;
}
TIM_ClearITPendingBit(TIM2,TIM_IT_Update); //清除标志位
}
}
```
#### 按键检测部分
编写一段简单的代码片段用于监测按键输入情况。一旦检测到有效边沿变化,则修改上述提到的`count`参数以达到调节目的[^5].
```c
extern u8 KEY_Scan(u8 mode); //声明外部函数原型
int main(){
...
while(1){
if(KEY_Scan(0)==1){ //如果检测到K1被按下
count++; //提高闪烁速率级别
Delay_ms(20); //去抖动延迟
}
}
}
u8 KEY_Scan(u8 mode){
static u8 key_up=1;
if(mode==0){
if(key_up&&(KEY1_GPIO_PORT->IDR&KEY1_PIN)==RESET){
key_up=0;
return 1;
}
if((KEY1_GPIO_PORT->IDR&KEY1_PIN)!=RESET){
key_up=1;
}
}
return 0;
}
```
以上就是利用STM32实现按键控制LED闪烁频率的具体方案之一。此方法基于定时器中断机制而非传统的软件延时函数(`delay`)实现了更高效的任务调度以及更好的用户体验效果。
阅读全文
相关推荐


















