r/pic_programming 7h ago

Did i understand it properly?

3 Upvotes

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:

  1. 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;
  2. 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.
  3. 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;
  4. 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;
  5. 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.
  6. I am still trying to become familiar with register names and meanings, i know i can be missing something else.
  7. 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

}

}