关于单片机液晶屏LCD12864的程序

关于单片机液晶屏LCD12864的程序,第1张

/

程序名称:带汉字库的12864液晶显示模块驱动

程序功能:显示字符 、汉字和

开发工具:Kile

MCU型号:AT89S52-24PU

时钟频率:110592MHZ

程序作者:yuan

版权说明:yuan

/

#include<reg52h>

#include "lcdh"

#include "utilh"

sbit E=P1^5;//脉冲使能

sbit RW=P1^6;//读写选择

sbit RS=P1^7;//数据命令选择

sbit rst=P3^6;//12864复位

// 延时ms函数:

// 12864检查状态函数:

void Check12864State(void)

{

P0=0xff;

E=0;//读状态前三控制线的状态

RS=0;

RW=1;

E=1;//拉高,读状态

while((P0&0x80)==0x80);//等待空闲

E=0;//写命令后三控制线的状态

RS=1;

RW=0;

}

// 12864写命令函数:

void Write12864Command( unsigned char com)

{

Check12864State();//检查状态

P0=com;//赋值

E=0;//写命令前三控制线的状态

RS=0;

RW=0;

E=1;//拉高,写命令

E=0;//写命令后三控制线的状态

RS=1;

RW=1;

}

//12864写数据函数:

void Write12864Data( unsigned char dat)

{

Check12864State();//检查状态

P0=dat;//赋值

E=0;//写数据前三控制线的状态

RS=1;

RW=0;

E=1;//拉高,写数据

E=0;//写数据后三控制线的状态

RS=0;

RW=1;

}

//在指定的位置显示字符串(汉字和ASCII码字符)函数:

void LCD12864DisplayString( unsigned char y,unsigned char x, unsigned char pstr)

//y-行数值0-3,x-列数值0-7,pstr-字符串指针

//12864可以显示32个汉字(四行每行8个),一个地址对应一个汉字

//可以显示64个ASCII码字符(四行每行16个),一个地址对应两个字符

//为了实现自动换行功能,这个函数比较繁琐

{

unsigned char row,n=0;

Write12864Command(0x30);//基本指令

Write12864Command(0x06);//地址计数器自动加以,光标右移

switch(y)//根据行号选择行地址

{

case 0:row=0x80;break;//第一行首地址

case 1:row=0x90;break;//第二行首地址

case 2:row=0x88;break;//第三行首地址

case 3:row=0x98;break;//第四行首地址

default:;

}

Write12864Command(row+x);//写地址

while(pstr!='\0')

{

Write12864Data(pstr);//写字符

pstr++;

n++;//计数

if((n+x2)==16)//如果一行写完 ,继续写第二行

{

if(y==0) Write12864Command(0x90);//写下一行地址

else if(y==1) Write12864Command(0x88);//写下一行地址

else if(y==2) Write12864Command(0x98);//写下一行地址

else ;

}

else if((n+x2)==32)//如果第二行写完 ,继续写第三行

{

if(y==0) Write12864Command(0x88);//写下一行地址

else if(y==1) Write12864Command(0x98);//写下一行地址

else ;

}

else if((n+x2)==48)//如果第三行写完 ,继续写第四行

{

if(y==0) Write12864Command(0x98);//写下一行地址

else ;

}

else ;

}

}

//模式清屏函数:

void Clear12864Screen()

{

unsigned char i,j;

Write12864Command(0x34);//功能设定:8位控制方式,使用扩充指令

Write12864Command(0x36);//使用扩充指令,绘图显示控制

for(i=0;i<32;i++)

//ST7920可控制25632点阵(32行256列),而12864液晶实际的行地址只有0-31行,

//12864液晶的32-63行的行是0-31行地址从第128列划分一半出来的,所以分为上下两半屏,

//也就是说第0行和第32行同属一行,行地址相同;第1行和第33行同属一行,以此类推

{

Write12864Command(0x80|i);//写行地址(垂直地址)

Write12864Command(0x80);//写列地址(水平地址)

for(j=0;j<32;j++)

Write12864Data(0x00);//清屏

}

}

//在任意位置显示任意大小的函数:

void LCD12864DisplayPictrue(unsigned char y,unsigned char x,

unsigned char px,unsigned char py, unsigned char pp)

//y-起始行(数值0-63),x-起始列(16位宽,数值0-7),

//px-宽度,py-高度,pp-指针指向数组

//因为上下屏的地址不连续,要在任意位置显示完整的图像,处理起来比较繁琐

{

unsigned char i,j,k;

Clear12864Screen();//清屏

if(y<32)//如果起始行在上半屏

{

k=32-y;//算出上半屏的行数

for(i=0;i<k;i++,y++)//上半屏行数

{

Write12864Command(0x80|y);//写行地址(垂直地址)

Write12864Command(0x80|x);//写列地址(水平地址)

for(j=0;j<px/8;j++)

Write12864Data(pp[ipx/8+j]);//写数据

}

y=0;//下半屏起始行,接上半屏继续写数据

for(;i<py;i++,y++)//下半屏剩下的行数

{

Write12864Command(0x80|y);//写行地址(垂直地址)

Write12864Command(0x80|(8+x));//写列地址(水平地址)

for(j=0;j<px/8;j++)

Write12864Data(pp[ipx/8+j]);//写数据

}

}

else //如果起始行在下半屏

{

for(i=0;i<py;i++,y++)//行数

{

Write12864Command(0x80|(y-32));//写行地址(垂直地址)

Write12864Command(0x80|(8+x));//写列地址(水平地址)

for(j=0;j<px/8;j++)

Write12864Data(pp[ipx/8+j]);//写数据

}

}

}

void Clear12864Text()

{

Write12864Command(0x34);//清屏

DelayMs(5);

Write12864Command(0x30);//清屏

DelayMs(5);

Write12864Command(0x01);//清屏

DelayMs(5);

}

//12864初始化函数:

void Initialize12864()

{

rst=0;//复位12864

DelayMs(30);

rst=1;

DelayMs(20);

Write12864Command(0x30);//功能设定:8位控制方式,使用基本指令

Write12864Command(0x08);//显示关

Write12864Command(0x01);//清屏

Write12864Command(0x06);//地址计数器加一、光标右移

Write12864Command(0x0c);//显示开

}

带字库的驱动

哈哈,你有福了 我也想了好久这程序 这不 刚写好 研究研究

#include <reg52h>

#include <intrinsh>

#include <stringh>

#define uint unsigned int

#define uchar unsigned char

sbit IO = P1^0;

sbit SCLK = P1^1;

sbit RST = P1^2;

sbit RS = P2^0;

sbit RW = P2^1;

