找回密码
 立即注册

QQ登录

只需一步,快速开始

帖子
查看: 2746|回复: 4
收起左侧

我改了一个“LCD 240124”年历程序,请有此屏试试

[复制链接]
ID:77707 发表于 2018-4-6 11:04 | 显示全部楼层 |阅读模式
我是改的别人的程序,版权属于这位同学。
/****************************************
程序设计部分
主函数中调用:draw_rect(19,5,160,87);

下面是LM4229驱动程序(0811更新)
****************************************/
//========================================
//   使用LCD 280124 液晶屏制作时钟
//   显示“北京欢迎您”
// 改进: 2008/08/08增加显示5个32*32汉字程序
//        2008/08/10增加显示a*b大小照片(a为8的倍数)
//        2008/08/11增加反白显示、画直线和矩形
//=========================================
#include<reg52.h>
#include<math.h>
#include<absacc.h>
//#include<ds1302.h>
//#include<lm4229.h>
//#include<en_code.h>
//#include<cn_code.h>
//#include<picture.h>
#define uchar unsigned char
#define uint unsigned int
#define DATA_PORT P0
//#define ASC_MSK[]

//------------------------------------------
//              管脚定义   
//------------------------------------------
sbit HALT=P2^0;   //暂不清楚
sbit FS1=P2^1;    //字体模式选择
sbit MD2=P2^2;    //方式选择
sbit RST=P2^3;    //复位
sbit CD=P2^4;     //数据(L)/命令(H)选择
sbit READ=P2^5;   //读,低电平有效
sbit WRIT=P2^6;   //写,低电平有效
sbit CE=P2^7;     //使能,低电平有效
//===========================================
//              函数声明
//-------------------------------------------
//void delay_lcd(uchar);
//void write_data(uchar);
//void write_com(uchar);
//void clr_lcd(uchar,uchar,uint);
unsigned char ASC_MSK[];
unsigned char GB_16[];
unsigned char tab_pic[];
unsigned char Index[];
unsigned char Msk[];
unsigned char tab_1302[];
unsigned char ds1302();
//--------------------------------------------
//              延时函数
//--------------------------------------------
void delay_lcd(uchar t)
{
for(;t!=0; t--);
}
//--------------------------------------------
//              写数据函数
//--------------------------------------------
void write_data(uchar dat)
{
CD=0;          //数据
CE=0;          //LCD使能
WRIT=0;        //写
DATA_PORT=dat; //把数据送到P口
delay_lcd(1);  //当晶振较高时加延时
WRIT=1;        //关写
CE=1;          //关使能
}

//--------------------------------------------
//              写命令函数
//--------------------------------------------
void write_com(uchar com)
{
CD=1;             //命令
CE=0;                 //LCD使能
WRIT=0;                 //写命令
DATA_PORT=com;   //把命令送到P口
delay_lcd(1);    //当晶振较高时加延时
WRIT=1;                 //关写命令
CE=1;                 //关使能
}
//--------------------------------------------
//           指定位置、长度清屏
//--------------------------------------------
void clr_lcd(uchar x,uchar y,uint length)
{
uint i,place;
place=x*30+y;
write_data(place&0xff);
write_data(place/256);
write_com(0x24);        //设置
for(i=0;i<length;i++)
write_data(0xff);       //写入空格,清屏
write_com(0xb2);        //关闭自动写
}
//--------------------------------------------
//   ------- 【显示16*16字符】 -------
//--------------------------------------------
//         指定位置向LCD写入指定字符
// 参数说明:x、y 坐标 cha字符串 flag 反白显示标志 1正常,0反白
//
//--------------------------------------------
void write_lcd(uchar x,uchar y,char *cha,bit flag)
{
uint place,i=0;
uchar length,c1,c2,j,k;
for(length=0;cha[length]!=0;length++);
   do
    {
      c1=cha[i];      //取字符串的ASCII码
      c2=cha[i+1];
      place=x*30+y;
      if(c1<=128)        //#####小于128为字符,大于128为汉字
       {
        for(k=0;k<16;++k)     //字符设置为16*8
        {
          write_data(place&0xff);   //写入地址高位
          write_data(place/256);    //写入地址低位
          write_com(0x24);          //地址设置
          write_com(0xb0);          //设置数据自动写
          if(flag)
          {
                  write_data (ASC_MSK[(c1-0x20)*16+k ]);
                  }
/*---例如:0的ASCII码为0x30,在ASC_MSK中的位置为0x10*16 ---16字节字码依次写入LCD---*/
          else
          {write_data(~ASC_MSK[(c1-0x20)*16+k]);}
          write_com(0xb2);          //自动复位
          place=place+30;
        }
        if(y>28)            //y>28时候需要换行
          {x=x+16;y=0;}
        else                //否则,不换行,继续写下一个字符
          {y++;}
           i++;
      }
     else                   //#####c1大于128为汉字
      {
        for(j=0;j<sizeof(GB_16)/sizeof(GB_16[0]);j++) //找到汉字
         {
           if(c1==GB_16[j],Index[0]&&c2==GB_16[j],Index[1])
           break;            //汉字找到则跳出   
         }
        if(j<sizeof(GB_16)/sizeof(GB_16[0]))   //------如果汉字在子码表内
         {
          for(k=0;k<16;k++)           //字符设置为16*8
           {
            write_data(place&0xff);   //写入地址高位
            write_data(place/256);    //写入地址低位
            write_com(0x24);          //地址设置
            write_com(0xb0);          //设置数据自动写
            if(flag)
            {
             write_data(GB_16[j]/Msk[k*2]);
             write_data(GB_16[j]/Msk[k*2+1]); //16*16,每行2字节
            }
            else
            {
             write_data(~GB_16[j]/Msk[k*2]);
             write_data(~GB_16[j]/Msk[k*2+1]); //16*16,每行2字节
            }
            write_com(0xb2);                 //自动复位
            place=place+30;                  //下一行
           }
         }
        else                            //-----没找到对应汉字则涂黑
         {
          for(k=0;k<16;k++)            //字符设置为16*8
           {
            write_data(place&0xff);   //写入地址高位
            write_data(place/256);    //写入地址低位
            write_com(0x24);          //地址设置
            write_com(0xb0);          //设置数据自动写
            write_data(0xff);
            write_data(0xff);
            write_com(0xb2);             //自动复位
            place=place+30;              //下一行
           }
         }
        if(y>27)      //-------换行
         {x+=16;y=0;}
        else          //--------不用换行,则下一个字
         {y+=2;}
         i+=2;
      }
    }
   while(i<length);
}

//--------------------------------------------
//         LM4229初始化函数
//--------------------------------------------
void lcd_init()
{
   FS1 = 0;            //fs1管脚高电平时表示字体为8*6;
                      //低电平时为8*8
MD2 = 0;
HALT = 0;
write_data(0);
write_data(0);        //图形首地址
write_com(0x42);     //图形首地址设置
write_data(30);
write_data(0);
write_com(0x43);     //图形区域设置
write_com(0x80);     //设置为OR模式
write_com(0x98);    //关闭文本显示,开图形显示
}
//========【显示5个大汉字】===================
//--------------------------------------------
//         LM4229在指定位置显示32*32汉字
//--------------------------------------------
void write_pic(uchar x,uchar y)
{
uint place;
uchar i,n;
place=x*30+y;
for(n=0;n<5;n++)                             //5个汉字
{
   for(i=0;i<32;i++)                         //32*32
    {
     write_data(place&0xff);
     write_data(place/256);
     write_com(0x24);                          //设置地址
     write_com(0xb0);                         //设置数据自动写
     write_data(tab_pic[4*i+0+128*n]);
     write_data(tab_pic[4*i+1+128*n]);
     write_data(tab_pic[4*i+2+128*n]);
     write_data(tab_pic[4*i+3+128*n]);
     write_com(0xb2);                        //自动复位
     place=place+30;
    }
   place=x*30+y+4*(n+1);
}
}
//=========【显示图片部分】====================
//--------------------------------------------
//         LM4229在指定位置显示a*b图片
//     a为图片长,b为图片宽(a为8的倍数)
//--------------------------------------------
void write_image(uchar x,uchar y,uchar a,uchar b,uchar *tab_image)
{
uint place;
uchar i,j;
place=x*30+y;
for(i=0;i<b;i++)                      //b行数据
{
    write_data(place&0xff);           //写地址低8位
    write_data(place/256);            //写地址高8位
    write_com(0x24);                  //设置地址
    write_com(0xb0);                  //设置数据自动写
    for(j=0;j<a/8;j++)                //a/8列数据
    {write_data(tab_image[(a/8)*i+j]);}
    write_com(0xb2);                  //自动复位
    place=place+30;                   //换行
}
}
//============【画线和矩形部分】==============
//--------------------------------------------
//         LM4229在指定位置画横线a
//      参数说明:x、y 坐标     a 长度   
//              (a为8的倍数)
//--------------------------------------------
void draw_h(uchar x,uchar y,uchar a)
{
uint place;
uchar j;
//---- 画横线长 a -----
place=x*30+y;
write_data(place&0xff);   //写地址低8位
write_data(place/256);    //写地址高8位
write_com(0x24);       //设置地址
write_com(0xb0);       //设置数据自动写
for(j=0;j<=a/8;j++)    //a/8列数据
{write_data(0xff);}
write_com(0xb2);      //自动复位
}
//--------------------------------------------
//         LM4229在指定位置画竖线b
// 参数说明:x、y 坐标     b 长度   0000 0001   
//--------------------------------------------
void draw_lr(uchar x,uchar y,uchar b)
{
uint place;
uchar j;
place=x*30+y;
for(j=0;j<b;j++)                //a/8列数据
{
    write_data(place&0xff);    //写地址低8位
    write_data(place/256);    //写地址高8位
    write_com(0x24);          //设置地址
    write_com(0xb0);          //设置数据自动写
    write_data(0x01);
    write_com(0xb2);          //自动复位
    place=place+30;
}
}
//--------------------------------------------
//         LM4229在指定位置画竖线b
//   参数说明:x、y 坐标     b 长度   1000 0000   
//--------------------------------------------
void draw_ll(uchar x,uchar y,uchar b)
{
uint place;
uchar j;
place=x*30+y;
for(j=0;j<b;j++)              //a/8列数据
{
    write_data(place&0xff);   //写地址低8位
    write_data(place/256);    //写地址高8位
    write_com(0x24);          //设置地址
    write_com(0xb0);          //设置数据自动写
    write_data(0x80);
    write_com(0xb2);          //自动复位
    place=place+30;
}
}
//--------------------------------------------
//         LM4229在指定位置画矩形a*b
//     参数说明:x、y 坐标     a、b 长度
//            调用到上面几个函数
//--------------------------------------------
void draw_rect(uchar x,uchar y,uchar a,uchar b)
{
draw_h(x,y,a);        //画上边
draw_lr(x,y-1,b);     //画左宽
draw_ll(x,y+a/8,b);   //画右宽
draw_h(x+b,y,a-8);    //画下边 ;a-8下边长才和上边长一样,不知道为啥??
}
/*----- 测试数据------*/
/*********************************
draw_h(33,4,160);     //画上边
draw_lr(33,3,51);     //画左宽
draw_ll(33,3+21,51); //画右宽
draw_h(83,4,152);     //
*********************************/

//=====================================
/***主程序部分 lm4229_ds1302.c ***/
//=====================================
//     祝福北京,祝福奥运
//          北京欢迎你  
//     时钟暂未加设置时间功能  
//=====================================
//#include<reg52.h>
//#include<math.h>
//#include<absacc.h>
//#include<ds1302.h>
//#include<lm4229.h>  
                        /* 0123 67 1011 1516 1819 2122*/  
unsigned char tab_time[]="2008年08月08日 00:00:00 星期";                  
                        /*    年 月 日 时 分 秒 星期   */
sbit k1=P3^3;
sbit k2=P3^4;  
//--------------------------
//------- 函数声明 --------
void trans();
void key_scan();
void week();  
void delay(uint);
//void write_lcd(uchar);  
//============================================
//             主函数  
//============================================
void main()
{  
lcd_init();  
write_lcd(10,0,"------------------------------");
write_lcd(102,0,"------------------------------");  //
write_lcd(0,0,"2008年08月08日 00:00:00 星期五");  
write_lcd(22,1,"同");
write_lcd(38,1,"一");
write_lcd(54,1,"个");
write_lcd(72,1,"世");
write_lcd(90,1,"界");
write_lcd(22,27,"同");
write_lcd(38,27,"一");
write_lcd(54,27,"个");
write_lcd(72,27,"梦");
write_lcd(90,27,"想");  
write_lcd(112,0," 伟大中国 厉害了我的国 我爱你");
write_pic(30,5);   //北京欢迎你 大字
write_lcd(70,8,"2008 北京奥运");
while(1)
{     
ds1302();   
trans();     
write_lcd(0,0,tab_time);   
week();
}
}   
//----------------------------------
//         按键函数  
//----------------------------------
void key_scan()
{  
if(k1==0)
{     
delay(5);   
if(k1==0)     
{      
tab_time[2]++;     
}
}
}  
void delay(uint k)
{  
uint i,j;  
for(i=k;i>0;i--)      
for(j=110;j>0;j--);
}  
//------------------------------------------
//              数据转换  
//------------------------------------------
void trans()
{  
tab_time[2]=tab_1302[6]/10+'0';     //年十位
tab_time[3]=tab_1302[6]%10+'0';     //年个位
tab_time[6]=tab_1302[4]/10+'0';     //月十位
tab_time[7]=tab_1302[4]%10+'0';     //月个位
tab_time[10]=tab_1302[3]/10+'0';     //日十位
tab_time[11]=tab_1302[3]%10+'0';     //日个位
tab_time[15]=tab_1302[2]/10+'0';     //小时十位
tab_time[16]=tab_1302[2]%10+'0';     //小时个位
tab_time[18]=tab_1302[1]/10+'0';     //分十位
tab_time[19]=tab_1302[1]%10+'0';     //分个位
tab_time[21]=tab_1302[0]/10+'0';     //秒十位
tab_time[22]=tab_1302[0]%10+'0';     //秒个位
}   
//------------------------------------------
//              星期显示  
//------------------------------------------
void week()
{
uchar i;  
i=tab_1302[5]-1;      
/*实时时钟里的值是6,但是2008/08/08是星期五,所以减1, Proteus的问题??  */
switch(i)
{     
case 1: write_lcd(0,28,"一"); break;   
case 2: write_lcd(0,28,"二"); break;   
case 3: write_lcd(0,28,"三"); break;   
case 4: write_lcd(0,28,"四"); break;   
case 5: write_lcd(0,28,"五"); break;   
case 6: write_lcd(0,28,"六"); break;   
case 7: write_lcd(0,28,"日"); break;   
default:  break; //其它情况  
}
}  

//======================================================  
//----- 星期一 monday 星期二 tuesday   星期三 wednesday
//----- 星期四 thursday 星期五 friday   星期六 saturday
//----- 星期日 sunday //----- //-----  
//======================================================
//--------------------------
//#define uchar unsigned char
//#define uint unsigned int
//--------------------------
//------ 定义端口 ---------
sbit rst=P3^0;
sbit sclk=P3^1;
sbit io=P3^2;  
//---------------------------  
uchar tab_1302[7]={0,10,19,30,7,3,8};     //初始化时时间日期设置         
//秒 分 时 日 月 星期 年
uchar tab1_1302[7]={0,10,19,30,7,3,8};
//--------------------------
//----- 函数声明 ------  
//--------------------------  
//void ds13021();                //获取DS1302时间
void writeds_byte(uchar);        //向DS1302写一字节
uchar readds_byte();             //从DS1302读一字节
void ds1302_init();              //DS1302初始化  
void writeds_add(uchar,uchar);   //指定地址向1302写一数据
uchar readds_add(uchar);         //指定地址从1302读一数据

//=========================================
//------    函数 ------  
//=========================================
//-------------------------------  
//---- 向DS1302写一字节 (上升沿有效) -------
//---- 数据输入从低位到高位     ------------
//-------------------------------  
void writeds_byte(uchar dat)     
{  
uchar i,
dat_w;  
dat_w=dat;         //数据送给变量
dat_w;
for(i=0;i<8;i++)   
{      
io=0;             //数据线先拉低     
if(dat_w&0x01)    //如果是1      
{io=1;}      
else              //如果是0      
{io=0;}      
dat_w=dat_w>>1;   //右移一位      
sclk=0;           //先拉低时钟信号     
sclk=1;           //拉高时钟信号      
}      
sclk=0;           //写一字节完毕,拉低时钟信号
}  
//-------------------------------  
//---- 从DS1302读一字节 (下降沿有效) --------
//---- 读出数据时从低位0位到高位7   -----------
//-------------------------------
uchar readds_byte()
{  
uchar i,k;k=0;  
for(i=0;i<8;i++)
{     
k=k>>1;           //k右移一位,确保先读来的数据在低位   
if(io)     
{k=k|0x80;}       //读取的值先送K最高位   
sclk=1;           //先拉低时钟信号   
sclk=0; }  
sclk=0;  
return (k);
}  
//-------------------------------
//---- 指定地址写一数据 --------
//-------------------------------  
void writeds_add(uchar add,uchar dat) //dat为十进制数
{  
rst=0;
sclk=0;  
rst=1;                      //拉高RST
writeds_byte(add);         // 写地址  
writeds_byte((dat/10<<4)|(dat%10)); // DS1302中的时间数据是BCD码形式
sclk=0;
rst=0;
}  
//-------------------------------
//---- 指定地址读出一数据 ------
//-------------------------------  
uchar readds_add(uchar add)
{  
uchar temp,dat1,dat2;
rst=0; sclk=0;
rst=1;  
writeds_byte(add);  
temp=readds_byte();   //读取的数据为16进制
sclk=0;              //读取完毕,拉低SCLK
rst=0;               //拉低SCLK  
dat1=temp/16;        //16进制转成BCD
dat2=temp%16;
temp=dat1*10+dat2;   //转换成10进制数字
return (temp);      
}  
//-------------------------------
//---- DS1302初始化 --------
//---- 设置初始时间 --------  
//-------------------------------  
void ds1302_init()
{  
uchar i,add;
add=0x80;  
writeds_add(0x8e,0x00);    //允许写入
for(i=0;i<7;i++)   
{      
writeds_add(add,tab1_1302[i]);     
add+=2;   
}  
writeds_add(0x90,0xa6);   //写充电控制寄存器.
writeds_add(0x8e,0x80);   //禁止写入
}  
//-------------------------------
//---- 获取DS1302时间 --------
//---- 在主函数中调用 --------
//-------------------------------  
void ds13021()
{
uchar i,add;
add=0x81; //
writeds_add(0x8e,0x00);        //允许向DS1302写入数据
for(i=0;i<7;i++)
{     
tab_1302[i]=readds_add(add);   //获得的数据已转换为十进制         
add+=2;
}  
writeds_add(0x8e,0x80);        //获取完一次时间,禁止向DS1302写入数据,提高可靠性
}

此程序虽然通过编译但不一定能用,故直接贴出来了,请版主见谅。

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

举报

ID:1 发表于 2018-4-6 16:39 | 显示全部楼层
有图吗?
回复

举报

ID:302675 发表于 2018-4-6 16:46 | 显示全部楼层
这是做什么的程序啊
回复

举报

ID:164988 发表于 2018-4-6 17:03 | 显示全部楼层
我有两块240X160的屏,没驱动程序。借鉴一下。
回复

举报

ID:77707 发表于 2018-4-6 17:50 | 显示全部楼层
有图,需要整理。
回复

举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表