PIC - přerušení přesně každých 10ms

Diskuze a poradna o programátorech a programování různých obvodů

Moderátor: Moderátoři

Odpovědět
Zpráva
Autor
petrfilipi
Příspěvky: 2551
Registrován: 13 zář 2005, 02:00

PIC - přerušení přesně každých 10ms

#1 Příspěvek od petrfilipi »

Dobrý den, dámy a pánové.
Prosím o radu s přerušením u PICu 16F877A. Mám už (na stole) hotové a funkční stopky pro hasičské závody (dva procesory(jeden u terčů předává po lince 232/485 info o sepnutých terčích do hlavního časoměrného procesoru), hlavní časoměrný procesor měří časy pro 4 dráhy, přesnost 0,01s). A právě s přesným měřením času mám problém. Používám samozřejmě přerušení (TMR0), krystal mám 7,9996 MHz, předděličku 1:16 (Option reg = 10000011), TMR0=9. To mi dává přerušení každých 200ms, každé 5. přerušení mi inkrementuje setiny sekundy. Nejpřesněji k požadovaným 10ms se dostanu na 10,0045ms.
Neznáte někdo nějaký způsob, jak pomocí SW nadefinovat přerušení přesně po 10,0000ms, pokud je to vůbec možné?

Děkuji za Vaše rady a nápady.

Petr Filipi

Uživatelský avatar
procesor
Příspěvky: 5284
Registrován: 02 říj 2009, 02:00
Bydliště: PO

#2 Příspěvek od procesor »

Použi Timer1 s modulom COMPARE.
Potom budeš môcť generovať interrupt s krokom 500ns/1us/2us/4us až do času cca 32ms/64ms/128ms/256.
Nechápem ten kryštáľ.... prečo nie 8,000MHz?
Timer0 sa na generovanie a dolaďovanie hodím nehodí.

petrfilipi
Příspěvky: 2551
Registrován: 13 zář 2005, 02:00

#3 Příspěvek od petrfilipi »

Díky za námět.
Krystal je samozřejmě 8 MHz, ve skutečnosti (změřeno) kmitá na 7,996 MHz.
Když dostanu přerušení 8ms, co mám pak dělat, abych měl 10ms?
Jinak nastavené hodnoty mi dělají přerušení každé 2ms, nikoli 200ms.

Petr Filipi

petrfilipi
Příspěvky: 2551
Registrován: 13 zář 2005, 02:00

#4 Příspěvek od petrfilipi »

Ještě jsem dostal jeden námět na řešení - co takhle nechat přerušení třeba na 9,985 ms a tech zbývajících 15us nechat v přerušovací proceduře odčasovat pomocí NOP. Asi to není systémové řešení, ale v mém případě by to mohlo být plně funkční. Pak bych mohl ladit na přesných 10ms. Budu muset ale optimalizovat tuto proceduru, aby probíhala stále po stejném množství instrukcí.
Potřebuji to udělat rychle a co možná nejpřesněji (asi by teď stačilo i 10,005ms - letos to budou používat jen naši chlapci na trénink), přes zimu to budu moci doladit - stejně chci zkusit bezdrátový přenos tak jako milý Marconi, velký elektromagnetický (LEDkový) display apod.
Petr

Uživatelský avatar
eljaro
Příspěvky: 441
Registrován: 03 pro 2004, 01:00
Bydliště: Krnov
Kontaktovat uživatele:

#5 Příspěvek od eljaro »

to že krystal kmitá na 7,996 je podivné pokud jsi jej umslně neodladil ! Ted nedávno jsem stavěl čítak použil jsem jako zdroj 20.000 krystal a bez problému a nastavování rovnou tato frekvence !
Ten časovač moc to komplikujěš použij bud TMR1 a Compare , anebo pokud chceš zustat u TMR0 pak je kousek urychli v přerušní udělej smyčku 5 a dolad to nejakým tím NOPem , nevím jestli má ten procesor i TMR2 pokud ano použij rovnou ten mužeš dělit před a po a nastavit čitač - tohle používám raději to bez problému lze aplikovat na 8MHz 100ms i 10ms mám to běžně jako hodiny a ostatní moduly mi zustavají na práci volné .

Uživatelský avatar
procesor
Příspěvky: 5284
Registrován: 02 říj 2009, 02:00
Bydliště: PO

#6 Příspěvek od procesor »

Pomocou Timer0 sa nedá presne generovať IT. TRM0reg je krátky. Musí sa použiť veľký prescaler prípadne postscaler, v každom prípade sa chyba násobí. Predlžovanie cyklu je prakticky nemožné.

edit:
Druhá možnosť je použiť kryštál s takou frekvenciou, aby po prescaleri vyšiel incremet pre TMR0reg celočiselný čas.

Uživatelský avatar
Chenzee
Příspěvky: 464
Registrován: 26 čer 2007, 02:00
Bydliště: Vysočina

#7 Příspěvek od Chenzee »

Před asi rokem jsem TMR0 použil pro počítání času hodin. Bylo to jen na zkoušku, takže nic jiného než hodiny a výstup na LCD to nedělalo. Za 1 den se to zpožďovalo o 1,5s. Hodnoty pro nastavení najdeš na připojeném obrázku i s poznámkami. Netvrdím, že je to nejlepší cesta, ale je to jedna z cest možných. Program bude samozřejmě potřeba poskládat tak, aby to mohlo fungovat i s dalšími funkcemi.
Přílohy
10ms_s_Q_8MHz.JPG
(87.51 KiB) Staženo 178 x
Žádnej učenej z nebe nespadl ...

Uživatelský avatar
procesor
Příspěvky: 5284
Registrován: 02 říj 2009, 02:00
Bydliště: PO

#8 Příspěvek od procesor »

Tak-tak, to vychádza na 9,984ms + 32 inštrukcčných cyklov aby sa pri zápise do TMR0 aj resetoval rescaler.

Uživatelský avatar
ZdenekHQ
Administrátor
Administrátor
Příspěvky: 25593
Registrován: 21 črc 2006, 02:00
Bydliště: skoro Brno
Kontaktovat uživatele:

#9 Příspěvek od ZdenekHQ »

V těchto aplikacích se dá místo kondíku u krystalu kapacitní trimr a krystal se "posadí" čítačem na požadovanou hodnotu.

Na druhou stranu, pokud se vyžaduje větší stabilita, nezbývá, než použít externí oscilátor buď v "plechovce", nebo třeba toto : http://www.hq-elektronic.eu/ref_osc.html
Pro moje oslovení klidně použijte jméno Zdeněk
Správně navržené zapojení je jako recept na dobré jídlo.
Můžete vynechat půlku ingrediencí, nebo přidat jiné,
ale jste si jistí, že vám to bude chutnat[?
]

petrfilipi
Příspěvky: 2551
Registrován: 13 zář 2005, 02:00

#10 Příspěvek od petrfilipi »

Pánové, děkuji za rady.
1. Krystal je 8 MHz, skutečně je na 7,9996MHz (chyběla mi tam jedna devítka), tj. chyba 400Hz na 8 000 000Hz, tj. 50Hz na 1 000 000Hz, tj. 50ppm, což není sice skvělé, ale ani nemožné (ještě jednou se omlouvám za tu devítku).
2. Ještě jsem našel článek pana Vonáška, KTE 2/2005, str. 25. Popisuje tam použití TMR0 i TMR2, včetně chybových konstant. Tak se na to mrknu. Nějak jsem zapomněl, že když mi program skočí na přerušení tak že musím počítat s tím, že instrukce v přerušení taky nějakou chvíli zaberou - to je právě ten řádek "kolik ins. cyklů je do nastavení TMR0" v excelovském příkladu od Chenzee. Vycházel jsem z popisů výpočtu přerušení, které jsem našel na webu, ale tam právě nebyly zapracované instrukce v přerušení. Takže to byl jen teoretický výpočet funkční pouze tehdy, kdyby v přerušení nebyla žádná instrukce, a navíc kdyby se TMR0 rozbíhal okamžitě. Proto jsem dostával různé hodnoty periody když v přerušení byla jedna instrukce, resp. jeden příkaz (portb.0:=not (portb.0) - inverze bitu 0 port B - program píšu v MikroPascalu od spol. Mikroelektronika) a když v přerušení bylo celé zpracování 4 časů, kontrola přetečení setin do sekund, sekund do minut apod. Navíc tam mám i čtení seriového portu (posílá se po něm info od terčů, který terč je sepnut) a ten se buď provádí (když je co číst) nebo neprovádí (což je většina času - takže s tím zatím počítat nebudu). Musel bych asi použít další procesor, který by linku RS232ku monitoroval a předával by info hlavnímu časoměrnému procesoru po klasických bitových portech, protože pak mohu jednoduše určit dobu trvání instrukce.
3. Ale jinak si myslím, že není důvod nepoužívat TMR0, že je stejně přesný jako TMR2 - když pominu nutnost skákat do přerušení jen proto abych vyhodnotil až každé 5. přerušení. Takže přepíšu program na použití TMR2 a postděličku 1:5 (tím se mi nebude 4x zbytečně provádět spousta kontrol v přerušení), tím zlepší se chyba "sama od sebe" a když doplním ty NOPy, tak to musí běžet bez problémů.

Chenzee - nebylo by možné poslat celý excelovský sešit s výpočtem?

Ještě jednou všem díky moc.

Petr Filipi

Uživatelský avatar
Chenzee
Příspěvky: 464
Registrován: 26 čer 2007, 02:00
Bydliště: Vysočina

#11 Příspěvek od Chenzee »

sedět na tom by asi nic nepřineslo takže ... (xls nelze vložit, tak jsem změnil příponu na TXT, po uložení na disk ji zase změň na xls :wink: )
Přílohy
Výpočet přerušení od TMR0.txt
(27.67 KiB) Staženo 252 x
Žádnej učenej z nebe nespadl ...

petrfilipi
Příspěvky: 2551
Registrován: 13 zář 2005, 02:00

#12 Příspěvek od petrfilipi »

Díky moc za zaslaný výpočet.

Petr Filipi

Odpovědět

Zpět na „Programování PIC, ATMEL, EEPROM a dalších obvodů“