sbit EN = P2^2;

sbit KEY1=P3^4;

sbit KEY2=P3^5;

sbit KEY3=P3^6;

uchar WEEK[]={"SUN","","MON","TUS","WEN","THU","FRI","SAT"};

uchar LCD_DSY_BUFFER1[]={"DATE 00-00-00 "};

uchar LCD_DSY_BUFFER2[]={"TIME 00:00:00 "};

uchar DateTime[7]; //秒,分,时,日,月,周,年

uchar flag,flag_1,i,miao,fen,shi,ri,yue,zhou,nian;

void DelayMS(uint ms)

{

uchar i;

while(ms--)

{

for(i=0;i<120;i++);

}

}

//

//函数名称: Write_A_Byte_TO_DS1302(uchar x)

//函数功能: 向1302写入一个字节

//入口参数: x

//出口参数: 无

//调用子程序: 无

//

void Write_A_Byte_TO_DS1302(uchar x)

{

uchar i;

for(i=0;i<8;i++)

{

IO=x&0x01;

SCLK=1;

SCLK=0;

x>>=1;

}

}

void Write_DS1302(uchar add,uchar num)

{

SCLK=0;

RST=0;

RST=1;

Write_A_Byte_TO_DS1302(add);

Write_A_Byte_TO_DS1302(num);

RST=0;

SCLK=1;

}

//

//函数名称: Get_A_Byte_FROM_DS1302()

//函数功能: 从1302读一个字节

//入口参数: 无

//出口参数: b/1610+b%16

//调用子程序: 无

//

uchar Get_A_Byte_FROM_DS1302()

{

uchar i,b=0x00;

for(i=0;i<8;i++)

{

b |= _crol_((uchar)IO,i);

SCLK=1;SCLK=0;

}

return b/1610+b%16;

}

//

//函数名称: Read_Data(uchar addr)

//函数功能: 指定位置读数据

//入口参数: addr

//出口参数: dat

//调用子程序: Write_Abyte_1302(addr)

//

uchar Read_Data(uchar addr)

{

uchar dat;

RST = 0;SCLK=0;RST=1;

Write_A_Byte_TO_DS1302(addr);

dat = Get_A_Byte_FROM_DS1302();

SCLK=1;RST=0;

return dat;

}

//

//函数名称: GetTime()

//函数功能: 读取时间

//入口参数: 无

//出口参数: 无

//调用子程序: 无

//

void GetTime()

{

uchar i,addr = 0x81;

for(i=0;i<7;i++)

{

DateTime[i]=Read_Data(addr);addr+=2;

}

}

uchar Read_LCD_State()

{

uchar state;

RS=0;RW=1;EN=1;DelayMS(1);

state=P0;

EN = 0;DelayMS(1);

return state;

}

void LCD_Busy_Wait()

{

while((Read_LCD_State()&0x80)==0x80);

DelayMS(5);

}

void Write_LCD_Data(uchar dat) //写数据到1602

{

LCD_Busy_Wait();

RS=1;RW=0;EN=0;P0=dat;EN=1;DelayMS(1);EN=0;

}

void Write_LCD_Command(uchar cmd) //写命令

{

LCD_Busy_Wait();

RS=0;RW=0;EN=0;P0=cmd;EN=1;DelayMS(1);EN=0;

}

void Init_LCD() //1602 初始化

{

Write_LCD_Command(0x38);

DelayMS(1);

Write_LCD_Command(0x01);

DelayMS(1);

Write_LCD_Command(0x06);

DelayMS(1);

Write_LCD_Command(0x0c);

DelayMS(1);

}

void Set_LCD_POS(uchar p)

{

Write_LCD_Command(p|0x80);

}

void Display_LCD_String(uchar p,uchar s) //1602显示

{

uchar i;

Set_LCD_POS(p);

for(i=0;i<16;i++)

{

Write_LCD_Data(s[i]);

DelayMS(1);

}

}

void write_com(uchar com)

{

RS=0;

P0=com;

DelayMS(5);

EN=1;

DelayMS(5);

EN=0;

}

void write_date(uchar date)

{

RS=1;

P0=date;

DelayMS(5);

EN=1;

DelayMS(5);

EN=0;

}

void display(uchar add,uchar date)

{

uchar shi,ge;

shi=date/10;

ge=date%10;

write_com(0x80+0x40+add);

write_date(0x30+shi);

write_date(0x30+ge);

}

void display1(uchar add,uchar date)

{

uchar shi,ge;

shi=date/10;

ge=date%10;

write_com(0x80+add);

write_date(0x30+shi);

write_date(0x30+ge);

}

void Format_DateTime(uchar d,uchar a)

{

a[0]=d/10+'0';

a[1]=d%10+'0';

}

uchar ZH(uchar dat)

{

uchar tmp;

tmp=dat/10;

dat=dat%10;

dat=dat+tmp16;

return dat;

}

void Keyscan()

