📄 lcd_1602.c
字号:
/* DS12C887时钟C语言编程 作者:赖楚君 时间:从2009-5-12至2009-
程序流程说明
一、LCD_1602驱动程序
1、1ms延时函数
2、读LCD函数
3、检测忙碌标志位函数
4、写LCD函数
5、字符显示定位函数
6、输出并显示字符函数
7、初始化LCD函数
二、DS12C887驱动程序
1、地址替换函数
2、读DS12C887函数
3、写DS12C887函数
4、初始化DS12C887函数
*/
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
/* 一、LCD_1602驱动程序
端口引脚定义 */
sfr LCD1602_DATA_PORT = 0x80;//P0口
sbit RS = P2^5;//命令/数据选择端(H/L)
sbit RW = P2^6;//读/写选择端(H/L)
sbit EN = P2^7;//下降沿触发
/*1ms延时函数*/
void Delay_ms(uint i)
{
uint j;
for(;i>0;i--)
for(j=125;j>0;j++);
}
/*读LCD函数*/
uchar Read_LCD(bit Style)
{
uchar Port;
RS = Style;
RW = 1;//读时高电平有效
EN = 1;
Port = LCD1602_DATA_PORT;
EN = 0;
RS = ~Style;
RW = 0;
return Port;
}
/*检测忙碌标志位函数*/
void Check_BusyFlag()
{
uint Retry;
for(Retry=1000;Retry>0;Retry--)
{
if(Read_LCD(0)&0x80==0) break;//BusyFlag=0表示不忙碌
}
}
/*写LCD函数*/
#define LCD_Command 0 //写指令宏定义
#define LCD_Data 1 //写数据宏定义
void Write_LCD(bit Style,uchar Data )
{
Check_BusyFlag();//写LCD前要先检测忙碌标志位,而读LCD前不用检测该位
RS = Style;
RW = 0;//写时低电平有效
EN = 1;
LCD1602_DATA_PORT = Data;
EN = 0;
RS = ~Style;
RW = 1;
}
/*字符显示定位函数*/
void Goto_XY(uchar X,uchar Y)
{
if(Y==0) Write_LCD(LCD_Command,0x80|X);//第一行显示
if(Y==1) Write_LCD(LCD_Command,0xC0|X);//第二行显示
}
/*输出并显示字符函数*/
void Output_String(uchar *Str)
{
while(*Str!='\0')//不为空字符串时输出
{
Write_LCD(LCD_Data,*Str);
Str++;
//Delay_ms(1);//加延时可以实现打字效果
}
}
/*初始化LCD函数*/
void Init_LCD()
{
Write_LCD(LCD_Command,0x38);//写指令0x38h(16x2显示,5x7点阵,8位数据接口)
Write_LCD(LCD_Command,0x38);
Write_LCD(LCD_Command,0x08);//关闭显示
Write_LCD(LCD_Command,0x01);//清屏
Write_LCD(LCD_Command,0x0C);//开启显示且显示光标
}
/* 二、DS12C887驱动程序
端口引脚定义(因特尔模式)
sfr DS12C887_DATA_PORT = 0x90;//P1口
sbit ALE = P2^4;//AS Pin
sbit RD_ = P2^3;//DS Pin
sbit WR_ = P2^2;//R/W pin
sbit CS = P2^1;//CS Pin
地址替换函数
因为DS12C887的基地址为7F00H
uint Replay_Address(uchar Address)
{
uint Replay;
Replay = 0x7F00 + Address;
return Replay;
}
读DS12C887函数
uchar Read_DS12C887(uint Address)
{
uchar Port;
ALE = 1;
RD_ = 1;
WR_ = 1;
CS = 0;
DS12C887_DATA_PORT = Address;//读取地址
ALE = 0;
RD_ = 0;
Port = DS12C887_DATA_PORT;//读取数据
RD_ = 1;
CS = 1;
ALE = 1;
return Port;
}
写DS12C887函数
void Write_DS12C887(uint Address,uchar Data)
{
ALE = 1;
RD_ = 1;
WR_ = 1;
CS = 0;
DS12C887_DATA_PORT = Address;
ALE = 0;
WR_ = 0;
DS12C887_DATA_PORT = Data;
WR_ = 1;
CS = 1;
ALE = 1;
}
初始化DS12C887函数
void Init_DS12C887()
{
Write_DS12C887(Replay_Address(0x0A),0x20);//对寄存器A进行设置:打开振荡器并使RTC计时;SWQ禁止
Write_DS12C887(Replay_Address(0x0B),0x06);//对寄存器B进行设置:时钟、日历格式为二进制;24小时模式
//Write_DS12C887(Replay_Address(0x0C),0x06);//对寄存器C进行设置:
if(Read_DS12C887(Replay_Address(0x0D)) == 0)//读寄存器D-bit7,如为0则DS12C887内部锂电池电能耗尽,并在LCD_1602显示"Warning:Battery Few"
{
Init_LCD();
Goto_XY(4,0);
Output_String("Warning:");
Goto_XY(2,1);
Output_String("Battery Few");
while(1);
}
}
时间处理函数
DS12C887时间地址宏定义
#define Second 0x00//秒
#define Second_Alarm 0x01//秒闹钟
#define Minute 0x02//分
#define Minute_Alarm 0x03//分闹钟
#define Hour 0x04//时
#define Hour_Alarm 0x05//时闹钟
#define Week 0x06//星期
#define Data 0x07//日
#define Month 0x08//月
#define Year 0x09//年
#define Century 0x32//世纪
void Time_Process()*/
/*DS12C887+LCD_1602时钟主函数*/
void main()
{
Init_LCD();
Goto_XY(0,0);
Output_String("2009-05-14");
Goto_XY(0,1);
Output_String("09:05:20");
while(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -