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

相关推荐
电子工程师-C519 分钟前
基于51单片机的红外防盗及万年历仿真
单片机·嵌入式硬件·51单片机
Camellia031125 分钟前
嵌入式学习--江协stm32day5
stm32·嵌入式硬件·学习
钢铁男儿29 分钟前
C# 表达式和运算符(表达式和字面量)
开发语言·c#
keke1031 分钟前
PLC入门【1】PLC的简单介绍(教学软件:FX-TRN-BEG-C)
嵌入式硬件
keke101 小时前
PLC入门【2】PLC的接线
嵌入式硬件
林鸿群1 小时前
C#子线程更新主线程UI及委托回调使用示例
开发语言·c#
o0向阳而生0o1 小时前
63、.NET 异常处理
c#·.net·异常处理
SteveDraw4 小时前
C++动态链接库封装,供C#/C++ 等编程语言使用——C++动态链接库概述(总)
开发语言·c++·c#·封装·动态链接库
Kookoos4 小时前
性能剖析:在 ABP 框架中集成 MiniProfiler 实现性能可视化诊断
后端·c#·.net·abp vnext·miniprofiler
江山如画,佳人北望5 小时前
stm32-c8t6实现语音识别(LD3320)
stm32·单片机·嵌入式硬件