Atmel AVR sinusový střídač a FB
Moderátor: Moderátoři
EDIT
V princípe je dôležité zachovať binárne pomery troch-štyroch miest kvôli jednoduchej aritmetike, niektoré krajné nepožívať.
Ak by sa počítalo s 8,25 až 16,5V a reál je 10 až 15V by to mohlo pracovať v pohode. Vypínanie pod 10V je iná vec.
Asi nie je ani potrebné stabilizovať výstup, ale stačí aby sa znížili zmeny oproti batérii z +-25% na +-5% na výstupe.
Trochu jsem to upravil, aby se ten mezičas snížil:
Kód: Vybrat vše
TIMER1: ;<< T1MAX
in r22,sreg
sbrc rbits,1 ;bit1 STOPflag
rjmp stop
LPM r16,Z ;nacist sinus
sbrc rbits,0
out OCR1A,r16
sbrs rbits,0
out OCR1B,r16
inc ZL
inc rcount
cpi rcount,156
brne t1end
stop:
ldi rcount,0
out OCR1A,rcount ;nuluj kanaly
out OCR1B,rcount
ldi ZL,LOW(SINUS<<1)
ldi ZH,HIGH(SINUS<<1)
ldi r16,$01
eor rbits,r16 ;CPL bit0-polarita
t1end:
out sreg,r22
RETIzhruba:
Regulační pásmo je tedy 90V, pásmo modulace 48% Tolerance sítě by měla být +-10%, když to vyhraje 10 tabulek tak je to +-5%, takže to bude asi stačit.
Možná by šlo snížit rozlišení na 128/půlperiodu, přičemž by se v RAM dal udělat dvojbuffer na 1/4 periodu, jednu v mainu počítat (třeba i pak odečítáním) a druhou v ISR používat pro generaci. A pro výpočty vyžít jen s registrama.
- místo lpm R16,Z použít lpm R16,Z+ a odpadne inc ZL
- rcount není potřeba, ta půlsinusovka může končit nulou a stačí tedy detekovat tu nulu
or R16,R16
brne t1end
- ZH není potřeba pokaždé nastavovat, pokud je celá tabulka sinu v jedné 256bytové stránce (což musí být, když jsi inkrementoval jen ZL)
- Když si vyhradíš jeden registr, do kterého si dáš nulu (já ho mám nazvaný zero), pak odpadá i ldi rcount, 0
- pokud příznak polarity bude samotný v registru, místo
ldi r16,$01 a eor rbits,r16 stačí jedna negace registru polarity (com rpol)
A hlavně, máš tam procesor s výpočetním výkonem až 8MIPS, tak proč se ten výkon bojíš využít? I kdyby ti obsluha přerušení od generování sinu zabrala 30us, tak pořád ti na ostatní věci zbývá víc než polovina výkonu procesoru, to je až 80 tisíc instrukcí na periodu generované sinusovky, to ti snad na přečtení dvou kanálů AD převodníku a spočtení jednoho koeficientu bohatě stačí, ne?
P.S.: Procesor by ti mohl vyprávět, jak rychle uměl počítat, když byl v plenkách a přesto zvládnul třeba přistání na Měsíci.
Je zvláštní že LPM Z+ není uvedená v datalistu jako podporovaná, nicméně to funguje.
vyhodím taky "nulovat kanály", protože druhý je 0 od poledního průchodu 0.
Taky mě napadlo použít dva předávací registry které by se v mainu načetly z tab a v ISR by se jen předaly do OCR1x, udělat tam nějaký SYCN flag mezi ISR a mainem, pak bych nemusel zálohovat ani SREG.
Pak by to mohlo být takto:
Kód: Vybrat vše
TIMER1:
out OCR1A,r_ch1
out OCR1B,r_ch2
ori rbits,2 ;bit2 sync
RETI
Pokud to bude tak, klesne i minimální možná modulace, která je teď OCR1x > $05, užší pulz z toho mám ten pocit nevyleze.
Možná i použít INT od CompareMatch kanálu namísto naplnění T1?
Jenda_KL píše:Je zvláštní že LPM Z+ není uvedená v datalistu jako podporovaná, nicméně to funguje.
Jo ty tam máš tinu26, no ta to v datašítu nemá, zajímavé.
Jenda_KL píše:Taky mě napadlo použít dva předávací registry které by se v mainu načetly z tab a v ISR by se jen předaly do OCR1x, udělat tam nějaký SYCN flag mezi ISR a mainem, pak bych nemusel zálohovat ani SREG.
To je hloupost. To co se má real-time obsloužit v přerušení netahej do mainu, v tom obsluhuj to, co nepotřebuje real-time obsluhu. Co tě tak strašně nutí, tu obsluhu přerušení zkracovat do absurdna, to tam vykresluješ na grafický displej spektrum té sinusovky a rotuješ k tomu 3D kostkou?
Jenda_KL píše:Pokud to bude tak, klesne i minimální možná modulace, která je teď OCR1x
> $05, užší pulz z toho mám ten pocit nevyleze.
Puls může být libovolně dlouhý, mezi 0 a maximem.
Jenda_KL píše:Možná i použít INT od CompareMatch kanálu namísto naplnění T1?
OCR1x měň v přerušení od overflow, od něj se do skutečných OCR1x překlápějí hodnoty z dočasných synchronizačních registrů. To co zapíšeš do OCR1x se použije v následující periodě T1.
Jakou tam máš předděličku a hodnotu v OCR1C?