www.mikrocontroller.net

Forum: Projekte & Code LCD 2x16 Ansteuerung per AVR


Autor: Volker Urban (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Volker urban (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.