標(biāo)題: 我改了一個(gè)“LCD 240124”年歷程序,請(qǐng)有此屏試試 [打印本頁(yè)]

作者: dpj555    時(shí)間: 2018-4-6 11:04
標(biāo)題: 我改了一個(gè)“LCD 240124”年歷程序,請(qǐng)有此屏試試
我是改的別人的程序,版權(quán)屬于這位同學(xué)。
/****************************************
程序設(shè)計(jì)部分
主函數(shù)中調(diào)用:draw_rect(19,5,160,87);

下面是LM4229驅(qū)動(dòng)程序(0811更新)
****************************************/
//========================================
//   使用LCD 280124 液晶屏制作時(shí)鐘
//   顯示“北京歡迎您”
// 改進(jìn): 2008/08/08增加顯示5個(gè)32*32漢字程序
//        2008/08/10增加顯示a*b大小照片(a為8的倍數(shù))
//        2008/08/11增加反白顯示、畫(huà)直線(xiàn)和矩形
//=========================================
#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;    //復(fù)位
sbit CD=P2^4;     //數(shù)據(jù)(L)/命令(H)選擇
sbit READ=P2^5;   //讀,低電平有效
sbit WRIT=P2^6;   //寫(xiě),低電平有效
sbit CE=P2^7;     //使能,低電平有效
//===========================================
//              函數(shù)聲明
//-------------------------------------------
//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();
//--------------------------------------------
//              延時(shí)函數(shù)
//--------------------------------------------
void delay_lcd(uchar t)
{
for(;t!=0; t--);
}
//--------------------------------------------
//              寫(xiě)數(shù)據(jù)函數(shù)
//--------------------------------------------
void write_data(uchar dat)
{
CD=0;          //數(shù)據(jù)
CE=0;          //LCD使能
WRIT=0;        //寫(xiě)
DATA_PORT=dat; //把數(shù)據(jù)送到P口
delay_lcd(1);  //當(dāng)晶振較高時(shí)加延時(shí)
WRIT=1;        //關(guān)寫(xiě)
CE=1;          //關(guān)使能
}

//--------------------------------------------
//              寫(xiě)命令函數(shù)
//--------------------------------------------
void write_com(uchar com)
{
CD=1;             //命令
CE=0;                 //LCD使能
WRIT=0;                 //寫(xiě)命令
DATA_PORT=com;   //把命令送到P口
delay_lcd(1);    //當(dāng)晶振較高時(shí)加延時(shí)
WRIT=1;                 //關(guān)寫(xiě)命令
CE=1;                 //關(guān)使能
}
//--------------------------------------------
//           指定位置、長(zhǎng)度清屏
//--------------------------------------------
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);        //設(shè)置
for(i=0;i<length;i++)
write_data(0xff);       //寫(xiě)入空格,清屏
write_com(0xb2);        //關(guān)閉自動(dòng)寫(xiě)
}
//--------------------------------------------
//   ------- 【顯示16*16字符】 -------
//--------------------------------------------
//         指定位置向LCD寫(xiě)入指定字符
// 參數(shù)說(shuō)明:x、y 坐標(biāo) cha字符串 flag 反白顯示標(biāo)志 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)     //字符設(shè)置為16*8
        {
          write_data(place&0xff);   //寫(xiě)入地址高位
          write_data(place/256);    //寫(xiě)入地址低位
          write_com(0x24);          //地址設(shè)置
          write_com(0xb0);          //設(shè)置數(shù)據(jù)自動(dòng)寫(xiě)
          if(flag)
          {
                  write_data (ASC_MSK[(c1-0x20)*16+k ]);
                  }
/*---例如:0的ASCII碼為0x30,在ASC_MSK中的位置為0x10*16 ---16字節(jié)字碼依次寫(xiě)入LCD---*/
          else
          {write_data(~ASC_MSK[(c1-0x20)*16+k]);}
          write_com(0xb2);          //自動(dòng)復(fù)位
          place=place+30;
        }
        if(y>28)            //y>28時(shí)候需要換行
          {x=x+16;y=0;}
        else                //否則,不換行,繼續(xù)寫(xiě)下一個(gè)字符
          {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]))   //------如果漢字在子碼表內(nèi)
         {
          for(k=0;k<16;k++)           //字符設(shè)置為16*8
           {
            write_data(place&0xff);   //寫(xiě)入地址高位
            write_data(place/256);    //寫(xiě)入地址低位
            write_com(0x24);          //地址設(shè)置
            write_com(0xb0);          //設(shè)置數(shù)據(jù)自動(dòng)寫(xiě)
            if(flag)
            {
             write_data(GB_16[j]/Msk[k*2]);
             write_data(GB_16[j]/Msk[k*2+1]); //16*16,每行2字節(jié)
            }
            else
            {
             write_data(~GB_16[j]/Msk[k*2]);
             write_data(~GB_16[j]/Msk[k*2+1]); //16*16,每行2字節(jié)
            }
            write_com(0xb2);                 //自動(dòng)復(fù)位
            place=place+30;                  //下一行
           }
         }
        else                            //-----沒(méi)找到對(duì)應(yīng)漢字則涂黑
         {
          for(k=0;k<16;k++)            //字符設(shè)置為16*8
           {
            write_data(place&0xff);   //寫(xiě)入地址高位
            write_data(place/256);    //寫(xiě)入地址低位
            write_com(0x24);          //地址設(shè)置
            write_com(0xb0);          //設(shè)置數(shù)據(jù)自動(dòng)寫(xiě)
            write_data(0xff);
            write_data(0xff);
            write_com(0xb2);             //自動(dòng)復(fù)位
            place=place+30;              //下一行
           }
         }
        if(y>27)      //-------換行
         {x+=16;y=0;}
        else          //--------不用換行,則下一個(gè)字
         {y+=2;}
         i+=2;
      }
    }
   while(i<length);
}

