Does any body can give me some information about interrupts of PICs and usage of them especially timers and counters . any PDF , links and so on can be my favorite
Download the datasheet (if you haven't done so already). Go to the timer section. READ CAREFULLY. Take a look at some sample codes. Start writing codes accordingly and test.
In the meantime, here are two pieces of code I wrote earlier (way back when I was learning the basics of PIC):
unsignedchar COUNT, PCOUNT;//declaring variables as 8-bitvoid interrupt(){//This is executed when any interrupt occurs
COUNT++;//Increment COUNTif(COUNT =0)//If count overflows to 0 from 255 (since it's an 8-bit register)
PCOUNT++;//Increment PCOUNT
PORTB = PCOUNT;//Assign the value of PCOUNT to PORTB
INTCON.TMR0IF=0;//Whenever interrupt occurs a flag is set//When a timer overflows the corresponding interrupt flag is raised//When TMR0 overflows and interrupt occurs, TMR0IF is raised//You HAVE to clear the flag}//Return from interruptvoid main(void){//main code
COUNT =1;//initializing count variable by putting 1 in it
CCP1CON =0;//disabling PWM
TRISB =0;//setting PORTB as output
CMCON =7;//disabling comparator
ADCON1 =7;//disabling ADC
OPTION_REG =0x82;//disabling pull-ups and setting TMR0 prescaler to 1:8
INTCON =0xA0;//INTCON - GIE | PEIE | TMR0IE | INTE | RBIE | TMR0IF | INTF | RBIF// Assigning 0xA0 to INTCON, means setting GIE to 1 and TMR0IE to 1// Whenever you need to have an interrupt GIE must be set to 1// Setting TMR0IE to 1 means that TMR0 interrupt is enable
PORTB =0;//Clearing any initial value PORTB holds
TMR0 =0;//Resetting TMR0 so that it holds 0while(1);// Loop here continuously//Since nothing is performed, the only action will be in the interrupt}
As you can see, I've explained the code by putting in comments.
If you need more help, feel free to ask. Also read the datasheet carefully.
thanks Tahmid . I have a question : you know I am using 20Mhz crystal in my circuit so should I use another crystal for using timer/counter ? or NO . I mean for using Timer/Counter we need a separated crystal than the original one or no just a unique one is enough for both object routin tasks of PIC and Timer/counter tasks ?
and here is An example of INTERNAL crystal as clock :
int count = 0;
void main ()
{
portb=0;
trisb=0
TMR0=0;
T0CS=0;
T0SE=0;
PSA=0;
PS0=1;
PS1=1;
PS2=1;
while(1)
{
while(!T0IF)
{
T0IF=0;
count++;
if(count==15) { count=0; portb=~portb;}
}}}
but unfortunately I have received this error : Assigning to non-lvalue and i am using MikroC compiler and PIC16F877 I want toggle portb every one second. please correct my mistakes
Dont you think this is a peculiar question? You are asking members "what is Your problem" and again asking how to solve it?.
Ok..anyways, you got a reply from Tahmid and i think it was very much usefull. Then you asked to commment it in detail, and Tahmid did that for you. Now as i see you still seem to be at the same way where you were, and never bother to click "Helpfull" for any of the Tahmids replies. Could you explain this behavior a bit?
int count =0;void main (){
portb=0;
trisb=0;
TMR0=0;
T0CS_bit=0;
T0SE_bit=0;
PSA_bit=0;
PS0_bit=1;
PS1_bit=1;
PS2_bit=1;while(1){while(!T0IF_bit){
T0IF_bit=0;
count++;if(count==15){ count=0; portb=~portb;}}}}
The error message tells you that you are trying to assign a value to a constant. T0IF is a constant and when you are referring to it, you are actually referring to 2 (bit 2 in INTCON). When you refer to T0IF_bit, you're referring to the bit T0IF.
I think it's better you refer to it as TMR0IF_bit as TMR0IF is what is stated in the datasheet. However, T0IF_bit shouldn't cause a problem.
Hope this helps.
Tahmid.
---------- Post added at 17:29 ---------- Previous post was at 17:29 ----------
You can use the same oscillator or another oscillator depending on your requirement.
Or look at this code that i got from examples of MiKro C , and I tested with proteus and it worked , dose any body can explain these codes line by line especially the red ones these program toggle the portB every 1 second and the mcu is p18F252 and the crystal frequency is 20MHZ
unsigned cnt;
void interrupt() { //ISR - Interrupt service routine cnt++; //increment the value of cnt TMR0L = 96; //assign 96 to TMR0 //As 96 is less than 255 and timer is configured as 8 bit //It is assigned to TMR0L and there is no need to assign anything to TMR0H as TMR0H:TMR0L act as the TMR0 16-bit register INTCON = 0x20; //INTCON - GIE/GIEH | PEIE/GIEL | TMR0IE | INT0IE | RBIE | TMR0IF | INT0IF | RBIF //Assigning 0x20 means TMR0IE = 1, all other bits = 0, so since GIE = 0, interrupts will no longer be generated until GIE is set to 1 again } void main() { ADCON1 = 0x3F; //ADFM | ADCS2 | — | — | PCFG3 | PCFG2 | PCFG1 | PCFG0 T0CON = 0xC4; //TMR0 is turned on, prescaler 1:32 assigned, 8 bit timer is used TRISB = 0; //PORTB is set as output PORTB = 0xFF; //All pins of PORTB are set high TMR0L = 96; //96 is loaded to TMR0 INTCON = 0xA0; //INTCON - GIE/GIEH | PEIE/GIEL | TMR0IE | INT0IE | RBIE | TMR0IF | INT0IF | RBIF //GIE and TMR0IE are set to 1, so global interrupt and TMR0 interrupt is enabled cnt = 0; do { if (cnt == 512) { PORTB = ~PORTB; //All PORTB bits are inverted cnt = 0; } } while(1); } Where is it that you have a problem? Understanding what the code does or the steps that the code carries out? I just explained the steps. Hope this helps. Tahmid.
---------- Post added at 00:49 ---------- Previous post was at 00:43 ----------
There is something wrong here. Everytime I fix the above appearance, it comes back to this.
Yea, I've always been wrapping it in tags. But when I tried that, it was like that, so I edited it and fixed it, but it didn't work, so I removed the code and fixed it, and it was still like that. So, I thought I can't fix it again and left it like that.
Anyways, thanks for pointing it out. I think there might have been some kind of temporary problem with EDAboard or something.