@be80beIt not work if your code don;t have this in it
OSCCON = 0x7E: //make the osc start up at 8 mhz
You have to set the OSCCON on the 18f2550 if not it will not run at the speed your setting the timer0 for the osc will be way off
#define REPEAT_COUNT 10000 // adjust this value to increase/decrease the delaY
void T0Delay(void);
#define IO_RB0_LAT LATBbits.LATB0
#define IO_RB0_Toggle() do { LATBbits.LATB0 = ~LATBbits.LATB0; } while(0)
/*
* File: main.c
* Author: burt
*
* Created on September 22, 2017, 10:27 PM
*/
// 'C' source line config statements
// CONFIG1L
#pragma config PLLDIV = 1 // PLL Prescaler Selection bits (No prescale (4 MHz oscillator input drives PLL directly))
#pragma config CPUDIV = OSC1_PLL2// System Clock Postscaler Selection bits ([Primary Oscillator Src: /1][96 MHz PLL Src: /2])
#pragma config USBDIV = 1 // USB Clock Selection bit (used in Full-Speed USB mode only; UCFG:FSEN = 1) (USB clock source comes directly from the primary oscillator block with no postscale)
// CONFIG1H
#pragma config FOSC = INTOSCIO_EC// Oscillator Selection bits (Internal oscillator, port function on RA6, EC used by USB (INTIO))
#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 = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOR = ON // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
#pragma config BORV = 3 // Brown-out Reset Voltage bits (Minimum setting 2.05V)
#pragma config VREGEN = OFF // USB Voltage Regulator Enable bit (USB voltage regulator disabled)
// 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 = ON // 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 Timer 1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = ON // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin 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))
// CONFIG5L
#pragma config CP0 = OFF // Code Protection bit (Block 0 (000800-001FFFh) is not code-protected)
#pragma config CP1 = OFF // Code Protection bit (Block 1 (002000-003FFFh) is not code-protected)
#pragma config CP2 = OFF // Code Protection bit (Block 2 (004000-005FFFh) is not code-protected)
#pragma config CP3 = OFF // Code Protection bit (Block 3 (006000-007FFFh) is not code-protected)
// CONFIG5H
#pragma config CPB = OFF // Boot Block Code Protection bit (Boot block (000000-0007FFh) is not code-protected)
#pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM is not code-protected)
// CONFIG6L
#pragma config WRT0 = OFF // Write Protection bit (Block 0 (000800-001FFFh) is not write-protected)
#pragma config WRT1 = OFF // Write Protection bit (Block 1 (002000-003FFFh) is not write-protected)
#pragma config WRT2 = OFF // Write Protection bit (Block 2 (004000-005FFFh) is not write-protected)
#pragma config WRT3 = OFF // Write Protection bit (Block 3 (006000-007FFFh) is not write-protected)
// CONFIG6H
#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) are not write-protected)
#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot block (000000-0007FFh) is not write-protected)
#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM is not write-protected)
// CONFIG7L
#pragma config EBTR0 = OFF // Table Read Protection bit (Block 0 (000800-001FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF // Table Read Protection bit (Block 1 (002000-003FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF // Table Read Protection bit (Block 2 (004000-005FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF // Table Read Protection bit (Block 3 (006000-007FFFh) is not protected from table reads executed in other blocks)
// CONFIG7H
#pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) is not protected from table reads executed in other blocks)
#include <xc.h>
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
void main ( void )
{
int cnt,COUNT;
// PIC_Init();
//TRISA = 0x00; /* make all of PORTA outputs */
OSCCON = 0x7E; //make the osc start up at 8 mhz
TRISB = 0b00000000; // make all PORTA pins output
PORTB = 0; //turn off PORTA pins
ADCON1 = 0b00001111; //make all analog pins as digital
CMCON = 0b00000111; //
//for(;;) /* loop forever */
//PORTBbits.RB1=0;//INITIALIZATION
while(1)
{
IO_RB0_LAT=0;//Toggle the pin1 of port A
for (cnt = REPEAT_COUNT;cnt;cnt--)
{
T0Delay(); // or even the actual code of the function
} // for (cnt = REPEAT_COUNT;cnt;cnt--)
//T0Delay();
IO_RB0_LAT=1;
for (cnt = REPEAT_COUNT;cnt;cnt--)
{
T0Delay(); // or even the actual code of the function
}
/*for (COUNT = REPEAT_COUNTS;COUNT;COUNT--)
{
T0Delay(); // or even the actual code of the function
} // for (cnt = REPEAT_COUNT;cnt;cnt--)*/
// T0Delay();
}
}
void T0Delay()
{
T0CON=0x01;//timer 0,16bit mode,1:4 prescalar(0000 0001)
TMR0H=0xFF; //load TH0(1001 1100) ONLY FOR THE 8 BIT SO ONLY YOU CAN GO FOR THE 256 CALCULATIONS.
TMR0L=0xEE; //LOAD TL0 ()
T0CONbits.TMR0ON=1; //START TIMER
while (INTCONbits.TMR0IF==0); // WAIT FOR TIMER0 TF0 TO ROLL OVER
T0CONbits.TMR0ON=0;//TURN OFF TIMER
INTCONbits.TMR0IF=0;// CLEAR TF0
}
@be80beThe code posted has tons of errors if the op post the project that be great here one that works it's in xc8
Code:#define REPEAT_COUNT 10000 // adjust this value to increase/decrease the delaY void T0Delay(void); #define IO_RB0_LAT LATBbits.LATB0 #define IO_RB0_Toggle() do { LATBbits.LATB0 = ~LATBbits.LATB0; } while(0) /* * File: main.c * Author: burt * * Created on September 22, 2017, 10:27 PM */ // 'C' source line config statements // CONFIG1L #pragma config PLLDIV = 1 // PLL Prescaler Selection bits (No prescale (4 MHz oscillator input drives PLL directly)) #pragma config CPUDIV = OSC1_PLL2// System Clock Postscaler Selection bits ([Primary Oscillator Src: /1][96 MHz PLL Src: /2]) #pragma config USBDIV = 1 // USB Clock Selection bit (used in Full-Speed USB mode only; UCFG:FSEN = 1) (USB clock source comes directly from the primary oscillator block with no postscale) // CONFIG1H #pragma config FOSC = INTOSCIO_EC// Oscillator Selection bits (Internal oscillator, port function on RA6, EC used by USB (INTIO)) #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 = OFF // Power-up Timer Enable bit (PWRT disabled) #pragma config BOR = ON // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled)) #pragma config BORV = 3 // Brown-out Reset Voltage bits (Minimum setting 2.05V) #pragma config VREGEN = OFF // USB Voltage Regulator Enable bit (USB voltage regulator disabled) // 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 = ON // 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 Timer 1 Oscillator Enable bit (Timer1 configured for higher power operation) #pragma config MCLRE = ON // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin 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)) // CONFIG5L #pragma config CP0 = OFF // Code Protection bit (Block 0 (000800-001FFFh) is not code-protected) #pragma config CP1 = OFF // Code Protection bit (Block 1 (002000-003FFFh) is not code-protected) #pragma config CP2 = OFF // Code Protection bit (Block 2 (004000-005FFFh) is not code-protected) #pragma config CP3 = OFF // Code Protection bit (Block 3 (006000-007FFFh) is not code-protected) // CONFIG5H #pragma config CPB = OFF // Boot Block Code Protection bit (Boot block (000000-0007FFh) is not code-protected) #pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM is not code-protected) // CONFIG6L #pragma config WRT0 = OFF // Write Protection bit (Block 0 (000800-001FFFh) is not write-protected) #pragma config WRT1 = OFF // Write Protection bit (Block 1 (002000-003FFFh) is not write-protected) #pragma config WRT2 = OFF // Write Protection bit (Block 2 (004000-005FFFh) is not write-protected) #pragma config WRT3 = OFF // Write Protection bit (Block 3 (006000-007FFFh) is not write-protected) // CONFIG6H #pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) are not write-protected) #pragma config WRTB = OFF // Boot Block Write Protection bit (Boot block (000000-0007FFh) is not write-protected) #pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM is not write-protected) // CONFIG7L #pragma config EBTR0 = OFF // Table Read Protection bit (Block 0 (000800-001FFFh) is not protected from table reads executed in other blocks) #pragma config EBTR1 = OFF // Table Read Protection bit (Block 1 (002000-003FFFh) is not protected from table reads executed in other blocks) #pragma config EBTR2 = OFF // Table Read Protection bit (Block 2 (004000-005FFFh) is not protected from table reads executed in other blocks) #pragma config EBTR3 = OFF // Table Read Protection bit (Block 3 (006000-007FFFh) is not protected from table reads executed in other blocks) // CONFIG7H #pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) is not protected from table reads executed in other blocks) #include <xc.h> // #pragma config statements should precede project file includes. // Use project enums instead of #define for ON and OFF. void main ( void ) { int cnt,COUNT; // PIC_Init(); //TRISA = 0x00; /* make all of PORTA outputs */ OSCCON = 0x7E; //make the osc start up at 8 mhz TRISB = 0b00000000; // make all PORTA pins output PORTB = 0; //turn off PORTA pins ADCON1 = 0b00001111; //make all analog pins as digital CMCON = 0b00000111; // //for(;;) /* loop forever */ //PORTBbits.RB1=0;//INITIALIZATION while(1) { IO_RB0_LAT=0;//Toggle the pin1 of port A for (cnt = REPEAT_COUNT;cnt;cnt--) { T0Delay(); // or even the actual code of the function } // for (cnt = REPEAT_COUNT;cnt;cnt--) //T0Delay(); IO_RB0_LAT=1; for (cnt = REPEAT_COUNT;cnt;cnt--) { T0Delay(); // or even the actual code of the function } /*for (COUNT = REPEAT_COUNTS;COUNT;COUNT--) { T0Delay(); // or even the actual code of the function } // for (cnt = REPEAT_COUNT;cnt;cnt--)*/ // T0Delay(); } } void T0Delay() { T0CON=0x01;//timer 0,16bit mode,1:4 prescalar(0000 0001) TMR0H=0xFF; //load TH0(1001 1100) ONLY FOR THE 8 BIT SO ONLY YOU CAN GO FOR THE 256 CALCULATIONS. TMR0L=0xEE; //LOAD TL0 () T0CONbits.TMR0ON=1; //START TIMER while (INTCONbits.TMR0IF==0); // WAIT FOR TIMER0 TF0 TO ROLL OVER T0CONbits.TMR0ON=0;//TURN OFF TIMER INTCONbits.TMR0IF=0;// CLEAR TF0 }
@be80beYou don't have to change the code I posted is C code and should work with mikroC with not a lot of changes I posted it to give you a idea to what should be set if you posted your Main C code I could fix it for you using MikroC.
// pic 18f2550 the pic i'm using
//MickroC Pro compiler
//Pickit 2 programmer
sbit Led at LATA1_bit;
sbit Led_Direction at TRISA1_bit;
unsigned char counter = 0, count = 2;
void InitTimer0 () {
T0CON = 0b11000111; //TMR0 on,at 8 bit,internal clock,low to high transition,1 : 256256 prescaler
TMR0L = 0xE9; //load value
GIE_bit = 1; // enable global interrupt
TMR0IE_bit = 1; // enable interrupt
}
void interrupt() {
if ((TMR0IF_bit)&&(TMR0IE_bit)){ //if both TMR0IF & TMR0IE is true
INTCON.TMR0IF = 0; //reset overflow flag
TMR0L = 0xE9;
if(++counter >=count){ // increment counter
Led = ~Led ; // toggle led
counter = 0; // reset counter
}
}
}
void main() {
TRISA = 0b00000000; // make all PORTA pins output
PORTA = 0; //turn off PORTA pins
ADCON1 = 0b00001111; //make all analog pins as digital
CMCON = 0b00000111; //
InitTimer0 ();
while (1){
}
}
I don't have a scope or anything like that to check the speed of the blink of the led but from looking at it, it seems to be blinking faster than 1 sec. can you tell me where i went wrong ?FOSC4 so 48/4 = 12
1/(12Mhz/256 prescaler/256) = 1/(.046875/256) = 1/.000183105 = 5461
1/(12Mhz/256) = 1/.046875 =21
so 1000 x 21 = 21 ms add 2 to 21 = 23
256 - 23 = 233 decimal = 0xE9
so i TMR0L = 0xE9
// 18f2550 pic
//MikroC Pro//compiler
// Pickit2 programmer
sbit Led at LATA1_bit;
sbit Led_Direction at TRISA1_bit;
unsigned char counter = 0, count = 1;
void InitTimer0 () {
T0CON = 0x83; //TMR0 on,at 16 bit,internal clock,low to high transition,1 : 16 prescaler
TMR0H = 0xB;
TMR0L = 0xE9; //load value
GIE_bit = 1; // enable global interrupt
TMR0IE_bit = 1; // enable interrupt
}
void interrupt() {
if ((TMR0IF_bit)&&(TMR0IE_bit)){ //if both TMR0IF & TMR0IE is true
INTCON.TMR0IF = 0; //reset overflow flag
TMR0H = 0xB;
TMR0L = 0xE9;
if(++counter >=count){ // increment counter
Led = ~Led ; // toggle led
counter = 0; // reset counter
}
}
}
void main() {
OSCCON = 0b1111110;
TRISA = 0b00000000; // make all PORTA pins output
PORTA = 0; //turn off PORTA pins
ADCON1 = 0b00001111; //make all analog pins as digital
CMCON = 0b00000111; //
InitTimer0 ();
while (1); // do nothing
}
@JohnInTX@chaosenvoy
So, it's running right but you want to know how the calculator did it? Well allrighty then!
The timer is just a big counter that counts the input frequency and generates an interrupt when it rolls over from FFFFh to 0000h. The way I do it is like this:
Figure out the input freq. to the counter. Ref. Fig 2-1 in the datasheet. You have
8MHz Fosc and OSCCON 6:4 routes that directly to the MUX where OSCCON 1:0 routes it to the peripheral clock. You are not using the USB clock section.
The peripheral clock is always Fosc / 4 in a PIC so the input to the timer is 2MHz for a period of 500ns.
You want a 500ms tik so just divide 500ms / 500ns = 1E6 counts i.e. it takes 1,000,000 timer ticks to make 500ms.
1E6 counts won't fit into a 16 bit timer (max 65536) so we need an external divider. Do a trial division to see what works. 1E6/65536 = 15.2587....
We pick a timer prescaler that is at least that big. 16 works. So does 32, 64, 128 and 256 but we want the smallest usable prescaler to keep the number of timer counts bigger. That makes each count a smaller time and gives us more resolution - always a good thing.
So with a prescaler of 16, the input period to the timer is 500ns * 16 = 8us.
The number of 8us ticks to make 500ms is 500ms / 8us = 62500. Almost there.
Your postscaler (counter >= count) is always 1 in this example so it does not contribute to the calculated time. Increase the value of 'count' and you get multiples of the interrupt period.
The counter counts UP and interrupts when it rolls over to 0 so we subtract the desired number of counts from the 16 bit timer base (2^16). 65536 - 62500 = 3036 = 0BDCh.
So TMR0H = 0Bh and TMR0L = DCh.
The calculator's answer is a little different - Might want to review the arithmetic but that's pretty much it.
Note that when you have to manually reload a timer, you lose a bit in overhead. Consider what happens when the interrupt happens. It takes some time to get the interrupt serviced and get to the point where you reload the timer BUT! You reload the timer with the value calculated with no overhead allowance so a correctly calculated timer value will result in the timer being a little slow (it times the 500ms PLUS the overhead). If you got the calculated values using MikroC's calculator, they may have adjusted the time to be a bit shorter to compensate for their overhead.
Let's see:
Me: 62500 counts at 8us/count = 500ms on the dot.
Them: 0BE9h = 3049. 65536-3049 = 62487 timer tiks
62487 tiks * 8us/tik = 499.896ms, a difference of 104us. At 500ns/instruction that's 208 Tcycs or about 200 instructions give or take (calls, returns gotos take 2Tcyc to execute). Maybe it takes that many to do the interrupt or we have a different view of 500ms.
Here's another problem with manually reloading a timer. If you have multiple interrupts, you can be servicing one when the timer rolls over, adding to the overhead time.
You can mitigate those problems somewhat by instead of loading the timer with the value, ADD the value to the current timer value (which has been accumulating tiks while the interrupt service routing was getting around to being serviced). That will take into account a lot (but not all) of the overhead.
Because of all that, I usually use TIMER2 / PR2 as a periodic timebase because once it is loaded, you don't have to reload it on each interrupt. The calculation is similar but the prescaler will be bigger because TIMER2 is only 8 bits. With your setup, the longest interrupt period from TMR2/PR2 is on the order of 32ms so you would need that secondary counter to extend the time to 500ms.
I usually use a TIMER2/PR2 system tik of 1ms - 10 ms depending on the system then run a series of derived timers for those extended times. I like to count down to 00 then reload since testing for 00 is usually cheaper than testing for <= some value.
That's about all there is to it.
Good luck.
Finally, when modifying I/O on an 18F or 16F1xxx, ALWAYS do your outputs to the LATx registers, never PORTx.T2CON = 0b01001010; // Postscaler = 16, Prescaler = 16, Timer OFF (for now)
PR2 = 125;
TMR2IF = 0; // clear any pending IF
TMR2IE = 1; // then enable timer 2 interrupt
PEIE = 1; // and peripheral interrupts
GIE = 1; // and global interrupts
counter = 50;
TMR2ON = 1; // then start timer
//The interrupt routine is the same except you look at TMR2IF and TMR2IE instead of those for timer 0.
// Note that if you never turn TMR2IE off, you don't have to test it in the interrupt routine
if ((TMR2IE) && (TMR2IF){
if(--counter == 0){
counter = 50;
// toggle LED or whatever
}
}
@JohnInTXSure.
As I said, TMR2 does not have enough bits to get a 500ms time so you'll have to use an additional counter to make a derived timer that counts interrupts generated by TMR2 / PR2.
Unlike timer 1 which interrupts when it rolls over from FFFFh -> 0000h, TMR2 counts up to the value set in PR2 then resets itself to 00h. The post scaler counts each time that happens and raises an interrupt on every nth time where n is the post scaler setting.
The databook has the formulae to determine the setting PR2 with prescaler and post scaler settings known. To get a rough idea of where you are, figure out the max time.
At 8Mhz, Tcyc is 500ns.
500ns * prescaler * PR2 counts* postscaler = 1500ns * 16 * 255 * 16 = 32.64ms max time.
To see how many of those max times you need for 500ms.
500ms / 32.64ms ~=15.2588. Note that 15.2588 is not an integer. Since you are going to drive a counter to count TMR2 interrupts up to 500ms, pick some nice factor of 500ms for the interrupt interval. 10ms is a good one.
So, figure out how to get to 10ms. Set up the prescaler and postscaler first to get the remaining counts in a one byte range for PR2. There may be more than one solution.
At 500ns/Tcyc, the number of counts for a 10ms interrupt is 10ms / 500ns = 20000.
Factor the number of counts into what works with TMR2. Make sure your results stay an integer.
20000/16 prescaler = 1250 left. Still too big for the 8 bit PR2 so factor 1250 to split it up, starting with what the postscaler will provide.
1250 = 10 * 125.
Use postscaler = 10 and PR2 = 125.
The derived counter will be set to 50 (500ms / 10ms)
The setup is:
Finally, when modifying I/O on an 18F or 16F1xxx, ALWAYS do your outputs to the LATx registers, never PORTx.
Have fun!
// 10/10/2017
// pic 18f2550
// MikroC Pro - compiler
// Pickit2 - programmer
sbit Led at LATA2_bit;
sbit Led_Direction at TRISA2_bit;
unsigned char counter = 20;
void InitTimer2 (){
T2CON = 0b01001010; // prostscaler set to 16, prescaler set to 10, turn off TMR2
PIR2 = 250;
PIR1 = 0b00000000; // clear all pending interrupt flags
PIE1 = 0b00000010; // enable TMR2 interrupt
INTCON = 0b11000000; // enable global & peripherial interrupts
IPR1 = 0b00000010; // enable priority enterrupt
counter = 20;
T2CON = 0b00000100; // start TMR2
}
void interrupt () {
if (( TMR2IE ) && ( TMR2IF )){
if (--counter = = 0) {
counter = 20;
Led = ~ Led; // toggle Led
}
}
void main () {
OSCCON = 0b1111110; // start oscillator at 8 Mhz
TRISA = 0b00000000; // make all PortA pins as output
PORTA = 0; // turn off all PortA pins
ADCON1 = 0b00001111; // all pins are digital
CMCON = 0b00000111;
InitTimer2 () ;
while (1){
}
}
@JohnInTXThe = = needs to be == (no space between)
sbit Led at LATA1_bit;
sbit Led_Direction at TRISA1_bit;
unsigned char counter = 0, count = 1;
void InitTimer0 () {
T0CON = 0b11000111; // TMR0 on,set at 8 bit,1;256 prescaler
TMR0L = 0x36; //TMR0L value to be loaded
GIE_bit = 1; // enable global interrupt
TMR0IE_bit = 1; // enable interrupt
}
void interrupt() {
if ((TMR0IF_bit)&&(TMR0IE_bit)){
INTCON.TMR0IF = 0; // reset interrupt flag
TMR0L = 0x36;
if(++counter >=count){
Led = ~Led ; // toggle led
counter = 0; // reset counter
}
}
}
void main() {
TRISA = 0b00000000; // make all port A pins as output
PORTA = 0; // turn off all portA pins
ADCON1 = 0b00001111; // make all pins digital
CMCON = 0b00000111;
InitTimer0 ();
while (1){
}
}
//pic 18f2550
//Pickit2 programmer
//MikroC Pro compiler
sbit Led at LATA1_bit;
sbit Led_Direction at TRISA1_bit;
unsigned char counter = 0, count = 1;
void InitTimer0 () {
T0CON = 0x83; //TMR0 on,at 16 bit,internal clock,low to high transition,1 : 16prescaler
TMR0H = 0x0B;
TMR0L = 0xDC; //load value
GIE_bit = 1; // enable global interrupt
TMR0IE_bit = 1; // enable interrupt
}
void interrupt() {
if ((TMR0IF_bit)&&(TMR0IE_bit)){ //if both TMR0IF & TMR0IE is true
INTCON.TMR0IF = 0;
TMR0H = 0x0B; //reset overflow flag
TMR0L = 0xDC;
if(++counter >=count){ // increment counter
Led = ~Led ; // toggle led
counter = 0; // reset counter
}
}
}
void main() {
OSCCON = 0b1111110;
TRISA = 0b00000000; // make all PORTA pins output
PORTA = 0; //turn off PORTA pins
ADCON1 = 0b00001111; //make all analog pins as digital
CMCON = 0b00000111; //
InitTimer0 ();
while (1){
}
You do not have to be the 'sharpest tack in the box' . - Persistence, and plodding your way through something until you understand it and can use it has solved more problems and progressed mankind farther than most genius thinking.@JohnlnTX
Thank you for all the help i got a sample code from Jayanthd & i forgot i have the timer calculator ;i'm not just about coping code that's why i ask too many questions i'm not the sharpest tack in the box sometimes minor parts of coding gives me trouble to figure out .
i just want know ( TMR0H = 0x3C & TMR0L=oxB0) in the code what am i doing & why do i need it in the ISR & InitTimer0? i looked at the data sheet trying to figure it out & if you can't explain it to me . where can i read up on it,
still not sure if i'm doing calculations with regards to crystal & prescaler right
8 Mhz crystal HS external
this is my calculation
so 8000000 divide by 1000 = 8000
to count 256 ticks in 8000 = 8000 divide by prescaler = 8000 divide by 32 = 250 which is within the 256 ticks
so interrupt fires every 32ms
@JohnInTX thank you for all your help i was looking at a post you commented on a few years ago on using TMR2, i will do my best to figure it out i, think i'm a bit confuse with the calculations of TMR2 & PR2 in terms of the postscaler & prescaler .i went through the datasheet on TRM2 a few times & i will go at it again this week, i will post the code i have & the calculations i'm using & the result i get.@chaosenvoy
Your math to generate 500ms tiks looks OK to me.
The write to timer order is correct for the 16 bit timer configuration. Write to H gets buffered then written with L when L is written.
Note that it is difficult to get a perfectly exact tik when using Timer 0 because any accumulated time between the rollover/interrupt and when you write the period value is lost, including ticks in the prescaler. You can't do much about the prescaler in this case. If the interrupt latency is such that you accumulate some tiks in the timer section itself, you can make that a little better by stopping the timer, ADDing the period value to the current timer value then restarting the timer. You also can get a few cycles out of the latency by resetting TMR0IF after you reset the time. Also, if TMR0 is always active, you don't have to test for TMR0IE, that can save cycles. If you do need to test it, consider not using the '&&' operator. I don't know about MicroC but in PICC18, testing with the && operator generated much more code (and lost time) than successive tests i.e.
if(TMR0IE)
if(TMR0IF){
// process interrupt
}
You can find out by examining the code in the Assembler Output window.
If you want to dispense with all of the uncertainty, consider using TMR2 / PR2. It reloads automatically so never loses any counts. Some guys also just run a timer open loop i.e. without loading. The base time might not be exactly what you want but the error is a fraction of the last tik, not accumulated over many tiks.
Other than that, well done! You know how to set up the timers and extend them with a counter. Which one you choose is just application from here.
// 07/02/2018
// pic 18f2550
// MikroC Pro - compiler
// Pickit2 - programmer
sbit Led at LATA2_bit;
sbit Led_Direction at TRISA2_bit;
unsigned char counter = 20;
void InitTimer2 (){
T2CON = 0b1001010; // prostscaler set to 16, prescaler set to 10, turn off TMR2
PR2 = 125;
PIR1 = 0b00000000; // clear all pending interrupt flags
PIE1 = 0b00000010; // enable TMR2 interrupt
INTCON = 0b11000000; // enable global & peripherial interrupts
IPR1 = 0b00000010; // enable priority enterrupt
T2CON = 0b1001110; // start TMR2
}
void interrupt () {
if (TMR2IF ) {
PIR1 = 0b00; // reset TRM2IF
if (--counter == 0) { // decrement counter from 20 till 0
Led = ~ Led; // toggle led after 20 counts of interrupts
counter = 20; // reset counter to 20
}
}
}
void main () {
OSCCON = 0b1111110; // start oscillator at 9 Mhz
TRISA = 0b00000000; // make all PortA pins as output
PORTA = 0; // turn off all PortA pins
ADCON1 = 0b00001111; // all pins are digital
CMCON = 0b00000111;
InitTimer2 () ;
while (1){
}
}