用了一个星期的时间写的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)
|