📄 ht1621.c
字号:
#include <AT89x52.h>
#include <intrins.h>
#include "93LC66.c"
struct
{unsigned char hour;
unsigned char min;
unsigned char sec;
}time1={12,0,0};
struct
{unsigned int hourclock;
unsigned int minclock;
unsigned int ampmclock;
}time2={7,0,0};
unsigned char Count=0,i=0,ampm=0,sec20=0;
unsigned int counter=300;
unsigned char Light_flag=0,Ledloop=0;
bit _500msflag=0,beep_flag=0;
void inc_hour(void);
void inc_min(void);
void inc_sec(void);
void ProcessKey(void);
void ScanKey(void);
void DisplayChange(void);
void light(void);
void delayms(unsigned int i);
#define BIAS 0x52 //0b1000 0101 0010 1/3duty 4com
#define SYSDIS 0X00 //0b1000 0000 0000 关振系统荡器和LCD偏压发生器
#define LCDOFF 0X04 //0b1000 0000 0100 关LCD偏压
#define LCDON 0X06 //0b1000 0000 0110 打开LCD偏压
#define SYSEN 0X02 //0b1000 0000 0010 打开系统振荡器
#define XTAL 0x28 //0b1000 0010 1000 外部接时钟
#define RC256 0X30 //0b1000 0011 0000 内部时钟
#define TONEON 0X12 //0b1000 0001 0010 打开声音输出
#define TONEOFF 0X10 //0b1000 0001 0000 关闭声音输出
#define WDTDIS 0X0a //0b1000 0000 1010 禁止看门狗*/
#define Switch P2_5
#define Up1 P2_4
#define Up2 P2_3
#define Uphour P2_2
#define Upmin P2_1
#define Enter P2_0
//HT1621控制位(液晶模块接口定义,根据自已的需要更改)
sbit HT1621_DAT=P3^5;
sbit HT1621_CS=P3^7; //lower enable
sbit HT1621_WR=P3^6; //rising edge
//0,1...8,9,A,P
unsigned char code Ht1621code[]=
{0xeb,0x60,0xc7,0xe5,0x6c,0xad,0xaf,0xe0,0xef,0xed,0xee,0xce};
unsigned char code Led[4]={0x01,0x04,0x02,0x08};
void DelayMS1(uint iMs)
{
uint i,j;
for(i=0;i<iMs;i++)
for(j=0;j<65;j++)
delayms(1);
}
//完成写一个命令包括头(100)
void Ht1621WrCmd(uchar ucTmpCmd)
{
uchar data i,ucCmdByte=0x80;
HT1621_CS=0;
_Nop();
_Nop();
for (i=0;i<4;i++)
{
if (ucCmdByte&0x80) HT1621_DAT=1;
else HT1621_DAT=0;
HT1621_WR=0;
_Nop();
_Nop();
HT1621_WR=1;
_Nop();
ucCmdByte<<=1;
}
for (i=0;i<8;i++)
{
if (ucTmpCmd&0x80) HT1621_DAT=1;
else HT1621_DAT=0;
HT1621_WR=0;
_Nop();
_Nop();
HT1621_WR=1;
_Nop();
ucTmpCmd<<=1;
}
HT1621_CS=1;
_Nop();
_Nop();
}
//写命令+地址
void Ht1621WrDataCmd(uchar ucAddr)
{ uchar data i,ucDataCmd=0x05; //101
HT1621_CS=0;
_Nop();
_Nop();
ucDataCmd<<=5;
for (i=0;i<3;i++)
{
if (ucDataCmd&0x80) HT1621_DAT=1;
else HT1621_DAT=0;
HT1621_WR=0;
_Nop();
_Nop();
HT1621_WR=1;
_Nop();
ucDataCmd<<=1;
}
ucAddr<<=2;
for (i=0;i<6;i++)
{
if (ucAddr&0x80) HT1621_DAT=1;
else HT1621_DAT=0;
HT1621_WR=0;
_Nop();
_Nop();
HT1621_WR=1;
_Nop();
ucAddr<<=1;
}
}
//完成写一个字节数据
void Ht1621WrByte(uchar ucTmpData)
{
uchar data i;
for (i=0;i<8;i++)
{
if (ucTmpData&0x80) HT1621_DAT=1;
else HT1621_DAT=0;
HT1621_WR=0;
_Nop();
_Nop();
HT1621_WR=1;
_Nop();
ucTmpData<<=1;
}
HT1621_CS=1;
_Nop();
_Nop();
}
void Ht1621WrByteDot(uchar ucTmpData)
{
uchar data i;
for (i=0;i<4;i++)
{
if (ucTmpData&0x80) HT1621_DAT=1;
else HT1621_DAT=0;
HT1621_WR=0;
_Nop();
_Nop();
HT1621_WR=1;
_Nop();
ucTmpData<<=1;
}
HT1621_CS=1;
_Nop();
_Nop();
}
void Ht1621_Init(void)
{
HT1621_CS=1;
HT1621_WR=0;
HT1621_DAT=1;
Ht1621WrCmd(BIAS);
Ht1621WrCmd(RC256); //使用内部振荡器
Ht1621WrCmd(TONEOFF);
Ht1621WrCmd(LCDOFF);
Ht1621WrCmd(SYSDIS);
Ht1621WrCmd(WDTDIS);
Ht1621WrCmd(SYSEN);
Ht1621WrCmd(LCDON);
}
void ProcessKey(void)
{if(Count==1)
{if(Up1==0)
{DelayMS1(55);
if(Up1==0)
inc_hour();
}
else if(Up2==0)
{DelayMS1(55);
if(Up2==0)
inc_min();
}
}
else if(Count==2)
{if(Up1==0)
{DelayMS1(55);
if(Up1==0)
ampm=!ampm;
}
else if(Up2==0)
{DelayMS1(55);
if(Up2==0)
TR0=0;
inc_sec();
}
}
else if(Count==3)
{if(Uphour==0)
{DelayMS1(55);
if(Uphour==0)
time2.ampmclock=!time2.ampmclock;
}
}
else if(Count==4)
{if(Uphour==0)
{DelayMS1(55);
if(Uphour==0)
{time2.hourclock++;
if(time2.hourclock>12)
time2.hourclock=1;}
}
else if(Upmin==0)
{DelayMS1(55);
if(Upmin==0)
{time2.minclock++;
if(time2.minclock>59)
{time2.minclock=0;
time2.hourclock++;
if(time2.hourclock>12)
time2.hourclock=1;
}
}
}
}
if(Enter==0)
{Count=0;
WRITE(0x03,time2.ampmclock);//ampm
WRITE(0x01,time2.hourclock);//hour
WRITE(0x02,time2.minclock);//min
TR0=1;
}
}
void ScanKey(void)
{if(Switch==0)
{DelayMS1(65);
if(Switch==0)
Count++;
}
if(Count!=0)
ProcessKey();
}
void DisplayChange(void)
{ if(Count==0)
{Ht1621WrDataCmd(0);
Ht1621WrByte(Ht1621code[time1.min%10]);
Ht1621WrDataCmd(2);
Ht1621WrByte(Ht1621code[time1.min/10]);
Ht1621WrDataCmd(5);
Ht1621WrByte(Ht1621code[time1.hour%10]);
Ht1621WrDataCmd(7);
if(time1.hour<10)
Ht1621WrByte(0);
else
Ht1621WrByte(Ht1621code[time1.hour/10]);
Ht1621WrDataCmd(9);
Ht1621WrByte(0x00);
}
else if(Count==1)
{Ht1621WrDataCmd(0);
Ht1621WrByte(Ht1621code[time1.min%10]);
Ht1621WrDataCmd(2);
Ht1621WrByte(Ht1621code[time1.min/10]);
Ht1621WrDataCmd(5);
Ht1621WrByte(Ht1621code[time1.hour%10]);
Ht1621WrDataCmd(7);
if(time1.hour<10)
Ht1621WrByte(0);
else
Ht1621WrByte(Ht1621code[time1.hour/10]);
Ht1621WrDataCmd(9);
Ht1621WrByte(0x08);
}
else if(Count==2)
{Ht1621WrDataCmd(5);
Ht1621WrByte(0);
Ht1621WrDataCmd(7);
if(ampm==0)
Ht1621WrByte(Ht1621code[10]);
else
Ht1621WrByte(Ht1621code[11]);
Ht1621WrDataCmd(0);
Ht1621WrByte(Ht1621code[time1.sec%10]);
Ht1621WrDataCmd(2);
Ht1621WrByte(Ht1621code[time1.sec/10]);
Ht1621WrDataCmd(9);
Ht1621WrByte(0x08);
}
else if(Count==3)
{Ht1621WrDataCmd(9);
Ht1621WrByte(0x01);
Ht1621WrDataCmd(0);
Ht1621WrByte(0);
Ht1621WrDataCmd(2);
if(time2.ampmclock==0)
Ht1621WrByte(Ht1621code[10]);
else
Ht1621WrByte(Ht1621code[11]);
Ht1621WrDataCmd(5);
Ht1621WrByte(0);
Ht1621WrDataCmd(7);
Ht1621WrByte(0);
}
else if(Count==4)
{Ht1621WrDataCmd(9);
Ht1621WrByte(0x01);
Ht1621WrDataCmd(0);
Ht1621WrByte(Ht1621code[time2.minclock%10]);
Ht1621WrDataCmd(2);
Ht1621WrByte(Ht1621code[time2.minclock/10]);
Ht1621WrDataCmd(5);
Ht1621WrByte(Ht1621code[time2.hourclock%10]);
Ht1621WrDataCmd(7);
if(time2.hourclock<10)
Ht1621WrByte(0);
else
Ht1621WrByte(Ht1621code[time2.hourclock/10]);
}
if(Count<3)
{if(_500msflag==1)
{Ht1621WrDataCmd(4);
Ht1621WrByteDot(0x80);
}
if(_500msflag==0)
{Ht1621WrDataCmd(4);
Ht1621WrByteDot(0x00);
}
}
else
{Ht1621WrDataCmd(4);
Ht1621WrByteDot(0x40);
}
}
void timer0(void) interrupt 1 using 0
{ TH0=0x7d; //50ms*20 8MHz
TL0=0xd9;
sec20++;
if(sec20<10)
{_500msflag=1;
}
if(sec20>=10)
{_500msflag=0;
}
if(sec20>=20)
{sec20=0;
inc_sec();
}
}
void play(void)
{
if(beep_flag==0)
return;
if(counter>0)
counter--;
else
{
i++;
if(i==0||i==2||i==4||i==6||i==8)counter=300;
if(i==1||i==3||i==5||i==7||i==9||i==11)counter=200;
if(i==10)counter=525;
}
if(i==0||i==2||i==4||i==6||i==8||i==10)
{
P3_3=1;
}
else if(i==1||i==3||i==5||i==7||i==9||i==11)
P3_3=0;
else
{
i=0;
beep_flag=0;
}
}
void timer1(void) interrupt 3 using 1
{ TH1=0xfa; //2ms 8MHz
TL1=0xd9;
if(ampm==time2.ampmclock&&time1.hour==time2.hourclock&&time1.min==time2.minclock&&time1.sec==00)beep_flag=1;
play();
if(time1.min==00||beep_flag==1)
{
Light_flag++;
if(Light_flag==250)
{Light_flag=0;
light();
}
}
else P1=0x00;
}
void inc_hour(void)
{
time1.hour++;
if(time1.hour >12)
{
time1.hour = 1;
ampm=!ampm;
}
}
void inc_min(void)
{
time1.min++;
if(time1.min > 59)
{
time1.min = 0;
inc_hour();
}
}
void inc_sec(void)
{
time1.sec++;
if(time1.sec > 59)
{
time1.sec = 0;
inc_min();
}
}
void light(void)
{if(Ledloop<4)
{P1=Led[Ledloop];
Ledloop++;
if(Ledloop>=4)
Ledloop=0;
}
}
void delayms(uint i) //毫秒延时子程序
{ while(--i); //采用while(--a) 不要采用while(a--); 各位可编译一下看看汇编结果就知道了!
}
void main(void)
{
TMOD = 0x11; // 定时器0, 1 工作模式1, 16 位定时方式
IE = 0x8a; // 使能timer0,1 中断
TH0=0x7d; //50ms
TL0=0xd9;
TH1=0xfa; //2ms
TL1=0xd9;
TR0 = 1; TR1 = 1;
P1=0x00; P2=0xff; P3_3=0;
Ht1621_Init(); //上电初始化LCD
if(READ(0x04)!=12)
{WRITE(0x01,time2.hourclock);//hour
WRITE(0x02,time2.minclock);//min
WRITE(0x03,time2.ampmclock);//ampm
WRITE(0x04,12);
}
else
{time2.ampmclock=READ(0x03);
time2.hourclock=READ(0x01);
time2.minclock=READ(0x02);
}
while(1)
{DisplayChange();
ScanKey();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -