Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Timer with pic12f675 and mikroc problem!

Status
Not open for further replies.

davoud

Full Member level 2
Joined
Mar 10, 2005
Messages
146
Helped
39
Reputation
78
Reaction score
39
Trophy points
1,308
Activity points
2,119
Hi all,
I am new in micro controller programming.
I decided to make a timer with external trigger(if external command continued we have square wave).
problem is when I change pot connected to micro I should wait one cycle to change time.
for this aim I used time interruption but there was no change to circuit working!.
Code:
#include <stdio.h>
#include <stdlib.h>

void init_ports(void)
{
   TRISIO = 0b00001111; // set as output
   ANSEL = 0x01;    //setting analoge or digital and analog osc
   CMCON = 0x07;    // disable comprator on port a
   ADCON0=0b00000001;           // Set RA0 as analog input
                            }
void InitTimer1()
{
//  T0CON         = 0x21;
  T0CON         = 0x01;
  TMR0IF_bit         = 0;
  TMR0H         = 0xFF;
  TMR0L         = 0xFF;
  TMR0IE_bit         = 1;
  INTCON         = 0xC0;
                           }

void Interrupt()
{
  if (TMR1IF_bit){
    TMR0IF_bit = 0;
    TMR0H         = 0x00;
    TMR0L         = 0xFF;

       asm bsf ADCON0,GO;//Start Conversion  read analoge
       while(ADCON0==0x03)      // till analoge port is open for AN0
       {

 //       s= 0.001*(ADRESH+(ADRESL<<8)) ;         /*+(ADRESL<<8)); */
        m= (ADRESH) ;
        r= m+5;

       }
    

                      }
                          }