{

flag_1=1;

while(flag_1)

{

if(KEY1==0)

{

DelayMS(5);

while(!KEY1);

flag=(flag+1)%8;

switch(flag)

{

case(1): Write_LCD_Command(0x0f);

Write_LCD_Command(0x80+0x40+11);

break;

case(2): Write_LCD_Command(0x80+0x40+8);

break;

case(3): Write_LCD_Command(0x80+0x40+5);

break;

case(4): Write_LCD_Command(0x80+13);

break;

case(5): Write_LCD_Command(0x80+11);

break;

case(6): Write_LCD_Command(0x80+8);

break;

case(7): Write_LCD_Command(0x80+5);

break;

case(0): flag_1=0;

Write_LCD_Command(0x0c);

//miao

Write_DS1302(0x8e,0x00);

Write_DS1302(0x80,ZH(DateTime[0]));

Write_DS1302(0x8e,0x80);

//fen

Write_DS1302(0x8e,0x00);

Write_DS1302(0x82,ZH(DateTime[1]));

Write_DS1302(0x8e,0x80);

//shi

Write_DS1302(0x8e,0x00);

Write_DS1302(0x84,ZH(DateTime[2]));

Write_DS1302(0x8e,0x80);

//ri

Write_DS1302(0x8e,0x00);

Write_DS1302(0x86,ZH(DateTime[3]));

Write_DS1302(0x8e,0x80);

// yue

Write_DS1302(0x8e,0x00);

Write_DS1302(0x88,ZH(DateTime[4]));

Write_DS1302(0x8e,0x80);

//nian

Write_DS1302(0x8e,0x00);

Write_DS1302(0x8c,ZH(DateTime[6]));

Write_DS1302(0x8e,0x80);

break;

}

}

if(flag!=0)

{

if(KEY2==0)

{

DelayMS(5);

if(KEY2==0)

while(!KEY2);

if(flag==1) //miao

{

DateTime[0]++;

if(DateTime[0]==60)

DateTime[0]=0;

write_com(0x80+0x40+11);

display(11,DateTime[0]);

}

if(flag==2) //fen

{

DateTime[1]++;

if(DateTime[1]==60)

DateTime[1]=0;

write_com(0x80+0x40+8);

display(8,DateTime[1]);

}

if(flag==3) //shi

{

DateTime[2]++;

if(DateTime[2]==24)

DateTime[2]=0;

write_com(0x80+0x40+5);

display(5,DateTime[2]);

}

/ if(flag==4) //zhou

{

DateTime[0]++;

if(DateTime[0]==60)

DateTime[0]=0;

write_com(0x80+0x40+11);

display(11,DateTime[0]);

} /

if(flag==5) // ri

{

DateTime[3]++;

if(DateTime[3]==30)

DateTime[3]=0;

write_com(0x80+11);

display1(11,DateTime[3]);

}

if(flag==6) //yue

{

DateTime[4]++;

if(DateTime[4]==13)

DateTime[4]=0;

write_com(0x80+8);

display1(8,DateTime[4]);

}

if(flag==7) //nian

{

DateTime[6]++;

if(DateTime[6]==100)

DateTime[6]=0;

write_com(0x80+5);

display1(5,DateTime[6]);

}

}

}

if(flag!=0)

{

if(KEY3==0)

{

DelayMS(5);

if(KEY3==0)

while(!KEY3);

if(flag==1) //miao

{

DateTime[0]--;

if(DateTime[0]==-1)

DateTime[0]=0;

write_com(0x80+0x40+11);

display(11,DateTime[0]);

}

if(flag==2) //fen

{

DateTime[1]--;

if(DateTime[1]==-1)

DateTime[1]=0;

write_com(0x80+0x40+8);

display(8,DateTime[1]);

}

if(flag==3) //shi

{

DateTime[2]--;

if(DateTime[2]==-1)

DateTime[2]=0;

write_com(0x80+0x40+5);

display(5,DateTime[2]);

}

/ if(flag==4) //zhou

{

DateTime[0]++;

if(DateTime[0]==60)

DateTime[0]=0;

write_com(0x80+0x40+11);

display(11,DateTime[0]);

} /

if(flag==5) // ri

{

DateTime[3]--;

if(DateTime[3]==-1)

DateTime[3]=0;

write_com(0x80+11);

display1(11,DateTime[3]);

}

if(flag==6) //yue

{

DateTime[4]--;

if(DateTime[4]==-1)

DateTime[4]=0;

write_com(0x80+8);

display1(8,DateTime[4]);

}

if(flag==7) //nian

{

DateTime[6]--;

if(DateTime[6]==-1)

DateTime[6]=0;

write_com(0x80+5);

display1(5,DateTime[6]);

}

}

}

}

}

void main()

{

Init_LCD();

while(1)

{

EA=1;

EX0=1;

GetTime();

Format_DateTime(DateTime[6],LCD_DSY_BUFFER1+5); //年

Format_DateTime(DateTime[4],LCD_DSY_BUFFER1+8); //月

Format_DateTime(DateTime[3],LCD_DSY_BUFFER1+11); //日

strcpy(LCD_DSY_BUFFER1+13,WEEK[DateTime[5]]); //周 串拷贝 包含于STRINGH

Format_DateTime(DateTime[2],LCD_DSY_BUFFER2+5); //时

Format_DateTime(DateTime[1],LCD_DSY_BUFFER2+8); //分

Format_DateTime(DateTime[0],LCD_DSY_BUFFER2+11); //秒

Display_LCD_String(0x00,LCD_DSY_BUFFER1);

Display_LCD_String(0x40,LCD_DSY_BUFFER2);

}

}

void int0() interrupt 0

{

Keyscan();

}

1、闹钟设置界面。

2、存储响闹时间。

3、时间中断,设置读取时间的flag

4、主程序中判断flag设置,读取时钟。

5、比较当前时钟在响闹时间范围内,输出闹铃(如果是蜂鸣器,给他一个输出频率的信号)。

基于DS1302的日历时钟

#include<reg51h> //包含单片机寄存器的头文件

#include<intrinsh> //包含_nop_()函数定义的头文件

/

以下是DS1302芯片的 *** 作程序

/

unsigned char code digit[10]={"0123456789"}; //定义字符数组显示数字

sbit DATA=P1^1; //位定义1302芯片的接口,数据输出端定义在P11引脚

sbit RST=P1^2; //位定义1302芯片的接口,复位端口定义在P11引脚

sbit SCLK=P1^0; //位定义1302芯片的接口,时钟输出端口定义在P11引脚

/

函数功能:延时若干微秒

入口参数:n

/

void delaynus(unsigned char n)

{

unsigned char i;

for(i=0;i<n;i++)

;

}

/

函数功能:向1302写一个字节数据

入口参数:x

/

void Write1302(unsigned char dat)

{

unsigned char i;

SCLK=0; //拉低SCLK,为脉冲上升沿写入数据做好准备

delaynus(2); //稍微等待,使硬件做好准备

for(i=0;i<8;i++) //连续写8个二进制位数据

{

DATA=dat&0x01; //取出dat的第0位数据写入1302

delaynus(2); //稍微等待,使硬件做好准备

SCLK=1; //上升沿写入数据

delaynus(2); //稍微等待,使硬件做好准备

SCLK=0; //重新拉低SCLK,形成脉冲

dat>>=1; //将dat的各数据位右移1位,准备写入下一个数据位

}

}

/

函数功能:根据命令字,向1302写一个字节数据

入口参数:Cmd,储存命令字;dat,储存待写的数据

/

void WriteSet1302(unsigned char Cmd,unsigned char dat)

{

RST=0; //禁止数据传递

SCLK=0; //确保写数居前SCLK被拉低

RST=1; //启动数据传输

delaynus(2); //稍微等待,使硬件做好准备

Write1302(Cmd); //写入命令字

Write1302(dat); //写数据

SCLK=1; //将时钟电平置于已知状态

RST=0; //禁止数据传递

}

/

函数功能:从1302读一个字节数据

入口参数:x

/

unsigned char Read1302(void)

{

unsigned char i,dat;

delaynus(2); //稍微等待,使硬件做好准备

for(i=0;i<8;i++) //连续读8个二进制位数据

{

dat>>=1; //将dat的各数据位右移1位,因为先读出的是字节的最低位

if(DATA==1) //如果读出的数据是1

dat|=0x80; //将1取出,写在dat的最高位

SCLK=1; //将SCLK置于高电平,为下降沿读出

delaynus(2); //稍微等待

SCLK=0; //拉低SCLK,形成脉冲下降沿

delaynus(2); //稍微等待

}

return dat; //将读出的数据返回

}

