LCD数字时钟2--C51单片机--从零开始的学习笔记
时间:10-02
整理:3721RD
点击:
LCD数字时钟,这次使用了DS1302时钟芯片,断电后仍能继续保持准确的时间。
代码:
main.c
#include<reg51.h>
#include"ds1302.c"
#include"lcd1602.c"
#define uint unsigned int
#define uchar unsigned char
sbit k1 = P3^0;
sbit k2 = P3^1;
sbit k3 = P3^2;
sbit k4 = P3^3;
uchar count,miao,fen,shi,k1num;
uchar xiqi,ri,yue,nian;
uchar _time_[7];
uchar code table[] = " 20 - - ";
uchar code table_week[8][4] = {"Sun ","Mon ","Tus ","Wed ","Thr ","Fri ","Sat ","Sun "};
void LCD1602_wrt_sfm ( uchar add , uchar dt ) {
uchar sh,ge;
sh = dt/10;
ge = dt%10;
LCD1602_wrt_cmd(0x80+0x40+add);
LCD1602_wrt_dt(0x30+sh);
LCD1602_wrt_dt(0x30+ge);
}
void LCD1602_wrt_date ( uchar add , uchar dt ) {
uchar sh,ge;
sh = dt/10;
ge = dt%10;
LCD1602_wrt_cmd(0x80+add);
LCD1602_wrt_dt(0x30+sh);
LCD1602_wrt_dt(0x30+ge);
}
void LCD1602_wrt_week ( uchar dt ) {
LCD1602_wrt_cmd(0x80+12);
LCD1602_wrt_dt(table_week[dt][0]);
LCD1602_wrt_dt(table_week[dt][1]);
LCD1602_wrt_dt(table_week[dt][2]);
}
void init() {
uchar num;
LCD1602_EN = 0;
Read_RTC( _time_ );
miao = _time_[0];
fen = _time_[1];
shi = _time_[2];
ri = _time_[3];
yue = _time_[4];
nian = _time_[6];
xiqi = _time_[5];
LCD1602_wrt_cmd(0x38);
delay(5);
LCD1602_wrt_cmd(0x38);
delay(5);
LCD1602_wrt_cmd(0x38);
delay(5);
LCD1602_wrt_cmd(0x0c);
delay(5);
LCD1602_wrt_cmd(0x06);
delay(5);
LCD1602_wrt_cmd(0x01);
delay(5);
LCD1602_wrt_cmd(0x80);
delay(5);
for( num=0 ; num<15 ; num++ ) {
LCD1602_wrt_dt( table[num] );
delay(5);
}
LCD1602_wrt_cmd(0x80+0x40+6);
LCD1602_wrt_dt(':');
delay(5);
LCD1602_wrt_cmd(0x80+0x40+9);
LCD1602_wrt_dt(':');
delay(5);
LCD1602_wrt_date(3,nian);
LCD1602_wrt_date(6,yue);
LCD1602_wrt_date(9,ri);
LCD1602_wrt_week(xiqi);
LCD1602_wrt_sfm(10,miao);
LCD1602_wrt_sfm(7,fen);
LCD1602_wrt_sfm(4,shi);
TMOD = 0x01;
TH0 = (65536-49998)/256;
TL0 = (65536-49998)%256;
EA = 1;
ET0 = 1;
TR0 = 1;
}
void keyscan () {
if ( !k1 ) {
delay(10);
if ( !k1 ) {
k1num++;
while ( !k1 ) Bp( 20 );
if ( 1==k1num ) {
TR0 = 0;
LCD1602_wrt_cmd(0x80+0x40+11);
LCD1602_wrt_cmd(0x0f);
}
if ( 2==k1num ) {
LCD1602_wrt_cmd(0x80+0x40+8);
}
if ( 3==k1num ) {
LCD1602_wrt_cmd(0x80+0x40+5);
}
if ( 4==k1num ) {
LCD1602_wrt_cmd(0x80+14);
}
if ( 5==k1num ) {
LCD1602_wrt_cmd(0x80+10);
}
if ( 6==k1num ) {
LCD1602_wrt_cmd(0x80+7);
}
if ( 7==k1num ) {
LCD1602_wrt_cmd(0x80+4);
}
if ( 8==k1num ) {
k1num = 1;
LCD1602_wrt_cmd(0x80+0x40+11);
}
}
}
if ( k1num ) {
if ( !k2 ) {
delay(10);
if ( !k2 ) {
while ( !k2 ) Bp( 20 );
if ( 1==k1num ) {
miao++;
if ( 60==miao ) miao=0;
LCD1602_wrt_sfm(10,miao);
//Write_RTC_adr(0,miao);
LCD1602_wrt_cmd(0x80+0x40+11);
}
if ( 2==k1num ) {
fen++;
if ( 60==fen ) fen=0;
LCD1602_wrt_sfm(7,fen);
//Write_RTC_adr(1,fen);
LCD1602_wrt_cmd(0x80+0x40+8);
}
if ( 3==k1num ) {
shi++;
if ( 24==shi ) shi=0;
LCD1602_wrt_sfm(4,shi);
//Write_RTC_adr(2,shi);
LCD1602_wrt_cmd(0x80+0x40+5);
}
if ( 4==k1num ) {
xiqi++;
if ( 7==xiqi ) xiqi = 0;
LCD1602_wrt_week(xiqi);
Write_RTC_adr(5,xiqi);
LCD1602_wrt_cmd(0x80+14);
}
if ( 5==k1num ) {
ri++;
if ( 32==ri ) ri = 1;
LCD1602_wrt_date(9,ri);
Write_RTC_adr(3,ri);
LCD1602_wrt_cmd(0x80+10);
}
if ( 6==k1num ) {
yue++;
if ( 13==yue ) yue = 1;
LCD1602_wrt_date(6,yue);
//Write_RTC_adr(4,yue);
LCD1602_wrt_cmd(0x80+7);
}
if ( 7==k1num ) {
nian++;
if ( 100==nian ) nian = 0;
LCD1602_wrt_date(3,nian);
//Write_RTC_adr(6,nian);
LCD1602_wrt_cmd(0x80+4);
}
}
}
}
if ( k1num ) {
if ( !k3 ) {
delay(10);
if ( !k3 ) {
while ( !k3 ) Bp( 20 );
if ( 1==k1num ) {
miao--;
if ( -1==miao ) miao=59;
LCD1602_wrt_sfm(10,miao);
//Write_RTC_adr(0,miao);
LCD1602_wrt_cmd(0x80+0x40+11);
}
if ( 2==k1num ) {
fen--;
if ( -1==fen ) fen=59;
LCD1602_wrt_sfm(7,fen);
//Write_RTC_adr(1,fen);
LCD1602_wrt_cmd(0x80+0x40+8);
}
if ( 3==k1num ) {
shi--;
if ( -1==shi ) shi=23;
LCD1602_wrt_sfm(4,shi);
//Write_RTC_adr(2,shi);
LCD1602_wrt_cmd(0x80+0x40+5);
}
if ( 4==k1num ) {
xiqi--;
if ( -1==xiqi ) xiqi = 6;
LCD1602_wrt_week(xiqi);
Write_RTC_adr(5,xiqi);
LCD1602_wrt_cmd(0x80+14);
}
if ( 5==k1num ) {
ri--;
if ( 0==ri ) ri = 31;
LCD1602_wrt_date(9,ri);
//Write_RTC_adr(3,ri);
LCD1602_wrt_cmd(0x80+10);
}
if ( 6==k1num ) {
yue--;
if ( 0==yue ) yue = 12;
LCD1602_wrt_date(6,yue);
//Write_RTC_adr(4,yue);
LCD1602_wrt_cmd(0x80+7);
}
if ( 7==k1num ) {
nian--;
if ( -1==nian ) nian = 99;
LCD1602_wrt_date(3,nian);
//Write_RTC_adr(6,nian);
LCD1602_wrt_cmd(0x80+4);
}
}
}
}
if ( k1num ) {
if ( !k4 ) {
delay(10);
if ( !k4 ) {
while ( !k4 ) Bp( 20 );
k1num = 0;
LCD1602_wrt_cmd(0x0c);
Write_RTC_adr(0,miao);
Write_RTC_adr(1,fen);
Write_RTC_adr(2,shi);
Write_RTC_adr(3,ri);
Write_RTC_adr(4,yue);
Write_RTC_adr(5,xiqi);
Write_RTC_adr(6,nian);
TR0 = 1;
}
}
}
}
void main () {
init();
while(1) {
keyscan();
}
}
void time0 () interrupt 1 {
TH0 = (65536-49998)/256;
TL0 = (65536-49998)%256;
count++;
if ( 5==count ){
count=0;
Read_RTC( _time_ );
miao = _time_[0];
fen = _time_[1];
shi = _time_[2];
ri = _time_[3];
yue = _time_[4];
nian = _time_[6];
xiqi = _time_[5];
LCD1602_wrt_sfm(10,miao);
if ( 0==miao )
LCD1602_wrt_sfm(7,fen);
if ( 0==fen )
LCD1602_wrt_sfm(4,shi);
if ( 0==shi )
LCD1602_wrt_date(9,ri);
if ( 1==ri )
LCD1602_wrt_date(6,yue);
if ( 0==shi )
LCD1602_wrt_week(xiqi);
if ( 1==yue )
LCD1602_wrt_date(3,nian);
}
}
DS1302.c
sbit SCK=P3^6; //时钟
sbit SDA=P3^4; //数据
sbit RST=P3^5;// DS1302复位
unsigned char code write_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //秒分时日月周年 最低位读写位
unsigned char code read_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
void _delay_() {
;;
}
/******************************************************************/
/* 写一个字节 */
/******************************************************************/
void Write_Ds1302_Byte(unsigned char temp)
{
unsigned char i;
for (i=0;i<8;i++) //循环8次 写入数据
{
SCK=0;
SDA=temp&0x01; //每次传输低字节
temp>>=1; //右移一位
SCK=1;
}
}
/******************************************************************/
/* 写入DS1302 */
/******************************************************************/
void Write_Ds1302( unsigned char address,unsigned char dat )
{
RST=0;
_delay_();
SCK=0;
_delay_();
RST=1;
_delay_(); //启动
Write_Ds1302_Byte(address); //发送地址
Write_Ds1302_Byte(dat); //发送数据
RST=0; //恢复
}
/******************************************************************/
/* 读出DS1302数据 */
/******************************************************************/
unsigned char Read_Ds1302 ( unsigned char address )
{
unsigned char i,temp=0x00;
RST=0;
_delay_();
_delay_();
SCK=0;
_delay_();
_delay_();
RST=1;
_delay_();
_delay_();
Write_Ds1302_Byte(address);
for (i=0;i<8;i++) //循环8次 读取数据
{
if(SDA)
temp|=0x80; //每次传输低字节
SCK=0;
temp>>=1; //右移一位
_delay_();
_delay_();
_delay_();
SCK=1;
}
RST=0;
_delay_(); //以下为DS1302复位的稳定时间
_delay_();
RST=0;
SCK=0;
_delay_();
_delay_();
_delay_();
_delay_();
SCK=1;
_delay_();
_delay_();
SDA=0;
_delay_();
_delay_();
SDA=1;
_delay_();
_delay_();
return (temp); //返回
}
/******************************************************************/
/* 读时钟数据 */
/******************************************************************/
void Read_RTC( unsigned char *q ) //读取 日历
{
unsigned char i,*p,tmp;
p=read_rtc_address; //地址传递
for(i=0;i<7;i++) //分7次读取 秒分时日月周年
{
*q=Read_Ds1302(*p);
tmp=*q/16;
*q%=16;
*q+=tmp*10;
p++;
q++;
}
}
/******************************************************************/
/* 设定时钟数据 */
/******************************************************************/
void Set_RTC( unsigned char * q)
{
unsigned char i,*p,tmp;
p=write_rtc_address; //传地址
Write_Ds1302(0x8E,0X00);
for(i=0;i<7;i++){
tmp=*q/10;
*q%=10;
*q+=tmp*16; //BCD处理
Write_Ds1302(*p,*q);
p++;
q++;
}
Write_Ds1302(0x8E,0x80);
}
unsigned char Read_RTC_adr ( unsigned char address ) {
unsigned char k, tmp;
k = Read_Ds1302 ( read_rtc_address[address] );
tmp=k/16;
k%=16;
k+=tmp*10;
return k;
} //读指定位置
void Write_RTC_adr ( unsigned char address , unsigned char k ) {
unsigned char tmp;
tmp=k/10;
k%=10;
k+=tmp*16;
Write_Ds1302(0x8E,0X00);
Write_Ds1302( write_rtc_address[address] , k );
Write_Ds1302(0x8E,0X80);
}
LCD1602.c
sbit LCD1602_RS = P2^6;
sbit LCD1602_RW = P2^5;
sbit LCD1602_EN = P2^7;
sbit Beep = P1^5;
void delay ( unsigned int z ) { //粗略延时
unsigned int x,y;
for ( x=z ; x>0 ; x-- )
for ( y=110 ; y>0 ; y-- );
}
void Bp ( unsigned int z ) { //蜂鸣器
unsigned int x;
for ( x=z ; x>0 ; x-- ) {
Beep = 0;
delay(1);
Beep = 1;
delay(1);
}
}
void LCD1602_wrt_cmd ( unsigned char cmd ) { //液晶写命令 LCD1602
LCD1602_RS = 0;
LCD1602_RW = 0;
LCD1602_EN = 0;
P0 = cmd;
delay(5);
LCD1602_EN = 1;
delay(5);
LCD1602_EN = 0;
}
void LCD1602_wrt_dt ( unsigned char dt ) { //液晶写数据 LCD1602
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_EN = 0;
P0 = dt;
delay(5);
LCD1602_EN = 1;
delay(5);
LCD1602_EN = 0;
}
从零开始的学习笔记呢?
其实我是想把我从零开始学习单片机的过程中写过的程序和心得一个个发上来。
只有程序了
·11111111111111111111111111111111111
哈哈。小编不管怎样,还是得顶你一个啊,毕竟你已经在改变了