PIC 18F4520 configuring TMR0 - Page 1
Forum section: electronics / general

author: nForce
author_rank: Frequent Contributor
timestamp: April 30, 2016, 05:02:21 pm
content: Hello,I have just started to learn the architecture of PICs. I am programming a 18F4520, but I have bumped into a first problem which I don't know how to solve it.The thing is, that I don't fully understand the datasheet.First of all; What is the clock speed of internal clock (Mhz) of 18F4520? In the datasheet is written that is configurable. But I haven't configure nothing which refers to clock speed, because I can damage the chip.Second; How can I configure TMR0 (16bit mode) so that the output of one pin will toggle with the frequency of 4 Hz?Can someone give an example for calculating the parameters for this particular chip. I am using the timer as 16 bit timer, I know that the internal clock for the timer is reduced 4 times, and then it can be reduced with the prescaler (which we configure).Thank you for your help.

author: Skimask
author_rank: Super Contributor
timestamp: April 30, 2016, 05:36:00 pm
content: Quote from: nForce on April 30, 2016, 05:02:21 pmPage 28 of DS39631A. The internal clock speed is whatever you configure it to be...from 31Khz, up to 32Mhz.QuoteSection 11 of DS39631A.Break it down...T0CON.6 = 0 = TMR0 is 16 bit counterT0CON.5 = 0 = TMR0 source is the internal clockT0CON.3 = 0 = TMR0 prescale is usedT0CON.2-0 = 001 = 1:4 prescaleAssume you're running 8 Mhz internal clock.8 Mhz / 4 = 2Mhz which is the internal instruction clock cycle2Mhz / 4 prescaler = 500khz16 counter overflows every 65,536 counts500khz / 65536 = 7.62939453125 HzNow you have to write code that uses either polling or an interrupt to check if the TMR0 counter overflowed and toggle a pin appropriately.Without pre-setting the TMR0L & TMR0H bytes to a preset value each time the TMR0 overflows, you aren't going to get exactly 4Hz.So, now write some code, some real code, and program it to a real PIC, on a real demo PCB of some sort, and report back.

author: JPortici
author_rank: Super Contributor
timestamp: April 30, 2016, 06:22:21 pm
content: For 8 bit pics, such as the PIC18s, the instruction clock is one fourth of the clock frequency. This means that if you're using the internal clock, configured as 8 MHz, your pic will effectively run at 8/4 = 2 MHz, or just about 2 MIPS.Timer 0 is a "dumb" timer. it will count from wherever it is upwards, until it overflows and restarts from zeroWhen Timer 0 overflows it also generates an interrupt and you can use it to execute code after X counts. To set a specific time between two interrupts set TMR0H:L at a specific valueTimer 0 can use either the internal system clock or an external clock, the clock can also be divided by using a prescaler, to achieve longer time.You can also use other timers, like timer 2. Timer 2 works in a different fashion. You set up the clock and then Timer 2 counts up until it matches a Period Register (PR2). in that moment it resets itself and generate an interrupt. As timer2 is also used by the CCP module as timebase, so it becomes useful to execute syncronious tasks, like loading the PWM module with a new period/sample

author: nForce
author_rank: Frequent Contributor
timestamp: April 30, 2016, 06:42:57 pm
content: Thank you,Sorry, but I can't find what is the clock speed if I don't configure it? It is written that the factory calibrated the chip so it runs on 8 Mhz. So if I don't configure nothing which refers to the clock speed, it is then 8 Mhz?I don't want to mess with the clock speed at the beginning.

author: dannyf
author_rank: Super Contributor
timestamp: April 30, 2016, 07:16:35 pm
content: Check the default values of fuse settings and default values of clock related registers. Typicslky it runs on the internal oscillators. Check the clock tree in the data sheet.

author: vodka
author_rank: Frequent Contributor
timestamp: April 30, 2016, 08:00:07 pm
content: Exactly from the schema What don't you understand?QuoteAre you referring if you don't configure the preescaleer?So, the answer can be unknown, because it is impossible knowlegde which data can have the register OSCCON when it turns on. Therefore ,my advice is that you always initialize when you use the internal oscillator.

author: Skimask
author_rank: Super Contributor
timestamp: April 30, 2016, 09:52:10 pm
content: Specifically to the O/P...Reading one page isn't going to tell you the whole story.You want to know what the default configuration of the PIC is upon power up? Search the PDF for the word "default".You want to know what the default config of the oscillator is on power up? Search the PDF for the word "oscillator".Page 30 and 250 of the datasheet will give you a clue as to what the default configuration of the oscillator is on power up.

author: nForce
author_rank: Frequent Contributor
timestamp: May 24, 2016, 01:44:45 pm
content: Quote from: Skimask on April 30, 2016, 05:36:00 pmI have successfuly read the datasheet, and now I know that the default internal osc is 1 Mhz.But how can I adjust the TMR0L and TMR0H appropriately so that I get 4 Hz toggle. Can you do the example for 4 Hz? I will play with different frequency later.I don't need the code, just a mathematical explanaiton and example. As I see this problem; at first I have to increase the prescaler (not 1:4 but 1:and then find two numbers for TMR0L and TMR0H.

author: dannyf
author_rank: Super Contributor
timestamp: May 24, 2016, 02:41:37 pm
content: 4Hz means each flip is 125ms, or 125000 cpu cycles.If you run the timer at 8 bits, that 125000/256 = 488.28 times. That means you can either a prescaler, and/or with re-load, and may have to some counting in the isr;for 16-bit timer, 125000/64K = 1.90 times. That means you can either reload + some processing in the isr.The approach above gives you the lowest jitter but may not be 100% accurate in terms of timing.An alternative approach, which provides accurate ***long-term*** timing but will give you jitter, is to not reset the timer but keeps track of its value.Like this in the isrCode:timer0_cnt+=0x100; //update timer0 counter for 8-bit; use 0x10000ul for 16-bit timer. Adjust appropriately if prescalers is usedif (timer0_cnt >= F_CPU / F_OUT / 2) { //desired duration has elapsedtimer0_cnt -= F_CPU / F_OUT / 2; //update timer0 counterflip PIN_OUTPUT; //flip output pin}

