原创 LCD三线控制

2009-11-1 10:08 2832 4 4 分类: MCU/ 嵌入式

 


 


点击开大图



写:Jon Wackley (VE3JTN)

.include "2313def.inc"


;**********************************************
;* Equates                                    *
;**********************************************


.equ    clock   = 10000000     ;10MHZ clock frequency


.equ    STACKTOP = RAMEND - 100


;**********************************************
;* The following delay constants are based on *
;* an 10MHZ clock (CLK)                       *
;* Times are not exact.                       *
;**********************************************


.equ    d15ms   = $6e          ;15ms CLK/1024
.equ    d4x1ms  = $d8          ;4.1ms CLK/1024
.equ    d1ms    = $64          ;1ms CLK/64
.equ    d500us  = $b2          ;500us CLK/64
.equ    d100us  = $f1          ;100us CLK/64
.equ    d40us   = $fa          ;40us CLK/64



.equ    TSTOP   =0             ;Stop Timer/Counter
.equ    TCK1    =1             ;Timer/Counter runs from CK
.equ    TCK8    =2             ;Timer/Counter runs from CK / 8
.equ    TCK64   =3             ;Timer/Counter runs from CK / 64
.equ    TCK256  =4             ;Timer/Counter runs from CK / 256
.equ    TCK1024 =5             ;Timer/Counter runs from CK / 1024
.equ    TEXF    =6             ;Timer/Counter runs from external falling edge
.equ    TEXR    =7             ;Timer/Counter runs from external rising edge


.equ    LCDE    =5             ;PORTB bit used for the LCD E signal
.equ    LCDDat  =6             ;PORTB bit used for the LCD serial data
.equ    LCDClk  =7             ;PORTB bit used for the LCD serial data clock



;**********************************************
;* Registers used                             *
;**********************************************


.def    SaveSREG    = r15      ;used in Delay


.def    AReg        = r16      ;working reg, like the 68HC11 A register
.def    BReg        = r17      ;working reg, like the 68HC11 B register
.def    ScratchL    = r18
.def    ScratchH    = r19
.def    DelayVal    = r20



;**********************************************
;* 100 bytes of data RAM are reserved by      *
;* the program. Only 1 byte used.             *
;**********************************************
.dseg
.org RAMEND - 99
                 
ClkDiv:        .byte 1


.cseg
.org    $000                   ;Reset Vector
        rjmp    Reset
  


 ;Interrupt vectors


.org    INT0addr               ;External Interrupt0 Vector
        reti
.org    INT1addr               ;External Interrupt1 Vector
        reti
.org    ICP1addr               ;Input Capture1 Interrupt Vector
        reti
.org OC1addr                ;Output Compare1 Interrupt Vector Address
        reti
.org    OVF1addr               ;Overflow1 Interrupt Vector
        reti
.org    OVF0addr               ;Overflow0 Interrupt Vector
        rjmp    Tim0int
.org    URXCaddr               ;UART Receive Complete Interrupt Vector
        reti
.org    UDREaddr               ;UART Data Register Empty Interrupt Vector
        reti
.org    UTXCaddr               ;UART Transmit Complete Interrupt Vector
        reti
.org    ACIaddr                ;Analog Comparator Interrupt Vector
        reti
   


Reset:
        ldi    AReg,low(STACKTOP)
        out    SPL,AReg        ;set low byte for stack pointer
        rcall  Setup           ;set up timer, LCD port bits and LCD
RPLoop:
        ldi    AReg,'H'        ;send "Hello World" to the LCD
  rcall  LCDChr
        ldi    DelayVal,d1ms   ;wait 1ms after each character is sent
        rcall  Delay
        ldi    AReg,'e'
  rcall  LCDChr
        ldi    DelayVal,d1ms
        rcall  Delay
        ldi    AReg,'l'
  rcall  LCDChr
        ldi    DelayVal,d1ms
        rcall  Delay
        ldi    AReg,'l'
  rcall  LCDChr
        ldi    DelayVal,d1ms
        rcall  Delay
        ldi    AReg,'o'
  rcall  LCDChr
        ldi    DelayVal,d1ms
        rcall  Delay
        ldi    AReg,' '
  rcall  LCDChr
        ldi    DelayVal,d1ms
        rcall  Delay
        ldi    AReg,'W'
  rcall  LCDChr
        ldi    DelayVal,d1ms
        rcall  Delay
        ldi    AReg,'o'
  rcall  LCDChr
        ldi    DelayVal,d1ms
        rcall  Delay
        ldi    AReg,'r'
  rcall  LCDChr
        ldi    DelayVal,d1ms
        rcall  Delay
        ldi    AReg,'l'
  rcall  LCDChr
        ldi    DelayVal,d1ms
        rcall  Delay
        ldi    AReg,'d'
  rcall  LCDChr
        ldi    DelayVal,d1ms
        rcall  Delay    
 
rtr:
        rjmp   rtr
        rjmp   RPLoop          ;wait here until something interesting happens
           
;**********************************************
;* Setup                                      *
;* Initialize the timer, LCD port and LCD     *
;**********************************************
Setup:              


;** Timer setup **
        ldi    AReg,TCK64
        sts    ClkDiv,AReg
        ldi    AReg,TSTOP      ;Timer 0 off (just in case)
        out    TCCR0,AReg      ;Stop timer
        ldi    AReg,0b00000010 ;Enable Timer 0 interrupt
        out    TIMSK,AReg
        sei                    ;enable interrupts


