⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcd_ds1302_1110_21.c

📁 大家用单片机控制19264读DS1302吗?这样自己就可以很简单做一个万年历了哦···很有用
💻 C
📖 第 1 页 / 共 2 页
字号:
#include<reg52.h>
#include<math.h>
#include<INTRINS.H>
#define uchar unsigned char


/***********液晶显示器接口引脚定义***************/
sbit CS1LCM= P2^2; //
sbit CS2LCM= P2^3; //
sbit CS3LCM= P2^4; /*这个连接只是做实验的临时接法。*/
sbit Dilcm = P2^5; //
sbit Rwlcm = P2^6; //
sbit Elcm  = P2^7; //
sfr Datalcm= 0x80; //数据口

/*********************************************************************/
/* 实时时钟模块 时钟芯片型号:DS1302 */
/*/
/*********************************************************************/
sbit T_CLK = P3^7; /*实时时钟时钟线引脚 */
sbit T_IO  = P2^0; /*实时时钟数据线引脚 */
sbit T_RST = P2^1; /*实时时钟复位线引脚 */

/***********常用操作命令和参数定义***************/
#define DISPON 0x3f /*显示on */
#define DISPOFF 0x3e /*显示off */
#define DISPFIRST 0xc0 /*显示起始行定义 */
#define SETX 0x40 /*X定位设定指令(页) */
#define SETY 0xb8 /*Y定位设定指令(列) */
#define Lcdbusy 0x80 /*LCM忙判断位 */

/**************显示分区边界位置*****************/
#define MODL 0x00 /*左区 */
#define MODM 0x40 /*左区和中区分界 */
#define MODR 0x80 /*中区和右区分界 */
#define LCMLIMIT 0xC0 /*显示区的右边界 */

/****************全局变量定义*******************/
uchar col,row,cbyte; /*列x,行(页)y,输出数据 */
//bit xy; /*画线方向标志:1水平 */

/*****************函数列表**********************/
//lcd19264函数说明
void Lcminit(void); /*液晶模块初始化 */
void Delay(uchar); /*延时,入口数为Ms */
void lcdbusyL(void); /*busy判断、等待(左区) */
void lcdbusyM(void); /*busy判断、等待(中区) */
void lcdbusyR(void); /*busy判断、等待(右区) */
void Putedot(uchar); /*半角字符输出 */
void Putcdot(uchar); /*全角(汉字)输出 */
void Wrdata(uchar); /*数据输出给LCM */
void Lcmcls( void ); /*LCM全屏幕清零(填充0) */
void wtcom(void); /*公用busy等待 */
void Locatexy(void); /*光标定位 */
void WrcmdL(uchar); /*左区命令输出 */
void WrcmdM(uchar); /*中区命令输出 */
void WrcmdR(uchar); /*右区命令输出 */
void Putstr(uchar *puts,uchar i); /*中英文字符串输出 */
void Rddata(void); /* 从液晶片上读数据 */

/******************数组列表*********************/
uchar code Ezk[]; /*ASCII常规字符点阵码表 */
uchar code Hzk[]; /*自用汉字点阵码表 */
uchar code STR1[]; /*自定义字符串 */
uchar code STR2[]; //
uchar code STR3[]; //
uchar code STR4[]; //


