řízení triaku - Timer1 ATMEGA8A – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

řízení triaku - Timer1 ATMEGA8A – C / C++ – Fórum – Programujte.comřízení triaku - Timer1 ATMEGA8A – C / C++ – Fórum – Programujte.com

 

Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
hlucheucho+10
Posthunter
8. 3. 2015   #1
-
0
-

Ahoj,

na PB0 ( = ICP1) mám přivedeny impulsy signalizující průchod sítě nulou, na PB2 je připojen optotriak ( = OC1B).  Taktování MCU je 4MHz

  #define Global_Enable_Interrupts()  __asm__ __volatile__ ("sei"::)
  #define Global_Disable_interrupts()  __asm__ __volatile__ ("cli"::)
  #define TC_ON  (1 << PORTB1)
  
  #define PREDSTIH  2000  //predstih ukonceni ridiciho impulsu pred pruchodem site nulou

#include <avr/io.h>
#include <avr/interrupt.h>


int main(void)
{
	DDRB = 0x04;
	PORTB = ~0x04;
	//nastavi casovac 1 a jeho preruseni
	Global_Disable_interrupts();
	TIMSK |= (1 << TICIE1);
	OCR1B = 28000; //spozdeni
	OCR1A = 30000; //max hodnota casovace, delka pulperiody - predstih cca 0.5 msec
	TCCR1A |= (1 << COM1B0) | (1 << COM1B1) | (1 << WGM10) | (1 << WGM11);  //Fast PWM Mode 15
	TCCR1B |= (1 << WGM12) | (1 << WGM13);
	TCCR1B |= (1 << CS10);   //clock source /1
	Global_Enable_Interrupts();

    while(1)
    {

    }
}

ISR(TIMER1_CAPT_vect)  //obsluha pruchodu site nulou
{
	TCNT1 = 0;
}

Optotriak se zapne při shodě s OCR1B a řídící impuls se ukončí při shodě s OCR1A, pokud jsem dobře porozuměl popisu v datasheetu dojde současně k vynulování časovače (registru TCNT1). Program funguje na reálném hardware, má však vadu - čas ukončení řídícího impulsu je pevně dán a je vztažen k začátku půlperiody sítě. Předpokládal jsem, že v ICR1 zůstane zachycen čas od ukončení řídícího impulsu optotriaku do obsluhy přerušení a vynuceném vynulování TNCT1. Podle hodnoty v ICR1 jsem zkusil modifikovat OCR1A tak, aby řídící impuls končil vždy danou dobu před průchodem sítě nulou - makro PREDSTIH : 

  #define Global_Enable_Interrupts()  __asm__ __volatile__ ("sei"::)
  #define Global_Disable_interrupts()  __asm__ __volatile__ ("cli"::)
  #define TC_ON  (1 << PORTB1)
  
  #define PREDSTIH  2000  //predstih ukonceni ridiciho impulsu pred pruchodem site nulou

#include <avr/io.h>
#include <avr/interrupt.h>


int main(void)
{
	DDRB = 0x04;
	PORTB = ~0x04;
	//nastavi casovac 1 a jeho preruseni
	Global_Disable_interrupts();
	TIMSK |= (1 << TICIE1);
	OCR1B = 28000; //spozdeni
	OCR1A = 30000; //max hodnota casovace, delka pulperiody - predstih cca 0.5 msec
	TCCR1A |= (1 << COM1B0) | (1 << COM1B1) | (1 << WGM10) | (1 << WGM11);  //Fast PWM Mode 15
	TCCR1B |= (1 << WGM12) | (1 << WGM13);
	TCCR1B |= (1 << CS10);   //clock source /1
	Global_Enable_Interrupts();

    while(1)
    {

    }
}

ISR(TIMER1_CAPT_vect)  //obsluha pruchodu site nulou
{
	TCNT1 = 0;
	OCR1A = (int)ICR1 - PREDSTIH + OCR1A;
}

Kód nefunguje, na výstupu je plné napětí. Bohužel k ATMEGA8A nelze připojit emulátor a zjistit, co v registrech opravdu je :( 

hu

Nahlásit jako SPAM
IP: 193.86.81.–
Reklama
Reklama
KIIV+42
God of flame
8. 3. 2015   #2
-
0
-

Jestli pocitam dobre, tak delka pulperiody by mela byt 40000

Kdyby neco, tak to muzes odladit na mega16, tam mas i jtag a timer1 se zda byt vcelku stejny.

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
hlucheucho+10
Posthunter
8. 3. 2015   #3
-
0
-

Using the Input Capture unit in any mode of operation when the TOP value (resolution) is actively changed during operation, is not recommended. 

Tuhle větu jsem v datasheetu přehlédl :( Akorát nechápu, jaký je k tomu důvod aby zachycení stavu časovače nefungovalo.

hu

Nahlásit jako SPAM
IP: 193.86.81.–
hlucheucho+10
Posthunter
13. 3. 2015   #4
-
0
-

Situaci se mi povedlo navodit v simulátoru. Vůbec jsem si neuvědomil, jak "double buffered" OCR1A funguje. V algoritmu z mého prvního příspěvku to způsobuje dvojí přičtení rozdílu ICR1 - PREDSTIH do OCR1A. Hotnota OCR1A po chvíli překročí 40 000 a pak ke shodě nedojde. Řešení, které obstojí v reálném provozu, jsem zatím nenašel.

hu

Nahlásit jako SPAM
IP: 2001:67c:1222:800:429:d30...–
KIIV+42
God of flame
13. 3. 2015   #5
-
0
-

Tak prinejhorsim se muzes poptat na AVR Freaks :)

Mozna by to slo resit i v normalnim modu, zapnout force output compare a zbytek resit softwarove.

Mimochodem, nepricte se ti 2x protoze v ICR1 hodnota pul periody (nebo dokonce cele periody?), k tomu prictes OCR1A a odectes predstih?

OCR1A = (int)ICR1 - PREDSTIH + OCR1A;
 

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
hlucheucho+10
Posthunter
13. 3. 2015   #6
-
0
-

OCR1A ukončí impulz pro optotriak dříve než prochází síť nulou. Současně dojde k HW vynulování časovače. ICR1 pak obsahuje skutečnou dobu mezi ukončením řídícího impulzu a průchodem sítě nulou. Cílem je dosáhnout stavu, kdy hodnota v ICR1 bude konstantní. Navíc se to musí umět vypořádat s drobnou odchylkou u impulsů signalizujících průchod sítě nulou. U konkrétního kusu HW je rozdíl mezi kladnou a zápornou půlperiodou asi 100 mikrosec (daň za jednodušší a levnější HW).

Děje se tam zhruba toto:
1. shoda s OCR1A vynuluje časovač a ukončí impulz pro optotriak. OCR1A je updatován na hodnotu, která je v jeho bufferu (v podstatě je tam stará hodnota)
2. Při průchodu sítě nulou je zachycen stav časovače a časovač je softwarově vynulován
3. Odchylka předstihu je přičtena ke starému stavu OCR1A, výsledná hodnota je vložena do bufferu OCR1A a nemá vliv na dění v právě započaté půlperiodě
4. shoda s OCR1A vynuluje časovač a ukončí impulz pro optotriak. OCR1A, teprve nyní je OCR1A updatován na novou hodnotu.
5. Při průchodu sítě nulou je zachycen stav časovače a časovač je softwarově vynulován, je však zachycen čas mezi starou hodnotou OCR1A, odchylka je tedy stejná jako v předešlé půlperiodě a je znovu přičtena do OCR1A

Zkusil jsem do OCR1A přidávat 1/16 odchylky, což fungovalo v simulátoru, v reálné situaci nikoliv. V simulátoru jsou impulzy průchodu sítě nulou nahrazeny Timerem 2. Proti reálné situaci naprosto synchronní a s přesnou periodou. Dál jsem se včera večer nedostal.

Pokud (ICR1 - PREDSTIH) nazvu regulační odchylkou a OCR1A nazvu akční veličinou, přicházím k myšlence použít SW PID regulátor. Jsem to někde v Application Notes viděl.

Softwarové řešení, kde pomocí ICR1 se měřila půlperioda a triak se řídil softwarově v obsluze přerušení, se neosvědčil. Proto se pokouším "vytřískat" co nejvíc z hardware.

hu

Nahlásit jako SPAM
IP: 2001:67c:1222:800:429:d30...–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 79 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý