单片机lcd实现滚屏

单片机lcd实现滚屏,第1张

分类: 电子数码

问题描述:

总体思想,如流程图等以及利用到51单片机哪些资源?

解析:

………………………………………………

16*16显示一个汉字,向左移动

只能显示8个汉字,受8位控制

………………………………………………

资源分析

………………………………………………

R0指向数据缓存地址,R1显示地址指针,R2数据增加指向指针,R3显示扫描次数

R4、R5延时程序,R6扫描延时,50H作片选字,51H右片选字

52H、53H、54H、55H、56H屏幕流动积存器,57H第二个字首地址

30H~4FH显示缓存

………………………………………………

引脚定义

………………………………………………

CLK BIT P2.0 74HC164清零,低电平清零

RCK BIT P2.1 74HC595移出脉冲,上升沿有效

SRCLR BIT P2.2 74HC595清零,低电平清零

G BIT P2.3 74HC595使凯伍能输出,低电平输出

………………………………………………

定义变量

………………………………………………

D_LIST EQU (8) 单个数据显示时间延时,即向右流动速度

………………………………………………

显存初始化

………………………………………………

CHULI: MOV R6,#D_LIST 单个数据显示时间延时

MOV R2,#0 定义编码数据指针,从0开始

MOV R0,#30H 首显存地址送R0,定义显存地址指针

LOOP3: MOV A,R2 编码数据指早孙指针送A

MOV DPTR,#TAB 表首地址送DPTR

MOVC A,@A+DPTR 查表取显示编码

MOV @R0,A 显示编码送现显存

INC R2 编码数据指针+1

INC R0 指向下一地址

CJNE R2,#32,LOOP3 判断是否完成一次数据刷新

LOOP6: ACALL START 调用显示程序作延时

DJNZ R6,LOOP6 判断是否完成延时

MOV R6,#D_LIST 恢复延时时间

………………………………………………

显示流动

…………………………………陆配……………

MOV 57H,#32 第二个字的编码首地址

LOOP1: MOV R2,#15 定义数据移动指针

MOV R0,#30H 显存首地址送R0

LOOP5: MOV 52H,R0 地址指针缓存

INC R0 地址指针加1,指向下一地址

MOV 53H,R0 地址指针缓存

INC R0 指向下一地址

MOV 55H,R0 地址指针缓存

MOV 54H,@R0 取指针地址里的数据存54H

MOV R0,52H 取回地址指针

MOV @R0,54H 刷新地址指针指向地址的数据

MOV R0,55H 取回地址指针

INC R0 地址指针+1,指向下一地址

MOV 56H,@R0 取指针地址里的数据存56H

MOV R0,53H 取回地址指针

MOV @R0,56H 刷新地址指针指向地址的数据

MOV R0,55H 地址指针缓存

DJNZ R2,LOOP5 完成15次刷新地址

MOV DPTR,#TAB 表首地址送DPTR

MOV A,57H 取回地址指针给A

MOVC A,@A+DPTR 查表取数

MOV R0,#4EH 送最后一列上地址指针

MOV @R0,A A送给最后一列上地址

INC 57H 编码数据地址加1

MOV A,57H 取回地址指针给A

MOVC A,@A+DPTR 查表取数

MOV R0,#4FH 送最后一列下地址指针

MOV @R0,A A送给最后一列下地址

INC 57H 指向下一地址

LOOP4: ACALL START 调用显示程序作延时

DJNZ R6,LOOP4 判断是否完成延时

MOV R6,#D_LIST 恢复延时时间

SJMP LOOP1 返回LOP1,继续刷新地址里的数据,使显示右移

………………………………………………

显示子程序

………………………………………………

START: CLR CLK 74HC164清零

SETB CLK

CLR SRCLR 74HC595清零

SETB SRCLR

LOOP2: MOV R3,#16 扫描次数送R3

MOV R1,#30H 显存首地址送R1

CLR C C置1

MOV 50H,#0FFH 左片选字

MOV 51H,#0FFH 右片选字

………………………………………………

LOOP: CLR RCK 74HC595移出脉冲准备

SETB G 置高74HC595使能端,使输出呈高阻

MOV A,@R1 取显存首地址里的是数

MOV SCON,#00H 选串口以方式0工作

MOV SBUF,A 把A从串口发送

JNB TI,$ 等待发送完一帧

CLR TI 清标志位

INC R1 地址指针加1

MOV A,@R1 取显存R0所指向地址里的是数

MOV SCON,#00H 选串口以方式0工作

MOV SBUF,A 把A从串口发送

JNB TI,$ 等待发送完一帧

CLR TI 清标志位

INC R1 地址指针加1

MOV A,50H 左片选字送A

RRC A 带进位位右移,选中第一列,低电平有效

MOV SCON,#00H 选串口以方式0工作

MOV SBUF,A 把A从串口发送

JNB TI,$ 等待发送完一帧

CLR TI 清标志位

MOV 50H,A 左片选字送回寄存器

MOV A,51H 右片选字送A

RRC A 带进位位右移,选中第九列,低电平有效

MOV SCON,#00H 选串口以方式0工作

MOV SBUF,A 把A从串口发送

JNB TI,$ 等待发送完一帧

CLR TI 清标志位

MOV 51H,A 右片选字送回寄存器

SETB RCK 74HC595移出脉冲呈上升沿,数据移出

CLR G 使能输出

ACALL DELAY 调延时子程序,是显示定格1ms

DJNZ R3,LOOP

RET

………………………………………………

1ms延时子程序

………………………………………………

DELAY : MOV R4,#1 延时毫秒数送R4

D2: MOV R5,#250 1ms延时值

D1: NOP

NOP

DJNZ R5,D1 1ms延时循环

DJNZ R4,D2 毫秒数减1,不等于0则继续循环,等于结束

RET

………………………………………………

显示编码数据

………………………………………………

TAB: DB 01H,00H,01H,00H,01H,00H,01H,00H,0FFH,0FFH,05H,02H,05H,84H,09H,48H

DB 09H,20H,11H,10H,21H,08H,41H,0CH,01H,06H,01H,04H,01H,00H,00H,00H"长",0

DB 08H,20H,08H,30H,0FFH,0E0H,08H,42H,08H,4CH,1FH,0F0H,12H,10H,12H,1AH

DB 13H,0F2H,10H,04H,0FFH,0C8H,10H,30H,50H,0CCH,37H,02H,12H,1CH,00H,00H"城",1

DB 00H,00H,00H,00H,1FH,0F0H,12H,20H,12H,20H,12H,20H,12H,20H,0FFH,0FCH

DB 12H,22H,12H,22H,12H,22H,12H,22H,1FH,0F2H,00H,02H,00H,0EH,00H,00H"电",2

DB 10H,40H,11H,80H,16H,00H,0FFH,0FFH,14H,00H,02H,04H,13H,0C8H,92H,50H

DB 72H,60H,1FH,0FFH,32H,40H,52H,40H,92H,48H,1EH,44H,00H,78H,00H,00H"梯",3

DB 00H,40H,20H,80H,21H,00H,22H,00H,27H,0FFH,2CH,90H,34H,90H,0E4H,90H

DB 24H,94H,24H,92H,24H,93H,27H,0FEH,20H,00H,20H,00H,20H,00H,00H,00H"有",4

DB 7FH,0FFH,40H,00H,4CH,40H,72H,20H,41H,0C0H,00H,00H,7FH,0FFH,52H,02H

DB 53H,04H,52H,0C0H,52H,30H,52H,48H,7EH,84H,00H,06H,00H,04H,00H,00H"限",5

DB 00H,00H,00H,80H,01H,04H,02H,0EH,0CH,14H,70H,24H,21H,0C4H,00H,8CH

DB 00H,08H,70H,08H,08H,28H,06H,1EH,03H,0CH,01H,80H,01H,00H,00H,00H"公",6

DB 00H,00H,08H,00H,49H,0F8H,49H,20H,49H,20H,49H,20H,49H,20H,49H,20H

DB 49H,20H,49H,0F0H,48H,00H,40H,04H,40H,02H,7FH,0FCH,00H,00H,00H,00H"司",7

//程序如下

#include <pic.h>

#define _XTAL_FREQ 4000000

__CONFIG(INTIO & WDTDIS & PWRTDIS& MCLRDIS & UNPROTECT &余稿唯 BORDIS & IESODIS & FCMDIS)

 

void main(void){

ANSEL =0x00

ANSELH=0x00

ADCON0=0x00

inta=0,b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0

if(RB5==0){

TRISA =0x00

TRISB =0x30

TRISC =0x00

while(1){

if(RB4==1){

PORTC=0xb6PORTA=0x01

__delay_ms(100) __delay_ms(100)

if(RB4==0){

a+=1j+=1

__delay_ms(100)__delay_ms(100)__delay_ms(100)__delay_ms(100)__delay_ms(100) //在改个函数,程竖培序更紧凑

if(a==3){

PORTA=0x20PORTC=0xb7

break //不要使用, 不然会跳敬知循环。程序结束。

}

if(j==3){

PORTC=0xfePORTA=0x00

break

}

}

PORTC=0x0cPORTA=0x01

__delay_ms(100)__delay_ms(100)

if(RB4==0){

b+=1j+=1

__delay_ms(100)__delay_ms(100)__delay_ms(100)__delay_ms(100)__delay_ms(100)

if(b==3){

PORTA=0x20PORTC=0x0d

break

}

if(j==3){

PORTC=0xfePORTA=0x00

break

}

}

PORTC=0x24PORTA=0x01

__delay_ms(100)__delay_ms(100)

if(RB4==0){

c+=1j+=1

__delay_ms(100)__delay_ms(100)__delay_ms(100)__delay_ms(100)__delay_ms(100)

if(c==3){

PORTA=0x20PORTC=0x25

break

}

if(j==3){

PORTC=0xfePORTA=0x00

break

}

}

PORTC=0xb0PORTA=0x01

__delay_ms(100)__delay_ms(100)

if(RB4==0){

d+=1j+=1

__delay_ms(100)__delay_ms(100)__delay_ms(100)__delay_ms(100)__delay_ms(100)

if(d==3){

PORTA=0x20PORTC=0xb1

break

}

if(j==3){

PORTC=0xfePORTA=0x00

break

}

}

PORTC=0x60PORTA=0x01

__delay_ms(100)__delay_ms(100)

if(RB4==0){

e+=1j+=1

__delay_ms(100)__delay_ms(100)__delay_ms(100)__delay_ms(100)__delay_ms(100)

if(e==3){

PORTA=0x20PORTC=0x61

break

}

if(j==3){

PORTC=0xfePORTA=0x00

break

}

}

PORTC=0x40PORTA=0x01

__delay_ms(100)__delay_ms(100)

if(RB4==0){

f+=1j+=1

__delay_ms(100)__delay_ms(100)__delay_ms(100)__delay_ms(100)__delay_ms(100)

if(f==3){

PORTA=0x20PORTC=0x41

break

}

if(j==3){

PORTC=0xfePORTA=0x00

break

}

}

PORTC=0x36PORTA=0x01

__delay_ms(100)__delay_ms(100)

if(RB4==0){

g+=1j+=1

__delay_ms(100)__delay_ms(100)__delay_ms(100)__delay_ms(100)__delay_ms(100)

if(g==3){

PORTA=0x20PORTC=0x37

break

}

if(j==3){

PORTC=0xfePORTA=0x00

break

}

}

PORTC=0x00PORTA=0x01

__delay_ms(100)__delay_ms(100)

if(RB4==0){

h+=1j+=1

__delay_ms(100)__delay_ms(100)__delay_ms(100)__delay_ms(100)__delay_ms(100)

if(h==3){

PORTA=0x20PORTC=0x01

break

}

if(j==3){

PORTC=0xfePORTA=0x00

break

}

}

PORTC=0x20PORTA=0x01

__delay_ms(100)__delay_ms(100)

if(RB4==0){

i+=1j+=1

__delay_ms(100)__delay_ms(100)__delay_ms(100)__delay_ms(100)__delay_ms(100)

if(i==3){

PORTA=0x20PORTC=0x21

break

}

if(j==3){

PORTC=0xfePORTA=0x00

break

}

}

}

}

}

// 按键使用break,,你就一层while会直接结束。显示小数点是跟你的赋值有关要连硬件调试下参数。

修改后的

#include <pic.h>

#define _XTAL_FREQ 4000000

__CONFIG(INTIO & WDTDIS & PWRTDIS& MCLRDIS & UNPROTECT & BORDIS & IESODIS & FCMDIS)

void delu(int i)

 {

  while(i--)

  __delay_ms(100)

 }

void main(void){

unsigned char flg=1    //去掉break,而增加的 是否进入循环的标志。

ANSEL =0x00

ANSELH=0x00

ADCON0=0x00

inta=0,b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0

if(RB5==0){

TRISA =0x00

TRISB =0x30

TRISC =0x00

while(1){

//打开flg 的条件也要增加上

if(RB4==0)flg=1

if(RB4==1&&flg==1){ PORTC=0xb6PORTA=0x01delu(2)  // 

 if(RB4==0){   a+=1j+=1  delu(5)

  if(a==3)  {  PORTA=0x20PORTC=0xb7 flg=0 }

  if(j==3)  {  PORTC=0xfePORTA=0x00 flg=0 }

           }

               PORTC=0x0cPORTA=0x01delu(2)      // 

 if(RB4==0){   b+=1j+=1  delu(5)

  if(b==3)  {  PORTA=0x20PORTC=0x0d flg=0 }

  if(j==3)  {  PORTC=0xfePORTA=0x00 flg=0 }

           }

               PORTC=0x24PORTA=0x01delu(2)      // 

 if(RB4==0){   c+=1j+=1 delu(5)

  if(c==3)  {  PORTA=0x20PORTC=0x25 flg=0}

  if(j==3)  {  PORTC=0xfePORTA=0x00 flg=0}

           }

               PORTC=0xb0PORTA=0x01delu(2)      // 

 if(RB4==0){   d+=1j+=1delu(5)

  if(d==3)  {  PORTA=0x20PORTC=0xb1 flg=0}

  if(j==3)  {  PORTC=0xfePORTA=0x00 flg=0}

           }

               PORTC=0x60PORTA=0x01delu(2)      // 

 if(RB4==0){   e+=1j+=1 delu(5)

 if(e==3)   {  PORTA=0x20PORTC=0x61 flg=0 }

 if(j==3)   {  PORTC=0xfePORTA=0x00 flg=0}

           }

               PORTC=0x40PORTA=0x01delu(2)      // 

 if(RB4==0){   f+=1j+=1 delu(5)

 if(f==3)   {  PORTA=0x20PORTC=0x41 flg=0 }

 if(j==3)   {  PORTC=0xfePORTA=0x00 flg=0 }

           }

               PORTC=0x36PORTA=0x01delu(2)      // 

 if(RB4==0){   g+=1j+=1delu(5)

    if(g==3){  PORTA=0x20PORTC=0x37 flg=0}

    if(j==3){  PORTC=0xfePORTA=0x00 flg=0}

           }

               PORTC=0x00PORTA=0x01delu(2)      // 

 if(RB4==0){   h+=1j+=1delu(5)

 if(h==3)   {  PORTA=0x20PORTC=0x01 flg=0}

 if(j==3)   {  PORTC=0xfePORTA=0x00 flg=0}

           }

               PORTC=0x20PORTA=0x01delu(2)     // 

if(RB4==0) {   i+=1j+=1delu(5)

if(i==3)    {  PORTA=0x20PORTC=0x21 flg=0}

if(j==3)    {  PORTC=0xfePORTA=0x00 flg=0}

           }

        }

     }

   }

}

//meiyou

1602的两行32个字符是相互独立的,每一个位置的字符都有一个地址,第一行的16个地址是00H到0FH,第二毁纳行的地址是40H到4FH。往哪地址上写入,哪个字符才改变。这样想滚动就得不停的改写,比如你想让第二行显示混动的1 2 3 4 5 6 7 8 — — — — — — — —升余首,你就得做一个16次改写(中间加延时)的循环程序,依次对40H到4FH的地址分别写1 2 3 4 5 6 7 8 — — — — — — — —,—1 2 3 4 5 6 7 8 — — — — — — — ,— —1 2 3 4 5 6 7 8 — — — — — — ,…… 2 3 4 5 6 7 8 — — — — — — — —1这样的改写连起来它就滚动效果了吵数


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12485319.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-25
下一篇 2023-05-25

发表评论

登录后才能评论

评论列表(0条)

保存