1.代码
HEADFILE.h
#ifndef __HEADFILE_H_
#define __HEADFILE_H_
#include <STC15F2K60S2.H>
#define Y4 P2 = (P2 & 0x1f) | 0x80
#define Y5 P2 = (P2 & 0x1f) | 0xa0
#define Y6 P2 = (P2 & 0x1f) | 0xc0
#define Y7 P2 = (P2 & 0x1f) | 0xe0
#define Y0 P2 = (P2 & 0x1f) | 0x00
#include"LED.h"
#include"KEY.h"
#include"SEG.h"
#include"TIMER.h"
#include"UART.h"
#include"DELAY.h"
#endif
main.c
#include"HEADFILE.h"
void main()
{
System_Init();
LED_Running();
SEG_Running();
Timer0_Init();
UART_Init();
while(1)
{
Timer0_Service();
SEG_CLOCK();
Working();
Key_Scan();
}
}
LED.c
#include"HEADFILE.h"
void System_Init()
{
Y5;
P0 = 0x00;
Y4;
P0 = 0xff;
Y0;
}
void LED_Running()
{
unsigned char i=0;
Y4;
for(i=0; i<8; i++)
{
P0 = 0xfe << i;
Delay(100);
}
for(i=0; i<8; i++)
{
P0 = ~(0xfe << i);
Delay(100);
}
Y0;
}
LED.h
#ifndef __LED_H_
#define __LED_H_
void LED_Running();
void System_Init();
#endif
SEG.c
#include"HEADFILE.h"
unsigned char code SEG_duanma[] = {0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90,
0xbf,0x00,0xff};
void SEG_Running()
{
unsigned char i;
for(i=0; i<=8; i++)
{
Y6;
P0 = ~(0xff<<i);
Y7;
P0 = 0x00;
Delay(100);
Y0;
}
for(i=1; i<=8; i++)
{
Y6;
P0 = 0xff<<i;
Y7;
P0 = 0x00;
Delay(100);
Y0;
}
}
void SEG_Display_Bit(unsigned char position,number)
{
Y6;
P0 = 0x01 << (position - 1);
Y7;
P0 = SEG_duanma[number];
Delay(1);
}
SEG.h
#ifndef __SEG_H_
#define __SEG_H_
void SEG_Running();
void SEG_Display_Bit(unsigned char position,number);
#endif
KEY.c
#include"HEADFILE.h"
sbit L7 = P0^6;
sbit L8 = P0^7;
sbit S5 = P3^2;
sbit S4 = P3^3;
unsigned char LED_state = 0xff;
void Key_Scan()
{
if(S4 == 0)
{
Delay(10);
while(S4 == 0)
{
Timer0_Service();
SEG_CLOCK();
}
LED_state = (LED_state | 0x80) & (~LED_state | 0x7f);
Y4;
P0 = LED_state;
Y0;
}
if(S5 == 0)
{
Delay(10);
while(S5 == 0)
{
Timer0_Service();
SEG_CLOCK();
}
LED_state = (LED_state | 0x40) & (~LED_state | 0xbf);
Y4;
P0 = LED_state;
Y0;
}
}
KEY.h
#ifndef __KEY_H_
#define __KEY_H_
void Key_Init();
void Key_Scan();
#endif
TIMER.c
#include"HEADFILE.h"
unsigned char h = 0,m = 0,s = 0,count = 0;
unsigned char state_flag = 0;
void Timer0_Init()
{
TMOD = (TMOD & 0xf0) | 0x01;
TH0 = (65535 - 50000) / 256;
TL0 = (65535 - 50000) % 256;
TR0 = 1;
ET0 = 1;
EA = 1;
}
void Timer0_Routine() interrupt 1
{
TH0 = (65535 - 50000) / 256;
TL0 = (65535 - 50000) % 256;
state_flag = 1;
}
void Timer0_Service()
{
if(state_flag == 1)
{
state_flag = 0;
count++;
if(count == 20)
{
count = 0;
s++;
if(s == 60)
{
s = 0;
m++;
if(m == 60)
{
m = 0;
h++;
if(h == 60)
{
h = 0;
}
}
}
}
}
}
void SEG_CLOCK()
{
SEG_Display_Bit(1,h/10);
SEG_Display_Bit(2,h%10);
SEG_Display_Bit(3,10);
SEG_Display_Bit(4,m/10);
SEG_Display_Bit(5,m%10);
SEG_Display_Bit(6,10);
SEG_Display_Bit(7,s/10);
SEG_Display_Bit(8,s%10);
}
TIMER.h
#ifndef __TIMER_H_
#define __TIMER_H_
void Timer0_Init();
void Timer0_Routine();
void Timer0_Service();
void SEG_CLOCK();
#endif
UART.c
#include"HEADFILE.h"
unsigned char urdata = 0x00;
extern unsigned char h, m, s;
extern unsigned char LED_state;
void UART_Init()
{
TMOD = (TMOD & 0x0f) | 0x20;
TH1 = 0xfd;
TL1 = 0xfd;
TR1 = 1;
SCON = 0x50;
AUXR = 0x00;
ES = 1;
EA = 1;
}
void UART_SendByte(unsigned char dat)
{
SBUF = dat;
while(TI == 0);
TI = 0;
}
void UART_Receive() interrupt 4 //½ÓÊÜÖжÏ
{
if(RI == 1)
{
RI = 0;
urdata = SBUF;
}
}
void Working()
{
if(urdata != 0x00)
{
switch(urdata & 0xf0)
{
case 0xa0:Y4; P0 = ~(urdata & 0x0f); Y0; urdata = 0x00;
LED_state = P0;
break;
case 0xb0:UART_SendByte(h / 1 * 16 + h % 10);
UART_SendByte(m / 10 * 16 + m % 10);
UART_SendByte(s / 10 * 16 + s % 10); urdata = 0x00;
break;
}
}
}
UART.h
#ifndef __UART_H_
#define __UART_H_
void UART_Init();
void UART_Receive();
void UART_SendByte(unsigned char dat);
void Working();
#endif
DELAY.c
#include"HEADFILE.h"
void Delay(unsigned int n)
{
while(n--)
{
unsigned char i, j;
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
}
DELAY.h
#ifndef __DELAY_H_
#define __DELAY_H_
void Delay(unsigned int n);
#endif
2.总结
数码管流水灯。数码管可以多位一起选,就像LED灯一样。
按键等待。按键在等待抬起的时候,要将显示时间的模块也放在循环中(在我的代码中,定时器中断的程序只有一个标志位,计数时间到了之后的操作放在另外一个函数,所以这个函数也放在while循环中)
按键一位取反。用与或赋值法。
LED和数码管P0口端口复用。在判断串口发送过来的数据的程序中,将P0口的数据记录下来,在判断按键是否按下的程序中,对需要的某一位按位取反。