PIC18F a časování 1s s Timer0

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

Moderátor: Moderátoři

Odpovědět
Zpráva
Autor
Uživatelský avatar
saitt
Příspěvky: 107
Registrován: 11 lis 2015, 01:00
Bydliště: Ostrava

PIC18F a časování 1s s Timer0

#1 Příspěvek od saitt »

Ahoj ,kdysi jsem si koupil PICKIT3 tak jsem ho chtěl ,až teď otestovat...
Začetl jsem se do knihy C pro mikrokontroléry PIC od Davida Matouška.
Tam popisuje jak udělat blikání s LED.

Problém je v tom že to popisuje s jiným mcu ,který má interní oscilátor.
a to tak že nastaví OSCCON =0b01110011 .
////////////////////////////////
otázka 1,Tady tkví první problém používám PIC18F452 a ten má jen
extrení oscilátor ,mám tam 4 MHz krystal-HS mode budu šahat při nastavení do OSCCONu?
////////////////////////////////
otázka 2, V knize se popisuje nastavení předděličky.... k tomu se se dělí knitočtem interního oscilátoru v knize 8Mhz /4 =2 mhz to znamená 0,5s je perioda.
Budu i ten kmitočet externího krystalu připojeného k PIC dělit 4 ?

////////////////////////////////
otázka 3, Z výše uvedené věty je zřejmé že budeme potřebovat 1 000 000 impulzů.
Jak proboha k tomu přišel to vycházelo jedině 2Mhz * 0,5s atohle nevím co je jak to nazvat co vlastně počítal atd.

Dále se v knize odhadne že 65536 x 16 = 1 048 576 , protože máme 16 bitovou šíři Timeru0 a nastavená předdělička je 16 to znamená nejbližší výsledek impulzů nebo co to je?
///A pak se řekne že 1 000 000 /16 = 62500 - tohle chápu.
////////////////////////////////

Dále se vydělí 8Mhz/4=2, 2Mhz/16 =125 Khz >>> T = 0,000008 s
Dále 0,5/0,000008 = 62500 impulzů
65536-62500 = 3036
A toto číslo se vloží do TMR0L a TMR0H aby mohl přetéct
////////////////////////////////
Zájímá mě tenhle ten postup, potřeboval bych objasnit Nastavení a výpočet ...díky doufám že se tu najde někdo přes PIC 18F.
Chtěl bych si nastavit třeba jedna sekunda a nebo libovolný čas pomocí Timer0.

Kód: Vybrat vše

#include <p18cxxx.h>

#pragma config OSC = INTIO2
#pragma config WDT = OFF

void inicializace();
void cekejTimer0();

void inicializace()
{ 
  OSCCON=0b01110011;  //8 MHz 
  T0CON=0b10010011;   //2 MHz, deleni 16 (125 kHz)
  TRISB=0b00000000; 
  PORTB=0b11111111;
}

void cekejTimer0()
{
  TMR0H=0x0B;
  TMR0L=0xDC;
  INTCON=INTCON&0b11111011;
  while(!(INTCON&0b00000100));
}

void main()
{
  inicializace();

  while(1)
  {
    PORTB=LATB^0b00000001;
    cekejTimer0();
  }
}

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

#2 Příspěvek od petrfilipi »

Viděl bych to asi takto:
OSCCON pouze přepíná zdroj pro systémové hodiny - a to mezi hlavním oscilátorem a Timerem1. Nezáleží tedy na tom, zdali máš interní nebo externí oscilátor. Já osobně bych toto nastavení ponechal podle původního článku.
Standardně trvá jedna instrukce procesoru 4 takty oscilátoru, proto to dělení 4. Když máš oscilátor 4MHz, tak procesor provede 1 milion instrukcí za sekundu. Tím samozřejmě myslím instrukce, které trvají jeden takt procesoru (= 4 takty oscilátoru). Některé instrukce podprogramů mohou trvat dva takty a některé instrukce rozhodování mohou trvat jeden nebo dva takty - viz tady (strana 9): http://asix.cz/download/museum/other/pi ... krokem.pdf

Takže když chceš blikat v rytmu jedné sekundy, potřebuješ udělat buď:
1. cyklus, počet opakování třeba 250 000 (když bude mít jedna iterace cyklu 4 instrukce)

nebo

2. nastavit přerušení časovače tak, aby proběhlo vždy po jedně sekundě

Výhodou prvního řešení je teoretická jednoduchost, ale program se v tu chvíli "zastaví" a bude čekat.
Výhodou druhého řešení, které je jistě profesionálnější, je to, že program si dál vesele běží, uživatel může mačkat tlačítka, displej zobrazuje znaky a jednou za sekundu se provede obsloužení od časovače. Ale to je pár instrukcí takže nikdo ani nepozná, že se to provedlo.

PF

Uživatelský avatar
saitt
Příspěvky: 107
Registrován: 11 lis 2015, 01:00
Bydliště: Ostrava

#3 Příspěvek od saitt »

Zkoušel jsem to zkuste někdo prosím udělat výpočet pro 4 Mhz oscilátor...


1.bod zkoušel jsem dát do smyčky for hodnotu 250 000 a ani trochu se to nepřibližuje intervalu jedné sekundy....

co se trošku přibližuje je for

Kód: Vybrat vše

(i = 0; i < 62500; i++) 
v knize v originálu bylo 50 000 zajímalo by mě jak se k tomu došlo...
tady asi dělám chybu že počítám s předdeličkou


2. který výpočet je správný v mém případě pro TIMER0 ?

Kód: Vybrat vše

   // TCY = 4/FOSC = 4/48MHz ~= 83.33 ns.
 Timer increments every 83.33 ns * prescaler = 83.88 ns * 256 = 21.33 us           // So, for a half second delay, the timer value would be .5/(21.33 uS) ~= 23441.
            
takže lets do the math

v knize je 62500

používá se interní oscilátor 8Mhz dělička je 16 blikání 0,5 s

8/4 = 2
perioda = 0,5 us
0,5 us * 16 = 8 us
0,5/8us = 62500

něco takového jsem myslel
ještě vědět jak určit správně pro smyčku for 62500 tam odpovídá tak okolo 1sekundy.

Proč výpočet na téhle stránce má 2x nasobení předděličkou ,
myslím to Overflow Period .




http://extremeelectronics.co.in/microch ... -tutorial/

hakamusai
Příspěvky: 943
Registrován: 17 dub 2007, 02:00

#4 Příspěvek od hakamusai »

Pro urychlení nastavení timeru můžeš zkusit použít tento program.

Uživatelský avatar
saitt
Příspěvky: 107
Registrován: 11 lis 2015, 01:00
Bydliště: Ostrava

#5 Příspěvek od saitt »

už to šlape ,přibližně přesně tady poslílám program na posouzení
na ten OSCON jsem nešahal podle mě tam ani není je to jen pro interní oscilátor ,aspoň jsi to myslím - v datasheetu PIC18F452 se o něm nepíše.

Kód: Vybrat vše

#include<xc.h>

#pragma config OSC = HS
//#pragma config FCMEN = OFF                                 // OR this way
//#pragma config BORV = 3
#pragma config WDT = OFF
#pragma config LVP = OFF
//#pragma config CPB = OFF
//#pragma config CPD = OFF

//prototypy
void inicializace();
void cekejTimer0();
//fce 
// 4 mhz Tpredd = (1 / 4/4 ) *16  prdelicka 0,5 blikani /T predd = vysledek
// 65536 - vysledek je hodnota bytu v registru TMR0H a TMR0L = 34286=85EE
void incializace()
{
    T0CON = 0b10010011;
    TRISB = 0b00000000;
    PORTB = 0b00000001;
}

void cekejTimer0()
{
    TMR0H=0x85;
    TMR0L=0xEE;
    
    INTCON = INTCON & 0b11111011; // vynuluje preteceni
    
    while(!(INTCON&0b00000100));// kdyz citac pretek pokracuj dal
}


void main(void) {
    incializace();
    while (1) 
    {
        PORTB=LATB^0b00000001; //zamen bit
        cekejTimer0();
        
    }
} 

Uživatelský avatar
MiloPS3
Příspěvky: 259
Registrován: 07 srp 2010, 02:00

#6 Příspěvek od MiloPS3 »

v datasheetu PIC18F452 se o něm nepíše.
strana 21 PIC18FXX2 Data Sheet

Uživatelský avatar
saitt
Příspěvky: 107
Registrován: 11 lis 2015, 01:00
Bydliště: Ostrava

#7 Příspěvek od saitt »

Díkes ,mě se zdálo že sem ho tam viděl ,ale v Indexu jsem ho nemohl najít ,měl by tedy zůstat na nule bit SCS.

Uživatelský avatar
Ruprecht
Příspěvky: 1114
Registrován: 28 zář 2005, 02:00
Bydliště: ZČ + JM

#8 Příspěvek od Ruprecht »

Proč výpočet na téhle stránce má 2x nasobení předděličkou ,
myslím to Overflow Period .
A není to náhodou jednou dělička 256 a podruhé 256 tiků, než přeteče timer?
20MHz xtal, hodiny pro timer jsou 4x pomalejší (tedy 5MHz), děličkou 256 se dostaneme na 5MHz/256=19531Hz, takže se jednička do timeru přičítá touto rychlostí. Timer přeteče když napočítá 256 svých tiků, tedy vyvolá přerušení s frekvencí 19531/256=76Hz. Takže když napočítám 76 přerušení, mám asi sekundu.
Kampaň, účelovka, nepodepsal, Palermo, ODS, Kalousek, je líp a jsou na to čísla, nastudujte si to.

Uživatelský avatar
saitt
Příspěvky: 107
Registrován: 11 lis 2015, 01:00
Bydliště: Ostrava

#9 Příspěvek od saitt »

jj vychází to i takle

(4mhz/4)/16=vysledek

vysledek * 0,5s =zbytek

65536-zbytek = 34286 = 0x85EE což vyšlo i prvním způsobem

hakamusai
Příspěvky: 943
Registrován: 17 dub 2007, 02:00

#10 Příspěvek od hakamusai »

Mě by jen zajímalo proč to řešíš tak problematicky. Pokud se použije HW timer,tak je možnost v přerušení řešit globální proměnou ,kdy na její stav se čeká v hlavní smyčce,případně tu část kódu řešit přímo v přerušení a v hlavní smyčce zpráv zpracovávat něco jinýho.

Uživatelský avatar
saitt
Příspěvky: 107
Registrován: 11 lis 2015, 01:00
Bydliště: Ostrava

#11 Příspěvek od saitt »

Dalo by se i přičítat náběžnou hranu přetečení např pro 10s ,ale to nastuduji zítra .

Díky všem, moc mi to pomohlo. :potlesk:

Odpovědět

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