//--------------------------------------------
//         LM4229初始化函數(shù)
//--------------------------------------------
void lcd_init()
{
   FS1 = 0;            //fs1管腳高電平時(shí)表示字體為8*6;
                      //低電平時(shí)為8*8
MD2 = 0;
HALT = 0;
write_data(0);
write_data(0);        //圖形首地址
write_com(0x42);     //圖形首地址設(shè)置
write_data(30);
write_data(0);
write_com(0x43);     //圖形區(qū)域設(shè)置
write_com(0x80);     //設(shè)置為OR模式
write_com(0x98);    //關(guān)閉文本顯示,開(kāi)圖形顯示
}
//========【顯示5個(gè)大漢字】===================
//--------------------------------------------
//         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個(gè)漢字
{
   for(i=0;i<32;i++)                         //32*32
    {
     write_data(place&0xff);
     write_data(place/256);
     write_com(0x24);                          //設(shè)置地址
     write_com(0xb0);                         //設(shè)置數(shù)據(jù)自動(dòng)寫(xiě)
     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);                        //自動(dòng)復(fù)位
     place=place+30;
    }
   place=x*30+y+4*(n+1);
}
}
//=========【顯示圖片部分】====================
//--------------------------------------------
//         LM4229在指定位置顯示a*b圖片
//     a為圖片長(zhǎng),b為圖片寬(a為8的倍數(shù))
//--------------------------------------------
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行數(shù)據(jù)
{
    write_data(place&0xff);           //寫(xiě)地址低8位
    write_data(place/256);            //寫(xiě)地址高8位
    write_com(0x24);                  //設(shè)置地址
    write_com(0xb0);                  //設(shè)置數(shù)據(jù)自動(dòng)寫(xiě)
    for(j=0;j<a/8;j++)                //a/8列數(shù)據(jù)
    {write_data(tab_image[(a/8)*i+j]);}
    write_com(0xb2);                  //自動(dòng)復(fù)位
    place=place+30;                   //換行
}
}
//============【畫(huà)線(xiàn)和矩形部分】==============
//--------------------------------------------
//         LM4229在指定位置畫(huà)橫線(xiàn)a
//      參數(shù)說(shuō)明:x、y 坐標(biāo)     a 長(zhǎng)度   
//              (a為8的倍數(shù))
//--------------------------------------------
void draw_h(uchar x,uchar y,uchar a)
{
uint place;
uchar j;
//---- 畫(huà)橫線(xiàn)長(zhǎng) a -----
place=x*30+y;
write_data(place&0xff);   //寫(xiě)地址低8位
write_data(place/256);    //寫(xiě)地址高8位
write_com(0x24);       //設(shè)置地址
write_com(0xb0);       //設(shè)置數(shù)據(jù)自動(dòng)寫(xiě)
for(j=0;j<=a/8;j++)    //a/8列數(shù)據(jù)
{write_data(0xff);}
write_com(0xb2);      //自動(dòng)復(fù)位
}
//--------------------------------------------
//         LM4229在指定位置畫(huà)豎線(xiàn)b
// 參數(shù)說(shuō)明:x、y 坐標(biāo)     b 長(zhǎng)度   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列數(shù)據(jù)
{
    write_data(place&0xff);    //寫(xiě)地址低8位
    write_data(place/256);    //寫(xiě)地址高8位
    write_com(0x24);          //設(shè)置地址
    write_com(0xb0);          //設(shè)置數(shù)據(jù)自動(dòng)寫(xiě)
    write_data(0x01);
    write_com(0xb2);          //自動(dòng)復(fù)位
    place=place+30;
}
}
//--------------------------------------------
//         LM4229在指定位置畫(huà)豎線(xiàn)b
//   參數(shù)說(shuō)明:x、y 坐標(biāo)     b 長(zhǎng)度   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列數(shù)據(jù)
{
    write_data(place&0xff);   //寫(xiě)地址低8位
    write_data(place/256);    //寫(xiě)地址高8位
    write_com(0x24);          //設(shè)置地址
    write_com(0xb0);          //設(shè)置數(shù)據(jù)自動(dòng)寫(xiě)
    write_data(0x80);
    write_com(0xb2);          //自動(dòng)復(fù)位
    place=place+30;
}
}
//--------------------------------------------
//         LM4229在指定位置畫(huà)矩形a*b
//     參數(shù)說(shuō)明:x、y 坐標(biāo)     a、b 長(zhǎng)度
//            調(diào)用到上面幾個(gè)函數(shù)
//--------------------------------------------
void draw_rect(uchar x,uchar y,uchar a,uchar b)
{
draw_h(x,y,a);        //畫(huà)上邊
draw_lr(x,y-1,b);     //畫(huà)左寬
draw_ll(x,y+a/8,b);   //畫(huà)右寬
draw_h(x+b,y,a-8);    //畫(huà)下邊 ;a-8下邊長(zhǎng)才和上邊長(zhǎng)一樣,不知道為啥??
}
/*----- 測(cè)試數(shù)據(jù)------*/
/*********************************
draw_h(33,4,160);     //畫(huà)上邊
draw_lr(33,3,51);     //畫(huà)左寬
draw_ll(33,3+21,51); //畫(huà)右寬
draw_h(83,4,152);     //
*********************************/

//=====================================
/***主程序部分 lm4229_ds1302.c ***/
//=====================================
//     祝福北京,祝福奧運(yùn)
//          北京歡迎你  
//     時(shí)鐘暫未加設(shè)置時(shí)間功能  
//=====================================
//#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 星期";                  
                        /*    年 月 日 時(shí) 分 秒 星期   */
sbit k1=P3^3;
sbit k2=P3^4;  
//--------------------------
//------- 函數(shù)聲明 --------
void trans();
void key_scan();
void week();  
void delay(uint);
//void write_lcd(uchar);  
//============================================
//             主函數(shù)  
//============================================
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,"個(gè)");
write_lcd(72,1,"世");
write_lcd(90,1,"界");
write_lcd(22,27,"同");
write_lcd(38,27,"一");
write_lcd(54,27,"個(gè)");
write_lcd(72,27,"夢(mèng)");
write_lcd(90,27,"想");  
write_lcd(112,0," 偉大中國(guó) 厲害了我的國(guó) 我愛(ài)你");
write_pic(30,5);   //北京歡迎你 大字
write_lcd(70,8,"2008 北京奧運(yùn)");
while(1)
{     
ds1302();   
trans();     
write_lcd(0,0,tab_time);   
week();
}
}   
//----------------------------------
//         按鍵函數(shù)  
//----------------------------------
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--);
}  
//------------------------------------------
//              數(shù)據(jù)轉(zhuǎn)換  
//------------------------------------------
void trans()
{  
tab_time[2]=tab_1302[6]/10+'0';     //年十位
tab_time[3]=tab_1302[6]%10+'0';     //年個(gè)位
tab_time[6]=tab_1302[4]/10+'0';     //月十位
tab_time[7]=tab_1302[4]%10+'0';     //月個(gè)位
tab_time[10]=tab_1302[3]/10+'0';     //日十位
tab_time[11]=tab_1302[3]%10+'0';     //日個(gè)位
tab_time[15]=tab_1302[2]/10+'0';     //小時(shí)十位
tab_time[16]=tab_1302[2]%10+'0';     //小時(shí)個(gè)位
tab_time[18]=tab_1302[1]/10+'0';     //分十位
tab_time[19]=tab_1302[1]%10+'0';     //分個(gè)位
tab_time[21]=tab_1302[0]/10+'0';     //秒十位
tab_time[22]=tab_1302[0]%10+'0';     //秒個(gè)位
}   
//------------------------------------------
//              星期顯示  
//------------------------------------------
void week()
{
uchar i;  
i=tab_1302[5]-1;      
/*實(shí)時(shí)時(shí)鐘里的值是6,但是2008/08/08是星期五,所以減1, Proteus的問(wèn)題??  */
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};     //初始化時(shí)時(shí)間日期設(shè)置         
//秒 分 時(shí) 日 月 星期 年
uchar tab1_1302[7]={0,10,19,30,7,3,8};
//--------------------------
//----- 函數(shù)聲明 ------  
//--------------------------  
//void ds13021();                //獲取DS1302時(shí)間
void writeds_byte(uchar);        //向DS1302寫(xiě)一字節(jié)
uchar readds_byte();             //從DS1302讀一字節(jié)
void ds1302_init();              //DS1302初始化  
void writeds_add(uchar,uchar);   //指定地址向1302寫(xiě)一數(shù)據(jù)
uchar readds_add(uchar);         //指定地址從1302讀一數(shù)據(jù)

