51单片机彩灯控制与数码管结合

1.这是控制灯的流程图

2.首先在proteus 8软件绘制电路图
配置好51的最小系统,复位电路,晶振电路,按键电路,彩灯电路,数码管电路等

这里的数码管采用共阴极接法,a=p02、b=p03、c=p04、d=p05、e=p06、f=p01、g=p00、dp无、com接地。因为我的实物是这种接法,不是标准的共阴数码管。

3.在keil软件进行编程

代码:

cpp 复制代码
#include <reg52.h>  // AT89C52头文件

typedef unsigned char u8;
typedef unsigned int u16;

sbit RED    = P2^1;  // Q1: 红灯
sbit YELLOW = P2^2;  // Q2: 黄灯
sbit GREEN  = P2^3;  // Q3: 绿灯

sbit START_BUTTON = P3^4;  // 启动按键
sbit RESET_BUTTON = P3^5;  // 复位按键

sbit a = P0^2;  // a段 -> P0.2
sbit b = P0^3;  // b段 -> P0.3
sbit c = P0^4;  // c段 -> P0.4
sbit d = P0^5;  // d段 -> P0.5
sbit e = P0^6;  // e段 -> P0.6
sbit f = P0^1;  // f段 -> P0.1
sbit g = P0^0;  // g段 -> P0.0

// 共阴极数码管0~9的段码
u8 seg_table[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

// 状态枚举(Q3Q2Q1顺序)
typedef enum
{
    STATE_000 = 0,  // 000(全灭)
    STATE_001,      // 001(红灯亮)
    STATE_011,      // 011(红灯+黄灯亮)
    STATE_010,      // 010(黄灯亮)
    STATE_110,      // 110(黄灯+绿灯亮)
    STATE_100,      // 100(绿灯亮)
    STATE_101,      // 101(红灯+绿灯亮)
    STATE_111       // 111(全亮)
} State;

State current_state = STATE_000; // 初始状态
bit is_started = 0;  // 启动标志

void delay(u16 n)//12.000MHz
{
	u8 i, j;
	while(n--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}

// 更新彩灯状态(严格按Q3Q2Q1顺序)
void update_leds()
{
    switch (current_state)
	{
        case STATE_000: // 000(全灭)
            GREEN = 1; YELLOW = 1; RED = 1;
            break;
        case STATE_001: // 001(红灯亮)
            GREEN = 1; YELLOW = 1; RED = 0;
            break;
        case STATE_011: // 011(红灯+黄灯亮)
            GREEN = 1; YELLOW = 0; RED = 0;
            break;
        case STATE_010: // 010(黄灯亮)
            GREEN = 1; YELLOW = 0; RED = 1;
            break;
        case STATE_110: // 110(黄灯+绿灯亮)
            GREEN = 0; YELLOW = 0; RED = 1;
            break;
        case STATE_100: // 100(绿灯亮)
            GREEN = 0; YELLOW = 1; RED = 1;
            break;
        case STATE_101: // 101(红灯+绿灯亮)
            GREEN = 0; YELLOW = 1; RED = 0;
            break;
        case STATE_111: // 111(全亮)
            GREEN = 0; YELLOW = 0; RED = 0;
            break;
	}
}

// 状态切换
void next_state() 
{
    switch (current_state)
	{
        case STATE_000: current_state = STATE_001; break;
        case STATE_001: current_state = STATE_011; break;
        case STATE_011: current_state = STATE_010; break;
        case STATE_010: current_state = STATE_110; break;
        case STATE_110: current_state = STATE_100; break;
        case STATE_100: current_state = STATE_101; break;
        case STATE_101: current_state = STATE_111; break;
        case STATE_111: current_state = STATE_000; break;
	}
}

// 数码管显示函数
void display_digit(u8 num)
{
    u8 seg = seg_table[num];

    // 将标准段码映射到实际引脚
    a = (seg >> 0) & 0x01;  // a对应段码的最低位
    b = (seg >> 1) & 0x01;  // b
    c = (seg >> 2) & 0x01;  // c
    d = (seg >> 3) & 0x01;  // d
    e = (seg >> 4) & 0x01;  // e
    f = (seg >> 5) & 0x01;  // f
    g = (seg >> 6) & 0x01;  // g
}

// 更新数码管显示
void update_seg_display()
{
   u8 display_num;
    switch (current_state)
	{
		case STATE_000: display_num = 1; break;
		case STATE_001: display_num = 2; break;
		case STATE_011: display_num = 3; break;
		case STATE_010: display_num = 4; break;
		case STATE_110: display_num = 5; break;
		case STATE_100: display_num = 6; break;
		case STATE_101: display_num = 7; break;
		case STATE_111: display_num = 8; break;
	}
    display_digit(display_num);
}

void main()
{
    while (1)
	{
		if (START_BUTTON == 0)
		{
			delay(20);
			if (START_BUTTON == 0) is_started = 1;
		}

		if (RESET_BUTTON == 0)
		{
			delay(20);
            if (RESET_BUTTON == 0)
			{
				current_state = STATE_000;
				is_started = 0;
				update_leds();
				display_digit(0); // 复位时数码管显示 0
			}
		}

		if (is_started)
		{
			update_leds();   // 更新LED状态
			update_seg_display(); // 更新数码管显示
			delay(1000);   // 每个状态持续1s
			next_state();    // 切换到下一状态
		}
	}
}

4.仿真效果

按下SB1:1-8循环显示,彩灯也一样循环显示

最后按下SB2:彩灯停止,数码管显示0

相关推荐
梦境虽美,却不长31 分钟前
51单片机快速入门之 SPI通信 2025年4月29日09:26:32
单片机·嵌入式硬件·51单片机·spi通信
钢铁男儿38 分钟前
C#:创建变量和类的实例
c#
XWXnb62 小时前
STM32 中断系统深度剖析
c语言·开发语言·stm32·嵌入式硬件
光子物联单片机2 小时前
GD32F407单片机开发入门(十七)内部RTC实时时钟及实战含源码
stm32·单片机·嵌入式硬件·mcu·gd32单片机
.似水2 小时前
2025.4.26_STM32_SPI
stm32·单片机·嵌入式硬件
了一li2 小时前
C#中用 OxyPlot 在 WinForms 实现波形图可视化(附源码教程)
开发语言·c#
大模型铲屎官2 小时前
Unity C# 与 Shader 交互入门:脚本动态控制材质与视觉效果 (含 MaterialPropertyBlock 详解)(Day 38)
c语言·unity·c#·交互·游戏开发·材质·shader
chegan3 小时前
用c#从头写一个AI agent,实现企业内部自然语言数据统计分析(三)--一个综合的例子
ai·c#·agent
小智学长 | 嵌入式4 小时前
单片机-89C51部分:8、定时器
单片机·嵌入式硬件
全栈小54 小时前
【C#】.net core6.0无法访问到控制器方法,直接404。由于自己的不仔细,出现个低级错误,这让DeepSeek看出来了,是什么错误呢,来瞧瞧
开发语言·c#·.netcore