;** LCD port setup and HD44780 LCD setup **
        sbi    DDRB,LCDE       ;DDRB bit 5 = 1 = output
   sbi    DDRB,LCDDat     ;DDRB bit 6 = 1 = output
        sbi    DDRB,LCDClk     ;DDRB bit 7 = 1 = output
        cbi    PORTB,LCDE      ;set E low
        cbi    PORTB,LCDDat    ;set Data bit low
        cbi    PORTB,LCDClk    ;set Clk low
  
  ldi    BReg,TCK1024    ;switch to a 1024 clock divisor
  sts    ClkDiv,BReg
  ldi    DelayVal,d15ms  ;15ms delay
        rcall  Delay


  ldi    AReg,$30
  rcall  LCDCmd


        ldi    DelayVal,d4x1ms ;4.1ms countdown
        rcall  Delay
 
  ldi    AReg,$30
  rcall  LCDCmd


  ldi    BReg,TCK64      ;switch to a 64 clock divisor
  sts    ClkDiv,BReg


  ldi    DelayVal,d100us
        rcall  Delay


  ldi    AReg,$30
  rcall  LCDCmd



        ldi    BReg,TCK1024    ;switch to a 1024 clock divisor
  sts    ClkDiv,BReg


        ldi    DelayVal,d4x1ms
        rcall  Delay


  ldi    AReg,$38        ;RS DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
  rcall  LCDCmd          ;0   0   0   1   1   1   0   x   x
                         ;8-bit operation, 1/16 duty cycle
          ;5x8 dot matrix


  ldi    BReg,TCK64      ;switch to a 64 clock divisor
  sts    ClkDiv,BReg
  ldi    DelayVal,d40us
        rcall  Delay


  ldi    AReg,$08        ;RS DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
  rcall  LCDCmd          ;0   0   0   0   0   1   0   0   0
                         ;Display off, cursor off, blink off
  ldi    DelayVal,d40us
        rcall  Delay


  ldi    AReg,$01        ;RS DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
  rcall  LCDcmd          ;0   0   0   0   0   0   0   0   1
                         ;Clear screen, cursor home
   ldi    DelayVal,d1ms
        rcall  Delay
        rcall  Delay


  ldi    AReg,$06        ;RS DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
  rcall  LCDCmd          ;0   0   0   0   0   0   1   1   0
                         ;Increment cursor to the right when writing, don't shift screen
  ldi    DelayVal,d40us
        rcall  Delay


  ldi    AReg,$0c        ;RS DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
  rcall  LCDCmd          ;0   0   0   0   0   0   1   1   0
                         ;Display on, cursor off, blink off
  ldi    DelayVal,d40us
        rcall  Delay


        ret
      
;**********************************************
;* Write byte to LCD bus                      *
;**********************************************


;**********************************************
;* PutByte clock byte into 74hc164.           *
;* Data is in AReg                            *
;* BReg is used as acounter                   *
;**********************************************
PutByte:
        ldi    BReg,8          ;bit counter
ShiftB:
        cbi    PORTB,LCDDat    ;set LCD Data bit to 0
        lsl    AReg            ;shift bits in AReg into carry
  brcc   CLKBit          ;if zero, clock it out
        sbi    PORTB,LCDDat    ;if 1, set LCD Data bit to 1
CLKBit:
        sbi    PORTB,LCDClk    ;bit clocks on rising edge
  cbi    PORTB,LCDClk    ;bring clock back to 0
NextB:
        dec    BReg            ;shift out 8 bits
        brne   ShiftB
        ret


;**********************************************
;* LCDCmd - Send a command to the LCD         *
;* data in AReg                               *
;**********************************************
LCDCmd:
        rcall  PutByte
  cbi    PORTB,LCDDat    ;set RS low
        sbi    PORTB,LCDE      ;set E High
  cbi    PORTB,LCDE      ;set E low
  ret


;**********************************************
;* LCDChr - Display a character on the LCD    *
;* data in AReg                               *
;**********************************************
LCDChr:
        rcall  PutByte
  sbi    PORTB,LCDDat    ;set RS High
        sbi    PORTB,LCDE      ;set E High
  cbi    PORTB,LCDE      ;set E low
        ret


;**********************************************
;* Misc timing routines                       *
;**********************************************


;**********************************************
;* Timer0 overflow interrupt handler          *
;**********************************************
Tim0int:
        cli                    ;disable interrupts
        set                    ;Set T flag
        ldi     ScratchH,TSTOP ;Stop Timer 0
        out     TCCR0,ScratchH
        sei                    ;re-enable interrupts
        reti                   


;**********************************************
;* Delay   time in us based on CLK value      *
;* DelayVal holds the delay value.            *
;* ClkDiv has the prescaler value             *
;**********************************************
Delay:
        in      SaveSREG,SREG  ;Save status register
        out     TCNT0,DelayVal
        clt                    ;Clear T
  lds     ScratchH,ClkDiv
        out     TCCR0,ScratchH ;Load prescaler and run timer
Dwait: 
        brtc    Dwait          ;Wait for timer 0 interrupt to set T
        out     SREG,SaveSREG
        ret


      
;**********************************************
;* Code ends here.                            *
;**********************************************


 


 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
4
关闭 站长推荐上一条 /1 下一条