📄 ledping.c
字号:
/*****************************************************
双色8字LED点阵屏+DS1302电子钟 C 程序
******************************************************
红色绿色屏须串联595连级输出数据,138行驱动。
根据小邓屏修改
修改:王一凡 时间:2008年9月16日
绿屏和红屏需联级叠加
********************************************************/
#include <AT89x55.H>
#define uchar unsigned char
#define uint unsigned int
uchar code hanzi3[13][32];
uchar code hanzi4[13][32];
uchar code hanzi[30][32];
uchar code hanzi2[];
uchar code timer[13][16];
uchar code sw[];
void xs_out(); /*输出显示*/
void out_rxd(unsigned char *d); /*串口发送一行*/
sbit R =P2^0; //数据
sbit G =P2^1;
sbit CLK =P2^4; //时钟 //使用串口发送的时候,P3.0为data,P3.1为s_clk
sbit STB =P2^2; //锁存
sbit EN =P2^3; //OE为高选通
uchar code sw[16]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};/*16行段码*/
void jingz();//静止显示1
void jingz2();//静止显示2
void jingz3();//静止显示3
void buxianshi();
/******************************************/
sbit resget=P1^3; //时钟复位
sbit key_moda=P1^0; //模式转换
sbit key_up=P1^1; //时钟加
sbit key_Down=P1^2; //时钟减
sbit T_CLK =P0^0; //DS1302引脚连接
sbit T_IO =P0^1;
sbit T_RST =P0^2;
sbit ACC0=ACC^0; //1bit数据存储位
sbit ACC7=ACC^7;
uchar inittime[7]={0x00,0x10,0x22,0x13,0x01,0x05,0x06}; //初始化后设置
uchar yid,i,e,id,miao,fen,shi,nian,yue,ri,xinqi,cnt,kk,mn; //时间变量
uint zimuo,ss;
uchar BUFF[10]; // 缓存
void RTInputByte(uchar); /* 输入 1Byte */
uchar RTOutputByte(void); /* 输出 1Byte */
void W1302(uchar, uchar); // 向DS1302写入一个字节
uchar R1302(uchar); // 从DS1302读出一个字节
void Set1302(uchar *); // 写DS1302时间
void du1302(); // 读时间
void DelayMs(void); // 延时
void Set(uchar,uchar ); // 变量调整
void rxd_data(void);
void in_data(void);
/**************************************************/
void init_timer()
{
TMOD=0x01;
IP=0x02;
TH0=-(10000/256);
TL0=-(10000%256);
ET0=1;
TR0=1;
EA=1;
}
/*****************************************************/
void time0(void) interrupt 1
{
TH0=-(10000/256);
TL0=-(10000%256);
cnt++;
if(cnt>=100)
{kk++;cnt=0;}
if(kk>=13){mn++;kk=0;}
if(mn>7){mn=0;}
}
/********************************************************/
/*主函数*/
void main(void)
{
uchar i,d=3; //移动速度调整
yid=0;
zimuo=0;
init_timer();
while(1)
{
while(yid<16) //数据移位
{
for(i=0;i<d;i++) //移动速度
{
if(resget==0)
{DelayMs();
if(resget==0)
Set1302(inittime); //初始化
W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/
W1302(0x90,0xa5); //打开充电二级管 一个二级管串联一个2K电阻
}
du1302(); //读取 秒 分 时 日 月 星期 年
if (key_moda==0) // 设置和选择项目键
{DelayMs();
if(key_moda==0)
{
id++;if(id==8) {id=0;yid=0;zimuo=0;}
while(key_moda==0){ xs_out();}
}
}
if (key_up==0) //增加
{
DelayMs();
if(key_up==0)
{
while(key_up==0)
{xs_out();}
ss=0;
Set(id,0);
}
}
if (key_Down==0) //减少
{
DelayMs();
if(key_Down==0)
{
while(key_Down==0)
{xs_out();}
ss=0;
Set(id,1);
}
}
xs_out();
}
yid++; //移动一步
}
yid=0;
zimuo=zimuo+32; //后移一个字,
if(zimuo>=768) //总数减3个字,
zimuo=0;
}
}
/************************************************/
void xs_out() //串行输出显示
{
for(i=0;i<16;i++)
{
ss++; //ss为闪烁延时计数器
if (ss==1500) //定义SS的大小决定调整时闪烁的快慢,小于750时为亮,大于750时为黑
{ss=0;}
if(id==0) //当ID为零时显示移动的汉字。在时间设置时ID不为零
{ if(zimuo<=96) //显示年。
{in_data(); //调整移动数据
rxd_data();} //串口发送移动数据
else if((zimuo>96)&&(zimuo<=256))
{ out_rxd(&hanzi[18][i*2+1]);
out_rxd(&hanzi[18][i*2]);
out_rxd(&timer[12][i]);
out_rxd(&timer[12][i]);
out_rxd(&hanzi[20][i*2+1]);
out_rxd(&hanzi[20][i*2]);
out_rxd(&timer[12][i]);
out_rxd(&timer[12][i]); }
else if((zimuo>256)&&(zimuo<=352))
{ in_data(); //调整移动数据
rxd_data();}
else if((zimuo>352)&&(zimuo<=512))
{buxianshi();}
else if((zimuo>512)&&(zimuo<=608))
{ in_data(); //调整移动数据
rxd_data();}
else
jingz3() ;
}
else //id不为零时,显示年。只有在时钟设置时ID才不为零。
{
out_rxd(&timer[12][i]); //不显示
if(id==1&&ss>750) //当ID为1和SS大于1000时年不显示。
{
out_rxd(&timer[12][i]); //不显示
out_rxd(&timer[12][i]); //不显示
out_rxd(&timer[12][i]); //不显示
out_rxd(&timer[12][i]); //不显示
}
else
{ out_rxd(&timer[2][i]); //20年
out_rxd(&timer[0][i]);
out_rxd(&timer[nian/16][i]); //年
out_rxd(&timer[nian%16][i]);
}
out_rxd(&timer[12][i]); //不显示
out_rxd(&hanzi[0][i*2+1]); //年字符
out_rxd(&hanzi[0][i*2]);
}
if(zimuo<=96) //显示年。
{buxianshi();} //串口发送移动数据
else if((zimuo>96)&&(zimuo<=256))
jingz() ;
else if((zimuo>256)&&(zimuo<=352))
{buxianshi();}
else if((zimuo>352)&&(zimuo<=512))
jingz2() ;
else if((zimuo>512)&&(zimuo<=608))
{buxianshi();}
else
{ out_rxd(&timer[12][i]);
out_rxd(&hanzi[26][i*2]);
out_rxd(&hanzi[27][i*2+1]);
out_rxd(&timer[12][i]);
out_rxd(&hanzi[28][i*2+1]);
out_rxd(&hanzi[28][i*2]);
out_rxd(&timer[12][i]);
out_rxd(&hanzi[29][i*2]);}
if(mn<=1)
{ out_rxd(&hanzi[2][i*2+1]); //星字符
out_rxd(&hanzi[2][i*2]);
out_rxd(&hanzi[3][i*2+1]); //期字符
out_rxd(&hanzi[3][i*2]);
out_rxd(&timer[12][i]); //不显示
if(id==4&&ss>750) //当ID为3和SS大于1000时星期不显示。
{out_rxd(&timer[12][i]); //不显示
out_rxd(&timer[12][i]);} //不显示
else
{out_rxd(&hanzi[xinqi+10][i*2+1]);//星期值字符
out_rxd(&hanzi[xinqi+10][i*2]);}
out_rxd(&timer[12][i]); } //不显示
else
{out_rxd(&timer[12][i]); //不显示
out_rxd(&timer[12][i]);
out_rxd(&timer[10][i]); //两点显示红色
out_rxd(&timer[12][i]);
out_rxd(&timer[12][i]); //不显示
out_rxd(&timer[12][i]);
out_rxd(&hanzi4[kk][i*2+1]);
out_rxd(&hanzi4[kk][i*2]);}
if(mn>1)
{if(id==5&&ss>750) //当ID为4和SS大于1000时时不显示。
{out_rxd(&timer[12][i]); //不显示
out_rxd(&timer[12][i]);} //不显示
else
{
if(shi/16==0)
out_rxd(&timer[12][i]); //当时十位为零时不显示
else
out_rxd(&timer[shi/16][i]); //从串口输出时十位。
out_rxd(&timer[shi%16][i]); //从串口输出时个位。
}
out_rxd(&timer[12][i]); //从串口输出两点不显示。
if(id==6&&ss>750) //当ID为6和SS大于1000时分不显示。
{out_rxd(&timer[12][i]); //不显示
out_rxd(&timer[12][i]);} //不显示
else
{out_rxd(&timer[fen/16][i]); //输出分值
out_rxd(&timer[fen%16][i]);}
out_rxd(&timer[12][i]); //从串口输出两点。
if(id==7&&ss>750) //当ID为6和SS大于1000时秒不显示。
{out_rxd(&timer[12][i]); //不显示
out_rxd(&timer[12][i]);} //不显示
else
{ out_rxd(&hanzi3[kk][i*2+1]);
out_rxd(&hanzi3[kk][i*2]);}}
else
{buxianshi();}
/*****************************************************************/
EN=0; //发送数据的时候开显示上一行的内容,发送完再关闭,然后锁存,选通行
DelayMs(); //延时一段时间保证共阳极电源确实关断,否则会有拖尾现象发生
STB=0; //锁存为高,595锁存信号
STB=1;
P1=sw[i]; //输出行信号
EN=1;
}}
void buxianshi()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -