Forum: Projekte & Code LCD 2x16 Ansteuerung per AVR


von Volker Urban (Gast)


Lesenswert?

(Wiedermal) eine Ansteuerung eines 2x16 Punktmatrix Display's
per AVR. Source im Anhang, ich werde erst in einer woche
wieder am Forum teilnehen koennen.

Besonderheiten in der Funktion:
-------------------------------
-Displaydaten werden aus EEPROM Bereich gelesen. Das gestattet
 eine Žnderung des Anzeigetextes ohne den PROGRAMMFlash be-
 schreiben zu mssen und schont so die Lebenszeit.

-Im Displaytext gibt es Kommandocodes fr:
 "Setze Cursor an Beginn 2. Zeile"
 "Mach Pause fr 1 sec"
 "L”sche Display"

-Der WDT startet das Programm nach max. WDT Pause neu.

-Es wurde versucht m”glichst stromsparend zu programmieren:
 .Analogcomp wird abgeschaltet
 .Timing wird per TimerINT und SLEEP erzeugt

Besonderheiten im Code:
-----------------------
 -nicht vergessen die Pfad fr das Include anzupassen

 -die 410 ns Pause werden mit einem Befehl erzeugt
  (read EEPROM stoppt den AVR fr 4 takte)

 -l„uft auf 1200, andere ungetestet, Anpassungen evt n”tig
  (polling bei EEPROM read)

In neuen versionen (falls jemals):
--------------------------------------
 -Komprimierung fr EEP Daten auf 6 bit:
  fr Gross- u. Kleinbuchstaben reichen 2^6 Zeichen,
  somit k”nnen 3 Bytes EEP zu 4 Buchstaben dekomprimiert werden,
  fehlende Zeichen (z.B. Ziffer) per Steuerzeichen fr
  "Zeichentabellenwechsel" realisierbar

 -Mehr Displayfunktionen realisieren (Scrolling,Cursor on/OFF,...)

Historie:
---------
Version V002 (Vorg„nger unver”ffentlicht)



Volker Urban

von Volker urban (Gast)


Lesenswert?

;Anhang klappt nicht ?! ->
;Source als texteingabe:
.nolist
.include "c:\MPRO\avr_asm\incLUDES\1200def.inc"
.list

;***********************************************************
;
; AVR LCD routines
; Volker Urban
;
;***********************************************************

;LCD interface

;AVR is 1200, so subroutines are not muched used (3 words stack)
;clock is 9.6 MHz
;AVR controller LCD display routines

;Pin
;1 GND
;2 VCC (+5V)
;3 Contrast
;4 RS (Register Select 1=data 0=command)
;5 R/W (0=write to display, 1= read from display)
;6 OE (Enable - data clocked on neg transition)
;7-14 D0-D7 (data)

;pinout as 22.Feb.2002
;PB0 -> 0
;PB1 -> 0
;PB2 -> D4   (11)
;PB3 -> D5   (12)
;PB4 -> D6   (13)
;PB5 -> D7   (14)
;PB6 -> res  (4)
;PB7 -> E    (6)

; Definitions : register and Bits
;*************
.def    delay           =r16    ;temporary register
.def    delay1          =r17
.def    delay2          =r18    ;temporary register
.equ    RS              =6      ; bit 6 at port D => LCD Register Select
.equ    OE              =7
.def    temp            =r19    ;temporary register
.def    temp_1          =r20
.def    temp_2          =r21    ;temporary register
.def    temp_3          =r22
.def    eeadr                  =r23.def    eecnt                   =r24
.def    misc                    =r25    ;a few bits used

;******************************
; Code
;******
.cseg
RESET:
.org 0
        rjmp    START           ; Reset vector bypass subroutines

.org INT0addr
 RETI
.org OVF0addr
 RJMP tmt_int
.org ACIaddr
 RETI

;***********
; subroutines
;***********
;MCU

.MACRO sleep_en
 IN  temp,MCUCR           ;going to sleep
 CBR temp,(1<<SM)             ;choose idle mode
 SBR temp,(1<<SE)             ;sleep enable
 OUT MCUCR,temp
.ENDMACRO

.MACRO  read_eep
  OUT  EEAR @0        ;set address
  SBI  EECR,EERE              ;start reading
.ENDM

;******************************
;* TIMINGS
;* adjust for at1200 running @10 MHz
;******************************

.MACRO WAIT_410N
 SBI     EECR,EERE       ; stop for 4 cycle (reads EEPROM)
.ENDMACRO

.MACRO WAIT_140N
 nop
.ENDMACRO



WAIT_40u:
 clr delay2
 ldi delay,2     ;set timer prescale  ck/8
 ldi delay1,255 - 50    ; set ticks to count
 RJMP WAIT_DEL

WAIT_2m:
 clr delay2
 ldi delay,5     ;set timer prescale  ck/1024
 ldi delay1,255 - 20    ; set ticks to count
 RJMP WAIT_DEL

WAIT_1s:
 LDI delay2,0x80
 ldi delay1,0     ;count start value
 ldi delay,5     ;set timer prescale  ck/1024
 RJMP WAIT_DEL

WAIT_del:
 out tcnt0,delay1 ;set timer start value
 SEI              ;global INT enable
 out tccr0,delay  ;set timer prescale and start
 SLEEP
 DEC delay2
 BRPL WAIT_del    ;branch if plus
 RET

; INTERUPT SEVICE ROUTINE (TIMER)
TMT_INT:
 ldi temp_3,0     ;stop timer
 out tccr0,temp
 RETI


;******************************************************
;
; Writes data/Command to display
; incorporates 40 usec delay
; data in temp
;
;********************************************************
DATA_display:
          SBR     misc,1<<1
                  RJMP    write2display
COMMAND_display:
          CBR     misc,1<<1
                  RJMP    write2display

write2DISPLAY:
          mov     temp_1,temp     ; Copy data to temp_1
                  CBR     misc,1<<0               ; mark 1st half cycle
          RJMP    DATA_DISPLAY_halfCycle
DD2nd_half:
                  SBR     misc,1<<0               ; mark 1st half cycle
          MOV     temp,temp_1
          swap    temp  ; get lower 4 bits

DATA_DISPLAY_halfCycle:
        andi    temp,0b11110000       ; mask off lower 4 bits
                LSR     temp                    ; shift to fit PORT B
                LSR     temp                    ; shift to fit PORT B
                SBRC    misc,1                  ; misc marks read access
            SBR     temp,1<<RS          ; DATA is written (RS=1[bit6])
        out     PORTB,temp      ; write lower 4 bits to LCD 
;
                WAIT_140N
        SBI     PORTB,OE        ; OE bit high
                WAIT_410N
        CBI     PORTB,OE        ; OE low to clock in data

                SBRS    misc,0                  ;in which half are we?
                RJMP    DD2nd_half
                RJMP    WAIT_40u        ;wait execution time


;*** LCD clear 1.64 ms lcd exec time
.MACRO LCD_CLR
 LDI TEMP,0x01
 RCALL COMMAND_DISPLAY
 RCALL WAIT_2m
.ENDM

;*** Cursor HOME 1.64 ms lcd exec time
.MACRO LCD_HOME
 LDI TEMP,0x02
 RCALL COMMAND_DISPLAY
 RCALL WAIT_2m
.ENDM

;*** set cursor to 2nd line: 40us lcd exec time
.MACRO LCD_2ndline ;
 LDI temp,0xc0     ; DDRAM addr = 0x40
 RCALL COMMAND_DISPLAY
.ENDM

;*******************
;* MAIN PROGRAMM BODY
;*******************

START:
;* Setting Up MCU
 LDI  temp,0b00000111    ; WDT period max and disable
 OUT  WDTCR,temp

 CLI                     ;disable all interupts
disable_analogcomp:              ;saves Power
 CBI  ACSR,ACIE          ;switch AC Interupt off, needed before ACD=1
 SBI  ACSR,ACD               ;switch AC off
 SLEEP_EN                                ;sleep enable
 ldi delay1,1<<TOIE0     ;timer INT enable
 out TIMSK,delay1  ; enable timer INT

;* Setting Up Display

        ldi     temp,0xff
        out     DDRB,temp           ; PORTB = all outputs;
                ldi     temp,0x7f
                out     DDRD,temp                       ;PORTD  = 
debugport (all out)
        ldi     temp,0x09               ; Wait at least 15msec after
D1:                                     ; powerup before writing
        rcall   WAIT_2m              ; to display
        dec     temp
        brne    D1

        ldi     temp,0b00001100         ; System set
        out     PORTB,temp
                WAIT_140N
        sbi     PORTB,OE                 ; OE high to clock in data
                WAIT_410N
                cbi     PORTB,OE 
;clock data in
        rcall   WAIT_2m             ; Wait 4,1 msec
        rcall   WAIT_2m
        rcall   WAIT_2m

        ldi     temp,0b00001100         ; System set
        out     PORTB,temp
                WAIT_140N
        sbi     PORTB,OE                 ; OE high to clock in data
        WAIT_410N
        cbi     PORTB,OE                                        ;clock 
data in
        rcall   WAIT_2m             ; Wait 4,1 msec

        ldi     temp,0b00001100         ;System set
        out     PORTB,temp
                WAIT_140N
        sbi     PORTB,OE                 ; OE high to clock in data
                WAIT_410N
        cbi     PORTB,OE                 ; OE low to clock in data
                WAIT_410N
        ldi     temp,0b00001000         ;System set; 4bit display
        out     PORTB,temp
                WAIT_140N
        sbi     PORTB,OE                 ; OE high to clock in data
                WAIT_410N
        cbi     PORTB,OE                 ; OE low to clock in data


        rcall   WAIT_40u              ;? Wait at least 40usec (2 msec)


        ldi     temp,0x28               ; Function set
                                        ; 4 bit mode, 2 lines 5X7 pixels
        rcall   COMMAND_DISPLAY         ;write to display

        ldi     temp,0x08         ;Display off, cursor off
                                        ; blink off
        rcall   COMMAND_DISPLAY

        ldi     temp,0x01         ; Display clear
        rcall   COMMAND_DISPLAY
        rcall   WAIT_2m              ; Need to wait 1.6 msec after clear

        ldi     temp,0x06         ; Entry mode set
                                        ; Increment RAM, dont shift 
display
        rcall   COMMAND_DISPLAY

        ldi     temp,0x0d         ; Display,cursor on, blink off
        rcall   COMMAND_DISPLAY


;write EEPROM to display
.equ  DIS_CLR   =0x01  ;clear display
.equ  DIS_2L    =0x02  ;set cursor to start of 2nd line
.equ  PAUSE     =0x00  ;do nothing for appr. 2 s
.equ  DIS_END   =0x03

           ldi  eeadr,0x00 ; adr 0x00 holds datalength
       READ_EEP,eeadr
           IN   eecnt,EEDR                ;get byte from EEPR
disp_loop:
           INC  eeadr
       READ_EEP,eeadr
           IN    temp,EEDR                ;get byte from EEPROM
           CPI   temp,PAUSE
           BRNE disp_loop1
           RCALL WAIT_1s
           RJMP  disp_loop4

disp_loop1:                                       ;clear
           CPI   temp,DIS_CLR
           BRNE disp_loop2
           LCD_CLR
           RJMP  disp_loop4

disp_loop2:                                      ; set cursor at start 
2nd line
           CPI   temp,DIS_2L
           BRNE  disp_loop3
           LCD_2ndline
           RJMP  disp_loop4

disp_loop3:
           CPI   temp,0x03               ;cursor home
           BRNE  disp_loop5
           LCD_HOME
           RJMP  disp_loop4


disp_loop5:
           RCALL data_display
disp_loop4:
           DEC   eecnt
           BRNE  disp_loop


forever: WDR
         LDI temp, 0x0f                           ;set slowest WDT
                 OUT WDTCR,temp
                 LDI temp,0x30                            ;enable and 
startWDT
                 OUT MCUCR,temp

         SLEEP                                        ;sleep WDT

.eseg
eelength:
.db eestop - eestart + 1
eestart:
.db "Dipl. Ing (Uni.)"
.db DIS_2L
.db "Heinz Mustermann"
.db PAUSE
.db DIS_CLR
.db "H.Mustermann"
.db 0x40
.db DIS_2L
.db "musternet.de"
eestop:
.db PAUSE

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.