btw - sto se tice te formule
Code:
unsigned long freq;
volatile unsigned short fl;
char txt[12];
void interrupt(){
if(CCP1IF_bit){
TMR1H=0;
TMR1L=0;
fl=1;
CCP1IF_bit=0;
}
if(TMR1IF_bit){
//not really good
TMR1IF_bit=0;
}
}
void main() {
OPTION_REG=0;
INTCON = 0xC0; // GIE + PEIE
PIE1 = 0x05; // CCP1IE + TMR1IE
T1CON = 0x01; // TMR1 PRESCALER 1:1, source Fosc/4, enabled
CCP1CON= 0x05; // Capture mode, reising edge
TRISC = 0xff;
TRISB = 0;
UART1_Init(9600);
VDelay_ms(100);
fl=0;
while(1) if (fl) {
freq = (Clock_kHz() *1000 / (CCPR1H << 8 | CCPR1L)) >> 2;
fl = 0;
LongToStr(freq, txt);
UART1_Write_text(txt);
UART1_Write_text("\r\n");
}
}
eto ga primer koji radi "uvek" ...
dakle:
freq = (Clock_kHz() *1000 / (CCPR1H << 8 | CCPR1L)) >> 2;
cisto da ne juri uvek "brojku" .. ovako mu mikroC sam vrati fosc a i ovaj >>2 na kraju lako menja ako menja prescaler na T1CON tako da ako je prescaler tu 1:2 onda je >> 3 :) etc ...
capture varijanta radi tako sto broji koliko je bilo TMR1 impulsa izmedju 2 eventa na capture pinu. ti biras koliko su ti dugacki tmr1 impulsi (sto su kraci, veca je preciznost ali posto je brojac 16 bita ako meris manju frekvenciju moras da povecas prescaler (duzinu trajanja tmr1 impulsa) a to ti zabada preciznost. Kada dobijes "koliko je impulsa bilo" pomnozis to sa duzinom trajanja TMR1 impulsa (ako je prescaler 1:1 onda je trajanje 1/(FOSC/4)sekundi) i onda sve to 1/x da bi dobio koliko je to Hz :) .. ovde sad imas varijante da povecas preciznost tako sto imas prescaler i za ulazne impulse, pa ne brojis izmedju 2 impulsa (tj izmedju 2 ivice, ulazne ili izlazne) nego moze da brojis izmedju svake 4 ili izmedju svakih 16 .. to je zgodno ako meris vece frekvencije
compare varijanta poredi vrednost CCPR1 registra sa TMR1 registrom (oba 16 bitna, CCPR1 ti upises vrednost u njega, TMR1 se menja kako prolazi vreme, tj kako radi TIMER1) i kada se poklope uradi nesto sa CCP1 pinom. Zgodno ako hoces na tom pinu da generises square wave neke frekvencije
pwm mod je valjda jasan?