The goal: the same as previous, to get the 1KHz pulse.
What do we have: PIC16f628a, the simple devboard + proteus.
For this particular uC the timer2 module is another 8bits timer, which has some peculiarities.
The reference frequency runs thru the prescaler with 3 ratios (1, 4 and 16). Then, divided pulses reach the TMR2 register and are used to increment it. The register TMR2 content compares with PR2 value, if there is a match, it is transferred to the second divider (called postcaler), and then we can have an interrupt generated.
To start\stop the timer we have the TMR2ON bit, also, both TMR2 and PR2 are re-writable. Prescaler setup:
T2CKPS1 T2CKPS0
0 0 1:1
0 1 1:4
1 x 1:16
Postcaler setup:
A couple more things we need to take into account, when you are dealing with PIC microcontroller, using the timer2 module.
- The power-on value of the PR2 register is FFh
- If you change TMR2 values, both dividers are cleared
- The uC reset will of course reset dividers ratios
Now is the practice time:
#include <htc.h> #define _XTAL_FREQ 4000000 #define out RB7 __CONFIG(WDTDIS & UNPROTECT & MCLREN & LVPDIS); void main() { __delay_ms(100); //небольшая задержка TRISB = 0x00; PORTB = 0x00; TMR2 = 0x01; //стартуем с 1 PR2 = 0x64; //считаем по 100 мкс T2CKPS0 = 0; T2CKPS1 = 0; //1 делитель не делит входную частоту TOUTPS2 = 1; TOUTPS1 = 0; TOUTPS3 = 0; TOUTPS0 = 0; //2 делитель делит на 5 GIE = 1; // глобальные прерывания PEIE = 1; // прерывания перефирии TMR2IE = 1; TMR2ON = 1; // Запуск таймера! for (;;) { //бесконечный цикл } } interrupt isr() { if (TMR2IF) { out = !out; TMR2 = 0x01; T2CKPS0 = 0; T2CKPS1 = 0; //1 делитель не делит входную частоту TOUTPS2 = 1; TOUTPS1 = 0; TOUTPS3 = 0; TOUTPS0 = 0; //2 делитель делит на 5 TMR2IF = 0; //сброс флага } }
The source code is here