/

函数功能:根据命令字,从1302读取一个字节数据

入口参数:Cmd

/

unsigned char ReadSet1302(unsigned char Cmd)

{

unsigned char dat;

RST=0; //拉低RST

SCLK=0; //确保写数居前SCLK被拉低

RST=1; //启动数据传输

Write1302(Cmd); //写入命令字

dat=Read1302(); //读出数据

SCLK=1; //将时钟电平置于已知状态

RST=0; //禁止数据传递

return dat; //将读出的数据返回

}

/

函数功能: 1302进行初始化设置

/

void Init_DS1302(void)

{

WriteSet1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令

WriteSet1302(0x80,((0/10)<<4|(0%10))); //根据写秒寄存器命令字,写入秒的初始值

WriteSet1302(0x82,((0/10)<<4|(0%10))); //根据写分寄存器命令字,写入分的初始值

WriteSet1302(0x84,((12/10)<<4|(12%10))); //根据写小时寄存器命令字,写入小时的初始值

WriteSet1302(0x86,((16/10)<<4|(16%10))); //根据写日寄存器命令字,写入日的初始值

WriteSet1302(0x88,((11/10)<<4|(11%10))); //根据写月寄存器命令字,写入月的初始值

WriteSet1302(0x8c,((8/10)<<4|(8%10))); //根据写小时寄存器命令字,写入小时的初始值

}

/

以下是对液晶模块的 *** 作程序

/

sbit RS=P2^0; //寄存器选择位,将RS位定义为P20引脚

sbit RW=P2^1; //读写选择位,将RW位定义为P21引脚

sbit E=P2^2; //使能信号位,将E位定义为P22引脚

sbit BF=P0^7; //忙碌标志位,,将BF位定义为P07引脚

/

函数功能:延时1ms

(3j+2)i=(3×33+2)×10=1010(微秒),可以认为是1毫秒

/

void delay1ms()

{

unsigned char i,j;

for(i=0;i<10;i++)

for(j=0;j<33;j++)

;

}

/

函数功能:延时若干毫秒

入口参数:n

/

void delaynms(unsigned char n)

{

unsigned char i;

for(i=0;i<n;i++)

delay1ms();

}

/

函数功能:判断液晶模块的忙碌状态

返回值:result。result=1,忙碌;result=0,不忙

/

bit BusyTest(void)

{

bit result;

RS=0; //根据规定,RS为低电平,RW为高电平时,可以读状态

RW=1;

E=1; //E=1,才允许读写

_nop_(); //空 *** 作

_nop_();

_nop_();

_nop_(); //空 *** 作四个机器周期,给硬件反应时间

result=BF; //将忙碌标志电平赋给result

E=0; //将E恢复低电平

return result;

}

/

函数功能:将模式设置指令或显示地址写入液晶模块

入口参数:dictate

/

void WriteInstruction (unsigned char dictate)

{

while(BusyTest()==1); //如果忙就等待

RS=0; //根据规定,RS和R/W同时为低电平时,可以写入指令

RW=0;

E=0; //E置低电平(根据表8-6,写指令时,E为高脉冲,

// 就是让E从0到1发生正跳变,所以应先置"0"

_nop_();

_nop_(); //空 *** 作两个机器周期,给硬件反应时间

P0=dictate; //将数据送入P0口,即写入指令或地址

_nop_();

_nop_();

_nop_();

_nop_(); //空 *** 作四个机器周期,给硬件反应时间

E=1; //E置高电平

_nop_();

_nop_();

_nop_();

_nop_(); //空 *** 作四个机器周期,给硬件反应时间

E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令

}

/

函数功能:指定字符显示的实际地址

入口参数:x

/

void WriteAddress(unsigned char x)

{

WriteInstruction(x|0x80); //显示位置的确定方法规定为"80H+地址码x"

}

/

函数功能:将数据(字符的标准ASCII码)写入液晶模块

入口参数:y(为字符常量)

/

void WriteData(unsigned char y)

{

while(BusyTest()==1);

RS=1; //RS为高电平,RW为低电平时,可以写入数据

RW=0;

E=0; //E置低电平(根据表8-6,写指令时,E为高脉冲,

// 就是让E从0到1发生正跳变,所以应先置"0"

P0=y; //将数据送入P0口,即将数据写入液晶模块

_nop_();

_nop_();

_nop_();

_nop_(); //空 *** 作四个机器周期,给硬件反应时间

E=1; //E置高电平

_nop_();

_nop_();

_nop_();

_nop_(); //空 *** 作四个机器周期,给硬件反应时间

E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令

}

/

函数功能:对LCD的显示模式进行初始化设置

/

void LcdInitiate(void)

{

delaynms(15); //延时15ms,首次写指令时应给LCD一段较长的反应时间

WriteInstruction(0x38); //显示模式设置:16×2显示,5×7点阵,8位数据接口

delaynms(5); //延时5ms ,给硬件一点反应时间

WriteInstruction(0x38);

delaynms(5); //延时5ms ,给硬件一点反应时间

WriteInstruction(0x38); //连续三次,确保初始化成功

delaynms(5); //延时5ms ,给硬件一点反应时间

WriteInstruction(0x0c); //显示模式设置:显示开,无光标,光标不闪烁

delaynms(5); //延时5ms ,给硬件一点反应时间

WriteInstruction(0x06); //显示模式设置:光标右移,字符不移

delaynms(5); //延时5ms ,给硬件一点反应时间

WriteInstruction(0x01); //清屏幕指令,将以前的显示内容清除

delaynms(5); //延时5ms ,给硬件一点反应时间

}

/

以下是1302数据的显示程序

/

/

函数功能:显示秒

入口参数:x

/

void DisplaySecond(unsigned char x)

{

unsigned char i,j; //j,k,l分别储存温度的百位、十位和个位

i=x/10;//取十位

j=x%10;//取个位

WriteAddress(0x49); //写显示地址,将在第2行第7列开始显示

WriteData(digit[i]); //将百位数字的字符常量写入LCD

WriteData(digit[j]); //将十位数字的字符常量写入LCD

delaynms(50); //延时1ms给硬件一点反应时间

}

/

函数功能:显示分钟

入口参数:x

/

void DisplayMinute(unsigned char x)

