单片机12864滚动显示程序,有什么方法能实现不到四行也能滚屏显示吗?,按网上的源码能实现整屏滚动,有什么方法能实现不到四行也能滚屏显示吗?求大佬指导一下
- #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 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);
- }
- 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;}
- }
- }
- }
复制代码