/*该程序只需更改RW,RS E对应的引脚即可正常使用*/

#include <STC89C5xRC.H>

#define LCD1602_RW   P36//定义引脚
#define LCD1602_RS   P35
#define LCD1602_E P34
#define LCM_Data P0
#define Busy 0x80 //用于检测LCM状态字中的Busy标识

void WriteDataLCM    (unsigned char WDLCM);
void WriteCommandLCM (unsigned char WCLCM,BuysC);
void DisplayOneChar  (unsigned char X, unsigned char Y, unsigned char DData);
void DisplayListChar (unsigned char X, unsigned char Y, unsigned char code *DData);
unsigned char ReadDataLCM(void);
unsigned char ReadStatusLCM(void);

void pro_timedate(void);
bit leap_year(); //判断是否为闰年
unsigned char data year=11,month=5,date=22;//年、月、日、星期
unsigned char disbuf[16];
unsigned char data hour=23,min=59,sec=55,sec20=0; //时、分、秒、百分之一秒
unsigned char code email[] = {"YEA:MON:DAT:TIME"};
void updatetime (void);
void LCMInit    (void);
void pro_display(void);
void Delay400Ms (void);
void Delay5Ms   (void);
void main(void)
{
     Delay400Ms(); //启动等待,等LCM讲入工作状态
     LCMInit(); //LCM初始化
     DisplayListChar(0, 1, email);
     TMOD=0X01;
     TH0=0X4C;
     TL0=0X00;
     TR0=1;
     ET0=1;
     EA=1;
     while(1);
}

void pro_timedate()
     {
       sec++;
        if(sec > 59)
               {sec = 0;
                     min++;
                        if(min>59)
                              {min=0;
                                  hour++;
                                    if(hour>23)
                                         {hour=0;
                                             date++;
         if (month==1||month==3||month==5||month==7||month==8||month==10||month==12)
         if (date>31)
                  {date=1;month++;} //大月31 天
         if (month==4||month==6||month==9||month==11)
         if (date>30) 
                  {date=1;month++;} //小月30 天
         if (month==2)
                   {if( leap_year()) //闰年的条件
                   {if (date>29) {date=1;month++;}} //闰年2 月为29 天
                     else
                   {if (date>28) {date=1;month++;}} //平年2 月为28 天
                   }
            if (month>12) {month=1;year++;}
            if (year>99) year=0;
                                        }
                             }
               }

}

bit leap_year()
{
       bit leap;
       if((year%4==0&&year%100!=0)||year%400==0)//闰年的条件
       leap=1;
       else
       leap=0;
       return leap;
}
//Timer0 中断处理程序,秒的产生
void timer0() interrupt 1
{
     TH0=0x4C; //Timer0 置10ms 定时初值dc00H(2^16=65536D,dc00H=56320D)
     TL0=0x00; //定时时间=(65536-56320)*(1/11.0592)*12=10ms (f0=11.0592Mhz)
     sec20++;      
     if(sec20 >= 20) //1 秒时间 (100*10ms=1000ms=1s)
          { sec20=0;
            updatetime  ();     
            pro_timedate(); 
            pro_display ();
            if(sec&0x01)
            disbuf[13]=' ';
            else disbuf[13]=':';
          }
}

void updatetime(void)
    {   disbuf[0] ='2';
        disbuf[1] ='0';
        disbuf[2] =year/10+48;
        disbuf[3] =year%10+48;
        disbuf[4] =' ';
        disbuf[5] =month/10+48;
        disbuf[6] =month%10+48;
        disbuf[7] ='.';
        disbuf[8] =date/10+48;
        disbuf[9] =date%10+48;
        disbuf[10] =' ';
        disbuf[11]=hour/10+48;
        disbuf[12]=hour%10+48;
        //disbuf[13]=' ';
        disbuf[14]=min/10+48;
        disbuf[15]=min%10+48;
    }
//显示处理程序
void pro_display()
{ unsigned char f;
   for (f=0;f<=15;f++)
   {DisplayOneChar( f,  0,  disbuf[f]);}
   
}
//写数据
void WriteDataLCM(unsigned char WDLCM)
{
ReadStatusLCM(); //检测忙
//WDLCM = ((WDLCM&0x01)<<7)|((WDLCM&0x02)<<5)|((WDLCM&0x04)<<3)|((WDLCM&0x08)<<1)|((WDLCM&0x10)>>1)|((WDLCM&0x20)>>3)|((WDLCM&0x40)>>5)|((WDLCM&0x80)>>7);
LCM_Data = WDLCM;
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_E = 0; //若晶振速度太高可以在这后加小的延时
LCD1602_E = 0; //延时
LCD1602_E = 1;
}

//写指令
void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
{
if (BuysC) ReadStatusLCM(); //根据需要检测忙
//WCLCM = ((WCLCM&0x01)<<7)|((WCLCM&0x02)<<5)|((WCLCM&0x04)<<3)|((WCLCM&0x08)<<1)|((WCLCM&0x10)>>1)|((WCLCM&0x20)>>3)|((WCLCM&0x40)>>5)|((WCLCM&0x80)>>7);
LCM_Data = WCLCM;

LCD1602_RS = 0;
LCD1602_RW = 0; 
LCD1602_E = 0;
LCD1602_E = 0;
LCD1602_E = 1; 
}

//读数据
unsigned char ReadDataLCM(void)
{
LCD1602_RS = 1; 
LCD1602_RW = 1;
LCD1602_E = 0;
LCD1602_E = 0;
LCD1602_E = 1;
return(LCM_Data);
}

//读状态
unsigned char ReadStatusLCM(void)
{
LCM_Data = 0xFF; 
LCD1602_RS = 0;
LCD1602_RW = 1;
LCD1602_E = 0;
LCD1602_E = 0;
LCD1602_E = 1;
while (LCM_Data & Busy); //检测忙信号
return(LCM_Data);
}

void LCMInit(void) //LCM初始化
{
LCM_Data = 0;
WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
Delay5Ms(); 
WriteCommandLCM(0x38,0);
Delay5Ms(); 
WriteCommandLCM(0x38,0);
Delay5Ms();

WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
WriteCommandLCM(0x08,1); //关闭显示
WriteCommandLCM(0x01,1); //显示清屏
WriteCommandLCM(0x06,1); // 显示光标移动设置
WriteCommandLCM(0x0C,1); // 显示开及光标设置
}

//按指定位置显示一个字符
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
X |= 0x80; //算出指令码
WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码
WriteDataLCM(DData);
}
//按指定位置显示一串字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
{
unsigned char ListLength;
ListLength = 0;
Y &= 0x1;
X &= 0xF;         //限制X不能大于15,Y不能大于1
while (DData[ListLength]>0x20) //若到达字串尾则退出
{
if (X <= 0xF) //X坐标应小于0xF
{
DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
ListLength++;
X++;
}
}
}
//50ms延时
void Delay5Ms(void)
{
unsigned int TempCyc = 5552;
while(TempCyc--);
}

//400ms延时
void Delay400Ms(void)
{
unsigned char TempCycA = 5;
unsigned int TempCycB;
while(TempCycA--)
{
TempCycB=7269;
while(TempCycB--);
};
}

51单片机驱动1602液晶显示器c程序---万年历相关推荐

  1. 单片机显示屏c语言程序,51单片机驱动1602液晶显示器c程序

    51单片机驱动1602液晶显示器c程序 /* 程序效果:单片机控制液晶显示器1602显示字母数字,用户自行更改io 程序版权:http://www.51hei.com */ #include //头文 ...

  2. 液晶显示器c语言编程,51驱动1602液晶显示器c程序

    /* 程序效果:单片机控制液晶显示器1602显示字母数字,用户自行更改io 程序版权:http://www.51hei.com */ #include //头文件 #define uchar unsi ...

  3. 单片机控制lcd序c语言,51单片机驱动1602液晶的C程序

    # include /***************************************** 电路连接 P1------DB0-DB7 P2.0------RS P2.1------RW ...

  4. 使用51单片机驱动YM12232B型液晶显示屏

    这是一个使用51单片机驱动YM12232B 液晶显示器的例子,本人水平有限,仅供参考. 本实例中将使用51单片机控制YM12232B LCD分别在主窗口和副窗口中显示"科"和&qu ...

  5. c语言编程TLC2543AD采集,51单片机驱动12位AD转换TLC2543电路图+程序

    51单片机驱动12位AD转换TLC2543电路图+程序 2015-06-18 16:51:15   来源:51hei void resultvolt() { volt=volt*5000.0/4334 ...

  6. 课设-51单片机+PM2.5+温湿度(程序+原理图+Protel仿真)

    51单片机PM2.5+温湿度(程序+原理图+Protel仿真) 一.功能 二.模块 三.代码程序 四.PCB原理图 一.功能 本系统以STC89C52单片机为核心,主要包括传感器温湿度采集,传感器PM ...

  7. 电子屏幕的51c语言程序,单片机控制LCD液晶显示器(含程序)

    <单片机控制LCD液晶显示器(含程序)>由会员分享,可在线阅读,更多相关<单片机控制LCD液晶显示器(含程序)(16页珍藏版)>请在人人文库网上搜索. 1.液晶显示器一 实验目 ...

  8. 基于51单片机驱动A4988实现步进电机逆时针转动

    基于51单片机驱动A4988实现步进电机逆时针转动 一.简介 二.接线 典型接线图 实际接线 三.部分代码 引脚定义 定时器初始化 主函数 四.实验现象 五.注意事项 一.简介 A4988 是一款完全 ...

  9. 51单片机驱动HMI串口屏,串口屏的下载方式

    51单片机驱动HMI串口屏,串口屏的下载方式 串口屏 串口屏的程序下载 51程序 总结 串口屏 串口屏是一个集成了单片机的屏幕模块,采用的是TTL串口协议,可以直接通过对应指令控制屏幕, 本文采用的串 ...

最新文章

  1. 淘宝服务端高并发分布式架构演进之路
  2. Visual Studio2019 应用程序无法正常启动0xc000007b
  3. 获取表单提交的数据getParameter()方法
  4. 计算机教室内网连接不了,校园网登陆不了内网怎么办?校园网登陆不了内网的解决方法...
  5. jQuery实现 div里面的文字如何自动缩小,避免文字溢出
  6. emlog评论ajax,Emlog评论通过QQ获取昵称资料
  7. HTTP的⼏种请求⽅法及⽤途小谈(面试)
  8. ORA-12541 TNS:无监听程序问题解决
  9. Visual Studio 11预览:DirectX和SharePoint特性
  10. Java语言基础--集合
  11. 安装keil5时,注册机在解压后消失的解决以及使用注册机破解keil5时,无法破解
  12. android我的世界连接pc,我的世界手机玩电脑版操作教程(可以连接pc版服务器)
  13. 【数据挖掘案例】财政收入影响因素分析及预测模型
  14. android adb命令安装apk的步骤
  15. Blazor The specified deps.json \bin\Debug\net5.0\BlazorWebApp.deps.json] does not exist
  16. 初级、中级、高级程序员的区别在哪里?
  17. Replace Autoprefixer browsers option to Browserslist config,VUECLI3报错
  18. 零基础Python爬虫实现(百度贴吧)
  19. 常用的Python3关键词提取方法
  20. LayIM 3.9.1与ASP.NET SignalR实现Web聊天室快速入门(五)之使用RabbitMQ缓存消息

热门文章

  1. C8051F系列单片机技术问答
  2. java 加载shellcode_动态加载 ShellCode绕过杀软
  3. 什么是ITIL中的变更管理
  4. 测试wlan的软件是什么,配置软件定义的WLAN测试系统
  5. 如何用Word做流程图
  6. 【六一为孩子建模吧】沐风老师3DMAX建模雕刻插件SculptTool使用教程
  7. mac下安装安装包,遇到“安装器遇到了一个错误,导致安装失败”
  8. 网络流量分析利器-可视化网络-netflow【6】-生产网流量监控架构设计
  9. Typora-setup-x64 0.9.93 下载及安装
  10. 用友U8生产不良退料案例教程