void main()
    {
        int i=1,j=1,n=1,k=1,p=1,q=1,a=0;
        unsigned long int m,r;
   //     bit a=0;
   init_ports();
        GP1_bit = 0;
        GP2_bit = 0;
        GP3_bit = 0;
        GP4_bit = 0;
        GP5_bit = 0;
     InitTimer1();
   while(1)
        {
   trig :   GP5_bit = 0,i=0,j=0,p=0,q=0,a=0;
       if(gp3_bit ==1) a=1;
 
     while( a==1)
                   {

       GP5_bit = 1;
      


              if(gp2_bit==0 && gp1_bit==0)
        { k=6 ;
          n=6;

          }
           else if(gp2_bit==0 &&gp1_bit==1)
               {
                k=200;
                 n=200;

                     }
            else if(gp2_bit==1 &&gp1_bit==0)
               {
                k=20;
                 n=1200;

                     }
                     else if(gp2_bit==1 &&gp1_bit==1)
               {
                   k=100;
                   n=1200;

                       }

              asm CLRWDT ;


              a=0;

              for(j=1;j<=k;j++)
                  {
                     asm CLRWDT ;

                 for(i=1;i<= r;i++)
                  {
                     asm CLRWDT ;

         GP5_bit = 0;

          for(j=1;j<=n;j++)
                    {

                       asm CLRWDT ;
          for(i=1;i<= r;i++)
                         {

           if(gp3_bit ==0) goto trig;

                       asm CLRWDT ;
                       Delay_ms(10);


                    }
                        }


                          }
                              }

                               }
help me please.
--- Updated ---

Circuit diagram
 

Attachments

  • Capture.PNG
    Capture.PNG
    92.9 KB · Views: 268
Last edited:

Hello,

Check if your variables "m" and "r" are visible inside the interrupt ...
For me , m and r must be declared as global ( outside the main) and volatile


Code:
void main()
    {
        int i=1,j=1,n=1,k=1,p=1,q=1,a=0;
        unsigned long int m,r;

after , i don't understand what do wand to do ?
 

I would expect an undefined error for variables m and r. Volatile attribute is required at least for optimizing compilers, probably to MikroC.
 

Hello,

Check if your variables "m" and "r" are visible inside the interrupt ...
For me , m and r must be declared as global ( outside the main) and volatile


Code:
void main()
    {
        int i=1,j=1,n=1,k=1,p=1,q=1,a=0;
        unsigned long int m,r;

after , i don't understand what do wand to do ?
Thanks dear friend,
You are right, if we declared variable as global, they valid in all the body of program.
But I think this is not my main mistake! So by this program, there is no malfunction at the timing except for my problem and if we declared variable as global, problem is not solved. The problem is: if we change pot. It takes one cycle to apply changes.
 

So you confirm that you posted a source that has never been compiled... :(

The problem description is also unclear.
Post #1 states
when I change pot connected to micro I should wait one cycle to change time.
But in post #4
if we change pot. It takes one cycle to apply changes.
Should or should not? And what is a cycle in this case? Do you mind to sketch a timing diagram of the intended operation?
 

I would expect an undefined error for variables m and r. Volatile attribute is required at least for optimizing compilers, probably to MikroC.
Dear FVM,
Thanks for your replay.
I am newbie at programming
Correct declaration of variable is basically needs but I have a different problem and I am confused .
--- Updated ---

So you confirm that you posted a source that has never been compiled... :(

The problem description is also unclear.
Post #1 states

But in post #4

Should or should not? And what is a cycle in this case? Do you mind to sketch a timing diagram of the intended operation?
I mean that there is a time delay to change cycle time. Sorry for my weak grammar.
 
Last edited:

I compiled this source, simulated it and also make a circuit and the circuit work complete but I have a problem that I have not any answer for it.
Thanks
 

Attachments

  • 20200810_120231.mp4
    16 MB
Last edited:

A few of comments on the source code in the first post:
- (my opinion) don't use a goto in the while loop to get back to the start - a 'continue' will do that for you
- don't write consecutive statements that update the GPIO - this is asking for RMW problems (and if you don't know what 'read-modify-write' problems are then look them up using a search engine
- in the 'init_ports()' function, you set GP0, GP1, GP2 and GP3 to input and GP4 and GP5 to output - despite the comment; in 'main()' you then set the input ports to 0 - fortunately this doesn't do anything but does show that you may not really understand the code you have written.
Can I suggest that you start with a pencil and paper and draw out a state transition diagram that sows what you want to achieve.It is always much easier to code these things when you start with proper specifications.
Susan
 

Dear Susan,
Thanks for your advise.
I am newbie at micro controller programming. I define ports with "TRISIO" so if need to add more code please tell me.
--- Updated ---

15971420522331860016230.jpg
 

I suggest that you read up on what a state transition diagram is. It may also be called a finite state machine.
Also I didn't mean that you should necessarily show us - only that you create one and take it so a sufficient level of detail that you can work through it by hand to make sure that it is correct and then program from it.
In your table at the bottom of the image, what do "on" and "off" refer to? In your circuit diagram you have 3 active switches so I assume that what you really need to have is a truth-table with 3 variables - 0 and 1 for each of the switches - and then the time interval in each cell.
From that you can also think about how to transition from one cell to another (which is where the state machine part may come in) - if you change the switch to go from (say) 10 minutes to 1 second, do you wait for the 10 minute period to elapse before you change (in which case you put the code for that in the part where the time has elapsed) or do you cut short the time period and transition directly to the new time. Further when you transition, do you keep the relay open or closed (depending on which state it is in when the transition occurs).
Once you have all of this sorted out on paper, then you can begin thinking of the coding.
Regarding the TRISO register and the related code: TRISO only defines if a pin is an input (1) or an output (0). If it is an input then there is no point in trying to set the value of the pin in your code - you can only read from the pin.
Also one of my point was around setting multiple outputs in consecutive statements. The hardware can play 'tricks' on you which is what the RMW problem is all about - it is also why more modern MCUs have introduced the LAT registers to get around this.
Susan
 

I suggest that you read up on what a state transition diagram is. It may also be called a finite state machine.
Also I didn't mean that you should necessarily show us - only that you create one and take it so a sufficient level of detail that you can work through it by hand to make sure that it is correct and then program from it.
In your table at the bottom of the image, what do "on" and "off" refer to? In your circuit diagram you have 3 active switches so I assume that what you really need to have is a truth-table with 3 variables - 0 and 1 for each of the switches - and then the time interval in each cell.
From that you can also think about how to transition from one cell to another (which is where the state machine part may come in) - if you change the switch to go from (say) 10 minutes to 1 second, do you wait for the 10 minute period to elapse before you change (in which case you put the code for that in the part where the time has elapsed) or do you cut short the time period and transition directly to the new time. Further when you transition, do you keep the relay open or closed (depending on which state it is in when the transition occurs).
Once you have all of this sorted out on paper, then you can begin thinking of the coding.
Regarding the TRISO register and the related code: TRISO only defines if a pin is an input (1) or an output (0). If it is an input then there is no point in trying to set the value of the pin in your code - you can only read from the pin.
Also one of my point was around setting multiple outputs in consecutive statements. The hardware can play 'tricks' on you which is what the RMW problem is all about - it is also why more modern MCUs have introduced the LAT registers to get around this.
Susan
Dear Susan,
Thank you for your precis answers.
This program is very simple and if I wanna explain it, so it is generator of an A-stable (Square wave ) that we can set on and off state duration with switches connected to GP1 and GP2 and Potentiometer connected to GP0.
GP3 is for starting pulses and Output is GP5.
if you change the switch to go from (say) 10 minutes to 1 second, do you wait for the 10 minute period to elapse before you change (in which case you put the code for that in the part where the time has elapsed) or do you cut short the time period and transition directly to the new time. Further when you transition, do you keep the relay open or closed (depending on which state it is in when the transition occurs).
ِDesire point is when I change the Potentiometer times change immediately, but changing sw1 and sw2 are not important to be rapid applied.
Regarding the TRISO register and the related code: TRISO only defines if a pin is an input (1) or an output (0). If it is an input then there is no point in trying to set the value of the pin in your code - you can only read from the pin.
Yes, I find my mistake and correct it for GP1,GP2 and GP3
I send the code again.
Regards.
Davoud

Code:
#include <stdio.h>
#include <stdlib.h>
unsigned long int m,r;
void init_ports(void)
{
   TRISIO = 0b00001111; // set as input-output
   ANSEL = 0x01;    //setting analoge or digital and analog osc
   CMCON = 0x07;    // disable comprator on port a
   ADCON0=0b00000001;           // Set RA0 as analog input
                            }
void InitTimer1()
{
//  T0CON         = 0x21;
  T0CON         = 0x01;
  TMR0IF_bit         = 0;
  TMR0H         = 0xFF;
  TMR0L         = 0xFF;
  TMR0IE_bit         = 1;
  INTCON         = 0xC0;
                           }

void Interrupt()
{
  if (TMR1IF_bit){
    TMR0IF_bit = 0;
    TMR0H         = 0x00;
    TMR0L         = 0xFF;
           asm bsf ADCON0,GO;//Start Conversion  read analoge
       while(ADCON0==0x03)      // till analoge port is open for AN0
       {

        m= (ADRESH) ;
        r= m+5;

       }
  

                      }
                          }

void main()
    {
        int i=1,j=1,n=1,k=1,p=1,q=1,a=0;
  //      unsigned long int m,r;

   init_ports();
   //     GP1_bit = 0;
  //      GP2_bit = 0;
   //     GP3_bit = 0;
        GP4_bit = 0;
        GP5_bit = 0;
     InitTimer1();
   while(1)
        {
   trig :   GP5_bit = 0,i=0,j=0,p=0,q=0,a=0;

       if(gp3_bit ==1) a=1;

     while( a==1)
                   {

              if(gp2_bit==0 && gp1_bit==0)
        { k=6 ;
          n=6;

          }
           else if(gp2_bit==0 &&gp1_bit==1)
               {
                k=200;
                 n=200;

                     }
            else if(gp2_bit==1 &&gp1_bit==0)
               {
                k=20;
                 n=1200;

                     }
                     else if(gp2_bit==1 &&gp1_bit==1)
               {
                   k=100;
                   n=1200;

                       }

              GP5_bit = 1;
              asm CLRWDT ;
              a=0;

              for(j=1;j<=k;j++)
                  {
                     asm CLRWDT ;

                 for(i=1;i<= r;i++)
                  {
                     asm CLRWDT ;

                    }
                      }

         GP5_bit = 0;
  // Off state time
          for(j=1;j<=n;j++)
               {

          if(gp3_bit ==0)
                      {
                  a=0;
                  Brake;
                       }
                       asm CLRWDT ;
          for(i=1;i<= r;i++)
                {
                      
                       asm CLRWDT ;
                       Delay_ms(10);


                        }
                               }
                                  }
                                     }

                                         }
 
Last edited:

hello,




Brake ;
Frein, Bremse .. or Break; ?

What is the use for all
asm CLRWDT

are you using Timer0 as time counter or for Watchdog


Please, present your code with a correct indentation
parenthesis aligned ! to be able to have a clear reading code.
Very confusing now..

Why
r=m+5 ?
+5 ???

Problem of Mixing Timer0 and Timer1 !

void InitTimer1()

you initialise Timer1 with timer0 register ?

interrupt on Timer1 ?
TMR0IF_bit=0; <-- this is timer0

so you will never get Timer0 or Timer1 interrupt ...
 

hello,
Brake ;
Frein, Bremse .. or Break; ?
Yes friend, at the new code I have some mistake but I don't know why there is no error at the compiling:oops:
I am relay confused.
I checked it with another PC and receive amazing result!😂
1.PNG
2.PNG
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top