Timer with pic12f675 and mikroc problem!

davoud

Full Member level 2
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
}
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;

while(ADCON0==0x03)      // till analoge port is open for AN0
{

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

}
}

}
}

}
--- Updated ---

Circuit diagram

Attachments

• 92.9 KB Views: 16
Last edited:

paulfjujo

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 ?

FvM

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

davoud

Full Member level 2
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.

FvM

Super Moderator
Staff member
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?

davoud

Full Member level 2
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,
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:

davoud

Full Member level 2
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

• 16 MB Views: 16
Last edited:

Aussie Susan

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

davoud

Full Member level 2
Dear Susan,
I am newbie at micro controller programming. I define ports with "TRISIO" so if need to add more code please tell me.
--- Updated ---

Aussie 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

davoud

Full Member level 2
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,
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
}
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;
while(ADCON0==0x03)      // till analoge port is open for AN0
{

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:

paulfjujo

hello,

Brake ;
Frein, Bremse .. or Break; ?

What is the use for all
asm CLRWDT

are you using Timer0 as time counter or for Watchdog

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 ...

davoud

Full Member level 2
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
I am relay confused.
I checked it with another PC and receive amazing result!