{

unsigned char i,j; //j,k,l分别储存温度的百位、十位和个位

i=x/10;//取十位

j=x%10;//取个位

WriteAddress(0x46); //写显示地址,将在第2行第7列开始显示

WriteData(digit[i]); //将百位数字的字符常量写入LCD

WriteData(digit[j]); //将十位数字的字符常量写入LCD

delaynms(50); //延时1ms给硬件一点反应时间

}

/

函数功能:显示小时

入口参数:x

/

void DisplayHour(unsigned char x)

{

unsigned char i,j; //j,k,l分别储存温度的百位、十位和个位

i=x/10;//取十位

j=x%10;//取个位

WriteAddress(0x43); //写显示地址,将在第2行第7列开始显示

WriteData(digit[i]); //将百位数字的字符常量写入LCD

WriteData(digit[j]); //将十位数字的字符常量写入LCD

delaynms(50); //延时1ms给硬件一点反应时间

}

/

函数功能:显示日

入口参数:x

/

void DisplayDay(unsigned char x)

{

unsigned char i,j; //j,k,l分别储存温度的百位、十位和个位

i=x/10;//取十位

j=x%10;//取个位

WriteAddress(0x0c); //写显示地址,将在第2行第7列开始显示

WriteData(digit[i]); //将百位数字的字符常量写入LCD

WriteData(digit[j]); //将十位数字的字符常量写入LCD

delaynms(50); //延时1ms给硬件一点反应时间

}

/

函数功能:显示月

入口参数:x

/

void DisplayMonth(unsigned char x)

{

unsigned char i,j; //j,k,l分别储存温度的百位、十位和个位

i=x/10;//取十位

j=x%10;//取个位

WriteAddress(0x09); //写显示地址,将在第2行第7列开始显示

WriteData(digit[i]); //将百位数字的字符常量写入LCD

WriteData(digit[j]); //将十位数字的字符常量写入LCD

delaynms(50); //延时1ms给硬件一点反应时间

}

/

函数功能:显示年

入口参数:x

/

void DisplayYear(unsigned char x)

{

unsigned char i,j; //j,k,l分别储存温度的百位、十位和个位

i=x/10;//取十位

j=x%10;//取个位

WriteAddress(0x06); //写显示地址,将在第2行第7列开始显示

WriteData(digit[i]); //将百位数字的字符常量写入LCD

WriteData(digit[j]); //将十位数字的字符常量写入LCD

delaynms(50); //延时1ms给硬件一点反应时间

}

/

函数功能:主函数

/

void main(void)

{

unsigned char second,minute,hour,day,month,year; //分别储存苗、分、小时,日,月,年

unsigned char ReadValue; //储存从1302读取的数据

LcdInitiate(); //将液晶初始化

WriteAddress(0x01); //写Date的显示地址,将在第1行第2列开始显示

WriteData('D'); //将字符常量写入LCD

WriteData('a'); //将字符常量写入LCD

WriteData('t'); //将字符常量写入LCD

WriteData('e'); //将字符常量写入LCD

WriteData(':'); //将字符常量写入LCD

WriteAddress(0x08); //写年月分隔符的显示地址, 显示在第1行第9列

WriteData('-'); //将字符常量写入LCD

WriteAddress(0x0b); //写月日分隔符的显示地址, 显示在第1行第12列

WriteData('-'); //将字符常量写入LCD

WriteAddress(0x45); //写小时与分钟分隔符的显示地址, 显示在第2行第6列

WriteData(':'); //将字符常量写入LCD

WriteAddress(0x48); //写分钟与秒分隔符的显示地址, 显示在第2行第9列

WriteData(':'); //将字符常量写入LCD

Init_DS1302(); //将1302初始化

while(1)

{

ReadValue = ReadSet1302(0x81); //从秒寄存器读数据

second=((ReadValue&0x70)>>4)10 + (ReadValue&0x0F);//将读出数据转化

DisplaySecond(second); //显示秒

ReadValue = ReadSet1302(0x83); //从分寄存器读

minute=((ReadValue&0x70)>>4)10 + (ReadValue&0x0F); //将读出数据转化

DisplayMinute(minute); //显示分

ReadValue = ReadSet1302(0x85); //从分寄存器读

hour=((ReadValue&0x70)>>4)10 + (ReadValue&0x0F); //将读出数据转化

DisplayHour(hour); //显示小时

ReadValue = ReadSet1302(0x87); //从分寄存器读

day=((ReadValue&0x70)>>4)10 + (ReadValue&0x0F); //将读出数据转化

DisplayDay(day); //显示日

ReadValue = ReadSet1302(0x89); //从分寄存器读

month=((ReadValue&0x70)>>4)10 + (ReadValue&0x0F); //将读出数据转化

DisplayMonth(month); //显示月

ReadValue = ReadSet1302(0x8d); //从分寄存器读

year=((ReadValue&0x70)>>4)10 + (ReadValue&0x0F); //将读出数据转化

DisplayYear(year); //显示年

}

}

改改 就是你的了

电子钟调时间步骤:

材料准备:电子钟。

1、先按一下“调整”按钮,数字开始闪动。

2、想调哪一个数就多按几次,按到的这个数就会闪动。再用“上调”,或者“下调”来调整。

3、在正常显示下,按一下“闹钟”按钮,会在“开”和“关”之间转换。按一下“喇叭”按钮,会在“开”和“关”的功能切换。

4、最后按复位。

应用与优点:

1、应用:

目前,在国内,电子钟因LCD数字显示效用直接有效,所以大多运用在城市的主要营业场所,以及车站、码头等公共场所。在对公共场所的电子钟设定的时候,使用者还可根据周边的气候、温度等对LCD屏进行设置。同时,因为LCD的显示耗电量很省,所以能够保持持续的工作效果。

夜间在睡觉的时候,床头如果放个带投影功能的电子钟,可以不用起床,直接让时间显示在天花板上,非常直观与有效。

现在生产的大部分汽车中,车内前方仪表盘旁边一般也都自带电子钟功能,采取蓝色背景光板成像效果,非常清晰。

2、优点:

与传统的机械钟相比,电子钟具有更突出的优点。由于电子钟采用数字集成电路的发展和采用了先进的石英技术,使电子钟具有走时准确、性能稳定、携带方便等优点,电子钟用于定时自动报警、按时自动打铃、时间程序自动控制、定时广播及自动控制等各个领域。

顶层文件 万年历C

#include<reg51h>

#include "LCD1602h"

#include "DS1302h"

#define uchar unsigned char

#define uint unsigned int

sbit speaker=P2^4;

bit key_flag1=0,key_flag2=0;

SYSTEMTIME adjusted;

uchar sec_add=0,min_add=0,hou_add=0,day_add=0,mon_add=0,yea_add=0;

uchar data_alarm[7]={0};

/键盘控制/

int key_scan() //扫描是否有键按下

{ int i=0;

uint temp;

P1=0xf0;

temp=P1;

if(temp!=0xf0)

i=1;

else

i=0;

return i;

}

uchar key_value() //确定按键的值

{

uint m=0,n=0,temp;

uchar value;

uchar v[4][3]={'2','1','0','5','4','3','8','7','6','b','a','9'} ;

P1=0xfe; temp=P1; if(temp!=0xfe)m=0;

P1=0xfd;temp=P1 ;if(temp!=0xfd)m=1;

P1=0xfb;temp=P1 ;if(temp!=0xfb)m=2;

P1=0xf7;temp=P1 ;if(temp!=0xf7)m=3;

P1=0xef;temp=P1 ;if(temp!=0xef)n=0;

P1=0xdf;temp=P1 ;if(temp!=0xdf)n=1;

P1=0xbf;temp=P1 ;if(temp!=0xbf)n=2;

value=v[m][n];

return value;

}

/设置闹铃函数/

void naoling(void)

{

uchar i=0,l=0,j;

init1602();

while(key_flag2&&i<12)

if(key_scan()){j=key_value();write_data(j);if(i%2==0)data_alarm[l]=(j-'0')10;else {data_alarm[l]+=(j-'0');l++;}i++;delay(600);}

write_com(0x01);

}

uchar according(void)

{ uchar k;

if(data_alarm[0]==adjustedYear&&data_alarm[1]==adjustedMonth&&data_alarm[2]==adjustedDay&&data_alarm[3]==adjustedHour&&data_alarm[4]==adjustedMinute&&data_alarm[5]==adjustedSecond)

k=1;

else k=0;

return k;

}

void speak(void)

{uint i=50;

while(i)

{speaker=0;

delay(1);

speaker=1;

delay(1);

i--;

}

}

void alarm(void)

{uint i=10;

while(i)

{

speak();

delay(10);

i--;

}

}

/修改时间 *** 作/

void reset(void)

{

sec_add=0;

min_add=0;

hou_add=0;

day_add=0;

mon_add=0;

yea_add=0 ;

}

void adjust(void)

{

if(key_scan()&&key_flag1)

switch(key_value())

{case '0':sec_add++;break;

case '1':min_add++;break;

case '2':hou_add++;break;

case '3':day_add++;break;

case '4':mon_add++;break;

case '5':yea_add++;break;

case 'b':reset();break;

default: break;

}

adjustedSecond+=sec_add;

adjustedMinute+=min_add;

adjustedHour+=hou_add;

adjustedDay+=day_add;

adjustedMonth+=mon_add;

adjustedYear+=yea_add;

if(adjustedSecond>59) adjustedSecond=adjustedSecond%60;

if(adjustedMinute>59) adjustedMinute=adjustedMinute%60;

if(adjustedHour>23) adjustedHour=adjustedHour%24;

if(adjustedDay>31) adjustedDay=adjustedDay%31;

if(adjustedMonth>12) adjustedMonth=adjustedMonth%12;

if(adjustedYear>100) adjustedYear=adjustedYear%100;

}

/中断处理函数/

void changing(void) interrupt 0 using 0 //需要修改时间和日期,或者停止修改

{

if(key_flag1)key_flag1=0;

else key_flag1=1;

}

void alarming(void) interrupt 3 using 0 //需要设置闹铃或者停止设置

{

if(key_flag2)key_flag2=0;

else key_flag2=1;

}

/主函数/

main()

