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
|