u8 OnTimer0(callback func, u8 timediv, u16 delay) { u8 _t0con = 0; u16 _cycles_; if (intUsed[INT_TMR0] == INT_NOT_USED) { intUsed[INT_TMR0] = INT_USED; intCount[INT_TMR0] = 0; intCountLimit[INT_TMR0] = delay; intFunction[INT_TMR0] = func; switch(timediv) { case INT_MICROSEC: // 1 us = 1.000 ns = 12 cy _cycles_ = System_getPeripheralFrequency() / 1000 / 1000; preloadH[INT_TMR0] = high8(0xFFFF - _cycles_); preloadL[INT_TMR0] = low8(0xFFFF - _cycles_); _t0con = T0_OFF | T0_16BIT | T0_SOURCE_INT | T0_PS_OFF; break; case INT_MILLISEC: // 1 ms = 1.000.000 ns = 12.000 cy _cycles_ = System_getPeripheralFrequency() / 1000 ; preloadH[INT_TMR0] = high8(0xFFFF - _cycles_); preloadL[INT_TMR0] = low8(0xFFFF - _cycles_); _t0con = T0_OFF | T0_16BIT | T0_SOURCE_INT | T0_PS_OFF; break; case INT_SEC: // 1 sec = 1.000.000.000 ns = 12.000.000 cy // 12.000.000 / 256 = 46875 _cycles_ = System_getPeripheralFrequency() >> 8; preloadH[INT_TMR0] = high8(0xFFFF - _cycles_); preloadL[INT_TMR0] = low8(0xFFFF - _cycles_); _t0con = T0_OFF | T0_16BIT | T0_SOURCE_INT | T0_PS_ON | T0_PS_1_256; break; } T0CON = _t0con; INTCON2bits.TMR0IP = INT_LOW_PRIORITY; TMR0H = preloadH[INT_TMR0]; TMR0L = preloadL[INT_TMR0]; INTCONbits.TMR0IF = 0; INTCONbits.TMR0IE = INT_ENABLE; return INT_TMR0; }
void PWM_setFrequency(u32 freq) { // PR2+1 calculation _pr2_plus1 = System_getPeripheralFrequency() / freq; // FOSC / (4 * PWM Frequency) // Timer2 prescaler calculation // PR2 max value is 255, so PR2+1 max value is 256 // highest prescaler value is 16 // 16 * 256 = 4096 so : if (_pr2_plus1 <= 4096) // check if it's not too high { if (_pr2_plus1 <= 256) // no needs of any prescaler { _t2con = 0b00000100; // prescaler is 1, Timer2 On } else if (_pr2_plus1 <= 1024) // needs prescaler 1:4 { _pr2_plus1 = _pr2_plus1 >> 2; // divided by 4 _t2con = 0b00000101; // prescaler is 4, Timer2 On } else // needs prescaler 1:6 {
void Audio_init(u16 samplerate) { u8 prescaler; // PR2+1 calculation // Timer2 clock input is the peripheral clock (FOSC/4). gPeriodPlus1 = System_getPeripheralFrequency() / samplerate; // stops interrupt INTCONbits.GIEH = 0; // disable global HP interrupts INTCONbits.GIEL = 0; // disable global LP interrupts // configures Timer2 interrut IPR1bits.TMR2IP = 1; // interrupt has high priority PIR1bits.TMR2IF = 0; // reset interrupt flag // Timer2 prescaler calculation // PR2 max value is 255, so PR2+1 max value is 256 // only 3 possible prescaler value : 1, 4 or 16 // so gPeriodPlus1 can not be > to 16 * 256 = 4096 // and frequency can not be < 2929Hz (12MHZ/4096) if (gPeriodPlus1 <= 4096) // check if it's not too high { if (gPeriodPlus1 <= 256) // no needs of any prescaler { prescaler = 0; // prescaler is 1, Timer2 On } else if (gPeriodPlus1 <= 1024) // needs prescaler 1:4 { gPeriodPlus1 = gPeriodPlus1 >> 2;// divided by 4 prescaler = 1; // prescaler is 4, Timer2 On } else // needs prescaler 1:6 {