r/pic_programming • u/aspie-micro132 • 15m ago
Did i understand it properly?
Please tell me if i understood it properly or at least i'm somwhere close to:
Using timers instead of "__delay_ms()" seems like this to me, at this moment:
- You have to choose whether to use Timer 0 (8 bits) or Timer 1 (16 Bits) by turning the TMR0ON or either TMR1ON to 1 in the settings part of the C code, before the Void Main() stage;
- You have to set another register to take internal clock as source for Tick counting, wich seems to be 1/4 of the main oscillator. If you have a 4mhz crystal, you have 1mhz worth of timer frequency.
- You have to find out how long it takes the TMR1ON's 16 bit register to be written from 0 to 1 before starting over after reaching the last desired bit wich resets the counter. You have a high and low register settings where you have to specify how many bits you wish to write before reaching the reset, like, if i do not misremember, tying the last pin of a CD4017 to Reset pin before reaching the full ic;
- Also you have to set up something called Prescaler which allows to divide the clock output between 1:1 and 1:256, meaning, 1:1 means one pulse input makes one output and 256 input pulses makes an output one;
- Once you have this stuff properly setted up, then you can use an If{} routine which counts clock ticks and then performs some action between curly braces. This is the replacement for "__delay_ms()", which, given the fact they do not block the whole microcontoller waiting, allows to blink a led while driving a motor or some other task.
- I am still trying to become familiar with register names and meanings, i know i can be missing something else.
- After searching in the web and reading some blocks, Google Ai gave me this code, i pasted it in my project and it built, altought i did not adapt it to the real thing yet;
void __interrupt() timer1_isr(void) {
if (TMR1IF) {
TMR1H = 0x0B; // Re-preload Timer1 high byte (3036 = 0x0BDC)
TMR1L = 0xDC; // Re-preload Timer1 low byte
TMR1IF = 0; // Clear interrupt flag
overflow_count++;
if (overflow_count >= 2) { // 2 x 0.5 seconds = 1 second
overflow_count = 0;
// Toggle an LED or do your 1-second task here
PORTBbits.RB0 = !PORTBbits.RB0;
}
}
}
void main(void) {
TRISB0 = 0; // Set RB0 as output for LED
T1CON = 0x31; // Prescaler 1:8 (T1CKPS = 11), Internal clock (TMR1CS = 0), Timer On (TMR1ON = 1)
TMR1H = 0x0B; // Load initial preload value 3036
TMR1L = 0xDC;
PIE1bits.TMR1IE = 1; // Enable Timer1 Interrupt
INTCONbits.PEIE = 1; // Enable Peripheral Interrupts
INTCONbits.GIE = 1; // Enable Global Interrupts
while(1) {
// Main loop does other tasks
}
}

