Punktmatrixanzeige zur Ausgabe von Zeichen
![]() |
![]() |
Anschluss an µControllerZeilen R1..R7 an PA0..PA6 pos. Logik Spalten C1..C5 an PC0..PC4 über Treiberbaustein. -> pos. Logik LED leuchtet wenn Zeile = 1 und Spalte = 1. |
Balken wandert von Spalte 1 bis Spalte 5
| Assembler [Quellcode] | C-Code [Quellcode] |
|---|---|
.include "m16def.inc"
.def tmp = R16 ;tmp-Register zum Arbeiten
.def tmp2 = R17
.def spalte = R18 ;Spalte fuer Darstellung
jmp reset ;Einsprung nach Reset
.org $2a ;folgender Code ab Adresse $2a
reset:
ldi tmp,high(RAMEND);Oberste RAM-Adresse holen
out SPH, tmp ;Stack-Pointer initialisieren
ldi tmp,low(RAMEND)
out SPL, tmp
ldi tmp,$ff
out DDRA,tmp ;PA als Ausgang
out DDRC,tmp ;PC als Ausgang
ldi spalte,1 ;Spalte initialisieren
out PORTA,tmp ;alle ZeilenLED an
loop:
out PORTC,spalte;Spalte einschalten
rol spalte ;naechste Spalte
sbrc spalte,5 ;wenn Spalte 6
ldi spalte,1 ;dann wieder Spalte 1
rcall wait ;warte zum Anzeigen
rjmp loop
wait:
ldi tmp,100 ;aeusseren Zaehler laden 100 ms
wl1:
ldi tmp2,250 ;inneren Zaehler 1ms bei 1Mhz
wl2:
nop
dec tmp2 ;tmp2--
brne wl2 ;Sprung wenn nicht null
dec tmp ;tmp--
brne wl1 ;Sprung wenn nicht null
ret
|
#include <avr/io.h> // Definitionen laden
#include <util/delay.h> // Delay-Bibliothek laden
int main(){
unsigned char spalte=1; // erste Spalte
DDRA=0xff; // PA als Ausgang
DDRC=0xff; // PC als Ausgang
PORTA=0xff; // alle LED an
while(1){ // Endlosschleife
PORTC = spalte; // Spalte anschalten
spalte *= 2; // naechste Spalte
if (spalte > 0b00010000)
spalte = 1;
_delay_ms(100); // warte 100ms
}
return 0;
}
|
Ausgeben eines Zeichens mit indirekter Adressierung des Programmspeichers
| Assembler [Quellcode] | C-Code [Quellcode] |
|---|---|
.include "m16def.inc"
.def tmp = R16 ;tmp-Register zum Arbeiten
.def tmp2 = R17
.def spalte = R18 ;Spalte fuer Darstellung
jmp reset ;Einsprung nach Reset
.org $2a ;folgender Code ab Adresse $2a
reset:
ldi tmp,high(RAMEND);Oberste RAM-Adresse holen
out SPH, tmp ;Stack-Pointer initialisieren
ldi tmp,low(RAMEND)
out SPL, tmp
ldi tmp,$ff
out DDRA,tmp ;PA als Ausgang
out DDRC,tmp ;PC als Ausgang
spalte1:
ldi spalte,1 ;Spalte1 initialisieren
ldi ZH, high(daten*2) ;Datenzeiger initialisieren
ldi ZL, low(daten*2)
nspalte:
lpm tmp, z+ ;lade Daten aus Flash
out PORTA,tmp ;ausgeben Spalte
out PORTC,spalte;Spalte einschalten
rcall wait ;warte zum Anzeigen
rol spalte ;naechste Spalte
sbrc spalte,5 ;wenn Spalte 6
rjmp spalte1 ;dann wieder Spalte 1
rjmp nspalte ;sonst naechste Spalte
wait:
ldi tmp,10 ;aeusseren Zaehler laden 10 ms
wl1:
ldi tmp2,250 ;inneren Zaehler 1ms bei 1Mhz
wl2:
nop
dec tmp2 ;tmp2--
brne wl2 ;Sprung wenn nicht null
dec tmp ;tmp--
brne wl1 ;Sprung wenn nicht null
ret
daten:
.db $08,$04,$7E,$04,$08
|
#include <avr/io.h> // Definitionen laden
#include <util/delay.h> // Delay-Bibliothek laden
const unsigned char daten[]={0x08,0x04,0x7e,0x04,0x08};
// Tabelle mit Daten
int main(){
unsigned char spalte=1,dzeiger=0; // erste Spalte
DDRA=0xff; // PA als Ausgang
DDRC=0xff; // PC als Ausgang
while(1){ // Endlosschleife
PORTA = daten[dzeiger++]; // Zeile laden
PORTC = spalte; // Spalte anschalten
spalte *= 2; // naechste Spalte
if (spalte > 0b00010000)
spalte = 1;
dzeiger = 0;
_delay_ms(10); // warte 10ms
}
return 0;
}
|
Ausgeben mehrerer Zeichen mit indirekter Adressierung des Programmspeichers
| Assembler [Quellcode] | C-Code [Quellcode] |
|---|---|
.include "m16def.inc"
.def tmp = R16 ;tmp-Register zum Arbeiten
.def tmp2 = R17
.def spalte = R18 ;Spalte fuer Darstellung
.def zeichen = R19 ;Index des Zeichens
.def durchlauf = R20
jmp reset ;Einsprung nach Reset
.org $2a ;folgender Code ab Adresse $2a
reset:
ldi tmp,high(RAMEND);Oberste RAM-Adresse holen
out SPH, tmp ;Stack-Pointer initialisieren
ldi tmp,low(RAMEND)
out SPL, tmp
ldi tmp,$ff
out DDRA,tmp ;PA als Ausgang
out DDRC,tmp ;PC als Ausgang
spalte1:
inc durchlauf ;weiterer Durchlauf
cpi durchlauf,50;nach 50 Durchlauf
brlo nix
clr durchlauf
inc zeichen ;neues Zeichen
andi zeichen,1
nix:
ldi spalte,1 ;Spalte1 initialisieren
ldi ZH, high(daten*2) ;Datenzeiger initialisieren
ldi ZL, low(daten*2)
ldi tmp,5 ;5 Byte pro Zeichen
mul tmp,zeichen ;Position in der Tabelle
add ZL,R0 ;Addiere Position
adc ZH,R1
nspalte:
lpm tmp, z+ ;lade Daten aus Flash
out PORTA,tmp ;ausgeben Spalte
out PORTC,spalte;Spalte einschalten
rcall wait ;warte zum Anzeigen
rol spalte ;naechste Spalte
sbrc spalte,5 ;wenn Spalte 6
rjmp spalte1 ;dann wieder Spalte 1
rjmp nspalte ;sonst naechste Spalte
wait:
ldi tmp,10 ;aeusseren Zaehler laden 10 ms
wl1:
ldi tmp2,250 ;inneren Zaehler 1ms bei 1Mhz
wl2:
nop
dec tmp2 ;tmp2--
brne wl2 ;Sprung wenn nicht null
dec tmp ;tmp--
brne wl1 ;Sprung wenn nicht null
ret
daten:
.db $08,$04,$7E,$04,$08,$10,$20,$7E,$20,$10
|
#include <avr/io.h> // Definitionen laden
#include <util/delay.h> // Delay-Bibliothek laden
const unsigned char daten[2][5]={{0x08,0x04,0x7e,0x04,0x08},
{0x10,0x20,0x7e,0x20,0x10}};
// Tabelle mit Daten
int main(){
unsigned char spalte=1,dzeiger=0,zeichen=0,durchlauf=0;
DDRA=0xff; // PA als Ausgang
DDRC=0xff; // PC als Ausgang
while(1){ // Endlosschleife
PORTA = daten[dzeiger++]; // Zeile laden
PORTC = spalte; // Spalte anschalten
spalte *= 2; // naechste Spalte
if (spalte > 0b00010000)
spalte = 1;
dzeiger = 0;
durchlauf++;
if (durchlauf > 50){
durchlauf = 0;
zeichen = 1 - zeichen;
}
}
_delay_ms(10); // warte 10ms
}
return 0;
}
|
Punktmatrixanzeige zur Ausgabe von Zeichen mit Interruptsteuerung
[AVR-GCC-Tutorial: Interrupts] [ATmega16 Headerdatei: iom16.h]
| Assembler [Quellcode] | C-Code [Quellcode] |
|---|---|
.include "m16def.inc"
.def tmp = R16 ;tmp-Register zum Arbeiten
.def tmp2 = R17
.def spalte = R18 ;Spalte fuer Darstellung
.def zeichen = R19 ;Index des Zeichens
.def durchlauf = R20;Zaehler fuer Zeichenwechsel
.def itmp = R21 ;tmp-Register bei Interrupt
.def led = R22 ;RGB-LED animieren
jmp reset ;Einsprung nach Reset
.org OVF0addr ;Einsprung nach Timer0 Ueberlauf
jmp isr_timer ;nach ISR
.org $2a ;folgender Code ab Adresse $2a
isr_timer:
in itmp,SREG ;SREG retten
push itmp
sbrs spalte,5 ;wenn nicht Spalte 6
rjmp nspalte ;dann naechste Spalte
inc durchlauf ;weiterer Durchlauf
cpi durchlauf,50;nach 50 Durchlauf
brlo nix
clr durchlauf
inc zeichen ;neues Zeichen
andi zeichen,1
nix:
ldi spalte,1 ;Spalte1 initialisieren
ldi ZH, high(daten*2) ;Datenzeiger initialisieren
ldi ZL, low(daten*2)
ldi itmp,5 ;5 Byte pro Zeichen
mul itmp,zeichen ;Position in der Tabelle
add ZL,R0 ;Addiere Position
adc ZH,R1
nspalte:
lpm itmp, z+ ;lade Daten aus Flash
out PORTA,itmp ;ausgeben Spalte
in itmp, PORTC
andi itmp,0b11100000
or itmp,spalte
out PORTC,itmp ;Spalte einschalten
rol spalte ;naechste Spalte
pop itmp
out SREG,itmp
reti ;return from Interrupt
reset: ;Hauptprogramm
ldi tmp,high(RAMEND);Oberste RAM-Adresse holen
out SPH, tmp ;Stack-Pointer initialisieren
ldi tmp,low(RAMEND)
out SPL, tmp
ldi tmp,$ff
out DDRA,tmp ;PA als Ausgang
out DDRC,tmp ;PC als Ausgang
ldi tmp,3 ;Systemtakt / 64
out TCCR0,tmp
in tmp,TIMSK ;Timerinterrupt einschalten
ori tmp, 1 << TOIE0
out TIMSK,tmp
sei ;globale Interruptfreigabe
loop:
inc led ;naechste Farbe
andi led,7 ;nur von 0 bis 7
mov tmp,led
swap tmp ;vertausche Nibble
lsl tmp ;und noch einmal schieben
in tmp2,PORTC ;schreibe auf PORTC
andi tmp2,0b00011111
or tmp2,tmp
out PORTC,tmp2
rcall wait
rjmp loop
wait:
ldi tmp,150 ;aeusseren Zaehler laden 150 ms
wl1:
ldi tmp2,250 ;inneren Zaehler 1ms bei 1Mhz
wl2:
nop
dec tmp2 ;tmp2--
brne wl2 ;Sprung wenn nicht null
dec tmp ;tmp--
brne wl1 ;Sprung wenn nicht null
ret
daten:
.db $08,$04,$7E,$04,$08,$10,$20,$7E,$20,$10
|
#include <avr/io.h> // Definitionen laden
#include <util/delay.h> // Delay-Bibliothek laden
#include <avr/interrupt.h> // Interrupt Vektroren laden
const unsigned char daten[2][5]={{0x08,0x04,0x7e,0x04,0x08},
{0x10,0x20,0x7e,0x20,0x10}};
volatile unsigned char zeichen=0;
ISR(TIMER0_OVF_vect){
static unsigned char spalte=1,dzeiger=0,durchlauf=0;
PORTA = daten[zeichen][dzeiger++]; // Zeile laden
PORTC = (PORTC & 0b11100000) | spalte; // Spalte anschalten
spalte *= 2; // naechste Spalte
if (spalte > 0b00010000){
spalte = 1;
dzeiger = 0;
durchlauf++;
if (durchlauf > 50){
durchlauf = 0;
zeichen = 1 - zeichen;
}
}
}
int main(){
unsigned char led =0;
TCCR0 = 3; // Systemtakt / 64
TIMSK |= (1<<TOIE0); // Timerinterrupt frei geben
DDRA=0xff; // PA als Ausgang
DDRC=0xff; // PC als Ausgang
sei(); // globale Interruptfreigabe
while(1){ // Endlosschleife
led++;
led &= 7;
PORTC = (PORTC & 0b00011111) | (led<<5);
_delay_ms(150); // warte 150ms
}
return 0;
}
Liste der Interrupt Vektornamen für C
|


