Led blinkt im Sekundentakt
von
am 25.11.2012 um 18:59 (5068 Hits)
Hallo ,
heute stelle ich ein einfaches Programm vor Led blinkt im Sekundentakt.
Es wird eine Zeitschleife 1ms im Unterprogramm erzeugt und 500mal aufgerufen ,0,5s leuchtet Die Led und 0,5s ist sie aus.
Seht selbst im Quellkode wird es gut kommentiert.
Code:;************************************************* ******************************** ; Titel: programmiervorlage ; Datum: 23.11.2012 ; Autor: enprog ; ; InformNationen zur Beschaltung ; Prozessor: ATmega32 Quarzfrequenz:extern 16MHz ; Eingänge: ; Ausgänge: ; Information zur Funktionsweise: ; ;************************************************* ****************************** ; Einbinden der Controllerspezifischen Definitionsdatei ; .NOLIST ;List-Output ausschalten .INCLUDE "m32def.inc" ;AVR-Definitionsdatei einbinden .LIST ;List output wieder einschalten ;----------------------------------------------------------------------------- ; Organisation des Datenspeichers (SRAM) ;----------------------------------------------------------------------------- ;.DSEG ;was ab hier folgt kommt in den SRAM-Speicher ;TAB1: .BYTE 100 ; 100Byte grosse Tabelle im Datensegment ; ;+++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++ ; Programmspeicher FLASH Programmstart nach Reset ab Adr. 0x0000 ;_________________________________________________ ____________________________ .CSEG ;was ab hier folgt kommt in FLASH Speicher .ORG 0x0000 ;Programmbeginn an der FLASH Adr. 0x0000 RESET1: rjmp INIT ; springe nach INIT (überspringe ISR Vectoren) ;_________________________________________________ ____________________ ; Sprungadressen für die Interrupts Organisieren (ISR VECTORS) ; Vektortabelle im Flashspeicher ;.ORG INTOaddr ;interner Vektor für INTO (alt.: .org 0x0002) ; rjmp ISR_I0 ;springe zur ISR von INTO ;_________________________________________________ ___________________________ ;Initialisierungen und eigene Definitionen ;---------------------------------------------- .ORG INT_VECTORS_SIZE ;Platz für ISR Vectoren lassen INIT: .DEF Zero = r15 ;Register 15 wird zum Rechnen benötigt clr r15 ;und mit Null belegt .DEF Tmp1 = r16 ;Reg. 16 dient als erster Zwischenspeicher .DEF Tmp2 = r17 ;Reg. 17 dient als zweiter Zwsp. .DEF Mask = r18 ;reg. 18 dient als Maske. .DEF WL = r24 ;Reg. 24 und 25 dienen als universelles .DEF WH = r25 ;Doppelregister ;Stapel initialisieren (fuer Unterprogramme bzw. Interrupts) ldi Tmp1,HIGH(RAMEND) ;Ramend (SRAM) ist in der Difinitionsdatei out SPH,Tmp1 ;festgelegt ldi Tmp1,LOW(RAMEND) out SPL,TMP1 ; nur pin6 von PortB als Ausgang initialisieren ldi Tmp1,0x40 ;Tmp1= 0B01000000 out DDRB,Tmp1 ;PB6 auf 1(Ausgang) alle anderen 0 (Eingang).Data Direction Register PortB ;_________________________________________________ ____________ ; Hauptprogramm ;---------------------------- MAIN: ldi XL,0xF4 ;Schleifenzähler mit G2=500 ldi XH,0x01 ; t=0,5s initialisieren rcall WX1ms ;Zeitschleife aufrufen ;Toggeln und Ausgabe ldi Mask,0x40 ;setze Maske zur invertierung eor Tmp1,Mask ;Invertiere mit EXOR out PORTB,Tmp1 ;LED Pin B6 wechselt Zustand rjmp MAIN ;Endlosschleife ;ende des Hauptprogramms(falls keine Endlosschleife) ;END: rjmp END ;Endlosschleife ;------------------------------------ ; Unterprogramme und Interrupt-Bechandlungsroutinen ;------------------------------------- .INCLUDE "SR_TIME_16M.asm" ;Zeitschleifenbibliothek einbinden ;------------------------------------------ ; Tabelle in Programmspeicher (FLASH) ;-------------------------- ;TAB: .DB "Hallo" .EXIT ;Ende des QuelltextesCode:; 16bit Zeitschleife wartet 1ms(Wait 1ms) W1ms: push WL ;rette verwendete Registerinhalte push WH ldi WL,0x9C ;Schleifenzähler W=3996 ldi WH,0x0F W1msL: sbiw WL,1 ;dekrementiere den schleifenzähler W brne W1msL ; Schleife wenn nicht gleich null pop WH ;Registerinhalte Wiederherstellen pop WL ret ; verschachtelte 16bit Zeitschleife wartet X mal 1ms WX1ms: tst XL ; Teste ob das Register gleich null oder negativ ist.Wenn X=0 dann zurück. brne WX1msp ;Sprung wenn nicht gleich null tst XH brne WX1msp ret WX1msp:push XL ;rette verwendete Registerinhalte push XH WX1msL: rcall W1ms ;Rufe innere Schleife (Uterprogramm W1ms) sbiw XL,1 ;dekrementiere den Schlaifenzähler brne WX1msL ;Schleife pop XH ;Registerinhalte Wiederherstellen pop XL ret
Gruß
enprog