用了一個星期的時間寫的12864自下而上滾動顯示- #include "csb.h"
- #define uchar unsigned char
- #define uint unsigned int
- uchar code SJ[]={"蒹葭蒼蒼,白露為霜需謹慎再創造出來的歷程都快來吃多了,段時間看好大好大很好的克拉克拉 "};
- /*12864端口定義*/
- #define LCD_data P0 //數據口
- sbit RS = P3^5; //寄存器選擇輸入
- sbit RW = P3^6; //液晶讀/寫控制
- sbit EN = P3^4; //液晶使能控制
- sbit PSB = P3^1; //串/并方式控制
- sbit DU =P2^6;
- sbit WE = P2^7;
-
- void delay5us()//5us延時
- {;;}
- /*void delay20() //20us
- {
- unsigned char a;
- for(a=109;a>0;a--);
- }*/
- void delay(uint z) //毫秒延時程序
- {
- unsigned char a,b;
- uint c;
- for(c=z+7;c>0;c--)
- for(b=197;b>0;b--)
- for(a=2;a>0;a--);
- }
- void check_busy()//判忙
- {
- uchar busy;
- P0=0xff;
- RS=0;
- RW=1;
- do
- {
- EN=1;
- busy=P0;
- EN=0;
- }while(busy&0x80);
- EN=0;
- }
- void lcdw_dat(uchar dat)//寫入數據
- {
- check_busy();
- RS=1;
- RW=0;
- EN=0;
- delay5us();
- P0=dat;
- delay5us();
- EN=1;
- delay5us();
- EN=0;
- }
- void lcdw_cmd(uchar cmd)//寫入指令
- {
- check_busy();
- RS=0;
- RW=0;
- EN=0;
- delay5us();
- P0=cmd;
- delay5us();
- EN=1;
- delay5us();
- EN=0;
- }
- void lcdinit()
- {
-
- DU=0;
- WE=0;
- PSB = 1; //并口方式
- lcdw_cmd(0x34); //擴充指令操作
- delay(5);
- lcdw_cmd(0x30); //基本指令操作
- delay(5);
- lcdw_cmd(0x0C); //顯示開,關光標
- delay(5);
- lcdw_cmd(0x01); //清除LCD的顯示內容
- delay(5);
- }
- /**************************************************************************************
- //函數功能:任意位置顯示漢字
- //形式參數:uchar hang,uchar lie,uchar dat
- //行參說明:hang(0~3) lie(0~7)
- //************************************************************************************/
- /*void lcd_display(uchar hang,lie,uchar *str)//行(0~3),列(0~7)一行最多顯示8個 漢字
- {//字符可以顯示8行,16列
- if(hang==0) hang=0x80;
- else if(hang==1) hang=0x90;
- else if(hang==2) hang=0x88;
- else if(hang==3) hang=0x98;
- lcdw_cmd(hang+lie);
- while(*str!='\0')
- {
- lcdw_dat(*str++);
- }
- }*/
- //圖片(128*64)顯示程序
- /*void lcd_imp(uchar code *imp)//code定義ROM區的指針,不可更改
- {
- uchar i,j,k;
- j=0x80;
- lcdw_cmd(0x34);
-
- for(i=0;i<32;i++)//上半屏
- {
- lcdw_cmd(j++);//列地址
- //lcdw_cmd(0x80);//行地址
- for(k=0;k<16;k++)
- {
- lcdw_dat(*imp++);
- }
- }
- for(i=0;i<32;i++)
- {
- lcdw_cmd(j++);//列地址
- lcdw_cmd(0x88);//行地址
- for(k=0;k<16;k++)
- {
- lcdw_dat(*imp++);
- }
- }
- lcdw_cmd(0x36); //打開繪圖顯示
- lcdw_cmd(0x30); //回到基本指令集
- }*/
- /**************************************************************************************
- //函數功能:任意位置顯示字符,可以變化,不可以顯示漢字
- //形式參數:uchar hang,uchar lie,uchar dat
- //行參說明:hang(0~3) lie(0~7) 注意:1個漢字位顯示兩個字符
- //************************************************************************************/
- /*void lcd_write(uchar hang,lie,uchar dat)//12864顯示變量
- {
- if(hang==0) hang=0x80;
- else if(hang==1) hang=0x90;
- else if(hang==2) hang=0x88;
- else if(hang==3) hang=0x98;
- lcdw_cmd(hang+lie);
- lcdw_dat(0x30|dat/10);//取十位
- lcdw_dat(0x30|dat%10);//取個位
- }*/
- /**************************************************************************************
- //函數功能:任意位置顯示字符,可以變化,不可以顯示漢字
- //形式參數:uchar hang,uchar lie,uchar dat
- //行參說明:hang(0~3) lie(0~7) 注意:1個漢字位顯示兩個字符
- //************************************************************************************/
- /*void lcd_display_dat(uchar hang,lie,uchar dat)//12864顯示變量
- {
- if(hang==0) hang=0x80;
- else if(hang==1) hang=0x90;
- else if(hang==2) hang=0x88;
- else if(hang==3) hang=0x98;
- lcdw_cmd(hang+lie);
- lcdw_dat(dat);
-
- }*/
- /**************************************/
- //反白函數,或用于非全屏繪圖時,其它地方寫入0
- //X,Y需要反白的起始地址,如第一行,X=0x80,Y=0x80,第二行X=0x90,Y=0x90
- //X1需要反白多少列,如反白第一行,則X1=16
- //Y1為需要反白那行中的幾個字(每行最多8個字),清除一整行,則Y1=8
- //dat=0xff,反白 dat=0x0,清除
- /******************************************************************************/
- /*void lcd_white(uchar X,Y,X1,Y1,dat )//
- {
- uchar i,j;
-
- for(i=0;i<X1;i++)
- {
- for(j=0;j<Y1;j++)
- {
- lcdw_cmd(0x34);//打開擴展功能 ,關繪圖
- lcdw_cmd(Y+i);
- lcdw_cmd(X+j);
-
- lcdw_dat(dat);//D15~D8
- lcdw_dat(dat);//D7~D0
- }
- }
- lcdw_cmd(0x36);//打開擴展功能
- lcdw_cmd(0x30); //回到基本指令集
-
- }
- */
- void main()
- {
- unsigned char i,addr;
- unsigned char flag,hang,over;
- unsigned char *ptdat;
- lcdinit();
-
-
- //addr用于存儲寫入地址
- //flag存儲卷動地址,名字沒取好!
- //hang存儲下一行要寫入數據的行號(1~4)
- //over記錄寫入的空字符數
- //ptdat存儲字符串的指針
- delay(1);
- ptdat = &SJ[0];
- over = 0; //寫入空字符數
- //這里先把前面DDRAM中的前3行的字符數據寫入
- //如果字符不足<=4行,那么不卷動,之后字符>4行才卷動
- //一直到末行顯示完畢則停止卷動
- lcdw_cmd(0x80); //寫屏幕第一行字符
- for(i = 0; i < 16; i++)
- {
- if(*ptdat != '\0')
- {
- lcdw_dat(*ptdat++);
- }
- else
- {
- lcdw_dat(0x20);
- over++;
- }
- }
- lcdw_cmd(0x90); //寫屏幕第二行字符
- for(i = 0; i < 16; i++){
- if(*ptdat != '\0'){
- lcdw_dat(*ptdat++);
- }else{
- lcdw_dat(0x20);
- over++;
- }
- }
- lcdw_cmd(0x88);//寫屏幕第三行字符
- for(i = 0; i < 16; i++){
- if(*ptdat != '\0'){
- lcdw_dat(*ptdat++);
- }else{
- lcdw_dat(0x20);
- over++;
- }
- }
- lcdw_cmd(0x98);//寫屏幕第四行字符
- for(i = 0; i < 16; i++){
- if(*ptdat != '\0'){
- lcdw_dat(*ptdat++);
- }else{
- lcdw_dat(0x20);
- over++;
- }
- }
- ptdat = ptdat - 32;
- lcdw_cmd(0xa0); //寫DDRAM第3行數據
- for(i = 0; i < 16; i++){
- if(*ptdat != '\0'){
- lcdw_dat(*ptdat++);
- }else{
- lcdw_dat(0x20);
- over++;
- }
- }
- ptdat = ptdat + 16;
- for(i = 0; i < 16; i++){
- if(*ptdat != '\0'){
- lcdw_dat(*ptdat++);
- }else{
- lcdw_dat(0x20);
- over++;
- }
- }
- //前面的代碼是往DDRAM中寫如下內容:
- //第一行字符 第三行字符
- //第二行字符 第四行字符
- //第三行字符 第五行字符
- //如果寫第5行時全為空,說明字符剛好4行,不卷動。
- //此時第5行寫入16個0x20空字符,over用于記錄空字符個數。
- //如果不足4行,則前面也將會寫入空字符,此時寫完了3行DDRAM后
- //over的值必大于16,而只要over>15,就不卷動
-
- lcdw_cmd(0x0c); //開顯示
- if(over > 15){;} //顯示字符不足4行,不卷動
- else //顯示字符大于4行,開啟卷動
- {
- hang = 4; //接下來要寫DDRAM第4行數據
- flag = 0x01; //初始卷動地址為1
-
- while(1){
-
- switch(hang){ //設置寫入DDRAM的地址
-
- case 1: addr = 0x80; break; //往地址變量中寫第一行首地址
- case 2: addr = 0x90; break; //往地址變量中寫第二行首地址
- case 3: addr = 0xa0; break; //往地址變量中寫第三行首地址
- case 4: addr = 0xb0; break; //往地址變量中寫第四行首地址
- }
-
- switch(hang){ //指出下一次要寫的行地址
-
- case 1: hang = 2; break;//第1行寫完了,下一行要寫第2行
- case 2: hang = 3; break;//第2行寫完了,下一行要寫第3行
- case 3: hang = 4; break;//第3行寫完了,下一行要寫第4行
- case 4: hang = 1; break;//第4行寫完了,下一行要寫第1行
- }
- //后續代碼為往每一行寫數據,卷動一次寫一個字。
- ptdat = ptdat - 32;
- for(i = 0; i < 8; i++)
- { //寫一行中的前8個字符
- lcdw_cmd(0x34); //打開擴展指令
- lcdw_cmd(0x03); //允許輸入卷動地址
- lcdw_cmd(0x40 + flag++); //設置卷動地址
- lcdw_cmd(0x30); //回到基本指令
- lcdw_cmd(addr + i);
- delay(100);
-
- if(*ptdat != '\0')
- {
- lcdw_dat(*ptdat++); //寫入高字節
- }
- else
- {
- lcdw_dat(0x20); //字符串結束則寫入空字符
- }
-
- if(*ptdat != '\0')
- {
- lcdw_dat(*ptdat++); //寫入低字節
- }
- else
- {
- lcdw_dat(0x20); //字符串結束則寫入空字符
- }
-
- }
-
- ptdat = ptdat + 16;
- for(i = 8; i < 16; i++)
- { //寫一行中的后8個字符
- lcdw_cmd(0x34); //打開擴展指令
- lcdw_cmd(0x03); //允許輸入卷動地址
- if(flag == 64)
- {
- flag = 0;
- }
- lcdw_cmd(0x40 + flag); //設置卷動地址
- flag++;
- lcdw_cmd(0x30); //回到基本指令
- lcdw_cmd(addr + i);
- delay(100);
-
- if(*ptdat != '\0')
- {
- lcdw_dat(*ptdat++); //寫入高字節
- }
- else
- {
- over++; //寫完最后一行字符,需要再卷動16次才能顯示出來。
- lcdw_dat(0x20); //字符串結束則寫入空字符
- }
-
- if(*ptdat != '\0')
- {
- lcdw_dat(*ptdat++); //寫入低字節
- }
- else
- {
- lcdw_dat(0x20); //字符串結束則寫入空字符
- }
- }
- if(over < 8){;}
- else {break;}
- }
- }
- }
復制代碼
源碼下載,大家多多指教,如果有錯誤,歡迎批評指正:
12864滾動顯示.rar.rar
(38.83 KB, 下載次數: 71)
2021-1-2 21:04 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|