[SOLVED] This project is easy for you but difficult for me

Status
Not open for further replies.
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
 

Here are some links:
**broken link removed**
PIC16F877 Timer Modules tutorials | PIC timer0 tutorial
PIC16F877 Timer Modules tutorials | Timer1
PIC timer2 tutorial

Let me google that for you

Use Google, you'll find lots of examples.

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):


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
unsigned char COUNT, PCOUNT;
 
void interrupt(){
     COUNT++;
     if (COUNT = 0)
        PCOUNT++;
     PORTB = PCOUNT;
     INTCON.TMR0IF = 0;
}
 
void main(void){
     COUNT = 1;
     CCP1CON = 0;
     TRISB = 0;
     CMCON = 7;
     ADCON1 = 7;
     OPTION_REG = 0x82;
     INTCON = 0xA0;
     PORTB = 0;
     TMR0 = 0;
     while (1);
}




Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
void interrupt(void) {
 
     if(T0IF_bit == 1)
     {
     RA5_bit=1;   //To see if interrupt is triggered
     Delay_ms(2000);
     RA5_bit = 0;
     T0IF_bit = 0; //You HAVE to clear interrupt flag
     }
  }
 
void main()
{
TMR0 = 0;   //Clear timer 0
 
OPTION_REG = 8;
GIE_bit = 1; //Enable Global Interrupt
T0IF_bit = 0;
T0IE_bit = 1; //Enable TMR0 interrupt
PEIE_bit = 1;
 
PORTA = 0; /*set RA0-RA5 low */
TRISA = 0; /*set PORTA to output*/
PORTD = 0; /*set RA0-RA5 low */
TRISD = 0; /*set PORTA to output*/
 
ADCON1 = 7; //Disable ADC
//CMCON = 7; - FOR 16F877A
 
while(1)
{
RA0_bit=1;
Delay_ms(200);
RA0_bit=0;
Delay_ms(200);
}
 
}



Hope this helps.
Tahmid.
 
Last edited:
Reactions: mf1364

    mf1364

    Points: 2
    Helpful Answer Positive Rating
thanks , Thamid can you explain your codes step by step , and say what is the conclusion of your program ?
 

Ok, let's see:

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
unsigned char COUNT, PCOUNT; //declaring variables as 8-bit
 
void interrupt(){ //This is executed when any interrupt occurs
     COUNT++; //Increment COUNT
     if (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 interrupt
 
void 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 0
     while (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.

Hope this helps.
Tahmid.
 
Reactions: mf1364

    mf1364

    Points: 2
    Helpful Answer Positive Rating
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
 
Last edited:

Hi every body
Dose any body know , what is my problem ? and how can I solve it ?
 

Hi every body
Dose any body know , what is my problem ? and how can I solve it ?
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?
 

Hi,
The problem is, in mikroC, you can't refer to a bit like PS2 as PS2, you have to refer to it by PS2_bit, T0IF_bit and so on.

So, the corrected code should be:

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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.
 
Reactions: mf1364

    mf1364

    Points: 2
    Helpful Answer Positive Rating
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() {
cnt++;
TMR0L = 96;
INTCON = 0x20;
}

void main() {
ADCON1 = 0x3F;
T0CON = 0xC4;

TRISB = 0;
PORTB = 0xFF;
TMR0L = 96;
INTCON = 0xA0;
cnt = 0;

do {
if (cnt == 512) {
PORTB = ~PORTB;
cnt = 0;
}
} while(1);
}
 

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.
 
Last edited:
Reactions: mf1364

    mf1364

    Points: 2
    Helpful Answer Positive Rating
[/COLOR]There is something wrong here. Everytime I fix the above appearance, it comes back to this.

You have to put the text inside a code tag or use the syntax highlighter, they both keep the text formatting (spaces and tabs)

Alex

---------- Post added at 21:09 ---------- Previous post was at 21:03 ----------


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void interrupt() {
    cnt++;
    TMR0L = 96;
    INTCON = 0x20;
}
 
void main() {
    ADCON1 = 0x3F;
    T0CON = 0xC4;
    TRISB = 0;
    PORTB = 0xFF;
    TMR0L = 96;
    INTCON = 0xA0;
    cnt = 0;
 
    do {
        if (cnt == 512) {
            PORTB = ~PORTB;
            cnt = 0;
        }
    } while(1);
}

 

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.
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…