32路流水灯C程序如何实现循环控制?

99ANYc3cd6
预计阅读时长 17 分钟
位置: 首页 C语言 正文

32路流水灯C语言程序

以下是一个使用C语言编写的32路流水灯程序,适用于基于单片机(如8051、AVR或ARM)的系统,这个程序将实现LED灯依次点亮的效果。

32路流水灯c语言程序
(图片来源网络,侵删)

基础版本(适用于8051单片机)

#include <reg51.h>  // 针对8051单片机头文件
#define LED_PORT P1  // 假设LED连接在P1口
void delay(unsigned int time) {
    unsigned int i, j;
    for(i = 0; i < time; i++)
        for(j = 0; j < 1275; j++);
}
void main() {
    unsigned char led_pattern = 0x01;  // 初始模式,只有最低位LED点亮
    while(1) {
        LED_PORT = led_pattern;  // 输出当前LED状态
        delay(500);  // 延时约500ms
        led_pattern <<= 1;  // 左移一位,点亮下一个LED
        if(led_pattern == 0) {  // 如果所有LED都熄灭(溢出)
            led_pattern = 0x01;  // 重新从第一个LED开始
        }
    }
}

改进版本(带双向流动效果)

#include <reg51.h>
#define LED_PORT P1
void delay(unsigned int time) {
    unsigned int i, j;
    for(i = 0; i < time; i++)
        for(j = 0; j < 1275; j++);
}
void main() {
    unsigned char led_pattern = 0x01;
    unsigned char direction = 0;  // 0表示向左,1表示向右
    while(1) {
        LED_PORT = led_pattern;
        delay(300);
        if(direction == 0) {  // 向左流动
            led_pattern <<= 1;
            if(led_pattern == 0x00) {  // 到达最右边
                led_pattern = 0x80;     // 回到最左边
                direction = 1;          // 改变方向
            }
        } else {  // 向右流动
            led_pattern >>= 1;
            if(led_pattern == 0x00) {  // 到达最左边
                led_pattern = 0x01;     // 回到最右边
                direction = 0;          // 改变方向
            }
        }
    }
}

更复杂的版本(带多种模式)

#include <reg51.h>
#define LED_PORT P1
void delay(unsigned int time) {
    unsigned int i, j;
    for(i = 0; i < time; i++)
        for(j = 0; j < 1275; j++);
}
void main() {
    unsigned char led_pattern = 0x01;
    unsigned char mode = 0;  // 0:单向左移 1:单向右移 2:双向流动 3:全亮全灭
    while(1) {
        switch(mode) {
            case 0:  // 单向左移
                LED_PORT = led_pattern;
                delay(200);
                led_pattern <<= 1;
                if(led_pattern == 0x00) led_pattern = 0x01;
                break;
            case 1:  // 单向右移
                LED_PORT = led_pattern;
                delay(200);
                led_pattern >>= 1;
                if(led_pattern == 0x00) led_pattern = 0x80;
                break;
            case 2:  // 双向流动
                LED_PORT = led_pattern;
                delay(200);
                static unsigned char direction = 0;
                if(direction == 0) {
                    led_pattern <<= 1;
                    if(led_pattern == 0x00) {
                        led_pattern = 0x80;
                        direction = 1;
                    }
                } else {
                    led_pattern >>= 1;
                    if(led_pattern == 0x00) {
                        led_pattern = 0x01;
                        direction = 0;
                    }
                }
                break;
            case 3:  // 全亮全灭
                LED_PORT = 0x00;
                delay(500);
                LED_PORT = 0xFF;
                delay(500);
                break;
        }
        // 可以在这里添加按键切换模式的代码
    }
}

注意事项

  1. 硬件连接:确保LED正确连接到单片机的I/O口,可能需要限流电阻。
  2. 延时函数:延时函数的精确值取决于单片机的时钟频率,可能需要调整。
  3. 端口定义:根据实际硬件连接修改LED_PORT的定义。
  4. 扩展性:如果使用其他架构的单片机(如STM32、AVR等),需要修改相应的寄存器定义和端口操作方式。

STM32版本示例(使用HAL库)

#include "stm32f1xx_hal.h"
void LED_Init(void) {
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    __HAL_RCC_GPIOA_CLK_ENABLE();
    GPIO_InitStruct.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_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 |
                          GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void delay_ms(uint32_t ms) {
    HAL_Delay(ms);
}
void main(void) {
    HAL_Init();
    LED_Init();
    uint16_t led_pattern = 0x0001;
    while(1) {
        GPIOA->ODR = led_pattern;
        delay_ms(200);
        led_pattern <<= 1;
        if(led_pattern == 0x0000) {
            led_pattern = 0x0001;
        }
    }
}

根据您的具体硬件平台和需求,可能需要对上述代码进行适当调整。

32路流水灯c语言程序
(图片来源网络,侵删)
-- 展开阅读全文 --
头像
dede文档更新失败,原因何在?
« 上一篇 前天
dede标签如何实现嵌套套用?
下一篇 » 前天

相关文章

取消
微信二维码
支付宝二维码

目录[+]