author: nForce
author_rank: Frequent Contributor
timestamp: May 24, 2016, 03:09:27 pm
content: Sorry, but forget the counting and jitter. It can be approx. 4 Hz. I don't know how to choose the numbers for TMR0L and TMR0H and prescaler such that the bit will toggle with frequency 4 Hz.This is a great example:QuoteI know how to program, I just need an explanation in a logical and mathematical way with an example.But I have to use TMR0H and TMR0L, because that way I can learn something new.Thanks.

author: dannyf
author_rank: Super Contributor
timestamp: May 24, 2016, 03:41:21 pm
content: 1. Create an isr that trips every 125000us/2 on 1:1 prescaler, and flip your output pin every two isr executions.2. create an isr that trips every 125000us on 2:1 prescaler, and flip your output pin every isr execution.

author: nForce
author_rank: Frequent Contributor
timestamp: May 24, 2016, 04:21:27 pm
content: How did you calculate/get the numbers which we assign to TMR0L and TMR0H?

author: Skimask
author_rank: Super Contributor
timestamp: May 24, 2016, 06:39:26 pm
content: Oh for fucks sake...QuoteCan you think out of the box for just a minute?Modify that quote just a bit maybe?Here...I'll do it for you.Let's see if you follow me...Quote

author: dannyf
author_rank: Super Contributor
timestamp: May 24, 2016, 07:19:09 pm
content: QuoteIt's all laid out bare in prior posts.Taking Approach 2 for example:Code:#define TMR0_OFST (F_CPU / F_OUT / 2 / 2) //tmr0 offset for 2:1 prescaler to generate F_OUT under F_CPUTMR0 = -TMR0_OFST; //load tmr0 offset for F_OUT. Prescaler is set to 2:1that's all you need.

author: MarkF
author_rank: Super Contributor
timestamp: May 24, 2016, 07:57:47 pm
content: Complete example. Sorry I don't have a pic18f4520 to test the code.Code:/** File: main.c* Author: Mark** Created on May 24, 2016, 2:38 PM*/#include <xc.h>#include <stdio.h>#include <stdlib.h>// Configuration bits// CONFIG1H#pragma config OSC = INTIO7 // Oscillator Selection bits (Internal oscillator block, CLKO function on RA6, port function on RA7)#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)#pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)// CONFIG2L#pragma config PWRT = ON // Power-up Timer Enable bit (PWRT enabled)#pragma config BOREN = OFF // Brown-out Reset Enable bits (Brown-out Reset disabled in hardware and software)#pragma config BORV = 3 // Brown Out Reset Voltage bits (Minimum setting)// CONFIG2H#pragma config WDT = OFF // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)// CONFIG3H#pragma config CCP2MX = PORTC // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)#pragma config PBADEN = ON // PORTB A/D Enable bit (PORTB<4:0> pins are configured as analog input channels on Reset)#pragma config LPT1OSC = OFF // Low-Power Timer1 Oscillator Enable bit (Timer1 configured for higher power operation)#pragma config MCLRE = OFF // MCLR Pin Enable bit (RE3 input pin enabled; MCLR disabled)// CONFIG4L#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)#pragma config LVP = ON // Single-Supply ICSP Enable bit (Single-Supply ICSP enabled)#pragma config XINST = OFF // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))// Global variablesint led=0;/** Main function*/void main() {// Configure the internal oscillatorOSCCONbits.IRCF = 7; // Set internal oscillator frequency to 8 MHzOSCCONbits.SCS = 2; // Select internal oscillator// Configure I/O pinTRISAbits.TRISA0 = 0; // Select RA0 pin as output// Configure Timer0/*The TMR0 interrupt is generated when the TMR0 registeroverflows from FFFFh to 0000h in 16-bit mode. This overflowsets the TMR0IF flag bit.For 4 Hz interrupt and 8 MHz clock:Fosc/4 = 2MHzticks = 2MHz / 256 prescaler / 4 Hz interrupt = 1953TMR0 = 65535 - 1953 = 0xf85eDON'T FORGET TO RESET TMR0 VALUES IN ISR*/TMR0H = 0xf8; // Timer0 register (high byte)TMR0L = 0x5e; // Timer0 register (low byte)T0CONbits.PSA = 0; // Timer0 clock input comes from prescaler outputT0CONbits.T0PS = 7; // Set 1:256 prescale valueT0CONbits.T0CS = 0; // Select internal instruction cycle clockT0CONbits.T08BIT = 0; // Select 16-bit timer/counterT0CONbits.TMR0ON = 1; // Enable timer0// Enable interruptsINTCON=0xc0; // GIE and PEIE interrupts// Enter main loopwhile (1) {}}/** Interrupt service routine*/void interrupt isr(){if (TMR0IE && TMR0IF) {TMR0IF = 0; // Clear Timer0 interruptTMR0H = 0xf8; // Timer0 register (high byte)TMR0L = 0x5e; // Timer0 register (low byte)if (++led > 1) led=0; // Toggle LED valueLATAbits.LA0 = led; // Set RA0 pin}}

author: nForce
author_rank: Frequent Contributor
timestamp: May 27, 2016, 08:51:02 pm
content: Thank you, I had a software bug in my code.I have one little question tho. I am programming this in assembly with simulator :Why is this line of code working:Code:bsf LATB,7But below the bit 4 it does not set.