一、项目需求
二、代码实现
main.c
#include "reg52.h"
#include "InitSystem.h"
#include "SMGchek.h"
#include "LEDrun.h"
#include "Uart.h"
#include "KEY.h"
#include "Timer.h"
#include "ChooseHC138.h"
void Device_Detect()
{
LEDrun();
while(flag);
SMGchek();
ChooseHC138(YC0);
}
void main()
{
InitSystem();
Device_Detect();
InitTimer0();
InitUart();
while(1){
Select();
DisPlay_Time();
KEY();
}
}
LEDrun.h
#ifndef _LEDrun_H
#define _LEDrun_H
void Delay(unsigned char t);
void LEDrun();
extern unsigned char flag;
void Delay500ms();
#endif
LEDrun.c
#include "reg52.h"
#include "LEDrun.h"
#include <intrins.h>
#include "ChooseHC138.h"
unsigned char star = 1;
unsigned char flag = 1;
void Delay(unsigned char t)
{
while(t--);
}
void Delay500ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 22;
j = 3;
k = 227;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void LEDrun()
{
unsigned char i = 0;
ChooseHC138(YC4);
for(i=0;i<8;i++){
P0 = 0xff << i;
Delay500ms();
}
for(i=0;i<8;i++){
P0 = ~(0xff << i);
Delay500ms();
}
star = 0;
P0 = 0xff;
ChooseHC138(YC0);
flag = 0;
}
SMGchek.h
#ifndef _SMGchek_H
#define _SMGchek_H
void SMG_Display_Bit(unsigned char pos,unsigned char dat);
void SMGchek();
extern unsigned char flag_2;
#endif
SMGchek.c
#include "reg52.h"
#include "SMGchek.h"
#include "LEDrun.h"
#include "LEDrun.h"
#include "ChooseHC138.h"
void SMG_Display_Bit(unsigned char pos,unsigned char dat)
{
ChooseHC138(YC7);
P0 = 0xff;
ChooseHC138(YC6);
P0 = 0x01 << pos;
ChooseHC138(YC7);
P0 = dat;
}
void SMGchek()
{
unsigned char i = 0;
ChooseHC138(YC7);
P0 = 0x00;
ChooseHC138(YC6);
for(i=0;i<8;i++){
P0 = ~(0xfe << i);
Delay500ms();
}
for(i=0;i<8;i++){
P0 = (0xfe << i);
Delay500ms();
}
ChooseHC138(YC0);
Delay500ms();
}
Uart.h
#ifndef _Uart_H
#define _Uary_H
extern unsigned char P0_uart;
extern unsigned char tmp;
void InitUart();
void SendByte(unsigned char dat);
void SendString(unsigned char* ptr);
void Select();
#endif
Uart.c
#include "Uart.h"
#include "reg52.h"
#include <string.h>
#include "ChooseHC138.h"
#include "Timer.h"
sfr AUXR = 0x8e;
unsigned char tmp = 0x00;
unsigned char P0_uart = 0xff;//初始化灯是全灭
void InitUart()
{
TMOD &= 0x0f;
TMOD |= 0x20;
TH1 = 0xfd;
TL1 = 0xfd;
TR1 = 1;
AUXR = 0x00;
SCON = 0x50;
ES = 1;
EA = 1;
}
void SendByte(unsigned char dat)
{
SBUF = dat;
while(!TI);
TI = 1;
}
void SendString(unsigned char* ptr)
{
while(*ptr != '\0'){
SendByte(*ptr);
ptr++;
}
}
void Select()
{
if(tmp != 0x00){
switch(tmp & 0xf0){
case 0xa0:
ChooseHC138(YC4);
P0_uart = (P0_uart | 0x0f) & (~(tmp) | 0xf0);//必须打括号!!!!不然会出bug,tmp取反是因为指令1是亮led,但是代码led亮是0,所以取反
P0 = P0_uart;
ChooseHC138(YC0);
tmp = 0x00;
break;
case 0xb0:
SendByte((shi/10) << 4 | (shi%10));
SendByte((fen/10) << 4 | (fen%10));
SendByte((miao/10)<< 4 | (miao%10));
tmp = 0x00;
break;
case 0xc0:
SendString("welcome to tx system\r\n");
tmp = 0x00;
break;
}
}
}
void Uart_server() interrupt 4
{
if(RI){
tmp = SBUF;
RI = 0;
}
if(TI){
TI = 0;
}
}
InitSystem.h
#ifndef _InitSysyem_H
#define _InitSysyem_H
void InitSystem();
#endif
InitSystem.c
#include "reg52.h"
#include "InitSystem.h"
#include "ChooseHC138.h"
void InitSystem()
{
ChooseHC138(YC5);
P0 = 0x00;
ChooseHC138(YC4);
P0 = 0xff;
ChooseHC138(YC0);
}
Timer.h
#ifndef _Timer_H
#define _Timer_H
void InitTimer0();
void DisPlay_Time();
extern code unsigned char array[];
extern unsigned char miao;
extern unsigned char fen;
extern unsigned char shi;
#endif
Timer.c
#include "reg52.h"
#include "Timer.h"
#include "SMGchek.h"
#include "LEDrun.h"
#include "InitSystem.h"
#include "ChooseHC138.h"
code unsigned char array[17] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,
0xa1,0x86,0x8e,0xbf};
unsigned char Timerchar[8] = {0};
unsigned char haomiao = 0;
unsigned char miao = 0;
unsigned char fen = 0;
unsigned char shi = 0;
void InitTimer0()
{
TMOD &= 0xf0;
TMOD |= 0x01;
TH0 = (65536 - 50000)/256;//50ms
TL0 = (65536 - 50000)%256;
TR0 = 1;
ET0 = 1;
EA = 1;
}
void DisPlay_Time()
{
SMG_Display_Bit(0,array[shi/10]);
Delay(1000);
SMG_Display_Bit(1,array[shi%10]);
Delay(1000);
SMG_Display_Bit(2,0xbf);
Delay(1000);
SMG_Display_Bit(3,array[fen/10]);
Delay(1000);
SMG_Display_Bit(4,array[fen%10]);
Delay(1000);
SMG_Display_Bit(5,0xbf);
Delay(1000);
SMG_Display_Bit(6,array[miao/10]);
Delay(1000);
SMG_Display_Bit(7,array[miao%10]);
Delay(1000);
ChooseHC138(YC6);
P0 = 0xff;
ChooseHC138(YC7);
P0 = 0xff;
}
void Timer0_server() interrupt 1
{
TH0 = (65536 - 50000)/256;
TL0 = (65536 - 50000)%256;
haomiao++;
if(haomiao == 20){
miao++;
haomiao = 0;
}
if(miao == 60){
fen++;
miao = 0;
}
if(fen == 60){
shi++;
fen = 0;
}
if(shi == 24){
shi = 0;
}
}
KEY.h
#ifndef _KEY_H
#define _KEY_H
extern unsigned char stat_led;
void Delay_Time(unsigned char t);
void KEY();
#endif
KEY.c
#include "reg52.h"
#include "KEY.h"
#include "LEDrun.h"
#include "Timer.h"
#include "ChooseHC138.h"
sbit S5 = P3^2;
sbit S4 = P3^3;
unsigned char stat_led = 0xff;//初始化led是全灭
void Delay_Time(unsigned char t)
{
while(t--){
DisPlay_Time();
}
}
void KEY()
{
if(!S5){
Delay_Time(50);
if(!S5){
ChooseHC138(YC4);
stat_led = (stat_led | 0x40) & (~stat_led | 0xbf);
P0 = stat_led;
ChooseHC138(YC0);
while(!S5){
DisPlay_Time();
}
}
}
if(!S4){
Delay_Time(50);
if(!S4){
ChooseHC138(YC4);
stat_led = (stat_led | 0x80) & (~stat_led | 0x7f);
P0 = stat_led; //执行现场灯光控制
ChooseHC138(YC0);
while(!S4){
DisPlay_Time();
}
}
}
}
ChooseHC138.h
#ifndef _ChooseHC138_H
#define _ChooseHC138_H
#define YC0 0
#define YC4 4
#define YC5 5
#define YC6 6
#define YC7 7
void ChooseHC138(unsigned char n);
#endif
ChooseHC138.c
#include "reg52.h"
#include "ChooseHC138.h"
void ChooseHC138(unsigned char n)
{
switch(n){
case YC4:
P2 = (P2 & 0X1F) | 0X80;
break;
case YC5:
P2 = (P2 & 0X1F) | 0XA0;
break;
case YC6:
P2 = (P2 & 0X1F) | 0XC0;
break;
case YC7:
P2 = (P2 & 0X1F) | 0XE0;
break;
case YC0:
P2 = (P2 & 0X1F) | 0X00;//锁存数据,退出前一锁存器,防止改变数据。
break;
}
}
三、代码编写过程中遇到的BUG
1. 上位机发送指令点灯,led未亮
解决方法: P0_uart = (P0_uart | 0x0f) & (~(tmp) | 0xf0);
(与,或操作必须打括号,提高优先级,不然会出bug)
2. 初始化led和蜂鸣器后,led任全亮
解决方法:先初始化蜂鸣器在初始化led,如果先初始化led后初始化蜂鸣器,led会全亮
3.数码管显示上电时间时,led会和数码管一起闪烁
解决方法:由于数码管显示和led亮灭都是使用的P0口,而锁存器转换是需要时间的,所以,定义一个中间变量,先操作中间变量再赋值给P0口(KEY.c和Uart.c中有使用),每次转换完锁存器后都要P2口高三位置0,锁存。