当前位置:首页 > 单片机 > 单片机
[导读]//DS1302时钟程序//液晶用的ST7920控制芯片的12864#include #include /********************************************************************/#define LCD12864_IOP0#defineCLERADISPLAYLCD12864_command(0x01);#d

//DS1302时钟程序
//液晶用的ST7920控制芯片的12864
#include
#include
/********************************************************************/
#define LCD12864_IOP0
#defineCLERADISPLAYLCD12864_command(0x01);
#define uchar unsigned char
#define uint unsigned int
/********************************************************************/
sbit LCD12864_EN=P2^7; //E
sbit LCD12864_DIN=P2^5; // RS
sbit LCD12864_CLK=P2^6; //RW
sbit DS1302_CLK =P2^0;// P1^0;
sbit DS1302_IO =P2^1;// P1^1;
sbit DS1302_RST =P2^2;// P1^2;
unsigned char time[]={0x10,0x01,0x27,0x03,0x14,0x00,0x00};// 初始化时间年月日星期时分秒
uchar Display_Buffer[]="12-22-00";//时、分、秒 的格式
uchar riqi[]="11-03-28";//年、月、日 的格式
uchar xingqi[]="week-3";//星期
unsigned char second,minute,hour,week,day,month,year;
/********************************************************************/
void LCD12864_busy(void);
void LCD12864_command(unsigned char command);
void LCD12864_data(unsigned char dat);
void LCD12864_address(unsigned char row,unsigned char line);
void LCD12864_string(unsigned char row,unsigned char line,unsigned char *s);
void LCD12864_picture(unsigned char *gImage);
void LCD12864_init(void);
void LCD12864_char (unsigned char row,unsigned char line,unsigned char a);
/********************************************************************/

