仿真图:
芯片/模块的特点:
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