hongmei 发表于 2006-4-8 11:50:16

用汇编程序控制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

hongmei 发表于 2006-4-14 20:16:50

自己顶一下,请好心人帮帮我,万分感谢!
页: [1]
查看完整版本: 用汇编程序控制LCD1602B的问题