{uint i;

uchar l;

uchar p1[]="D:",p2[]="T:";

SYSTEMTIME T;

EA=1;

EX0=1;

IT0=1;

EA=1;

EX1=1;

IT1=1;

init1602();

Initial_DS1302() ;

while(1)

{ write_com(0x80);

write_string(p1,2);

write_com(0xc0);

write_string(p2,2);

DS1302_GetTime(&T) ;

adjustedSecond=TSecond;

adjustedMinute=TMinute;

adjustedHour=THour;

adjustedWeek=TWeek;

adjustedDay=TDay;

adjustedMonth=TMonth;

adjustedYear=TYear;

for(i=0;i<9;i++)

{

adjustedDateString[i]=TDateString[i];

adjustedTimeString[i]=TTimeString[i];

}

adjust();

if(key_flag2)naoling();

if(according())alarm();

DateToStr(&adjusted);

TimeToStr(&adjusted);

write_com(0x82);

write_string(adjustedDateString,8);

write_com(0xc2);

write_string(adjustedTimeString,8);

delay(10);

}

(二)头文件1 显示模块 LCD1602H

#ifndef LCD_CHAR_1602_2009_5_9

#define LCD_CHAR_1602_2009_5_9

#define uchar unsigned char

#define uint unsigned int

sbit lcdrs = P2^0;

sbit lcdrw = P2^1;

sbit lcden = P2^2;

void delay(uint z) // 延时

{

uint x,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

void write_com(uchar com) // 写入指令数据到 lcd

{

lcdrw=0;

lcdrs=0;

P0=com;

delay(5);

lcden=1;

delay(5);

lcden=0;

}

void write_data(uchar date) // 写入字符显示数据到 lcd

{

lcdrw=0;

lcdrs=1;

P0=date;

delay(5);

lcden=1;

delay(5);

lcden=0;

}

void init1602() // 初始化设定

{

lcdrw=0;

lcden=0;

write_com(0x3C);

write_com(0x0c);

write_com(0x06);

write_com(0x01);

write_com(0x80);

}

void write_string(uchar pp,uint n)

{

int i;

for(i=0;i<n;i++)

write_data(pp[i]);

}

#endif

(三)头文件2 时钟模块 DS1302H

#ifndef _REAL_TIMER_DS1302_2009_5_20_

#define _REAL_TIMER_DS1302_2003_5_20_

sbit DS1302_CLK = P2^6; //实时时钟时钟线引脚

sbit DS1302_IO = P2^7; //实时时钟数据线引脚

sbit DS1302_RST = P2^5; //实时时钟复位线引脚

sbit ACC0 = ACC^0;

sbit ACC7 = ACC^7;

typedef struct SYSTEM_TIME

{

unsigned char Second;

unsigned char Minute;

unsigned char Hour;

unsigned char Week;

unsigned char Day;

unsigned char Month;

unsigned char Year;

unsigned char DateString[9]; //用这两个字符串来放置读取的时间

unsigned char TimeString[9];

}SYSTEMTIME; //定义的时间类型

#define AM(X) X

#define PM(X) (X+12) // 转成24小时制

#define DS1302_SECOND 0x80

#define DS1302_MINUTE 0x82

#define DS1302_HOUR 0x84

#define DS1302_WEEK 0x8A

#define DS1302_DAY 0x86

#define DS1302_MONTH 0x88

#define DS1302_YEAR 0x8C

#define DS1302_RAM(X) (0xC0+(X)2) //用于计算 DS1302_RAM 地址的宏

/内部指令/

void DS1302InputByte(unsigned char d) //实时时钟写入一字节(内部函数)

{

unsigned char i;

ACC = d;

for(i=8; i>0; i--)

{

DS1302_IO = ACC0;

DS1302_CLK = 1;

DS1302_CLK = 0;

ACC = ACC >> 1; //因为在前面已经定义了ACC0 = ACC^0;以便再次利用DS1302_IO = ACC0;

}

}

unsigned char DS1302OutputByte(void) //实时时钟读取一字节(内部函数)

{

unsigned char i;

for(i=8; i>0; i--)

{

ACC = ACC >>1;

ACC7 = DS1302_IO;

DS1302_CLK = 1;

DS1302_CLK = 0;

}

return(ACC);

}

//

void Write1302(unsigned char ucAddr, unsigned char ucDa) //ucAddr: DS1302地址, ucData: 要写的数据

{

DS1302_RST = 0;

DS1302_CLK = 0;

DS1302_RST = 1;

DS1302InputByte(ucAddr); // 地址,命令

DS1302InputByte(ucDa); // 写1Byte数据

DS1302_CLK = 1;

DS1302_RST = 0;

}

unsigned char Read1302(unsigned char ucAddr) //读取DS1302某地址的数据

{

unsigned char ucData;

DS1302_RST = 0;

DS1302_CLK = 0;

DS1302_RST = 1;

DS1302InputByte(ucAddr|0x01); // 地址,命令

ucData = DS1302OutputByte(); // 读1Byte数据

DS1302_CLK = 1;

DS1302_RST = 0;

return(ucData);

}

void DS1302_SetProtect(bit flag) //是否写保护

{

if(flag)

Write1302(0x8E,0x10);

else

Write1302(0x8E,0x00);

}

void DS1302_SetTime(unsigned char Address, unsigned char Value) // 设置时间函数

{

DS1302_SetProtect(0);

Write1302(Address, ((Value/10)<<4 | (Value%10))); //将十进制数转换为BCD码

} //在DS1302中的与日历、时钟相关的寄存器存放的数据必须为BCD码形式

void DS1302_GetTime(SYSTEMTIME Time)

{

unsigned char ReadValue;

ReadValue = Read1302(DS1302_SECOND);

Time->Second = ((ReadValue&0x70)>>4)10 + (ReadValue&0x0F); //将BCD码转换为十进制数

ReadValue = Read1302(DS1302_MINUTE);

Time->Minute = ((ReadValue&0x70)>>4)10 + (ReadValue&0x0F);

ReadValue = Read1302(DS1302_HOUR);

Time->Hour = ((ReadValue&0x70)>>4)10 + (ReadValue&0x0F);

ReadValue = Read1302(DS1302_DAY);

Time->Day = ((ReadValue&0x70)>>4)10 + (ReadValue&0x0F);

ReadValue = Read1302(DS1302_WEEK);

Time->Week = ((ReadValue&0x70)>>4)10 + (ReadValue&0x0F);

ReadValue = Read1302(DS1302_MONTH);

Time->Month = ((ReadValue&0x70)>>4)10 + (ReadValue&0x0F);

ReadValue = Read1302(DS1302_YEAR);

Time->Year = ((ReadValue&0x70)>>4)10 + (ReadValue&0x0F);

}

unsigned char DataToBCD(SYSTEMTIME Time)

{

unsigned char D[8];

D[0]=Time->Second/10<<4+Time->Second%10;

D[1]=Time->Minute/10<<4+Time->Minute%10;

D[2]=Time->Hour/10<<4+Time->Hour%10;

D[3]=Time->Day/10<<4+Time->Day%10;

D[4]=Time->Month/10<<4+Time->Month%10;

D[5]=Time->Week/10<<4+Time->Week%10;

D[6]=Time->Year/10<<4+Time->Year%10;

return D;

}

void DateToStr(SYSTEMTIME Time)

{

//将十进制数转换为液晶显示的ASCII值

Time->DateString[0] = Time->Year/10 + '0';

Time->DateString[1] = Time->Year%10 + '0';

Time->DateString[2] = '-';

Time->DateString[3] = Time->Month/10 + '0';

Time->DateString[4] = Time->Month%10 + '0';

Time->DateString[5] = '-';

Time->DateString[6] = Time->Day/10 + '0';

Time->DateString[7] = Time->Day%10 + '0';

Time->DateString[8] = '\0';

}

void TimeToStr(SYSTEMTIME Time)

{

//将十进制数转换为液晶显示的ASCII值

Time->TimeString[0] = Time->Hour/10 + '0';

Time->TimeString[1] = Time->Hour%10 + '0';

Time->TimeString[2] = ':';

Time->TimeString[3] = Time->Minute/10 + '0';

Time->TimeString[4] = Time->Minute%10 + '0';

Time->TimeString[5] = ':';

Time->TimeString[6] = Time->Second/10 + '0';

Time->TimeString[7] = Time->Second%10 + '0';

Time->DateString[8] = '\0';

}

void Initial_DS1302(void)

{

unsigned char Second;

Second=Read1302(DS1302_SECOND);

if(Second&0x80) //初始化时间

DS1302_SetTime(DS1302_SECOND,0);

}

void DS1302_TimeStop(bit flag) // 是否将时钟停止

{

unsigned char Data;

Data=Read1302(DS1302_SECOND);

DS1302_SetProtect(0);

if(flag)

Write1302(DS1302_SECOND, Data|0x80);

else

Write1302(DS1302_SECOND, Data&0x7F);

}

#endif

#include <reg51h>

#define uchar unsigned char //定义unsigned int为uint

#define uint unsigned int //定义unsigned uchar为uchar

sbit LCD_RS = P2^0 ;

sbit LCD_RW = P2^1 ;

sbit LCD_EN = P2^2 ;

sbit D_SDA = P2^6; //定义74HC164数据线为P26端口

sbit D_SCL = P2^7; //定义74HC164数据线为P27端口

sbit CLK = P1^3; /实时时钟时钟线引脚 /

sbit IO = P1^4; /实时时钟数据线引脚 /

sbit RST = P1^5; /实时时钟复位线引脚 /

sbit ACC0 = ACC^0;

sbit ACC7 = ACC^7;

uchar time[8] = {0x50,0x30,0x19,0x30,0x12,0x06,0x06};

//========= 延时函数 ============

//延时时间以1ms为单位

//s决定延时时间长短

void delay_ms(uint s)

{

uint x;

for(s;s>0;s--)

{

x = 200;

while(x--);

}

}

//========= 送出一个字节给74HC164(实现串并转换) ==========

void send_out(unsigned char out)//传送一个字节8位

{

uchar i;

D_SCL = 0;

for (i=8;i>=1;i--)

{

D_SDA = out&0x80; //送数据到数据口

D_SCL = 1; //时钟线置1

D_SCL = 0; //送一时钟

out<<=1; //左移

}

}

//========= 写命令函数 ==========

void lcd_wcmd(uchar cmd)

{

LCD_RS = 0;

LCD_RW = 0;

LCD_EN = 0;

send_out(cmd);

LCD_EN = 1;

LCD_EN = 0 ;

}

//========= 写数据函数 ==========

void lcd_wdat(uchar dat)

{

LCD_RS = 1;

LCD_RW = 0;

LCD_EN = 0;

send_out(dat);

LCD_EN = 1;

LCD_EN = 0;

}

//========= LCD初始化函数 ==========

void lcd_init()

{

lcd_wcmd(0x38);

delay_ms(1);

lcd_wcmd(0x0c); //显示开,关光标

delay_ms(1);

lcd_wcmd(0x06); //向右移动光标

delay_ms(1);

lcd_wcmd(0x01); //清除LCD显示屏

delay_ms(1);

}

//========== 往DS1302写入1Byte数据 (内部函数) =============

void w_byte(uchar dat)

{

uchar i;

for(i=8; i>0; i--)

{

IO = dat & 0x01;

CLK = 1;

CLK = 0;

dat = dat >> 1;

}

}

//======== 从DS1302读取1Byte数据 (内部函数) ===================

uchar r_byte(void)

{

uchar i;

for(i=8; i>0; i--)

{

ACC = ACC >> 1;

ACC7 = IO;

CLK = 1;

CLK = 0;

}

return(ACC);

}

//========== 指定地址往DS1302写入1Byte数据 (内部函数) =============

void write_byte(uchar addr, uchar dat)

{

RST = 0;

CLK = 0;

RST = 1;

w_byte(addr);

w_byte(dat);

CLK = 1;

RST = 0;

}

//========== 指定地址往DS1302读1Byte数据 (内部函数) =============

uchar read_byte(uchar addr)

{

uchar ucData;

RST = 0;

CLK = 0;

RST = 1;

w_byte(addr);

ucData = r_byte();

CLK = 1;

RST = 0;

return(ucData);

}

//============ 设置ds1302日期和时间 =============

void write_ds1302(uchar p)

{

uchar i;

uchar addr = 0x80;

write_byte(0x8e,0x00); // 控制命令,WP=0,写 *** 作

for(i =7; i>0; i--)

{

write_byte(addr,p); // 秒 分 时 日 月 星期 年

p++;

addr +=2;

}

write_byte(0x8e,0x80); // 控制命令,WP=1,写保护

}

//============ 读ds1302当前日期和时间 =============

void read_ds1302(uchar p)

{

uchar i;

uchar addr = 0x81;

for (i=0; i<7; i++)

{

p = read_byte(addr); //格式为: 秒 分 时 日 月 星期 年

addr += 2;

p++;

}

}

//============ 显示函数 ===================

void lcd_disp()

{

uchar addr = 4;

lcd_wcmd(0x80 + addr);

lcd_wdat(((time[2]>>4)&0x0f)+0x30); //显示小时

addr++;

lcd_wcmd(0x80 + addr);

lcd_wdat((time[2]&0x0f)+0x30);

addr++;

lcd_wcmd(0x80 + addr);

lcd_wdat(':'); //显示":"

addr++;

lcd_wcmd(0x80 + addr);

lcd_wdat(((time[1]>>4)&0x0f)+0x30); //显示分

addr++;

lcd_wcmd(0x80 + addr);

lcd_wdat((time[1]&0x0f)+0x30);

addr++;

lcd_wcmd(0x80 + addr);

lcd_wdat(':'); //显示":"

addr++;

lcd_wcmd(0x80 + addr);

lcd_wdat(((time[0]>>4)&0x0f)+0x30); //显示秒

addr++;

lcd_wcmd(0x80 + addr);

lcd_wdat((time[0]&0x0f)+0x30);

addr = 2;

lcd_wcmd(0xc0 + addr); //在第二行显示年月日和星期

lcd_wdat('2'); //显示2

addr++;

lcd_wcmd(0xc0 + addr);

lcd_wdat('0'); //显示0

addr++;

lcd_wdat(((time[6]>>4)&0x0f)+0x30); //年

addr++;

lcd_wcmd(0xc0 + addr);

lcd_wdat((time[6]&0x0f)+0x30);

addr++;

lcd_wcmd(0xc0 + addr);

lcd_wdat(' ');

addr++;

lcd_wcmd(0xc0 + addr);

lcd_wdat(((time[4]>>4)&0x0f)+0x30); //显示月

addr++;

lcd_wcmd(0xc0 + addr);

lcd_wdat((time[4]&0x0f)+0x30);

addr++;

lcd_wcmd(0xc0 + addr);

lcd_wdat(' ');

addr++;

lcd_wcmd(0xc0 + addr);

lcd_wdat(((time[3]>>4)&0x0f)+0x30); //显示日

addr++;

lcd_wcmd(0xc0 + addr);

lcd_wdat((time[3]&0x0f)+0x30);

addr++;

lcd_wcmd(0xc0 + addr);

lcd_wdat(' ');

addr++;

lcd_wcmd(0xc0 + addr);

lcd_wdat((time[5]&0x0f)+0x30); //显示星期

}

//=========== 主函数 ===============

void main()

{

lcd_init(); // 初始化LCD

write_ds1302(time);

while(1)

{

read_ds1302(time); //读DS1302数据

lcd_disp(); //LCD显示

delay_ms(500); //延时05秒

}

}

这是一个电子时钟,在LCD1602上显示,时钟芯片是DS1302

以上就是关于关于单片机液晶屏LCD12864的程序全部的内容,包括:关于单片机液晶屏LCD12864的程序、(急!!!)用DS1302与1602LCD设计的可调式电子日历与时钟 我要C程序啊。、基于msp430f149+ds1302+lcd1602的可调数字钟(带闹铃)的C语言程序,我现在程序已经写好了等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/10167269.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-05
下一篇 2023-05-05

发表评论

登录后才能评论

评论列表(0条)

保存