📄 nixie.c
字号:
/********************************************************
*功能:Nixie Clock电子管时钟程序
*作者:章 健
*版本:Ver.01
*日期:2007.06.17
********************************************************/
#include <reg2051.h>
#include <intrins.h>
/**************************************
*宏定义
**************************************/
#define uchar unsigned char
#define uint unsigned int
#define CLOCK_1302 (0)
#define RAM_1302 (1)
#define NOP() _nop_();_nop_();_nop_();
/**************************************
*I/O口定义
**************************************/
sbit SCK_595 = P3^2;
sbit RCLK_595 = P3^0;
sbit SDAT_595 = P3^1;
sbit SCLK_1302 = P1^5;
sbit IO_1302 = P1^4;
sbit RST_1302 = P1^3;
sbit key1 = P1^0;
sbit key2 = P1^1;
sbit key3 = P1^2;
/**************************************
*变量定义
**************************************/
uchar hour,min,sec;
bit key_down = 0;
bit sec_inc = 0;
bit min_inc = 0;
bit hour_inc = 0;
bit disp_req = 0;
/**************************************
*电子管段码定义
**************************************/
uint code SEG[10]={0x0401,0x0402,0x0404,0x0408,0x0410,
0x0420,0x0440,0x0480,0x0500,0x0600};
/**************************************
*函数声明
**************************************/
void init_io();
void delay_ms(uchar j);
void init_timer();
void send_data(uchar count,uint dat);
void disp_time();
void write_byte(uchar byt);
uchar read_byte();
void write_data(uchar add,uchar dat,bit type);
uchar read_data(uchar add,bit type);
void get_key();
/**************************************
*I/O口初始化
**************************************/
void init_io()
{
SCK_595 = 0;
RCLK_595 = 0;
P1 |= 0x07;//按键的三位置高(输入)
}
/**************************************
*毫秒级延时
**************************************/
void delay_ms(uchar j)
{
uint i;
for(;j>0;j--)
{
for(i=0;i<121;i++)
{;}
}
}
/**************************************
*定时器0初始化,定时时间50ms
**************************************/
void init_timer()
{
TMOD = 0x01;
TH0 = 0x3C;
TL0 = 0xB0;
IE = 0x82;
TR0 = 1;
}
/**************************************
*向74HC595发送显示数据
**************************************/
void send_data(uchar count,uint dat)
{
for(;count>0;count--)
{
SDAT_595 = dat&0x0001;
NOP();
SCK_595 = 1;
NOP();
SCK_595 = 0;
NOP();
dat>>=1;
}
}
/**************************************
*刷新电子管上显示的时间
**************************************/
void disp_time()
{
send_data(3,SEG[((hour&0x30)>>4)]);
send_data(11,SEG[hour&0x0f]);
send_data(6,SEG[(min&0x70)>>4]);
send_data(11,SEG[min&0x0f]);
send_data(6,SEG[(sec&0x70)>>4]);
send_data(11,SEG[sec&0x0f]);
RCLK_595 = 1;
NOP();
RCLK_595 = 0;
NOP();
}
/**************************************
*向DS1302写一个字节
**************************************/
void write_byte(uchar byt)
{
uchar i;
for(i = 0;i < 8;i ++)
{
IO_1302 = byt&0x01;
NOP();
SCLK_1302 = 1;
NOP();
SCLK_1302 = 0;
NOP();
byt>>=1;
}
}
/**************************************
*从DS1302读一个字节
**************************************/
uchar read_byte()
{
uchar i;
uchar dat=0;
for(i = 0;i < 8;i ++)
{
dat>>=1;
if(IO_1302==1)
{dat|= 0x80;}
SCLK_1302 = 1;
NOP();
SCLK_1302 = 0;
NOP();
}
return(dat);
}
/**************************************
*向DS1302的指定地址写一个字节
**************************************/
void write_data(uchar add,uchar dat,bit type)
{
uchar temp;
RST_1302 = 0;
SCLK_1302 = 0;
RST_1302 = 1;
if(type == RAM_1302)
{
temp = 0xC0;
}
else
{
temp = 0x80;
}
temp|=((add&0x1f)<<1);
SCLK_1302 = 0;
NOP();
RST_1302 = 1;
NOP();
write_byte(temp);
write_byte(dat);
RST_1302 = 0;
NOP();
}
/**************************************
*从DS1302的指定地址读一个字节
**************************************/
uchar read_data(uchar add,bit type)
{
uchar temp;
RST_1302 = 0;
NOP();
SCLK_1302 = 0;
NOP();
RST_1302 = 1;
NOP();
if(type == RAM_1302)
{
temp = 0xC1;
}
else
{
temp = 0x81;
}
temp|=((add&0x1f)<<1);
SCLK_1302 = 0;
NOP();
RST_1302 = 1;
NOP();
write_byte(temp);
temp = read_byte();
RST_1302 = 0;
NOP();
return(temp);
}
/**************************************
*获得按键状态
**************************************/
void get_key()
{
if((P1&0x07) != 0x07)
{
if(key_down == 1)
{
return;
}
else
{
delay_ms(10);
if((P1&0x07) != 0x07)
{
if(key1 == 0)
{
sec_inc = 1;
}
else if(key2 == 0)
{
min_inc = 1;
}
else if(key3 == 0)
{
hour_inc = 1;
}
}
}
}
else
{
key_down = 0;
}
}
/**************************************
*定时器中断
**************************************/
void timer0_task() interrupt 1
{
TH0 = 0x3C;
TL0 = 0xB0;
get_key();
}
/**************************************
*主函数
**************************************/
void main()
{
init_io();
init_timer();
if(read_data(0x05,RAM_1302)!=0xA5)//是否断电?
{
write_data(0x07,0x00,CLOCK_1302);//开写保护
write_data(0x05,0xA5,RAM_1302); //写断电标志
write_data(0x02,0x12,CLOCK_1302);//初始化时间
write_data(0x01,0x00,CLOCK_1302);
write_data(0x00,0x00,CLOCK_1302);
}
write_data(0x07,0x80,CLOCK_1302);//写保护
while(1)
{
if(sec_inc == 1)
{
sec = read_data(0x00,CLOCK_1302);
sec++;
if((sec&0x0f)>9)
{
sec &= 0xf0;
sec += 0x10;
}
if(sec > 59)
{
sec = 0;
}
write_data(0x07,0x00,CLOCK_1302);
write_data(0x00,sec,CLOCK_1302);
write_data(0x07,0x80,CLOCK_1302);
sec_inc = 0;
disp_req = 1;
}
if(min_inc == 1)
{
min = read_data(0x01,CLOCK_1302);
min++;
if((min&0x0f)>9)
{
min &= 0xf0;
min += 0x10;
}
if(min > 59)
{
min = 0;
}
write_data(0x07,0x00,CLOCK_1302);
write_data(0x01,min,CLOCK_1302);
write_data(0x07,0x80,CLOCK_1302);
min_inc = 0;
disp_req = 1;
}
if(hour_inc == 1)
{
hour = read_data(0x02,CLOCK_1302);
hour++;
if((hour&0x0f)>9)
{
hour &= 0xf0;
hour += 0x10;
}
if(hour > 23)
{
hour = 0;
}
write_data(0x07,0x00,CLOCK_1302);
write_data(0x02,hour,CLOCK_1302);
write_data(0x07,0x80,CLOCK_1302);
hour_inc = 0;
disp_req = 1;
}
if((sec != read_data(0x00,CLOCK_1302))|(disp_req == 1))
{
sec = read_data(0x00,CLOCK_1302);
min = read_data(0x01,CLOCK_1302);
hour = read_data(0x02,CLOCK_1302);
disp_time();
disp_req = 0;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -