一、使用proteus绘制简单的电路图,用于后续仿真
二、编写程序
/********************************************************************************************************************
---- @Project: LED-74HC595
---- @File: main.c
---- @Edit: ZHQ
---- @Version: V1.0
---- @CreationTime: 20200529
---- @ModifiedTime: 20200529
---- @Description: 第1个至第8个LED灯一直不亮。在第9个至第16个LED灯,依次逐个
---- 亮灯并且每次只能亮一个灯。每按一次独立按键S13键,原来运行的跑马灯会暂停,原
---- 来暂停的跑马灯会运行。用S1来改变方向,用S5和S9来改变速度。
---- 单片机:AT89C52
********************************************************************************************************************/
#include "reg52.h"
/*——————宏定义——————*/
#define FOSC 11059200L
#define T1MS (65536-FOSC/12/1000) /*1ms timer calculation method in 12Tmode*/
#define const_voice_short 80 /*蜂鸣器短叫的持续时间*/
#define const_key_time1 40
#define const_key_time2 40
#define const_key_time3 40
#define const_key_time4 40
/*——————变量函数定义及声明——————*/
/*定义74HC595*/
sbit Hc595_Sh = P2^3;
sbit Hc595_St = P2^4;
sbit Hc595_Ds = P2^5;
/*定义蜂鸣器*/
sbit Beep = P2^7;
/*定义按键*/
sbit Key_S1 = P0^0; /*定义按键S1,对应S1*/
sbit Key_S2 = P0^1; /*定义按键S2,对应S5*/
sbit Key_S3 = P0^2; /*定义按键S3,对应S9*/
sbit Key_S4 = P0^3; /*定义按键S4,对应S13*/
sbit Key_Gnd = P0^4; /*定义按键模拟地*/
unsigned char ucLED1 = 0; /*代表16个灯的亮灭状态,0代表灭,1代表亮*/
unsigned char ucLED2 = 0;
unsigned char ucLED3 = 0;
unsigned char ucLED4 = 0;
unsigned char ucLED5 = 0;
unsigned char ucLED6 = 0;
unsigned char ucLED7 = 0;
unsigned char ucLED8 = 0;
unsigned char ucLED9 = 0;
unsigned char ucLED10 = 0;
unsigned char ucLED11 = 0;
unsigned char ucLED12 = 0;
unsigned char ucLED13 = 0;
unsigned char ucLED14 = 0;
unsigned char ucLED15 = 0;
unsigned char ucLED16 = 0;
unsigned char ucLed_update = 0; /*刷新变量。每次更改LED灯的状态都要更新一次。*/
unsigned char ucLedStep_01_08 = 0; /*第1个至第8个LED跑马灯的步骤变量*/
unsigned int uiTimeCnt_01_08 = 0; /*第1个至第8个LED跑马灯的统计定时中断次数的延时计数器*/
unsigned char ucLedStep_09_16 = 0; /*第9个至第16个LED跑马灯的步骤变量*/
unsigned int uiTimeCnt_09_16 = 0; /*第9个至第16个LED跑马灯的统计定时中断次数的延时计数器*/
unsigned char ucLedStatus16_09 = 0; /*代表底层74HC595输出状态的中间变量*/
unsigned char ucLedStatus08_01 = 0; /*代表底层74HC595输出状态的中间变量*/
unsigned char ucKeySec = 0; /*被触发的按键编号*/
unsigned int uiKeyTimeCnt1 = 0; /*按键去抖动延时计数器*/
unsigned char ucKeyLock2 = 0; /*按键触发后自锁的变量标志*/
unsigned int uiKeyTimeCnt2 = 0; /*按键去抖动延时计数器*/
unsigned char ucKeyLock3 = 0; /*按键触发后自锁的变量标志*/
unsigned int uiKeyTimeCnt3 = 0; /*按键去抖动延时计数器*/
unsigned char ucKeyLock1 = 0; /*按键触发后自锁的变量标志*/
unsigned int uiKeyTimeCnt4 = 0; /*按键去抖动延时计数器*/
unsigned char ucKeyLock4 = 0; /*按键触发后自锁的变量标志*/
unsigned int uiVoiceCnt = 0; /*蜂鸣器鸣叫的持续时间计数器*/
unsigned int uiSetTimeLevel_09_16 = 300; /*速度变量,此数值越大速度越慢,此数值越小速度越快。*/
unsigned char ucLedDirFlag = 0; /*方向变量,把按键与跑马灯关联起来的核心变量,0代表正方向,1代表反方向*/
unsigned char ucLedStartFlag = 1; /*启动和暂停的变量,0代表暂停,1代表启动*/
/**
* @brief 定时器0初始化函数
* @param 无
* @retval 初始化T0
**/
void Init_T0(void)
{
TMOD = 0x01; /*set timer0 as mode1 (16-bit)*/
TL0 = T1MS; /*initial timer0 low byte*/
TH0 = T1MS >> 8; /*initial timer0 high byte*/
}
/**
* @brief 外围初始化函数
* @param 无
* @retval 初始化外围
**/
void Init_Peripheral(void)
{
ET0 = 1;/*允许定时中断*/
TR0 = 1;/*启动定时中断*/
EA = 1;/*开总中断*/
}
/**
* @brief 初始化函数
* @param 无
* @retval 初始化单片机
**/
void Init(void)
{
Key_Gnd = 0;
Beep = 1;
Init_T0();
}
/**
* @brief 延时函数
* @param 无
* @retval 无
**/
void Delay_Long(unsigned int uiDelayLong)
{
unsigned int i;
unsigned int j;
for(i=0;i<uiDelayLong;i++)
{
for(j=0;j<500;j++) /*内嵌循环的空指令数量*/
{
; /*一个分号相当于执行一条空语句*/