/******************************************************************** 
*
* 名称: v_RTInputByte
* 说明: 
* 功能: 往DS1302写入1Byte数据
* 调用:
* 输入: ucDa 写入的数据 
* 返回值: 无
***********************************************************************/
void v_RTInputByte (uchar ucDa)
{ 
	uchar i;
	ACC = ucDa;
	for(i=8; i>0; i--)
	{
		T_IO = ACC_0; /*相当于汇编中的 RRC */
		T_CLK = 1;
		T_CLK = 0;
		ACC = ACC >> 1; 
	} 
}
/******************************************************************** 
*
* 名称: uchar uc_RTOutputByte
* 说明: 
* 功能: 从DS1302读取1Byte数据
* 调用: 
* 输入: 
* 返回值: ACC
***********************************************************************/
uchar uc_RTOutputByte(void) 
{ 
	uchar i;
	for(i=8; i>0; i--)
	{
		ACC = ACC >>1; /*相当于汇编中的 RRC */
		ACC_7 = T_IO;
		T_CLK = 1;
		T_CLK = 0;
	} 
	return(ACC); 
}
/******************************************************************** 
*
* 名称: v_W1302
* 说明: 先写地址,后写命令/数据
* 功能: 往DS1302写入数据
* 调用: v_RTInputByte() 
* 输入: ucAddr: DS1302地址, ucDa: 要写的数据
* 返回值: 无
***********************************************************************/
void v_W1302(uchar ucAddr, uchar ucDa)
{
	T_RST = 0;
	T_CLK = 0;
	T_RST = 1;
	v_RTInputByte(ucAddr); /* 地址,命令 */
	v_RTInputByte(ucDa); /* 写1Byte数据*/
	T_CLK = 1;
	T_RST =0;
} 
/******************************************************************** 
*
* 名称: uc_R1302
* 说明: 先写地址,后读命令/数据
* 功能: 读取DS1302某地址的数据
* 调用: v_RTInputByte() , uc_RTOutputByte()
* 输入: ucAddr: DS1302地址
* 返回值: ucDa :读取的数据
***********************************************************************/
uchar uc_R1302(uchar ucAddr)
{
	uchar ucDa;
	T_RST = 0;
	T_CLK = 0;
	T_RST = 1;
	v_RTInputByte(ucAddr); /* 地址,命令 */
	ucDa = uc_RTOutputByte(); /* 读1Byte数据 */
	T_CLK = 1;
	T_RST =0;
	return(ucDa);
}
/******************************************************************** 
*
* 名称: v_Set1302
* 说明: 
* 功能: 设置初始时间
* 调用: v_W1302() 
* 输入: pSecDa: 初始时间地址。初始时间格式为: 秒 分 时 日 月 星期 年 
* 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B
* 返回值: 无
***********************************************************************/
void v_Set1302(uchar *pSecDa) 
{
	uchar i;
	uchar ucAddr = 0x80; 
	v_W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/
	for(i =7;i>0;i--)
	{ 
		v_W1302(ucAddr,*pSecDa); /* 秒 分 时 日 月 星期 年 */
		pSecDa++;
		ucAddr +=2;
	}
	v_W1302(0x8e,0x80); /* 控制命令,WP=1,写保护?*/
}
/******************************************************************** 
*
* 名称: v_Get1302
* 说明: 
* 功能: 读取DS1302当前时间
* 调用: uc_R1302() 
* 输入: ucCurtime: 保存当前时间地址。当前时间格式为: 秒 分 时 日 月 星期 年 
* 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B
* 返回值: 无
***********************************************************************/
void v_Get1302(uchar ucCurtime[]) 
{
	uchar i;
	uchar ucAddr = 0x81;
	for (i=0;i<7;i++)
	{
		ucCurtime[i] = uc_R1302(ucAddr);/*格式为: 秒 分 时 日 月 星期 年 */
		ucAddr += 2;
	}
} 


/****************************************/
/* 一个字串的输出 */
/****************************************/
void Putstr(uchar *puts,uchar i)
{
	uchar j,X;
	for (j=0;j<i;j++)
	{
		X = puts[j];
		if (X&0x80)
	{
		Putcdot(X&0x7f); /*只保留低7位*/
	}
		else Putedot(X-0x20); /*ascii码表从0x20开始*/
	}
}

