Skocz do zawartości

[Atmega8][ASM] Timer1 PWM phase and frequency correct


szimon

Pomocna odpowiedź

Piszę program w AVRStudio 4.13SP2. Działanie programu jest (a właściwie powinno być) następujące:

Mikrokontroler generuje sygnał PWM o częstotliwości 50Hz i czasie trwania od 0,5ms do 2,5ms. Sygnał wysyłany jest na wyprowadzenie OC1A. Przy wyzerowaniu licznika podczas zliczania w dół wywoływane jest przerwanie włączające przetwarzanie A/C. Wewnątrz przerwania od przetwornika A/C ustalana jest szerokość impulsów PWM.

Przetwornik działa dobrze, ale z Timerem męczę się już jakiś czas, a niestety do szafy tego schować i zapomnieć nie mogę. Problem jest taki:

Zgodnie z trybem pracy ustalonym bitami WGM1 3:0 = 8 licznik powinien zliczać w górę aż do osiągnięcia wartości rejestru ICR1, następnie zacząć zliczać w dół, aż do osiągnięcia poziomu zerowego, co uruchamia przerwanie. W międzyczasie osiąga wartość zapisaną w rejestrze OCR1A, co powoduje zmianę stanu na wyjściu. Przeglądam program któryś raz z kolei i nie mogę dojść dlaczego licznik po osiągnięciu wartości TOP (ICR1) nie przestaje zliczać w górę. Liczy dalej, dochodzi do wartości 0xFFFF, zeruje się i generuje przerwanie. Próbowałem jeszcze trybu Phase correct PWM (WGM1 3:0=9).

Być może ktoś miał podobny przypadek? Niewykluczone, że gdzieś się rypnąłem w pojedynczym bicie i od ciągłego szukania błędu przestałem cokolwiek zauważać. Poniżej kod programu:

.include "m8def.inc"

.cseg

;******** DEFINICJA WEKTORA PRZERWAŃ ************
.org 0x00 rjmp Reset	; RESET
.org 0x08 rjmp T1ovf	; T1 OVERFLOW
.org 0x0E rjmp ADconv	; ADC CONVERSION COMPLETE
;************************************************

Reset:

ldi r16, high(RAMEND)
out SPH, r16
ldi r16, low(RAMEND)
out SPL, r16

ldi r16, 0xFF
out DDRD, r16
ldi r16, 0xFF
out PORTD, r16

ldi r16, 0xFF
out DDRB, r16
ldi r16, 0x00
out PORTB, r16


;********* PRZETWORNIK A/C ***************
ldi r16, 0x00
ori r16, (1<<REFS0 | 1<<ADLAR)
out ADMUX, r16

ldi r16, 0x00
ori r16, (1<<ADEN | 1<<ADIE | 1<<ADPS1 | 1<<ADPS0)
out ADCSRA, r16
;*****************************************

;********* TIMER1 ************
ldi r16, 0x00
out TCNT1H, r16
out TCNT1L, r16

ldi r17, 0x01
ldi r16, 0xF4
out OCR1AH, r17
out OCR1AL, r16

ldi r17, 0x27
ldi r16, 0x10
out ICR1H, r17
out ICR1L, r16

ldi r16, 0x00
ori r16, (1<<TOIE1)				;T1 ovf enable
out TIMSK, r16

ldi r16, 0x00
ori r16, (1<<COM1A1)			;kanal OC1A, non-inv PWM
out TCCR1A, r16

ldi r16, 0x00
ori r16, (1<<WGM13 | 1<<CS11)	;PWM phase & freq correct
out TCCR1B, r16
;*****************************

sei

Main:


rjmp Main

;********** PROCEDURY OBSŁUGI PRZERWAŃ **********

; Czytaj wynik przetwarzania i wyrzuć na port D
ADconv:
in r16, ADCH
ldi r17, 240
cp r17, r16
brcs ADCgreater
ldi r17, 60
cp r17, r16
brcc ADClower
out PORTD, r16
rjmp ADCustaw

ADCgreater:
ldi r16, 240
out PORTD, r16
rjmp ADCustaw

ADClower:
ldi r16, 60
out PORTD, r16

ADCustaw:
ldi r17, 10
mul r16, r17
out OCR1AH, r1
out OCR1AL, r0
reti

T1ovf:
sbi ADCSRA, ADSC

reti
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.