/* tohle jsou nejake pokusy, nevim, zda to funguje * File: oscilator02.c * Author: kubalik * * Created on 17. dubna 16:43 * odvozeno z oscilator01.c * * vzsilame FM na kmitoctu 98,55 MHz * ale FRC na toleranci -+2 proc., takze kdovi .... * * pin 12 RP20 RA4 - tadz budeme vzsilat FM * * REFCLKO - to je vzstup referencniho kmitoctu * * kmitoctz radii * http://ok1sb.cbmonitor.cz/fm_radio/index.php * * tento program demonstruje pouziti PLL * frekvenci oscilatoru je mozno sledovat na bitech RA0 RA1 RA2 * mezi zmenou na portu uplyne 10000 period Fcy * tedy 10000 instrukcnich cyklu, kmitocet oscilatoru je potom x 2 * na portu RA je tato doba od hrany k hrane, takze polovina periody * * * bity RB0 a RB1 rikaji, ze jsme kmitocet uspesne prepnuli - hodnota 1 * * bit RB4 rika, ze jsme v programu dosahli mista, kde zacina prepnuti kmitoctu * * bity PORTA,0 1, 2 dodavaji kmitocet instrukcu deleno 10000 * tady muzeme zmerit, co ma procesor uvnitr * pri mereni nezapomente, ze kmitocet instrukci je dan casem * od vzestupne k sestupne hrane na techto pinech, * tedy tenhle cas * 10000 da periodu instukci, a /2 da periodu vnitrniho oscilatoru * * postupujeme podle example 7.2, strana 27 , oscilator.pdf * */ #include "p33EV32GM002.h" /* nasledujici makra nastavuji oscilator * hledame v header file * * Macros for setting device configuration registers * pin OSC1 jako I/O pin * vypinaji Watchdog - opet se podivejte do header file, co vsecno se da nastavit * */ // nastaveni fuses funguje, prepnuti take vyzkouseno _FOSCSEL(FNOSC_FRC & IESO_OFF); /* - po RESETu je zapnut FRC oscilátor */ _FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_NONE & IOL1WAY_OFF ); /*- umo?níme programem p?epnout mezi dv?ma oscilátory */ _FWDT( FWDTEN_OFF ) /* Select Internal FRC at POR , bod d kap. 7.7.2.2 v oscilator.pdf po resetu NENI PLL, zatim pracujeme jenom s FRC oscilatorem */ // _FOSCSEL(FNOSC_FRC & IESO_OFF); /* Enable Clock Switching and Configure Primary Oscillator in XT mode */ /* na & IOL1WAY_OFF se podivame do file * C:\Program Files (x86)\Microchip\xc16\v1.25\support\dsPIC33E\inc\p33EV32GM002.inc * IOL1WAY_OFF Allow Multiple reconfigurations je pro PPS, * toho se zatim nedeste */ unsigned int i; /* i je globalni promenne, potrebujeme, aby si pamatovala svou hodnotu i v dobe, kdy se nevykonava obsluha preruseni */ unsigned int j; /* * */ int main() { i = 0; /* sem si dejte breakpoint ! */ j = 0; TRISA = 0x0; // zapisujeme do celeho registru najednou TRISB = 0x00; PORTB = 0; PORTA = 0; ANSELB = 0; ANSELA = 0; /* TIMER T2 * T2CON 1X1- ---- -000 0-0- * | | ||| | | * | | ||| | internal clock - FRC oscil F je 7.37 / 2 * | | ||| T32 - mame 16bitoc\ve citace * | | ||| * | | |TCKPS 00 - delime 1 u preddelicky * | | TGATE je vypnuto * | TSIDLE pracujeme i v idle stavu - to je ted dost jedno * TON citac zapnut * * cely citac je naprogramovan tak, aby deleil 10000 * delicka v citaci 1 , registr PR 10000 * */ CLKDIVbits.FRCDIV = 0; /* delíme 1 */ PR2 = 10000; T2CON = 0xA000; /* v tomhle miste bezi vnitrni oscilator na 7.3 MHz * takze na pinech RA0 RA1 RA2 jsou pulsiky s frekvenci 365 Hz */ /* povoluji preruseni */ IEC0bits.T2IE = 1; /* globalni povoleni preruseni, tohle se musi povolit, * jinak nebude zadne preruseni krome TRAP */ IFS0bits.T2IF = 0; /* pro jistotu nuluji pozadavkovy bit */ INTCON2bits.GIE = 1; asm(" bset PORTB, #4 "); /* bit RB4 rika, jsme dospeli az sem * a je to opravdu 10 sec od zacatku * frekvence je tedy 365 hz */ /* nastavime si PLL a vnitrni oscilator na 50 MHz */ // Configure PLL prescaler, PLL postscaler, PLL divisor // strana 26 v oscilator.pdf // na zaklade mereni muzeme doufat, ze FRC ma kmitocet 307 x 2 = 7.4 MHz PLLFBD=79; // M=81 /* PLLFBD deli * 0 - delime 2 * 1 - delime tremi * 0x1ff - delime 513 , vic to nejde * na obrazku 7-8 se tyto bity jmenuji PLLDIV * timhle cislem tedy delime vystup z VCO, abychom dostali * ten kmitocet, ktery leze do bloku PFD z FPLU * * Nas kmitocet Fplli je 2.43 MHz * x 81 = 197.1 MHz - to je Fsys * */ CLKDIVbits.PLLPOST=0; // N2=2 /* a fsys delime 4 197.1 / 2 = 98,55 MHz */ CLKDIVbits.PLLPRE=1; // N1=3 7.4 MHz / 3 = 2.43MHz - Kmitocet Fplli /* 12 RP20 RPOR0 XXXXXXXXBBBBBBBB * REFCLKO 110001 RPn tied to Reference Clock Output a manual se tvari, ze to nepotrebuje LOPCK ani UNLOCK sekvenci*/ RPOR0 = 0x31 ; REFOCON = 0x00 ; /* strana 132, nejdrime jenom ta delicka */ REFOCONbits.ROON = 1; /* a nakonec se to zapne */ /*Initiate Clock Switch to Primary Oscillator with PLL (NOSC=0b011) * postupujeme podle example 7.2, strana 27 , oscilator.pdf */ INTCON2bits.GIE = 0; __builtin_write_OSCCONH(0x01); __builtin_write_OSCCONL(OSCCON | 0x01); INTCON2bits.GIE = 1; // Wait for Clock switch to occur ????? tohle je mozna blbe, ale fungovalo to s tim while (OSCCONbits.COSC != 0b011) { i++; }; asm(" bset PORTB, #0 "); /* bit RB0 rika, ze jsme prepli hodiny */ // Wait for PLL to lock while (OSCCONbits.LOCK != 1){ i++; }; asm(" bset PORTB, #1 "); /* bit RB1 rika, ze PLL ma spravny kmitocet */ while (1) { i++ ; /* thleje je k nicemu, ale musi tady byt nejaka instrukce, aby fungoval simulator */ } return 0; } // interrupt od TMR2 void __attribute__((interrupt, auto_psv)) _T2Interrupt(void) { IFS0bits.T2IF = 0; /* shazujeme pozadavkovy bit */ asm(" bclr IFS0, #7 "); // nuluji bit pro preteceni citace /* s kmitoctem fCY / 10000 se meni stav na techto pinech * to pouzijeme pro kontrolu kmitoctu vnitrniho oscilatoru * od hrany k hrane to pred zmenou Fosc je 2.7ms, to odpovida 370Hz * a x 10000 odp[ovida 3.7MHz kmitoctu instrukci */ asm(" btg PORTA, #0 "); asm(" btg PORTA, #1 "); asm(" btg PORTA, #2 "); j++; } /* zaviraci od podprogramu _T2Interrupt retfie prida prekladac sam, je to dano atributem interrupt */