/****************************************/
/* 半角字符点阵码数据输出 */
/****************************************/
void Putedot(uchar Order)
{
uchar i,bakerx,bakery; /*共定义4个局部变量 */
int x; /*偏移量,字符量少的可以定义为UCHAR */
bakerx = col; /*暂存x,y坐标,已备下半个字符使用 */
bakery = row;
x=Order * 0x10; /*半角字符,每个字符16字节 */
/*上半个字符输出,8列 */
for(i=0;i<8;i++)
{
cbyte = Ezk[x]; /*取点阵码,rom数组 */
Wrdata(cbyte); /*写输出一字节 */
x++;
col++;
if (col==LCMLIMIT){col=0;row++;row++;}; /*下一列,如果列越界换行*/
if (row>7) row=0; /*如果行越界,返回首行 */
} /*上半个字符输出结束 */

col = bakerx; /*列对齐 */
row = bakery+1; /*指向下半个字符行 */
/*下半个字符输出,8列 */
for(i=0;i<8;i++)
{
cbyte = Ezk[x]; /*取点阵码 */
Wrdata(cbyte); /*写输出一字节 */
x++;
col++;
if (col==LCMLIMIT){col=0;row=row+2;}; /*下一列,如果列越界换行*/
if (row>7) row=1; /*如果行越界,返回首行 */
} /*下半个字符输出结束 */
row=bakery;
} /*整个字符输出结束 */


/****************************************/
/* 全角字符点阵码数据输出 */
/****************************************/
void Putcdot(uchar Order)
{
uchar i,bakerx,bakery; /*共定义3个局部变量 */
int x; /*偏移量,字符量少的可以定义为UCHAR */
bakerx = col; /*暂存x,y坐标,已备下半个字符使用 */
bakery = row;
x=Order * 0x20; /*每个字符32字节 */

/*上半个字符输出,16列 */
for(i=0;i<16;i++)
{
Wrdata(Hzk[x]); /*写输出一字节 */
x++;
col++;
if (col==LCMLIMIT){ col=0;row++;row++;} /*下一列,如果列越界换行*/
if (row>6) row=0; /*如果行越界,返回首行 */
} /*上半个字符输出结束 */

/*下半个字符输出,16列 */
col = bakerx;
row = bakery+1;
for(i=0;i<16;i++) /*下半部分*/
{
Wrdata(Hzk[x]);
x++;
col++;
if (col==LCMLIMIT){col=0;row++;row++;} /*下一列,如果列越界换行*/
if (row>7) row=1; /*如果行越界,返回首行 */
} /*下半个字符输出结束 */
row = bakery;
} /*整个字符输出结束 */

/****************************************/
/* 清屏,全屏幕清零 */
/****************************************/
void Lcmcls( void )
{
for(row=0;row<8;row++)
for(col=0;col<LCMLIMIT;col++) Wrdata(0);
}

/****************************************/
/* 从液晶片上读数据,保留在全局变量中 */
/****************************************/
void Rddata(void)
{
Locatexy(); /*坐标定位,返回时保留分区状态不变 */
Datalcm=0xFF;
Dilcm = 1; /*数据*/
Rwlcm = 1; /*读数据*/
Elcm = 1; /*读入到LCM*/
_nop_();
cbyte = Datalcm; /*虚读一次 */
Elcm = 0;
Locatexy(); /*坐标定位,返回时保留分区状态不变 */
Datalcm=0xFF;
_nop_();
Dilcm = 1; /*数据*/
Rwlcm = 1; /*读数据*/
Elcm = 1; /*读入到LCM*/
_nop_();
cbyte = Datalcm; /*从数据口读数据,真读 */
Elcm = 0;
}

/****************************************/
/* 数据写输出 */
/****************************************/
void Wrdata(uchar X)
{
Locatexy(); /*坐标定位,返回时保留分区状态不变 */
// wtcom();
Dilcm = 1; /*数据输出*/
Rwlcm = 0; /*写输出 */
Datalcm = X; /*数据输出到数据口 */
Elcm = 1; /*读入到LCM*/
_nop_();
Elcm = 0;
}

/****************************************/
/********************************/
/* 命令输出到左区控制口 */
/********************************/
void WrcmdL(uchar X)
{
lcdbusyL(); /*确定分区,返回时保留分区状态不变*/
Dilcm = 0; /*命令操作 */
Rwlcm = 0; /*写输出 */
Datalcm = X; /*数据输出到数据口 */
Elcm = 1;_nop_();Elcm = 0; /*读入到LCM*/
}

/********************************/
/* 命令输出到中区控制口 */
/********************************/
void WrcmdM(uchar X)
{
lcdbusyM(); /*确定分区,返回时保留分区状态不变*/
Dilcm = 0; /*命令操作 */
Rwlcm = 0; /*写输出 */
Datalcm = X; /*命令输出到数据口 */
Elcm = 1;_nop_();Elcm = 0; /*读入到LCM*/
}

/********************************/
/* 命令输出到右区控制口 */
/********************************/
void WrcmdR(uchar X)
{
lcdbusyR(); /*确定分区,返回时保留分区状态不变 */
Dilcm = 0; /*命令操作 */
Rwlcm = 0; /*写输出 */
Datalcm = X; /*命令输出到数据口 */
Elcm = 1;_nop_();Elcm = 0; /*读入到LCM*/
}

/********************************************************/
/* 分区操作允许等待,返回时保留分区选择状态 */
/********************************************************/
void lcdbusyL(void)
{
CS1LCM = 0; /*CLR CS1 */
CS2LCM = 1; /*SETB CS2 */
CS3LCM = 1; /*SETB CS3 */
wtcom(); /* waitting for enable */
}
void lcdbusyM(void)
{
CS1LCM = 1; /*SETB CS1 */
CS2LCM = 0; /*CLR CS2 */
CS3LCM = 1; /*SETB CS3 */
wtcom(); /* waitting for enable */
}
void lcdbusyR(void)
{
CS1LCM = 1; /*SETB CS1 */
CS2LCM = 1; /*SETB CS2 */
CS3LCM = 0; /*CLR CS3 */
wtcom(); /* waitting for enable */
}
void wtcom(void)
{
Dilcm = 0; /*CLR DI */
Rwlcm = 1; /*SETB RW */
Datalcm = 0xFF; /*MOV DATA_LCM,#0FFH */
Elcm = 1;_nop_(); 
while(Datalcm & Lcdbusy);
Elcm = 0;
}

/********************************************************/
/*根据设定的坐标数据,定位LCM上的下一个操作单元位置 */
/********************************************************/
void Locatexy(void)
{
unsigned char x,y;
switch (col&0xc0) /* col.and.0xC0 */
{ /*条件分支执行 */
case 0: {lcdbusyL();break;} /*左区 */
case 0x40: {lcdbusyM();break;} /*中区 */
case 0x80: {lcdbusyR();break;} /*右区 */
}
x = col&0x3F|SETX; /* col.and.0x3f.or.setx */
y = row&0x07|SETY; /* row.and.0x07.or.sety */
wtcom(); /* waitting for enable */
Dilcm = 0; /*CLR DI */
Rwlcm = 0; /*CLR RW */
Datalcm = y; /*MOV P0,Y */
Elcm = 1;_nop_();Elcm = 0;
wtcom(); /* waitting for enable */
Dilcm = 0; /*CLR DI */
Rwlcm = 0; /*CLR RW */
Datalcm = x; /*MOV P0,X */
Elcm = 1;_nop_();Elcm = 0;
}

/********************************/
/*液晶屏初始化 */
/********************************/

void Lcminit(void)
{
cbyte = DISPOFF; /*关闭显示屏 */
WrcmdL(cbyte);
WrcmdM(cbyte);
WrcmdR(cbyte);
cbyte = DISPON; /*打开显示屏 */
WrcmdL(cbyte);
WrcmdM(cbyte);
WrcmdR(cbyte);
cbyte = DISPFIRST; /*定义显示起始行为零 */
WrcmdL(cbyte);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -