STM32控制流水灯

目录

1、开发板

2、目的

3、代码

4、现象


1、开发板

开发板使用的是野火STM32F103RCT6min开发板

2、目的

使用HAL库,实现流水灯,KEY1控制流水灯的开始和暂停,KEY2控制流水灯的方向,初始化默认所有灯熄灭

3、代码

按键中断代码

KEY_EXTI.c

#include "./EXTI/KEY_EXTI.h"

extern uint8_t led_running;
extern uint8_t led_direction;


void EXTI_Key_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure; 

    /*开启按键GPIO口的时钟*/
    KEY1_INT_GPIO_CLK_ENABLE();
    KEY2_INT_GPIO_CLK_ENABLE();

    /* 选择按键1的引脚 */ 
    GPIO_InitStructure.Pin = KEY1_INT_GPIO_PIN;
    /* 设置引脚为输入模式 */ 
    GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING;	    		
    /* 设置引脚不上拉也不下拉 */
    GPIO_InitStructure.Pull = GPIO_NOPULL;
    /* 使用上面的结构体初始化按键 */
    HAL_GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStructure); 
    /* 配置 EXTI 中断源 到key1 引脚、配置中断优先级*/
    HAL_NVIC_SetPriority(KEY1_INT_EXTI_IRQ, 0, 0);
    /* 使能中断 */
    HAL_NVIC_EnableIRQ(KEY1_INT_EXTI_IRQ);

    /* 选择按键2的引脚 */ 
    GPIO_InitStructure.Pin = KEY2_INT_GPIO_PIN;  
    /* 其他配置与上面相同 */
    HAL_GPIO_Init(KEY2_INT_GPIO_PORT, &GPIO_InitStructure);      
    /* 配置 EXTI 中断源 到key1 引脚、配置中断优先级*/
    HAL_NVIC_SetPriority(KEY2_INT_EXTI_IRQ, 0, 0);
    /* 使能中断 */
    HAL_NVIC_EnableIRQ(KEY2_INT_EXTI_IRQ);
}


void EXTI0_IRQHandler(void)
{
  if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_0) != RESET)
  {
	  
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_0);  // 清除中断标志
	led_running = !led_running; // 切换开始/暂停状态

  }
}

void EXTI15_10_IRQHandler(void)
{
  if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_13) != RESET)
  {
	  
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_13); // 清除中断标志
	led_direction = !led_direction; // 切换方向

  }
}


KEY_EXTI.h

#ifndef __EXTI_H
#define	__EXTI_H

#include "stm32f1xx.h"

//引脚定义
/*******************************************************/
#define KEY1_INT_GPIO_PORT                GPIOA
#define KEY1_INT_GPIO_CLK_ENABLE()        __HAL_RCC_GPIOA_CLK_ENABLE();
#define KEY1_INT_GPIO_PIN                 GPIO_PIN_0
#define KEY1_INT_EXTI_IRQ                 EXTI0_IRQn


#define KEY2_INT_GPIO_PORT                GPIOC
#define KEY2_INT_GPIO_CLK_ENABLE()        __HAL_RCC_GPIOC_CLK_ENABLE();
#define KEY2_INT_GPIO_PIN                 GPIO_PIN_13
#define KEY2_INT_EXTI_IRQ                 EXTI15_10_IRQn


/*******************************************************/


void EXTI_Key_Config(void);

#endif /* __EXTI_H */

流水灯代码

bsp_led.h

#ifndef __LED_H
#define	__LED_H

#include "stm32f1xx.h"


#define LED_GPIO_PORT       GPIOC
#define LED3_PIN            GPIO_PIN_4
#define LED4_PIN            GPIO_PIN_5
#define LED5_PIN            GPIO_PIN_6
#define LED6_PIN            GPIO_PIN_7
#define LED7_PIN            GPIO_PIN_8

					

extern uint8_t led_running;
extern uint8_t led_direction;


void LED_Init(void);
void LED_Show(uint8_t index);
void TIM3_Init(uint16_t period);
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);

#endif /* __LED_H */

bsp_led.c

#include "./led/bsp_led.h"   

TIM_HandleTypeDef htim3;
// 内部状态变量
uint8_t led_index = 0;		 // 当前点亮第几个灯
uint8_t led_running = 0;     // 默认暂停
uint8_t led_direction = 0;   // 方向,0为向右,1为向左



void LED_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct ; // 定义 GPIO 初始化结构体

    __HAL_RCC_GPIOC_CLK_ENABLE(); // 使能 GPIOC 端口时钟

    // 设置 PC4~PC8(LED3~LED7)为推挽输出,无上拉下拉,中速
    GPIO_InitStruct.Pin = LED3_PIN | LED4_PIN | LED5_PIN | LED6_PIN | LED7_PIN;  // 这几个宏定义应在 led.h 中定义为 GPIO_PIN_4~GPIO_PIN_8
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;    // 推挽输出模式
    GPIO_InitStruct.Pull = GPIO_NOPULL;            // 无上拉下拉
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM; // 中速输出

    HAL_GPIO_Init(LED_GPIO_PORT, &GPIO_InitStruct); // 初始化 GPIOC 的这几个引脚

    // 初始时将所有 LED 熄灭(假设高电平熄灭,低电平点亮)
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8, GPIO_PIN_SET);
}


void LED_Show(uint8_t index)
{
    // 将 5 个 LED 引脚保存到数组,便于用下标访问
    uint16_t pins[5] = {LED3_PIN, LED4_PIN, LED5_PIN, LED6_PIN, LED7_PIN};

    // 先将所有 LED 熄灭
    for (int i = 0; i < 5; i++)
    {
        HAL_GPIO_WritePin(LED_GPIO_PORT, pins[i], GPIO_PIN_RESET);  // 全部拉低(假设低电平熄灭)
    }

    // 如果 index 在 0~4 范围内,点亮对应编号的 LED
    if (index < 5)
    {
        HAL_GPIO_WritePin(LED_GPIO_PORT, pins[index], GPIO_PIN_SET);  // 指定引脚拉高,点亮
    }
}


void TIM3_Init(uint16_t period)
{
    __HAL_RCC_TIM3_CLK_ENABLE(); // 使能 TIM3 时钟

    htim3.Instance = TIM3;       // 选择使用的定时器是 TIM3
    htim3.Init.Prescaler = 7200 - 1;  // 设置预分频器,系统时钟72MHz / 7200 = 10kHz
    htim3.Init.Period = period - 1;   // 自动重装值,定时器计满周期为 period / 10ms
    htim3.Init.CounterMode = TIM_COUNTERMODE_UP; // 向上计数模式
    HAL_TIM_Base_Init(&htim3);   // 初始化定时器

    HAL_TIM_Base_Start_IT(&htim3); // 启动定时器并开启中断

    HAL_NVIC_SetPriority(TIM3_IRQn, 1, 0); // 设置 TIM3 中断优先级为 1
    HAL_NVIC_EnableIRQ(TIM3_IRQn);        // 使能 TIM3 中断
}


void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    // 判断是否是 TIM3 产生的中断,且 LED 状态为运行中
    if (htim->Instance == TIM3 && led_running)
    {
        LED_Show(led_index);  // 显示当前的 LED 灯

        // 根据方向判断向左或向右移动
        if (led_direction == 0)  // 向右(编号增加)
        {
            led_index++;              // 下一个灯编号
            if (led_index >= 5) led_index = 0; // 超过4则回到0
        }
        else  // 向左(编号减少)
        {
            if (led_index == 0) led_index = 4; // 如果当前是0,则跳转到最后一个
            else led_index--;                 // 否则递减
        }
    }
}


void TIM3_IRQHandler(void)
{
    HAL_TIM_IRQHandler(&htim3); // 调用 HAL 库的 TIM3 中断处理函数
}


main.c程序中只需各个函数初始即可

4、现象

视频链接:流水灯现象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值