//=========================================
//------    函數(shù) ------  
//=========================================
//-------------------------------  
//---- 向DS1302寫(xiě)一字節(jié) (上升沿有效) -------
//---- 數(shù)據(jù)輸入從低位到高位     ------------
//-------------------------------  
void writeds_byte(uchar dat)     
{  
uchar i,
dat_w;  
dat_w=dat;         //數(shù)據(jù)送給變量
dat_w;
for(i=0;i<8;i++)   
{      
io=0;             //數(shù)據(jù)線(xiàn)先拉低     
if(dat_w&0x01)    //如果是1      
{io=1;}      
else              //如果是0      
{io=0;}      
dat_w=dat_w>>1;   //右移一位      
sclk=0;           //先拉低時(shí)鐘信號(hào)     
sclk=1;           //拉高時(shí)鐘信號(hào)      
}      
sclk=0;           //寫(xiě)一字節(jié)完畢,拉低時(shí)鐘信號(hào)
}  
//-------------------------------  
//---- 從DS1302讀一字節(jié) (下降沿有效) --------
//---- 讀出數(shù)據(jù)時(shí)從低位0位到高位7   -----------
//-------------------------------
uchar readds_byte()
{  
uchar i,k;k=0;  
for(i=0;i<8;i++)
{     
k=k>>1;           //k右移一位,確保先讀來(lái)的數(shù)據(jù)在低位   
if(io)     
{k=k|0x80;}       //讀取的值先送K最高位   
sclk=1;           //先拉低時(shí)鐘信號(hào)   
sclk=0; }  
sclk=0;  
return (k);
}  
//-------------------------------
//---- 指定地址寫(xiě)一數(shù)據(jù) --------
//-------------------------------  
void writeds_add(uchar add,uchar dat) //dat為十進(jìn)制數(shù)
{  
rst=0;
sclk=0;  
rst=1;                      //拉高RST
writeds_byte(add);         // 寫(xiě)地址  
writeds_byte((dat/10<<4)|(dat%10)); // DS1302中的時(shí)間數(shù)據(jù)是BCD碼形式
sclk=0;
rst=0;
}  
//-------------------------------
//---- 指定地址讀出一數(shù)據(jù) ------
//-------------------------------  
uchar readds_add(uchar add)
{  
uchar temp,dat1,dat2;
rst=0; sclk=0;
rst=1;  
writeds_byte(add);  
temp=readds_byte();   //讀取的數(shù)據(jù)為16進(jìn)制
sclk=0;              //讀取完畢,拉低SCLK
rst=0;               //拉低SCLK  
dat1=temp/16;        //16進(jìn)制轉(zhuǎn)成BCD
dat2=temp%16;
temp=dat1*10+dat2;   //轉(zhuǎn)換成10進(jìn)制數(shù)字
return (temp);      
}  
//-------------------------------
//---- DS1302初始化 --------
//---- 設(shè)置初始時(shí)間 --------  
//-------------------------------  
void ds1302_init()
{  
uchar i,add;
add=0x80;  
writeds_add(0x8e,0x00);    //允許寫(xiě)入
for(i=0;i<7;i++)   
{      
writeds_add(add,tab1_1302[i]);     
add+=2;   
}  
writeds_add(0x90,0xa6);   //寫(xiě)充電控制寄存器.
writeds_add(0x8e,0x80);   //禁止寫(xiě)入
}  
//-------------------------------
//---- 獲取DS1302時(shí)間 --------
//---- 在主函數(shù)中調(diào)用 --------
//-------------------------------  
void ds13021()
{
uchar i,add;
add=0x81; //
writeds_add(0x8e,0x00);        //允許向DS1302寫(xiě)入數(shù)據(jù)
for(i=0;i<7;i++)
{     
tab_1302[i]=readds_add(add);   //獲得的數(shù)據(jù)已轉(zhuǎn)換為十進(jìn)制         
add+=2;
}  
writeds_add(0x8e,0x80);        //獲取完一次時(shí)間,禁止向DS1302寫(xiě)入數(shù)據(jù),提高可靠性
}

此程序雖然通過(guò)編譯但不一定能用,故直接貼出來(lái)了,請(qǐng)版主見(jiàn)諒。

作者: admin    時(shí)間: 2018-4-6 16:39
有圖嗎?
作者: 安其拉要努力    時(shí)間: 2018-4-6 16:46
這是做什么的程序啊

作者: LXJ50    時(shí)間: 2018-4-6 17:03
我有兩塊240X160的屏,沒(méi)驅(qū)動(dòng)程序。借鑒一下。
作者: dpj555    時(shí)間: 2018-4-6 17:50
有圖,需要整理。




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1