|
#include <reg52.h>
#include<intrins.h>
#include <stdio.h>
#include <absacc.h>
#define uchar unsigned char
#define uint unsigned short int
#define aa_time 200 //发送显示命令的时间间隔
#define clk_z 0x00 //i2c时序线
#define clk_o 0x01
#define pass_wd 0x0000 //设置密码
#define goto_company_timeago 2880 //距离去单位时间(min)
#define w_check_timeago 10080 //距离周检时间(min)
#define time0_time 976
#define time_a PBYTE[0x0a]
#define time_b PBYTE[0x0b]
#define time_c PBYTE[0x0c]
uchar save_w_check1 = 0;
uchar save_w_check0 = 0;
uchar save_a6_flag = 0;
uchar save_a2_flag = 0;
sfr T2MOD = 0xC9;
sfr SCONF = 0xBF;
sbit bell_ctrl = P0^7;
sbit JL26 = P2^6; //74LS373锁存器LE端
sbit A_ctrl = P0^5; //4052模拟开关
sbit B_ctrl = P0^4;
sbit sda = P2^4;
sbit scl = P2^5;
sbit t2ex = P1^1; //计程脉冲信号
sbit kcp = P1^6; //车灯
sbit ZT_key = P1^4;
sbit JLIO = P2^1;
sbit JLCLK = P2^3;
sbit JLPLS = P0^3;
sbit JLPOW = P0^6;
sbit P_4053 = P0^0;
uchar idata cReceive_data2[5]={0,0,0,0,0};
uchar idata show_data[17]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; //KEY值显示累计信息buf--->直通显示
uchar cNumber = 0;
uchar year,month,date;
uchar hour,minute,second;
uchar hour_mao,s_pfuf = 0,s_pf,s_uf;
uchar ZT_allkey_nu = 0;
uchar zhuangtai = 0;
uint idata car_nu = 0; //24C64总车次 ,最大为400
uint idata car_nu_node = 0; //24C64循环存储的车次坐标
uint idata aa = 0;
bit cFlag = 0;
bit mflag = 1;
bit pie = 0;
bit uie = 0;
bit time_flag2 = 1;
bit per_time = 0;
bit one_show_flag = 0;
bit ZT_func = 0;
uchar code table_duan[] = {
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x00,0x40,0x3f|0x80,0x06|0x80,
0x5b|0x80,0x4f|0x80,0x66|0x80,0x6d|0x80,
0x7d|0x80,0x07|0x80,0x7f|0x80,0x6f|0x80,
0x00|0x80,0x40|0x80};
void a6_handler();
void a6_key_function();
void a6_show_function();
void a6_ZT_function();
void send_A6();
void init_device();
void init_device_uart1();
void key_null();
void beep_r();
void adj_clock();
void Ls373_4052_1();
void a6_on_show();
void Send_char(unsigned char cCharacter);
void delay(uint z);
void get_time(void);
//24c64函数:
void delay1(void) { ; ;}
void main()
{
delay(100);
init_device(); //初始化串口
init_device_uart1();
Ls373_4052_1();
EA = 0;
delay(300);
zhuangtai = 0 ;
EA = 1;
delay(500); //500ms
while(1)
{
if((per_time) && ((s_pf) == 1)) //用一位来设冒号位
{
hour_mao = (hour & 0x0f) + 12;
}else if((!per_time) && ((s_pf) == 1))
{
hour_mao = (hour & 0x0f);
}
a6_handler();
a6_key_function();
if(ZT_func)
{
a6_ZT_function();
}else
{
a6_show_function();
a6_on_show();
}
if(aa>=aa_time)
send_A6();
}
}
void a6_handler()
{
zhuangtai &= 0xFB;
}
void a6_key_function()
{
if(ZT_key == 0)
{ delay(5);
if(ZT_key == 0)
{delay(5);
beep_r();
aa = aa_time;
ZT_allkey_nu++;
one_show_flag = 1;
ZT_func = 1;
}
}
}
void a6_show_function()
{
show_data[0] = table_duan[second&0x0F];
show_data[1] = table_duan[second>>4];
show_data[2] = table_duan[year&0x0F];;
show_data[3] = table_duan[year>>4];;
show_data[4] = table_duan[date&0x0F];
show_data[5] = table_duan[date>>4];
show_data[6] = table_duan[month&0x0F];
show_data[7] = table_duan[month>>4];
show_data[8] = table_duan[minute&0x0F];
show_data[9] = table_duan[minute>>4];
show_data[10] = table_duan[hour_mao];
show_data[11] = table_duan[hour>>4];
}
void a6_ZT_function()
{
if(one_show_flag)
{
if(ZT_allkey_nu == 1) //暂停键 调时钟、补打印、清当班、返回a6
{
show_data[0] = 0; //ADJ
show_data[1] = 0;
show_data[2] = 0;
show_data[3] = 0;
show_data[4] = 0;
show_data[5] = 0;
show_data[6] = 0;
show_data[7] = 0;
show_data[8] = 0;
show_data[9] = 0;
show_data[10] = 0;
show_data[11] = 0;
show_data[12] = 0;
show_data[13] = 0;
show_data[14] = 0x77;
show_data[15] = 0x5E;
show_data[16] = 0x0E;
}else if(ZT_allkey_nu == 2) //PRN
{
show_data[0] = 0;
show_data[1] = 0;
show_data[2] = 0;
show_data[3] = 0;
show_data[4] = 0;
show_data[5] = 0;
show_data[6] = 0;
show_data[7] = 0;
show_data[8] = 0;
show_data[9] = 0;
show_data[10] = 0;
show_data[11] = 0;
show_data[12] = 0;
show_data[13] = 0;
show_data[14] = 0x73;
show_data[15] = 0x50;
show_data[16] = 0x54;
}else if(ZT_allkey_nu == 3) //CLR
{
show_data[0] = 0;
show_data[1] = 0;
show_data[2] = 0;
show_data[3] = 0;
show_data[4] = 0;
show_data[5] = 0;
show_data[6] = 0;
show_data[7] = 0;
show_data[8] = 0;
show_data[9] = 0;
show_data[10] = 0;
show_data[11] = 0;
show_data[12] = 0;
show_data[13] = 0;
show_data[14] = 0x39;
show_data[15] = 0x38;
show_data[16] = 0x50;
}else if(ZT_allkey_nu>3)
{
key_null();
}
one_show_flag = 0;
}
}
void send_A6() //直通显示
{
TB8 = 1;
Send_char(0xAA);
TB8 = 0;
Send_char(0x20);
TB8 = 0;
Send_char(0xA6);
TB8 = 0;
Send_char(show_data[12]);
TB8 = 0;
Send_char(show_data[13]);
TB8 = 0;
Send_char(show_data[14]);
TB8 = 0;
Send_char(show_data[15]);
TB8 = 0;
Send_char(show_data[16]);
TB8 = 0;
Send_char(show_data[0]);
TB8 = 0;
Send_char(show_data[1]);
TB8 = 0;
Send_char(show_data[2]);
TB8 = 0;
Send_char(show_data[3]);
TB8 = 0;
Send_char(show_data[4]);
TB8 = 0;
Send_char(show_data[5]);
TB8 = 0;
Send_char(show_data[6]);
TB8 = 0;
Send_char(show_data[7]);
TB8 = 0;
Send_char(0x00);
TB8 = 0;
Send_char(0x00);
TB8 = 0;
Send_char(0x00);
TB8 = 0;
Send_char(0x00);
TB8 = 0;
Send_char(0x00);
TB8 = 0;
Send_char(0x00);
TB8 = 0;
Send_char(show_data[8]);
TB8 = 0;
Send_char(show_data[9]);
TB8 = 0;
Send_char(show_data[10]);
TB8 = 0;
Send_char(show_data[11]);
TB8 = 0;
Send_char(0x00);
TB8 = 0;
Send_char(0x00);
TB8 = 0;
Send_char(0x00);
TB8 = 0;
Send_char(0x00);
TB8 = 0;
Send_char(0x00);
TB8 = 0;
Send_char(zhuangtai);
TB8 = 0;
Send_char(0x00);
TB8 = 0;
Send_char((0x86)^(zhuangtai)^(show_data[0])^(show_data[1])^(show_data[2])^(show_data[3])^(show_data[4])^(show_data[5])^(show_data[6])\
^(show_data[7])^(show_data[8])^(show_data[9])^(show_data[10])^(show_data[11])^(show_data[12])^(show_data[13])^(show_data[14])\
^(show_data[15])^(show_data[16]));
TB8 = 1;
Send_char(0xCC);
delay(100); //100ms
}
void init_device()
{
SCONF &=0XFD;
/*****************************************
设置初值:分、时、日、月、年
******************************************/
delay(5);
time_a = 0x30;
delay(5);
time_b = 0x82;
// PBYTE[0x01] = 0xC0;
PBYTE[0x02] = 0x59;
// PBYTE[0x03] = 0xC0;
PBYTE[0x04] = 0x11;
// PBYTE[0x05] = 0xC0;
PBYTE[0x07] = 0x11;
PBYTE[0x08] = 0x09;
PBYTE[0x09] = 0x10;
PBYTE[0x32] = 0x21;
time_a = 0x20;
delay(5);
time_b = 0x12; //DM = 0 BCD格式 时钟范围00-59
delay(5);
time_a = 0x30;
delay(5);
time_a |= 0x0F;
delay(5);
time_b |= 0x40;
delay(5);
time_a &= 0xEF;
delay(100);
TMOD = 0x61; //TMOD:定时器0,方式1
TH0 = (65536 - time0_time) / 256;
TL0 = (65536 - time0_time) % 256;
ET0 = 1;
TR0 = 1; //启动定时器0运行
IT0 = 0;//INT0 触发方式: 低电平
EX0 = 1;
PS = 1; //串口设置为高优先级中断源
ES = 1; //开串口中断
EA = 1; //开总中断
}
void init_device_uart1()
{
SM0 = 1; //SCON:SM0 = 1;SM1 = 0;工作方式2, 9-bit UART,允许串行接收位(REN=1)
SM1 = 0;
REN = 1;
}
void key_null()
{
ZT_func = 0;
ZT_allkey_nu = 0;
}
void beep_r()
{
bell_ctrl = 1; //开启蜂鸣器
JL26 = 1;
JL26 = 0;
delay(40); //40ms
bell_ctrl = 0; //关闭蜂鸣器
JL26 = 1;
JL26 = 0;
}
void Ls373_4052_1()
{
bell_ctrl = 0; //关闭蜂鸣器
JLPLS = 1;
P_4053 = 0;
A_ctrl = 0;
B_ctrl = 0;
JL26 = 1;
JL26 = 0;
}
void a6_on_show()
{
show_data[12] = 0x00;
show_data[13] = 0x00;
show_data[14] = table_duan[0+12];
show_data[15] = table_duan[0];
show_data[16] = table_duan[0];
}
void Send_char(unsigned char cCharacter)
{
SBUF = cCharacter; //发送数据给“串口调试助手”接收窗口
while( TI == 0 ); //等待发送完,TI置1
TI = 0; //清零 TI为发送中断标志
}
void delay(uint z)
{
uint x,y;
for( x = z;x > 0;x--)
for(y = 119;y > 0;y--);
}
void get_time(void)
{
//if((time_a&0x80)==0)
//{
year = PBYTE[9];
month = PBYTE[8];
date = PBYTE[7];
hour = PBYTE[4];
minute = PBYTE[2];
second = PBYTE[0];
//}
}
void UART_Routine() interrupt 4 using 2
{
uchar ucRecBuf;
if(RI == 1) //RI为接受中断标志,可能是发送产生的中断
{
RI = 0; //接受中断标志软件清零
ES = 0; //关串口中断
ucRecBuf = SBUF;
if (RB8 == 1)
{
if (ucRecBuf == 0xaa)
{
cNumber = 0;
cReceive_data2[cNumber++] = ucRecBuf;
}
else if (ucRecBuf == 0xcc)
{
cReceive_data2[cNumber++] = ucRecBuf;
if (cReceive_data2[0] == 0xaa) //数据校验位
{
TB8 = 1;
Send_char(0xBB);
TB8 = 0;
Send_char(cReceive_data2[2]);
TB8 = 1;
Send_char(0xCC);
cFlag = 1;
}
else if(cReceive_data2[0] == 0xbb)
{
cFlag = 1;
}
else{
TB8 = 1;
Send_char(0xBB);
TB8 = 0;
Send_char(0xFF);
TB8 = 1;
Send_char(0xCC);//返回出错
}
}else if(ucRecBuf == 0xbb)
{
cNumber = 0;
cReceive_data2[cNumber++] = ucRecBuf;
}
}else //RB8 == 0
{
if (cNumber < sizeof(cReceive_data2))
cReceive_data2[cNumber++] = ucRecBuf; //数据取出赋值
}
ES = 1;
}
}
void timer0() interrupt 1 using 1
{
TH0 = (65536 - time0_time) / 256;//FC
TL0 = (65536 - time0_time) % 256;//18
aa++;
}
void timer1() interrupt 0 using 3
{
s_pfuf = ((time_c & 0x50) >> 4); //清ds12c887周期中断标识PF,清ds12c887更新中断标识UF
s_pf = ((s_pfuf &0x04) >> 2);
s_uf = (s_pfuf & 0x01);
pie = ((time_b & 0x40) >> 6); //周期性中断使能
uie = ((time_b & 0x10) >> 4); //更新中断使能
if((pie)&&(s_pf))
{
per_time ^= 1;
get_time(); //一秒读一次DS12C887时钟芯片
}
}
用数码管显示12C887时钟,仿真器仿真一切正常,烧到SM5964里,一按按键就死机。
取时间和冒号显示放在12C887的周期中断(500ms)里的。
12C887作为单片机的外扩RAM :
单片机 --- 12C887
P00-P07 --- D0-D7
WR --- RW
RD --- DS
ALEX --- AS
--- CS接地
|
|