当前位置: 首页 > article >正文

单片机:实现流水灯左移、右移程序(附带源码)

1. 设计思路

  • 硬件连接
    • 假设使用 STM32 单片机的多个 GPIO 引脚(例如 PA0 到 PA7)连接 8 个 LED 灯。
    • LED 灯的亮灭状态通过控制 GPIO 引脚的电平来实现。通常,使用 "1" 点亮 LED,使用 "0" 熄灭 LED。
  • 左移和右移的实现
    • 左移:从最左端的 LED 开始依次点亮到最右端,然后循环回到最左端。
    • 右移:从最右端的 LED 开始依次点亮到最左端,然后循环回到最右端。
  • 定时控制
    • 通过定时器或者延时函数控制 LED 的切换速度,使得流水灯效果明显。

2. 硬件连接

假设连接 8 个 LED 到 STM32 的 PA0 到 PA7 引脚,并且每个 LED 连接到对应的 GPIO 引脚上,控制它们的电平实现亮灭。

  • PA0PA7 连接到 8 个 LED。

3. 程序设计

程序的主要任务是通过 GPIO 控制 LED 的状态变化,实现流水灯效果。下面分别实现流水灯左移和右移的代码。

3.1. GPIO 初始化

首先需要初始化 STM32 的 GPIO 引脚,将 PA0 到 PA7 配置为输出模式。

#include "stm32f10x.h"

void GPIO_Init_LED(void) {
    // 开启 GPIOA 时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStructure;
    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_Mode = GPIO_Mode_Out_PP;  // 推挽输出模式
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}
  • 在上面的代码中,我们将 PA0 到 PA7 配置为推挽输出模式,这样可以控制 LED 的开关。
3.2. 流水灯左移程序

左移的原理是将一个 "1" 从最低位逐步移到最高位,每次点亮一个 LED,其他 LED 熄灭。

void LED_Left_Shift(void) {
    uint8_t led_state = 0x01;  // 初始时点亮最左边的 LED (PA0)
    
    while (1) {
        GPIOA->ODR = led_state;  // 设置 GPIOA 输出寄存器,控制 PA0 - PA7 的电平
        for (int i = 0; i < 1000000; i++);  // 延时
        
        // 左移,直到最右边
        led_state <<= 1;  // 将 1 左移
        if (led_state == 0x00) {  // 如果已经移到最右边,则重新从最左边开始
            led_state = 0x01;
        }
    }
}
  • 思路:每次将 led_state 左移一位,控制相应的 LED 灯亮灭。
  • GPIOA->ODR = led_state; 用于设置 GPIOA 的输出数据寄存器,根据 led_state 中的值来点亮相应的 LED。
  • 左移操作是通过 led_state <<= 1; 完成的,当 led_state0x00 时,表示已经将所有 LED 点亮过一次,此时将其重置为 0x01,从左边第一个 LED 开始。
3.3. 流水灯右移程序

右移的实现方式类似,不过是将一个 "1" 从最高位逐步移到最低位。

void LED_Right_Shift(void) {
    uint8_t led_state = 0x80;  // 初始时点亮最右边的 LED (PA7)
    
    while (1) {
        GPIOA->ODR = led_state;  // 设置 GPIOA 输出寄存器,控制 PA0 - PA7 的电平
        for (int i = 0; i < 1000000; i++);  // 延时
        
        // 右移,直到最左边
        led_state >>= 1;  // 将 1 右移
        if (led_state == 0x00) {  // 如果已经移到最左边,则重新从最右边开始
            led_state = 0x80;
        }
    }
}
  • 思路:每次将 led_state 右移一位,控制相应的 LED 灯亮灭。
  • GPIOA->ODR = led_state; 同样用于设置 GPIOA 的输出数据寄存器,控制 LED 状态。
  • 右移操作是通过 led_state >>= 1; 完成的,当 led_state0x00 时,表示已经将所有 LED 点亮过一次,此时将其重置为 0x80,从右边第一个 LED 开始。
3.4. 主程序

主程序可以通过调用 LED_Left_ShiftLED_Right_Shift 来控制流水灯的方向。

int main(void) {
    // 初始化 GPIOA 引脚
    GPIO_Init_LED();

    // 流水灯左移
    LED_Left_Shift();  // 或调用 LED_Right_Shift() 实现右移效果
    
    while (1) {
        // 主循环可以执行其他任务
    }
}

4. 总结

  • 硬件设计:通过将 STM32 的 GPIO 引脚连接到 8 个 LED,实现流水灯效果。通过控制 GPIO 输出的电平,实现 LED 的亮灭。
  • 控制原理:通过左移和右移操作改变点亮的 LED 位置,每次更新 GPIO 输出的电平,形成流水灯效果。
  • 延时控制:使用简单的 for 循环实现延时,可以调整延时时间来控制流水灯的速度。

5. 扩展功能

  1. 双向流水灯:可以通过在左移和右移之间切换,实现双向流水灯的效果。
  2. 速度控制:通过调整延时函数的循环次数,改变流水灯的切换速度。
  3. 多种显示模式:可以加入更多的控制逻辑,例如不同的模式(如闪烁、闪烁模式、交替模式等)。

http://www.kler.cn/a/443556.html

相关文章:

  • (南京观海微电子)——GH7009开机黑屏案例分析
  • 【Halcon】例程讲解:基于形状匹配与OCR的多图像处理(附图像、程序下载链接)
  • QML 之状态
  • 【从零开始入门unity游戏开发之——unity篇01】unity6基础入门开篇——游戏引擎是什么、主流的游戏引擎、为什么选择Unity
  • linux ext4文件系统
  • 游戏开发-UE4高清虚幻引擎教程
  • 51c大模型~合集91
  • mobilenetv2-inceptionv3-resnet50三大模型对比实现人脸识别反欺诈系统【带UI界面】
  • 矽睿半导体专为汽车领域研发出一系列应用型霍尔传感器
  • CentOS系统安装rustup
  • EPMA技术:高效率分析仪器的原理与应用-测试狗
  • 贝叶斯推断的条件观点
  • Redis 附加功能(三)— 持久化、发布与订阅及模块
  • 计算机基础知识——数据结构与算法(二)(山东省大数据职称考试)
  • Linux服务器上安装JDK1.8
  • ilqr算法原理推导及代码实践
  • 音视频入门基础:MPEG2-TS专题(19)——FFmpeg源码中,解析TS流中的PES流的实现
  • [网络]tcp通信协议接口函数及一些简易项目
  • 【后端面试总结】深入解析进程和线程的区别
  • 《C++ 赋能强化学习:Q - learning 算法的实现之路》
  • 【Java 数据结构】如何写一副扑克牌 (附:全部码源) !!!
  • 量子通信学习路径(一)
  • JS使用random随机数实现简单的四则算数验证
  • transformer学习笔记-位置编码
  • 使用 NVIDIA DALI 计算视频的光流
  • 【设计模式】单例模式的应用场景