Po raz kolejny zwracam się z prośbą do kolegów forumowiczów. Od pewnego czasu pracuję nad regulatorem fazowym zwykłe sterowanie triaka, wykrywanie 0 sieci nastawiane opóźnienie załączenia nic odkrywczego. Postanowiłem napisać taki program aby rozpocząć przygodę z uC. Pierwsza wersja powstała w C dodałem do tego coś a'la soft start i nawet to pracowało ale ponieważ cała ta heca miała służyć nauce więc postanowiłem napisać taki sam program w asemblerze i tu zaczęły się schody. W C zasada działania była prosta w przerwaniu od wejścia INT0 (tutaj są podawane impulsy w zerze) był zerowany timer1, który sobie od zera w górę zliczał impulsy zegarowe (podział przez 8,zegar 8MHz) do rejestru OCR1A wpisywałem wartość opóźnienia jeżeli wartość timera1 była równa OCR1A następowało przerwanie od porównania triak jest załączany i tak w kółko. Tak samo zrobiłem program w asemblerze(listing poniżej) alee nie działało to tak samo jak w C. Po kilku dniowej analizie zauważyłem, że regulator działa ale przy wartości OCR1A powiedzmy równej 64 535 triak była załączany tak jak by zamiast przerwania z OCR1A następowało przerwanie od przepełnienia timera1?Oco tu chodzi?!?
Poniżej przedstawiam listing w asemblerze na pewno będzie pomocny:
bedę wdzięczny za wszelką pomoc
Poniżej przedstawiam listing w asemblerze na pewno będzie pomocny:
.include "2313def.inc"
.macro SUB16
subi ZL,low(@0)
sbci ZH,high(@0)
.endmacro
.cseg
.org 0x00
rjmp init
.org INT0addr
rjmp INT0_vect
.org OC1addr
rjmp TIMER1_COMP1_vect
.org OVF0addr
rjmp TIMER0_OVF0_vect
.org INT1addr
reti
.org ICP1addr
reti
.org OVF1addr
reti
.org URXCaddr
reti
.org UDREaddr
reti
.org UTXCaddr
reti
.org ACIaddr
reti
;przerwanie, narastające zbocze na wejściu PD2.
;Tutaj wchodza impulsy z detekcji zera co 10ms
INT0_vect:
cbi PORTD,4 ;skasowanie triaka
ldi r16,0x02
out TCCR1B,r16 ;uruchomienie licznika
ldi r16,0x00
ldi r17,0x00
out TCNT1L,r16 ;wyzerowanie licznika
out TCNT1H,r17
out OCR1AL,ZL ;wpisanie ustawienia
out OCR1AH,ZH
reti
;
TIMER1_COMP1_vect: ;przerwanie od porównania włącza triaka
sbi PORTD,4 ;triak ON
;ldi r16,0x00 ;zatrzymuje licznik
;out TCCR1B,r16
reti
TIMER0_OVF0_vect: ;Timer0 jest wykorzystywany jako odliczacz czasu np.eliminacja drgań styków
inc r25
reti
;-----------------------------------------------------------
;inicjalizacja mikrokontrolera
;-----------------------------------------------------------
init:
cli
ldi r16,RAMEND ;Wskaźnik stosu
out SPL,r16
ldi r16,0b0110000 ;Ustawienia portu D
out DDRD,r16
ldi r16,0b0000011
out PORTD,r16
ldi r16,0b11111111 ;Ustawienia portu B
out DDRB,r16
out PORTB,r16
ldi r16,0x00 ;Konfiguracja TIMERA1
out TCCR1A,r16
ldi r16,0x00
ldi r17,0x00
out TCNT1L,r16
out TCNT1H,r17
ldi r16,0x42
out TIMSK,r16
ldi ZL,low(2000) ;wartość początkowa
ldi ZH,high(2000)
out OCR1AL,ZL
out OCR1AH,ZH
ldi r16,0x03 ; konfiguracja TIMERA0
out TCCR0,r16
ldi r16,125
out TCNT0,r16
ldi r16,0x40 ;konfiguracja przerwania INT0
out GIMSK,r16
ldi r16,0x03
out MCUCR,r16
sei ;odblokowanie przerwan
;-----------------------------------------------------------
; Pętla główna programu
;-----------------------------------------------------------
main_loop:
sbis PIND,6 ;\
brne line3 ; |
out PORTB,ZL ; |
line3: ; \ na port B wysylam wartosc ZL,ZH czyli poziom mocy w zaleznosci
sbic PIND,6 ; / od stanu koncowki PD6 górny lub dolny bajt.Dodane w celu diagnostyki
brne line4 ; |
out PORTB,ZH ;/
line4:
ldi r17,high(10000) ; ograniczenie wartosci mocy
cpi ZL,low(10000)
cpc ZH,r17
brsh line1
sbis PIND,1
brne UP
line1:
ldi r17,high(1000) ;ograniczenie wartosci mocy
cpi ZL,low(1000)
cpc ZH,r17
brlo line2
sbis PIND,0
brne DOWN
line2:
ldi r24,0x00
rjmp main_loop
;-----------------|Obsługa klawiszy|-----------------
UP:
sbrc r24,1
rjmp main_loop
cpi r25,20
brne main_loop
ldi r24,0x02
SUB16 -1000
rjmp main_loop
DOWN:
sbrc r24,0
rjmp main_loop
cpi r25,20
brne main_loop
ldi r24,0x01
SUB16 1000
rjmp main_loop
;---------------------------------------------------------------------------------------------
.exit
bedę wdzięczny za wszelką pomoc