用汇编程序控制LCD1602B的问题
请问马老师,用汇编程序控制LCD1602B的问题(共七线)。显示总是不正常,只能显示8个字符,当中有4个是对的(间隔一个字符)。我调整了delay_us延时时间,设为200问题都一样,请教是程序哪里出了问题?4个数据线输入程序写入的方法对吗?我原来是搞PLC编程的,不懂c.感觉汇编有点像PLC里的指今表,就开始学AVR了,请各位高手多多指教。期待您的回音,多谢了!.include"m16def.inc"
;(外部8M晶振)
;接线方式:
;PB7--->D7
;PB6--->D6
;PB5--->D5
;PB4--->D4
;PD5--->E
;PD4--->R/W
;PD3--->RS
;M16中断向量地址:
rjmpRESET ; 复位中断向量
.def cnt_us =r22
.def cnt_LCD_bit =r23
.def LCD_buffer =r24
.org$024
reset:
;************************************************
ldi r16,low(ramend) ;设置堆栈指针。
out spl,r16
ldi r16,high(ramend)
out sph,r16
ldi r16,$ff ;设置D口输出,B口作输入。
out ddrd,r16
out portd,r16
clr r16
out ddrb,r16
out portb,r16
;**************;LCD1602系统初始化*****************
LCD:
ldi LCD_buffer,$01 ;清屏设定//01
rcallContrl_LCD
ldi r16,$20 ;设置时间常数//20
rcalldelay
ldi LCD_buffer,$28 ;2行 5*7 8个数据线(4个数据线为28)功能设定//38
rcallContrl_LCD
ldi LCD_buffer,$06 ;自动增量,显示不移位//06
rcallContrl_LCD
ldi LCD_buffer,$0c ;字形开关ON,光标开关OFF//0c
rcallContrl_LCD
;**************;LCD1602系统初始化END**************
display:
;SYSTEM-CHECKING! ...OK
ldi zl,low(sys_reset*2)
ldi zh,high(sys_reset*2)
ldi LCD_buffer,$80
rcallContrl_LCD ;写控制字入LCD中第一行0位
ldi cnt_LCD_bit,16
rcallRead_data
ldi LCD_buffer,$c0
rcallContrl_LCD ;写控制字入LCD中第二行0位
ldi cnt_LCD_bit,16
rcallRead_data
here:rjmp here
sys_reset:
;SYSTEM-CHECKING!
; ...OK
.DB $53,$59,$53,$54,$45,$4D,$2D,$43,$48,$45,$43,$4B,$49,$4E,$47,$21
; S Y S T E M - C H E C K I N G !
.DB $20,$20,$20,$20,$20,$A5,$A5,$A5,$4F,$4B,$21,$20,$20,$20,$20,$20
; . . . O K !
Read_data:
wdr
lpm
mov LCD_buffer,r0
rcallWrite_LCD ;写入LCD显示数据
adiw zl,1
dec cnt_LCD_bit
brne Read_data
ret
Contrl_LCD:
ldi r16,0B00110000 ;写控制字入LCD中
out portd,r16
rcalldelay_us
cbi portd,5 ;使E=0 ,LCD片选有效
rcalldelay_us
sbi portd,5
BUSYY:
wdr
sbic pinb,7 ;读取DB7=PINB7是否为0,为0则非忙跳过一行
rjmp BUSYY ;DB7=1为忙,跳回BUSYY再等待DB7=0以写入
ldi r16,0b00100000;写入数据写入控制字
out portd,r16
rcalldelay_us ;延时以免AVR速度太快而使LCD无法工作
ldi r16,$ff ;设定B口为输出
out ddrb,r16
out portb,LCD_buffer;要写入LCD的数据TEMP1输出到PORTB
rcalldelay_us
cbi portd,5
rcalldelay_us
sbi portd,5
rcalldelay_us
swap lcd_buffer ;写低四位
out portb,LCD_buffer
rcalldelay_us
cbi portd,5
rcalldelay_us
ldi r16,0B00111000
out portd,r16
clr r16
out ddrb,r16
out portb,r16
ret
Write_LCD:
ldi r16,0B00110000 ;写数据入LCD中
out portd,r16
rcalldelay_us ;延时以免AVR速度太快而使LCD无法工作
cbi portd,5 ;使E=0, LCD片选有效
rcalldelay_us
sbi portd,5
BUZY1:
wdr
sbic pinb,7 ;读取DB7=PINB7是否为0,为0则非忙跳过一行
rjmp BUZY1 ;DB7=1为忙,跳回BUSY1再等待DB7=0以写入
ldi r16,0B00101000 ;写控制字入LCD中
out portd,r16
rcalldelay_us ;延时以免AVR速度太快而使LCD无法工作
ldi r16,$ff ;设定B口为输出
out ddrb,r16
out portb,LCD_buffer ;要写入LCD的数据TEMP1输出到PORTB
rcalldelay_us
cbi portd,5
rcalldelay_us
sbi portd,5
rcalldelay_us
swap lcd_buffer ;写低四位
out portb,LCD_buffer
rcalldelay_us
cbi portd,5
rcalldelay_us
ldi r16,0B00111000 ;写控制字入LCD中
out portd,r16
rcalldelay_us
clr r16 ;PORTB为输入
out ddrb,r16
out portb,r16
ret
delay_us:
ldi cnt_us,$50 ;//24
delay_us_1:
wdr
dec cnt_us
brne delay_us_1
ret
delay:
;延时时间对照表
;**************************************
;fos=8MHz
;r16time r16 timer16 time
;22 1ms 29 2ms 40 5ms
;51 10ms 65 20ms 90 50ms
;114100ms 144200ms 197 500ms
;249 1s
;**************************************
push r16
del0: push r16
del1: push r16
del2: push r16
del3: dec r16
brne del3
pop r16
dec r16
brne del2
pop r16
dec r16
brne del1
pop r16
dec r16
brne del0
pop r16
ret 自己顶一下,请好心人帮帮我,万分感谢!
页:
[1]