Skip to content

6502 - Programmbeispiel am LCD

Vollständiger Adressdekoder

alt: "Schaltplan des Adressdekoders", w:100

Initialisierung und Anzeige auf dem LCD

alt: "Schaltplan des LCD", w:50

  • Befehlsregister des LCD (RS=0): 0x7F10
  • Datenregister des LCD (RS=1): 0x7F11

alt: "Ansteuerung des LCD", src: "HD44780 Datenblatt, S. 24f", w:66

Initialisierung und Anzeige einer Zeichenkette

LCD_CMD = 0x7F10
LCD_DATA = 0x7F11

    .org 0x8000
reset:
    cli
    ldx #$ff
    txs

    lda #0b00111000
    sta LCD_CMD
    lda #0b00001110
    sta LCD_CMD
    lda #0b00000110
    sta LCD_CMD
    lda #0b00000001
    sta LCD_CMD

    ldx #0
print_loop:
    lda message,x
    beq loop
    sta LCD_DATA
    inx
    jmp print_loop

loop:
    jmp loop

message:
    .asciiz "Hello World!"

Auslesen der Busy-Flag

Auslesen der Busy-Flag: Subroutine

    lda #0b00111000
    jsr lcd_command
    lda #0b00001110
    jsr lcd_command
    lda #0b00000110
    jsr lcd_command
    lda #0b00000001
    jsr lcd_command

lcd_command:
    sta LCD_CMD
lcd_wait: 
    lda LCD_CMD
    and #0x80
    bne lcd_wait
    rts

Programmierung eines Zählers

  • Auf Tastendruck soll eine Variable hochgezählt werden.
  • Eine Anzeige dieser Zählervariable auf dem LCD.

Manipulation der Cursorposition und Anzeige von ASCII-Zeichen

  • Um den Cursor des LCDs zu bewegen, muss die DDRAM-Adresse verändert werden.
  • Zeile 1 beginnt mit Adresse 0x00, die Zeile 2 mit Adresse 0x40. Pro Spalte wird der Adresswert um 1 erhöht.

Anzeige vorlaufender ASCII-Zeichen

counter = 0x00
update = 0x01

LCD_CMD = 0x7F10
LCD_DATA = 0x7F11
LCD_GOTO_LINE1 = 0x80
LCD_GOTO_LINE2 = 0xC0

    ...
    lda #32
    sta counter
    lda #1
    sta update
    ...    
loop:
    lda update
    beq loop

    lda #LCD_GOTO_LINE1
    jsr lcd_command
    lda counter
    sta LCD_DATA

    lda #0
    sta update
    jmp loop

...
irq:
    pha
    lda IFR
    and #CA1
    beq exit_irq
    inc counter
    inc update
    bit ORA
exit_irq:
    pla
    rti

alt: "ASCII Tabelle", src: "whatasciicode.com", w:75

Taster entprellen

alt:"Schalterprellen - Drücken", w:33, half:1 alt:"Schalterprellen - Loslassen", w:33, half:1

alt:"Hardware-Entprellen - Schaltungsvorschlag", src: "Entprellte Taste - Wikipedia Commons", w:33, half:1 alt:"Hardware-Entprellen - Signalverlauf", src: "mikrocontroller.net", w:50, half:1

Software-Verzögerung in der ISR zum Entprellen

irq:
    pha
    lda IFR
    and CA1
    beq exit_irq

    ldx #0xFF
debounce_loop:
    dex
    bne debounce_loop

    lda ORA
    and #0x01
    bne exit_irq

    inc counter
    inc update
exit_irq:
    pla
    rti

Darstellung als Binärzahl

  • Schiebe-Anweisungen:
    ASL (Arithmetic Shift Left): C ← 7 6 5 4 3 2 1 0 ← 0
    LSR (Logical Shift Right): 0 → 7 6 5 4 3 2 1 0 → C
    ROL (Rotate Left): C ← 7 6 5 4 3 2 1 ← C
    ROR (Rotate Right): C → 7 6 5 4 3 2 1 → C

Anzeige des Zählers als Binärzahl auf dem LCD

counter = 0x00
update = 0x01
convertion = 0x02
number_buff = 0x03 ; 9 Byte

    ...
    lda #0
    sta counter
    lda #1
    sta update
    lda #0
    sta number_buff+8
    ...
loop:
    lda update
    beq loop

    lda #LCD_GOTO_LINE1
    jsr lcd_command

    lda counter
    sta convertion
    ldx #8
convertion_loop:
    ; Modulo
    lda #1
    and convertion
    adc #48
    sta number_buff-1,x

    ; /2
    lsr convertion

    dex
    bne convertion_loop

    ldx #0
print_loop:
    lda number_buff,x
    beq exit_print_loop
    sta LCD_DATA
    inx
    jmp print_loop

exit_print_loop:
    lda #0
    sta update
    jmp loop

    ...

Darstellung als Hexadezimalzahl

Anzeige des Zählers als Hexadezimalzahl auf dem LCD

  ...
loop:
    lda update
    beq loop

    lda #LCD_GOTO_LINE1
    jsr lcd_command

    lda counter
    clc
    lsr
    clc
    lsr
    clc
    lsr
    clc
    lsr
    jsr lcd_print_nibble

    lda counter
    and #0xF
    jsr lcd_print_nibble

    lda #0
    sta update
    jmp loop

lcd_print_nibble:
    cmp #10
    bpl lcd_print_nibble_letter
    clc
    adc #48
    sta LCD_DATA
    rts
lcd_print_nibble_letter:
    clc
    adc #55
    sta LCD_DATA
    rts

Darstellung als BCD-Zahl

  • BCD = binary coded decimal
  • Jeweils eine Dezimalziffer wird durch exakt 4 Bits dargestellt.

Darstellung im BCD-Format

Dezimalzahl BCD
0 0000 0000
1 0000 0001
2 0000 0010
... ...
9 0000 1001
10 0001 0000
11 0001 0001
12 0001 0010
... ...
19 0001 1001
20 0010 0000
... ...
99 1001 1001
  • Setzen des Decimal-Bits im Status-Register

alt: "6502 Status Register", w:50,  src: "W65C02 Datenblatt, S. 8"

  • Zugehörige Anweisungen:
    SED Set Decimal Mode
    CLD Clear Decimal Mode
  • Der Decimal Mode funktioniert nur mit den beiden Anweisungen ADC und SBC.

Inkrementieren der Zählervariable als BCD

    lda counter
    sed
    clc
    adc #1
    cld
    sta counter
    inc update