Mit Assembler eine Blinkschaltung bauen
Hallo Leute,
ich habe vor eine Blinkschaltung mit den LEDs D15 und D16 zu schreiben.
Auf Assemblerbassis ...
Ist das möglich?
Könntet ihr mir ein bisschen helfen?
Code:
.include "m8def.inc"
LDI r16, 0b00000011 ; Hier kommt der Kommentar ... :D <-- Lade Register 16 mit 01000000
OUT DDRC, r16 ; R16 wird nach DDRD (Datenrichtungsregister!) übertragen
OUT PORTC, r16
LDI r17, 0b11100000
OUT DDRD, r17
main: RJMP main
Für die Back-LEDs habe ich den obrigen Code benutzt ...
Nun soll abwechselnd die eine und dann die Andere leuchten, wie mache ich das?
Blinkschaltung mit Assembler und ASURO
Hallo
Hier eine Programmversion, die alle LEDs des ASURO ansteuert.
Code:
.include "m8def.inc"
.def temp = r16 ; Arbeitsregister
.def temp2 = r17 ; Arbeitsregister
.equ CLOCK = 8000000
.dseg
timer_1: .byte 1 ; 8 Bit Sekunden Zähler
timer_6: .byte 1 ; 8 Bit milisekunden Zähler
.cseg
.org 0x000
rjmp Prog_Initial ;Interruptvektoren überspringen
reti ;INT0addr - Externer Interrupt 0
reti ;INT1addr - Externer Interrupt 1
reti ;OC2addr - Output Compare2
reti ;OVF2addr - Overflow2
reti ;ICP1addr - Input Capture1
reti ;OC1Aaddr - Output Compare1A
reti ;OC1Baddr - Output Compare1B
reti ;OVF1addr - Overflow1
rjmp delay ;OVF0addr - Overflow0
reti ;SPIaddr - SPI
reti ;URXCaddr - USART Receive Complete
reti ;UDREaddr - USART Data Register Empty
reti ;UTXCaddr - USART Transmit Complete
reti ;ADCCaddr - Analog Digital wandler
reti ;ERDYaddr - EEPROM
reti ;ACIaddr - Analog Comparator
reti ;TWIaddr - Two - Wire Interface
reti ;SPMaddr - SPM complete
Prog_Initial:
;*********************************************
; Stack Pointer setzen *
;*********************************************
ldi temp, LOW(RAMEND) ; Stack Pointer low
out SPL, temp ; setzen
ldi temp, HIGH(RAMEND) ; Stack Pointer high
out SPH, temp ; setzen
;********************************************
;* Init Timer / Counter 0 *
;********************************************
;Preclaer Divisions Factor = 64
ldi temp, 131 ; Counter = (256 - 125)
out TCNT0, temp ;125 Takten erfolgt ein Überlauf
ldi temp, 0b00000011 ; CS00 + CS01 = 1
out TCCR0, temp ; Prescaler Division = 64
in temp, TIMSK
ori temp, 0b00000001 ; Interrupt
out TIMSK, temp ; erlauben
;**********************************************
;* Init LEDs *
;**********************************************
sbi DDRB, DDB0 ; Duo LED grün
sbi DDRD, DDD2 ; Duo LED rot
cbi PORTB, PORTB0 ; aus
cbi PORTD, PORTD2 ; schalten
sbi DDRD, DDD6 ; Front LED
cbi PORTD, PORTD6 ; aus
sbi DDRD, DDD7 ; Back LEDs
cbi PORTD, PORTD7
sbi DDRC, DDC0
sbi DDRC, DDC1
cbi PORTC, PORTC1
cbi PORTC, PORTC1 ; ausschalten
ldi temp, 0x00
sts timer_1, temp ; max
sts timer_6, temp ; max 255 mili Sekunden
sei ; Interrupts erlauben
;**************** Ende Init **********
Prog_Run:
loop:
rcall back_led_r_on
ldi temp2, 1 ; 1 sekunde nichts tun
rcall wait_timer_1
rcall back_led_r_off
rcall back_led_l_on
ldi temp2, 1 ; 1 sekunde nichts tun
rcall wait_timer_1
rcall back_led_l_off
rcall front_led_on
ldi temp2, 1 ; 1 sekunde nichts tun
rcall wait_timer_1
rcall front_led_off
rcall gruen_ein
ldi temp2, 1 ; 1 sekunde nichts tun
rcall wait_timer_1
rcall rot_ein
ldi temp2, 1 ; 1 sekunde nichts tun
rcall wait_timer_1
rcall gelb_ein
ldi temp2, 1 ; 1 sekunde nichts tun
rcall wait_timer_1
rcall duo_led_aus
rjmp loop
;*****************************************************
;* Interrupt Routine für Timer 0 *
;*****************************************************
delay:
push ZH
push ZL
push temp2
push temp
in temp, SREG
push temp ; sichern
lds temp, timer_6 ; Milisekunenden
inc temp ; Zähler
sts timer_6, temp ; + 1
adiw r25:r24, 1 ; Counter + 1
ldi temp, 0xE8 ;0xE8 ; 0x03E8 = 1000
ldi temp2, 0x03 ;0x03
cp r24, temp ; Counter Low / 16 Bit compare
cpc r25, temp2 ; Counter High
brne next_step ; noch keine Sekunde vergangen
lds temp, timer_1 ; erhöhe die Sekunden Zähler um 1
inc temp
sts timer_1, temp
ldi r24, 0
ldi r25, 0
next_step:
ldi temp, 131 ; Counter Register
out TCNT0, temp ; neu Vorbelegen
pop temp ; Register
out SREG, temp
pop temp
pop temp2
pop ZL
pop ZH ; wieder herstellen
reti
;********************************************
;* Hintere LED rechts Ein *
;********************************************
back_led_r_on:
sbi DDRD, DDD7
cbi PORTD, PORTD7
sbi DDRC, PORTC0
sbi PORTC, PORTC0
ret
;*******************************************
;* Hintere LED rechts Aus *
;*******************************************
back_led_r_off:
cbi PORTC, PORTC0
ret
;*******************************************
;* Hintere LED links Ein *
;*******************************************
back_led_l_on:
sbi DDRD, DDD7
cbi PORTD, PORTD7
sbi DDRC, PORTC1
sbi PORTC, PORTC1
ret
;*******************************************
;* Hintere LED links Aus *
;*******************************************
back_led_l_off:
cbi PORTC, PORTC1
ret
;******************************************
;* DUO LED grün ein *
;******************************************
gruen_ein:
sbi PORTB, PORTB0
cbi PORTD, PORTD2
ret
;******************************************
;* UO LED rot ein *
;******************************************
rot_ein:
cbi PORTB, PORTB0
sbi PORTD, PORTD2
ret
;******************************************
;* DUO LED gelb ein *
;******************************************
gelb_ein:
sbi PORTB, PORTB0
sbi PORTD, PORTD2
ret
;******************************************
;* DUO LED Aus *
;******************************************
duo_led_aus:
cbi PORTB, PORTB0
cbi PORTD, PORTD2
ret
;******************************************
;* Front LED Ein *
;******************************************
front_led_on:
sbi PORTD, PORTD6
ret
;******************************************
;* Front LED Aus *
;******************************************
front_led_off:
cbi PORTD, PORTD6
ret
;******************************************
;* warten auf timer_1
;*temp2 Zeit in Sekunden übergeben *
;******************************************
wait_timer_1:
push temp2 ; Register
push temp
in temp, SREG
push temp ; sichern
ldi temp, 0x00 ; timer_1
sts timer_1, temp ;auf Null setzen
w_t_1:
lds temp, timer_1
cp temp, temp2 ; timer_1 => temp2
brsh ret_t_1 ; ja
rjmp w_t_1
ret_t_1:
pop temp ; Register
out SREG, temp
pop temp
pop temp2 ; wieder herstellen
ret
;***********************************************
;* warten auf timer_6 *
;*temp2 Zeit in mili Sekunden übergeben *
;***********************************************
wait_timer_6:
push temp2 ; Register
push temp
in temp, SREG
push temp ; sichern
ldi temp, 0x00 ; timer_6
sts timer_6, temp ; auf Null setzen
w_t_6:
lds temp, timer_6
cp temp, temp2 ;timer_6 => temp2
brsh ret_t_6 ; ja
rjmp w_t_6
ret_t_6:
pop temp ; Register
out SREG, temp
pop temp
pop temp2 ; wieder herstellen
ret
MfG
A.Hoffmann