fuchs hat folgendes geschrieben: |
...hast du deine AVRs mit assembler oder in c programmiert? |
Code: |
.include "m16def.inc" ;bzw. 2333def.inc .def temp1 = r21 .def temp2 = r22 .def temp3 = r23 ;############################################################################# ;############ Stack initialisieren um Unterprogramme aufzurufen ############## ;############################################################################# ldi r16, LOW(RAMEND) ; LOW-Byte der obersten RAM-Adresse out SPL, r16 ldi r16, HIGH(RAMEND) ; HIGH-Byte der obersten RAM-Adresse out SPH, r16 ;############################################################################# ;############################################################################# ;########### Startwerte setzen ############## ;############################################################################# ldi r16, 0xFF out DDRB, r16 ;Port B durch Ausgabe von 0xFF ins ;Richtungsregister DDRB als Ausgang konfigurieren ldi r16, 0xFF out DDRC, r16 ;Port C durch Ausgabe von 0xFF ins ;Richtungsregister DDRB als Ausgang konfigurieren ldi r16, 0x00 out DDRD, r16 ;Port D durch Ausgabe von 0x00 ins ;Richtungsregister DDRD als Eingang konfigurieren ldi r16, 0xFF out PORTB, r16 ;PORTB auf 0xFF setzen -> alle LEDs aus rcall lcd_init ;Display initialisieren rcall lcd_clear ;Display löschen rcall setze1 ; Taste 1 wurde gerückt zum Start des Prgoramms ;############################################################################# ;############################################################################# ;########### Hauptprogramm ############## ;############################################################################# main: sbrs r20,1 ; Ist im Arbeitsregister 20 das 2 Bit null so wurde Taste 1 gedrückt und lauflicht 1 wird ausgeführt rcall lauflicht1 sbrs r20,2 rcall lauflicht2 sbrs r20,3 rcall lauflicht3 sbrs r20,4 rcall lauflicht4 sbrs r20,5 rcall lauflicht5 rjmp main ;############################################################################# ;############################################################################# ;########### Hauptprogramm ############## ;############################################################################# lese: sbis PIND,2 ; Ist im Inputregister das 2 Bit null so wird Taste 1 gedrückt und setzte 1 wird ausgeführt rcall setze1 sbis PIND,3 rcall setze2 sbis PIND,4 rcall setze3 sbis PIND,5 rcall setze4 sbis PIND,6 rcall setze5 ret ;############################################################################# ;############################################################################# ;########### Hauptprogramm ############## ;############################################################################# setze1: ldi r20, 0b11111101 ;Arbeitsregister 20 wird auf 11111101 gesetzt rcall schreibe ; schreibe wird ausgeführt ldi temp1, '1' ;Zeichen '1' ans Dislpay senden rcall lcd_data ; " ret ;############################################################################# ;############################################################################# ;########### Hauptprogramm ############## ;############################################################################# setze2: ldi r20, 0b11111011 rcall schreibe ldi temp1, '2' ;Zeichen anzeigen rcall lcd_data ret ;############################################################################# ;############################################################################# ;########### Hauptprogramm ############## ;############################################################################# setze3: ldi r20, 0b11110111 rcall schreibe ldi temp1, '3' ;Zeichen anzeigen rcall lcd_data ret ;############################################################################# ;############################################################################# ;########### Hauptprogramm ############## ;############################################################################# setze4: ldi r20, 0b11101111 rcall schreibe ldi temp1, '4' ;Zeichen anzeigen rcall lcd_data ret ;############################################################################# ;############################################################################# ;########### Hauptprogramm ############## ;############################################################################# setze5: ldi r20, 0b11011111 rcall schreibe ldi temp1, '5' ;Zeichen anzeigen rcall lcd_data ret ;############################################################################# ;############################################################################# ;########### Proceduer Schreibe ############## ;############################################################################# schreibe: rcall lcd_clear ;Display löschen ldi temp1, 'L' ;Schreibt 'Lauftlicht Nr ' ins Display rcall lcd_data ldi temp1, 'a' rcall lcd_data ldi temp1, 'u' rcall lcd_data ldi temp1, 'f' rcall lcd_data ldi temp1, 'l' rcall lcd_data ldi temp1, 'i' rcall lcd_data ldi temp1, 'c' rcall lcd_data ldi temp1, 'h' rcall lcd_data ldi temp1, 't' rcall lcd_data ldi temp1, ' ' rcall lcd_data ldi temp1, 'N' rcall lcd_data ldi temp1, 'r' rcall lcd_data ldi temp1, ' ' rcall lcd_data ret ;############################################################################# ;############################################################################# ;########### Procedure Warte ############## ;############################################################################# warte: ; delaying 199998 cycles: ;Es werden 199998 Dürchgänge nix getan ldi R17, $06 WGLOOP0: ldi R18, $37 WGLOOP1: ldi R19, $C9 WGLOOP2: dec R19 rcall lese ; Aber dazwischen wird bei jedem Schritt noch mal der Inputport gelesen brne WGLOOP2 dec R18 brne WGLOOP1 dec R17 brne WGLOOP0 ; ----------------------------- ret ;############################################################################# ;########### Die verscheidenen Lauflichter und LCD Proceduren ############## ;############################################################################# lauflicht1: ldi r16,0b00111111 out PORTB, r16 rcall warte ldi r16,0b11001111 out PORTB, r16 rcall warte ldi r16,0b11110011 out PORTB, r16 rcall warte ldi r16,0b11111100 out PORTB, r16 rcall warte ldi r16,0b11111111 out PORTB, r16 rcall warte ret lauflicht2: ldi r16,0b11111110 out PORTB, r16 rcall warte ldi r16,0b11111011 out PORTB, r16 rcall warte ldi r16,0b11101111 out PORTB, r16 rcall warte ldi r16,0b10111111 out PORTB, r16 rcall warte ldi r16,0b01111111 out PORTB, r16 rcall warte ldi r16,0b11011111 out PORTB, r16 rcall warte ldi r16,0b11110111 out PORTB, r16 rcall warte ldi r16,0b11111101 out PORTB, r16 rcall warte ret lauflicht3: ldi r16,0b11111100 out PORTB, r16 rcall warte ldi r16,0b11110000 out PORTB, r16 rcall warte ldi r16,0b11000000 out PORTB, r16 rcall warte ldi r16,0b00000000 out PORTB, r16 rcall warte ldi r16,0b00000011 out PORTB, r16 rcall warte ldi r16,0b00001111 out PORTB, r16 rcall warte ldi r16,0b00111111 out PORTB, r16 rcall warte ldi r16,0b11111111 out PORTB, r16 rcall warte ret lauflicht4: ldi r16,0b11111010 out PORTB, r16 rcall warte ldi r16,0b11101011 out PORTB, r16 rcall warte ldi r16,0b10101111 out PORTB, r16 rcall warte ldi r16,0b00111111 out PORTB, r16 rcall warte ldi r16,0b01011111 out PORTB, r16 rcall warte ldi r16,0b11010111 out PORTB, r16 rcall warte ldi r16,0b11110101 out PORTB, r16 rcall warte ldi r16,0b11111100 out PORTB, r16 rcall warte ret lauflicht5: ldi r16,0b11111111 out PORTB, r16 rcall warte ldi r16,0b00111111 out PORTB, r16 rcall warte ldi r16,0b00111100 out PORTB, r16 rcall warte ldi r16,0b00001100 out PORTB, r16 rcall warte ldi r16,0b00000000 out PORTB, r16 rcall warte ldi r16,0b11000000 out PORTB, r16 rcall warte ldi r16,0b11000011 out PORTB, r16 rcall warte ldi r16,0b11110011 out PORTB, r16 rcall warte ret ;sendet ein Datenbyte an das LCD lcd_data: mov temp2, temp1 ;"Sicherungskopie" für ;die Übertragung des 2.Nibbles swap temp1 ;Vertauschen andi temp1, 0b00001111 ;oberes Nibble auf Null setzen sbr temp1, 1<<4 ;entspricht 0b00010000 out PORTC, temp1 ;ausgeben rcall lcd_enable ;Enable-Routine aufrufen ;2. Nibble, kein swap da es schon ;an der richtigen stelle ist andi temp2, 0b00001111 ;obere Hälfte auf Null setzen sbr temp2, 1<<4 ;entspricht 0b00010000 out PORTC, temp2 ;ausgeben rcall lcd_enable ;Enable-Routine aufrufen rcall delay50us ;Delay-Routine aufrufen ret ;zurück zum Hauptprogramm ;sendet einen Befehl an das LCD lcd_command: ;wie lcd_data, nur ohne RS zu setzen mov temp2, temp1 swap temp1 andi temp1, 0b00001111 out PORTC, temp1 rcall lcd_enable andi temp2, 0b00001111 out PORTC, temp2 rcall lcd_enable rcall delay50us ret ;erzeugt den Enable-Puls lcd_enable: sbi PORTC, 5 ;Enable high nop ;3 Taktzyklen warten nop nop cbi PORTC, 5 ;Enable wieder low ret ;Und wieder zurück ;Pause nach jeder Übertragung delay50us: ;50us Pause ldi temp1, $02 EGLOOP0: ldi temp2, $84 EGLOOP1: dec temp2 brne EGLOOP1 dec temp1 brne EGLOOP0 ;wieder zurück ;Längere Pause für manche Befehle delay5ms: ;5ms Pause ldi temp1, $86 PGLOOP0: ldi temp2, $C6 PGLOOP1: dec temp2 brne PGLOOP1 dec temp1 brne PGLOOP0 ret ;wieder zurück ;Initialisierung: muss ganz am Anfang des Programms aufgerufen werden lcd_init: ldi temp3,50 powerupwait: rcall delay5ms dec temp3 brne powerupwait ldi temp1, 0b00000011 ;muss 3mal hintereinander gesendet out PORTC, temp1 ;werden zur Initialisierung rcall lcd_enable ;1 rcall delay5ms rcall lcd_enable ;2 rcall delay5ms rcall lcd_enable ;und 3! rcall delay5ms ldi temp1, 0b00000010 ;4bit-Modus einstellen out PORTC, temp1 rcall lcd_enable rcall delay5ms ldi temp1, 0b00101000 ;noch was einstellen... rcall lcd_command ldi temp1, 0b00001100 ;...nochwas... rcall lcd_command ldi temp1, 0b00000100 ;endlich fertig rcall lcd_command ret ;Sendet den Befehl zur Löschung des Displays lcd_clear: ldi temp1, 0b00000001 ;Display löschen rcall lcd_command rcall delay5ms ret |
Code: |
counter=0; /*Funktionsaufrufe VOR den Zeitscheibenfunktionen*/ startfunktion(); while (1) /* schleife unendlich wiederholen */ counter++; /* Es wird die naechste Zeitscheibe "adressiert" */ if (counter & 0x01) /*Funktionen alle 5 ms*/ funktion_5ms_1(); /*Zeitkritische funktion 1*" funktion_5ms_2(); /*Zeitkritische funktion 2*" usw... else if (counter & 0x02) /*Funktionen alle 10 ms*/ funktion_10ms_1(); funktion_10ms_2(); usw.... else if (counter & 0x04) /*Funktionen alle 20 ms*/ funktion_20ms_1(); /*Zeitunkritische Funktion 1*/ funktion_20ms_2(); /*Zeitunkritische Funktion 2*/ else if ((counter & 0x08) != 0) /*Zähler zurücksetzen*/ counter = 0; |