基于51单片机的交通灯控制系统仿真

仿真图:

在这里插入图片描述

芯片/模块的特点:

AT89C52简介:
AT89C52是一款经典的8位单片机,是意法半导体(STMicroelectronics)公司生产的一系列单片机之一。它基于8051内核,并具有许多与其兼容的特性。

AT89C52的主要特点如下:

内部存储器:AT89C52具有8KB的闪存(Flash)存储器,可用于存储用户程序和数据。这些存储器的内容可以通过编程器进行编程和擦除。

RAM存储器:AT89C52配备了256字节的随机存取存储器(RAM),用于暂存数据和程序的变量。

外部扩展性:AT89C52支持多种外部扩展设备的连接,包括外部存储器(如RAM、EEPROM)和外设(如ADC、LCD、UART等),通过外部硬件连接,可以扩展单片机的功能和应用。

通用I/O引脚:AT89C52拥有32个可编程的通用输入/输出引脚,可用于连接外部设备和与其他芯片进行通信。

定时器/计数器:AT89C52内置了3个16位定时器/计数器和一个可编程的串行定时器/计数器。这些计时器/计数器可用于实现定时功能、生成脉冲信号、测量时间间隔等。0

串行通信:AT89C52支持串行通信接口,包括UART(串行异步通信)和SPI(串行外设接口),便于与其他设备进行数据通信和交互。

低功耗模式:AT89C52具有多种低功耗模式,如空闲模式和电源下模式,在不需要执行任务的时候可以将CPU进入低功耗状态以节省能量。

宽电源电压范围:AT89C52的工作电压范围通常为4.0V至5.5V,可以满足大多数应用需求。

主程序:

#include <reg52.h>
#include "delay.h"

#define SMG_Port P0

//实物请屏蔽该句
#define _SIMULATION_

#ifdef _SIMULATION_
sbit SMG1 = P2^4;     //定义南北方向数码管低位
sbit SMG2 = P2^3;     //定义南北方向数码管高位
#else
sbit SMG1 = P4^3;     //定义南北方向数码管低位
sbit SMG2 = P4^2;     //定义南北方向数码管高位
#endif


sbit SMG3 = P3^2;     //定义东西方向数码管低位
sbit SMG4 = P3^3;     //定义东西方向数码管高位
sbit N_GREEN = P2^0;  //定义北向绿灯端口
sbit N_RED = P2^1;    //定义北向红灯端口
sbit N_YELLOW = P2^2; //定义北向黄灯端口

sbit S_GREEN = P2^7;  //定义南向绿灯端口
sbit S_RED = P2^6;    //定义南向红灯端口
sbit S_YELLOW = P2^5; //定义南向黄灯端口

sbit W_GREEN = P1^0;  //定义西向绿灯端口
sbit W_RED = P1^1;    //定义西向红灯端口
sbit W_YELLOW = P1^2; //定义西向黄灯端口

sbit E_GREEN = P1^7;  //定义东向绿灯端口
sbit E_RED = P1^6;    //定义东向红灯端口
sbit E_YELLOW = P1^5; //定义东向黄灯端口

sbit KEY_RST = P3^4;     //定义复位按键
sbit KEY_NIGHT = P3^5;   //定义夜间模式按键
sbit KEY_URGENCY = P3^6; //定义紧急模式按键
sbit KEY_SET = P3^7;     //定义设定时间按键
sbit KEY_ADD = P1^3;     //定义时间加按键
sbit KEY_SUB = P1^4;     //定义时间减按键  

unsigned char code table[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x40}; //共阴极数码管段值
unsigned char greenNSCnt;
unsigned char greenEWCnt;
unsigned char setGreenNSTime = 20;
unsigned char setGreenEWTime = 20;
unsigned char setIndex = 0;

bit dispFlag = 0;
bit rekey = 0;
enum {NORMAL, SETTIME, URGENCY, NIGHT}dispMode;
enum {GREEN_NS_MODE, GREEN_EW_MODE}LEDMode;



void Timer0_Init(void);
void DispNormal(void);
void DispUrgency(void);
void DispNight(void);
void KeyProcess(void);
void RefreshSMG(unsigned char dat);
void AllOff(void);
void DispSet(void);

void main()
{
    Timer0_Init();

    greenNSCnt = setGreenNSTime;
    greenEWCnt = setGreenEWTime;

    while (1)
    {

        if (dispMode == NORMAL)
        {
            DispNormal();
        }
        else if (dispMode == SETTIME)
        {
            DispSet();
        }
        else if (dispMode == URGENCY)
        {
            DispUrgency();
        }
        else if (dispMode == NIGHT)
        {
            DispNight();
        }

        KeyProcess();
    }
}

void RefreshSMG(unsigned char dat)
{
    int highByte, lowByte;

    highByte = dat / 10; //将倒计时时间的高位赋予highByte
    lowByte = dat % 10; //将倒计时时间的低位赋予lowByte
    P0 = table[highByte];
    SMG1 = 0;
    DelayMs(3);
    SMG1 = 1; //显示highByte

    P0 = table[lowByte];
    SMG2 = 0;
    DelayMs(3);
    SMG2 = 1; //显示lowByte

    P0 = table[highByte];
    SMG3 = 0;
    DelayMs(3);
    SMG3 = 1; //显示highByte

    P0 = table[lowByte];
    SMG4 = 0;
    DelayMs(3);
    SMG4 = 1; //显示lowByte
}

void SetNSSMG(unsigned char dat)
{
    int highByte, lowByte;

    highByte = dat / 10; //将倒计时时间的高位赋予highByte
    lowByte = dat % 10; //将倒计时时间的低位赋予lowByte
    P0 = table[highByte];
    SMG1 = 0;
    DelayMs(3);
    SMG1 = 1; //显示highByte

    P0 = table[lowByte];
    SMG2 = 0;
    DelayMs(3);
    SMG2 = 1; //显示lowByte


    // P0 = table[highByte];
    // SMG3 = 0;
    // DelayMs(3);
    SMG3 = 1; //显示highByte

    // P0 = table[lowByte];
    // SMG4 = 0;
    // DelayMs(3);
    SMG4 = 1; //显示lowByte
}

void SetEWSMG(unsigned char dat)
{
    int highByte, lowByte;

    highByte = dat / 10; //将倒计时时间的高位赋予highByte
    lowByte = dat % 10; //将倒计时时间的低位赋予lowByte
    // P0 = table[highByte];
    // SMG1 = 0;
    // DelayMs(3);
    SMG1 = 1; //显示highByte

    // P0 = table[lowByte];
    // SMG2 = 0;
    // DelayMs(3);
    SMG2 = 1; //显示lowByte


    P0 = table[highByte];
    SMG3 = 0;
    DelayMs(3);
    SMG3 = 1; //显示highByte

    P0 = table[lowByte];
    SMG4 = 0;
    DelayMs(3);
    SMG4 = 1; //显示lowByte
}

void AllOff()
{
    N_GREEN = 1;
    N_RED = 1;
    N_YELLOW = 1;

    S_GREEN = 1;
    S_RED = 1;
    S_YELLOW = 1;

    E_GREEN = 1;
    E_RED = 1;
    E_YELLOW = 1;

    W_GREEN = 1;
    W_RED = 1;
    W_YELLOW = 1;
}

void DispNormal(void)
{
    if (LEDMode == GREEN_NS_MODE)
    {
        RefreshSMG(greenNSCnt);
        if (greenNSCnt == 0)
        {
            AllOff();
            greenNSCnt = setGreenNSTime;
            LEDMode = GREEN_EW_MODE;
        }
        else if (greenNSCnt <= 3)
        {
            N_GREEN = 1;
            N_RED = 1;
            N_YELLOW = 0;

            S_GREEN = 1;
            S_RED = 1;
            S_YELLOW = 0;

            E_GREEN = 1;
            E_RED = 0;
            E_YELLOW = 1;

            W_GREEN = 1;
            W_RED = 0;
            W_YELLOW = 1;
        }
        else
        {
            N_GREEN = 0;
            N_RED = 1;
            N_YELLOW = 1;

            S_GREEN = 0;
            S_RED = 1;
            S_YELLOW = 1;

            E_GREEN = 1;
            E_RED = 0;
            E_YELLOW = 1;

            W_GREEN = 1;
            W_RED = 0;
            W_YELLOW = 1;
        }
    }
    else if (LEDMode == GREEN_EW_MODE)
    {
        RefreshSMG(greenEWCnt);
        if (greenEWCnt == 0)
        {
            AllOff();
            greenEWCnt = setGreenEWTime;
            LEDMode = GREEN_NS_MODE;
        }
        else if (greenEWCnt <= 3)
        {
            N_GREEN = 1;
            N_RED = 0;
            N_YELLOW = 1;

            S_GREEN = 1;
            S_RED = 0;
            S_YELLOW = 1;

            E_GREEN = 1;
            E_RED = 1;
            E_YELLOW = 0;

            W_GREEN = 1;
            W_RED = 1;
            W_YELLOW = 0;
        }
        else
        {
            N_GREEN = 1;
            N_RED = 0;
            N_YELLOW = 1;

            S_GREEN = 1;
            S_RED = 0;
            S_YELLOW = 1;

            E_GREEN = 0;
            E_RED = 1;
            E_YELLOW = 1;

            W_GREEN = 0;
            W_RED = 1;
            W_YELLOW = 1;
        }
    }
}

void DispSet(void)
{
    AllOff();

    if (setIndex == 1)
    {
        SetNSSMG(setGreenNSTime);
    }
    else if (setIndex == 2)
    {
        SetEWSMG(setGreenEWTime);
    }
}

void DispUrgency(void)
{
    SMG1 = 1;
    SMG2 = 1;
    SMG3 = 1;
    SMG4 = 1;

    N_RED = 0;
    S_RED = 0;
    E_RED = 0;
    W_RED = 0;

    N_GREEN = 1;
    S_GREEN = 1;
    E_GREEN = 1;
    W_GREEN = 1;

    N_YELLOW = 1;
    S_YELLOW = 1;
    E_YELLOW = 1;
    W_YELLOW = 1;
}

void DispNight(void)
{
    SMG1 = 1;
    SMG2 = 1;
    SMG3 = 1;
    SMG4 = 1;

    N_RED = 1;
    S_RED = 1;
    E_RED = 1;
    W_RED = 1;

    N_GREEN = 1;
    S_GREEN = 1;
    E_GREEN = 1;
    W_GREEN = 1;

    N_YELLOW = 1;
    S_YELLOW = 1;
    E_YELLOW = 1;
    W_YELLOW = 1;

    DelayMs(250);

    N_YELLOW = 0;
    S_YELLOW = 0;
    E_YELLOW = 0;
    W_YELLOW = 0;

    DelayMs(250);
}

void KeyProcess()
{
    if (!KEY_ADD || !KEY_SUB || ((P3 & 0xF0) != 0xF0))
    {
        DelayMs(10);
        if (!KEY_RST && rekey == 0)
        {
            rekey = 1;
            if (dispMode == NORMAL)
            {
                TR0 = 1;
                setIndex = 0;
                LEDMode = GREEN_NS_MODE;
                greenNSCnt = setGreenNSTime;
                greenEWCnt = setGreenEWTime;
            }            
        }

        if (!KEY_SET && rekey == 0)
        {
            rekey = 1;
            if (dispMode == NORMAL)
            {
                TR0 = 0;
                setIndex = 1;
                dispMode = SETTIME;
            }
            else if (dispMode == SETTIME)
            {
                setIndex++;
                if (setIndex == 3)
                {
                    setIndex = 0;
                    TR0 = 1;
                    dispMode = NORMAL;
                }
            }
            
        }

        if (!KEY_ADD && rekey == 0)
        {
            rekey = 1;
            if (dispMode == SETTIME)
            {
                if (setIndex == 1)
                {
                    setGreenNSTime++;
                    if (setGreenNSTime > 99)
                    {
                        setGreenNSTime = 5;
                    }
                }
                else if (setIndex == 2)
                {
                    setGreenEWTime++;
                    if (setGreenEWTime > 99)
                    {
                        setGreenEWTime = 5;
                    }
                }
            }
        }

        if (!KEY_SUB && rekey == 0)
        {
            rekey = 1;
            if (dispMode == SETTIME)
            {
                if (setIndex == 1)
                {
                    setGreenNSTime--;
                    if (setGreenNSTime < 5)
                    {
                        setGreenNSTime = 99;
                    }
                }
                else if (setIndex == 2)
                {
                    setGreenEWTime--;
                    if (setGreenEWTime < 5)
                    {
                        setGreenEWTime = 99;
                    }
                }
            }
        }

        if (!KEY_URGENCY && rekey == 0)
        {
            rekey = 1;
            if (dispMode == NORMAL)
            {
                TR0 = 0;
                dispMode = URGENCY;
            }
            else if (dispMode == URGENCY)
            {
                TR0 = 1;
                dispMode = NORMAL;
            }
        }

        else if (!KEY_NIGHT && rekey == 0)
        {
            rekey = 1;
            if (dispMode == NORMAL)
            {
                TR0 = 0;
                dispMode = NIGHT;
            }
            else if (dispMode == NIGHT)
            {
                TR0 = 1;
                dispMode = NORMAL;
            }
        }


    }
    else
    {
        rekey = 0;
    }
}

void Timer0_Init(void)
{
    TMOD &= 0xF0;
    TMOD |= 0x01;                //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
    TH0 = (65536 - 18432) / 256; //重新赋值 20ms
    TL0 = (65536 - 18432) % 256;
    EA = 1;  //总中断打开
    ET0 = 1; //定时器中断打开
    TR0 = 1; //定时器开关打开
}

void Timer0_Int(void) interrupt 1
{
    static unsigned char cnt = 0;

    TH0 = (65536 - 18432) / 256; //重新赋值 20ms
    TL0 = (65536 - 18432) % 256;

    cnt++;

    if (cnt >= 50)
    {
        if (LEDMode == GREEN_NS_MODE)
        {
            greenNSCnt--;
        }
        else if (LEDMode == GREEN_EW_MODE)
        {
            greenEWCnt--;
        }

        cnt = 0;
    }
}

设计文件:
链接:https://pan.baidu.com/s/15fGqy86LNXBDSeeSTUwVBw?pwd=74dh

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值