//
void delayms(uint k)
{
uint data i,j;
for(i=0;i {
for(j=0;j<121;j++)
{;}
}
}
void delayus(uchar x)
{
while(--x);
}


void Mcu_init(void)
{

LCD12864_init();


CLERADISPLAY
CLERADISPLAY
LCD12864_init();
}



void Delay(void)
{
unsigned char i;
unsigned int j;
for(i=0;i<200;i++)
for(j=1000;j>0;j--);
}

/*****************************************************************************
函数功能:向DS1302送一字节数据子程序
入口参数:
出口参数:
*****************************************************************************/
void InputByte(unsigned char BYTE)
{
char i;
for(i=8;i>0;i--)
{ //前面在read_ds1302()函数里已经把CLK清0了
DS1302_CLK=0;//这里再清0一次,看着清楚。呵呵
DS1302_IO=(bit)(BYTE&0x01);//取出低位数据给数据引脚
DS1302_CLK=1;//置1,时钟上升沿,引脚上的数据传入1302寄存器中
BYTE>>=1;//因为这里移位的BYTE不是最后要的结果,虽然最后循环完会多移一位,但没影响。
//循环最后一次后,时钟状态是高电平。
}
}


/*****************************************************************************
函数功能:读DS1302一个字节子程序,读数据是下降沿读
入口参数:
出口参数:
*****************************************************************************/
unsigned char OutputByte(void)
{
unsigned char i;
unsigned char ucdat=0;
for(i=8;i>0;i--)
{ //前面时钟状态是高电平。
ucdat>>=1; //移位注意,移位不能放在循环语句末,否则最后循环完会多移一位。得到结果就错了。
DS1302_IO=1;//单片机端置高防止破坏1302传来的数据,开始接收1302端的高低数据对数据线的改变。
DS1302_CLK=0;//紧接着时钟变低,下降沿数据输出。
if(DS1302_IO)//数据已经输出,判断是1还是0.
ucdat|=0x80;//如果引脚是高则此位保存1。低不保存,右移的时候自然补0了。
DS1302_CLK=1;//读完一位数据,再置高时钟,准备读下一个。
_nop_();//延时一下。

}
//读完数据还是把时钟清0,下次好直接用。
DS1302_CLK=0;//读完数据还是把时钟清0,下次好直接用。
DS1302_RST=0;
_nop_();
DS1302_CLK=0;
DS1302_RST=0;
return(ucdat);


}


/*****************************************************************************
函数功能:向DS1302某地址写一字节数据子程序
入口参数:addr,TDat
出口参数:
*****************************************************************************/
void write_ds1302(unsigned char addr,unsigned char TDat)
{
DS1302_RST=0;
_nop_();
DS1302_CLK=0;
_nop_();
DS1302_RST=1;
_nop_();
InputByte(addr);//先写地址
InputByte(TDat);//再写数据
DS1302_IO=1;//单片机端置高防止破坏1302传来的数据,开始接收1302端的高低数据对数据线的改变。
DS1302_RST=0;
_nop_();
DS1302_CLK=0;
}


/*****************************************************************************
函数功能:读DS1302地址子程序
入口参数:add
出口参数:timedata
*****************************************************************************/
unsigned char read_ds1302(unsigned char addr)
{
unsigned char timedata;
DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;
InputByte(addr);//先写入读命令
timedata=OutputByte();//再读出数据
DS1302_IO=1;//单片机端置高防止破坏1302传来的数据,开始接收1302端的高低数据对数据线的改变。
DS1302_RST=0;
_nop_();
DS1302_CLK=0;
return(timedata);
}


/*****************************************************************************
函数功能:初始化DS1302子程序
入口参数:time[](全局变量)
出口参数:
*****************************************************************************/
void initial_ds1302()
{
DS1302_IO=1;//单片机端置高防止破坏1302传来的数据,开始接收1302端的高低数据对数据线的改变。
DS1302_RST=0;
DS1302_CLK=0;
write_ds1302(0x8e,0x00); //写保护寄存器,在对时钟或RAM写前WP一定要为0
write_ds1302(0x8c,time[0]); //年
write_ds1302(0x88,time[1]); //月
write_ds1302(0x86,time[2]); //日
write_ds1302(0x8A,time[3]); //星期
write_ds1302(0x84,time[4]); //时
write_ds1302(0x82,time[5]); //分
write_ds1302(0x80,time[6]); //秒
write_ds1302(0x8e,0x80); //写保护寄存器
}



/*****************************************************************************
函数功能:读DS1302时间子程序
入口参数:
出口参数:全局变量(second,minute,hour,week,day,month,year)
*****************************************************************************/
void read_time()
{
second=read_ds1302(0x81); //秒寄存器
minute=read_ds1302(0x83); //读分
hour=read_ds1302(0x85); //读时
//week=read_ds1302(0x8B); //读星期
//day=read_ds1302(0x87); //日
//month=read_ds1302(0x89); //月
//year=read_ds1302(0x8d); //年
}


void main(void)
{
Mcu_init();
DS1302_RST=0;
DS1302_IO=1;
delayms(1000);
DS1302_CLK=0;
delayms(1000);
initial_ds1302(); //初始化DS1302


Delay();Delay();
CLERADISPLAY
LCD12864_string(1,1,"日期");
LCD12864_string(2,1,"星期");
LCD12864_string(3,1,"时间");
while(1)
{


read_time();//读取时间
Display_Buffer[0]=hour/16+'0';//存储下时的高位进数组
Display_Buffer[1]=hour%16+'0';//存储下时的低位进数组
Display_Buffer[3]=minute/16+'0';//注意+'0'后存储的是ASCII。用于下面液晶显示。
Display_Buffer[4]=minute%16+'0';//注意+'0'后存储的是ASCII。用于下面液晶显示。
Display_Buffer[6]=second/16+'0';
Display_Buffer[7]=second%16+'0';
// riqi[0]=year/16+'0';
// riqi[1]=year%16+'0';
// riqi[3]=month/16+'0';
// riqi[4]=month%16+'0';
// riqi[6]=day/16+'0';
// riqi[7]=day%16+'0';
// xingqi[1]=week%16+'0';


//LCD12864_string(1,3,riqi);//液晶的第1行从第3位开始显示日期
//LCD12864_string(2,3,xingqi);//液晶的第2行从第3位开始显示星期
LCD12864_string(3,3,Display_Buffer);//液晶的第3行从第3列开始显示时间
}
}


/*******************************************************************/
void LCD12864_busy(void)
{
bit BF = 0;
LCD12864_EN=0;
LCD12864_DIN=0;
LCD12864_CLK=1;
LCD12864_IO=0xff;//单片机读数据之前必须先置高位
do
{
LCD12864_EN=1;
BF=LCD12864_IO&0x80;
LCD12864_EN=0;
} while(BF);

}
/*******************************************************************/
// 写入命令
/*******************************************************************/
void LCD12864_command(unsigned char command)
{
LCD12864_busy();
LCD12864_EN=0;
LCD12864_DIN=0;
LCD12864_CLK=0;
LCD12864_IO=0xff;
LCD12864_EN=1;
LCD12864_IO=command;
LCD12864_EN=0;
}
/*******************************************************************/
// 写入一字节数据
/*******************************************************************/
void LCD12864_data(unsigned char dat)
{

LCD12864_busy();
LCD12864_EN=0;
LCD12864_DIN=1;
LCD12864_CLK=0;
LCD12864_IO=0xff;
LCD12864_EN=1;
LCD12864_IO=dat;
LCD12864_EN=0;
}



/*******************************************************************/
// 设置显示位置 X(1~8),Y(1~4)
/*******************************************************************/
void LCD12864_address(unsigned char row,unsigned char line)
{
switch(row)
{
case 1:LCD12864_command(0x7f + line);
break;
case 2:LCD12864_command(0x8f + line);
break;
case 3:LCD12864_command(0x87 + line);
break;
case 4:LCD12864_command(0x97 + line);
default:
break;
}
}


/*****************显示 一个 字符 **************/


void LCD12864_char (unsigned char row,unsigned char line,unsigned char a)
{

LCD12864_address(row,line);
LCD12864_data(a);
}


/*******************************************************************/
// 在指定位置显示字符串
/*******************************************************************/
void LCD12864_string(unsigned char row,unsigned char line,unsigned char *s)
{
unsigned char LCD12864_temp;
LCD12864_address(row,line);
LCD12864_temp=*s;
while(LCD12864_temp != 0x00)
{
LCD12864_data(LCD12864_temp);
LCD12864_temp=*(++s);
}
}


/*******************************************************************/
// 绘制一幅图片
/*******************************************************************/
void LCD12864_picture(unsigned char *gImage)
{
unsigned char X = 0x80,Y = 0x80;
unsigned char i,j;
for(i=0;i<64;i++)
{
for(j=0;j<16;j++)
{
LCD12864_command(0x34);
LCD12864_command(Y);
LCD12864_command(X);
LCD12864_data(*(gImage+i*16+j)); // low 8 bits
LCD12864_data(*(gImage+i*16+j+1)); // high 8 bits
LCD12864_command(0x36);
X++;
j++;
}
Y++;
if(Y>0x9f)
Y=0x80;
X=0x80+((i+1)/32)*8;
}
LCD12864_command(0x30);

}
/*******************************************************************/
// 初始化设置
/*******************************************************************/
void LCD12864_init(void)
{
CLERADISPLAY // clear DDRAM
LCD12864_command(0x30); // 8 bits unsigned interface,basic instrument
LCD12864_command(0x02); // cursor return
LCD12864_command(0x0c); // display,cursor on
LCD12864_command(0x03);
LCD12864_command(0x06);
CLERADISPLAY // clear DDRAM
}


本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

51单片机学习笔记———13.1DS1302实时时钟原理部分

关键字: ds1302 时钟

由于昨天照着手册写了一下DS1302的驱动程序,发现耗时挺多的,并且在考场上不可能一步步去自己写驱动,所以今天看了一下蓝桥杯提供的DS1302官方驱动程序,发现直接引用还是不行的,程序当中有些小问题需要去修改。下面就对那...

关键字: ds1302 时钟

DS1302时钟模块通信原理(SPI总线)

关键字: ds1302 时钟

现在流行的串行时钟电路很多,如DS1302、 DS1307、PCF8485等。这些电路的接口简单、价格低廉、使用方便,被广泛地采用

关键字: ds1307 ds1302

现在流行的串行时钟电路很多,如DS1302、 DS1307、PCF8485等。这些电路的接口简单、价格低廉、使用方便,被广泛地采用。它可以对年、月、日、周、时、分、秒进行计时,且具有闰年补偿等多种功能。

关键字: ds1302 时钟芯片 电路

Ds3231+12864液晶显示AT89C51带温度功能的时钟程序。

关键字: 12864 at89c51 ds3231 时钟程序 液晶显示

DS1302 我们前边也有提起过,是三根线,分别是 CE、I/O 和 SCLK,其中 CE 是使能线,SCLK 是时钟线,I/O 是数据线。前边我们介绍过了 SPI 通信,同学们发现没发现,这个 DS1302 的通信线定...

关键字: ds1302 通信时序

/************************************** PCF8563时钟程序 * * 文 件 名:1602_8563.c * * 版 本:V22.02 * * 主控芯片:Mega16L...

关键字: iccavr iic pcf8563 时钟程序

//引入文件***********************************************************#include "delay.h" #include "...

关键字: ds1302 pic16f84a 读取时钟芯片

参考DS1302数据手册,尽管数据手册是英文,但是很有帮助,再结合网上众多的代码写出了下面这个例子,除了涓流充电(trickle charger)功能没使用外,内部的RAM和寄存器功能都使用到了,包括多字节方式(burs...

关键字: ds1302 演示代码
关闭
关闭