Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronic 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.

Register Log in

Advice for Pic c compiler

Status
Not open for further replies.

abdoalghareeb

Member level 4
Joined
Feb 5, 2010
Messages
77
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
1,925
What is the most reliable PIC compiler using C language ?
I have started with MIKROC compile (version 5.0), but I have some problems in time calculation .
 

Tahmid

Advanced Member level 5
Joined
Jun 17, 2008
Messages
4,758
Helped
1,791
Reputation
3,574
Reaction score
1,650
Trophy points
1,393
Location
Silicon Valley, California, USA (from Dhaka, Bangl
Activity points
30,545
Among the numerous compilers available, mikroC is quite a popular compiler. There is no single best compiler. It ultimately comes down to preference. I recommend mikroC but not everyone likes mikroC or feels comfortable using it.

Can you please explain what time calculation problems you are experiencing?
 

abdoalghareeb

Member level 4
Joined
Feb 5, 2010
Messages
77
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
1,925
I use PIC 18F452 , Mikroc compiler , winpic800 with serial JDM programmer

My simple program is about flashing LED on PORTA.B0 with frequency = 1 HZ .
My problem is : the output frequency is more than 1Hz

I use external crystal = 20 MHz
this is my code And my method of time calculation :

Code:
////////////////////////////////////////////////////////////////////////////
/////////   crystal friquncy = 20000000 Hz                         /////////
/////////                                                          /////////
/////////                      1                                   /////////
/////////   1 Sec = -------------------------  x (256-61) x 100    /////////
/////////                 (20MHz /4) / 256                         /////////
////////////////////////////////////////////////////////////////////////////

unsigned int count = 0;
//=============================================
//=============================================
void interrupt()
{
if (TMR0IF_bit)
   {
   TMR0IF_bit=0;
   TMR0H=0;
   TMR0L=61;
   if (++count==100)
      {
      count=0;
      PORTA.B0 ^= 1;
      }
   }
}
//==================================================
//==================================================
void main() 
{
//--------------------
ADCON0=0x00;
ADCON1=0x07;
//--------------------
TRISA=0b11000000;
PORTA=0b00000000;
//--------------------
INTCON.GIE=1;
//--------------------
T0CON = 0b11000111;
INTCON.TMR0IE=1;
INTCON1.TMR0IP=1;
TMR0H=0;
TMR0L=61;
//--------------------
while(1)
{

}
}
//=============================================
//=============================================

 

Attachments

  • 328.9 KB Views: 9

Tahmid

Advanced Member level 5
Joined
Jun 17, 2008
Messages
4,758
Helped
1,791
Reputation
3,574
Reaction score
1,650
Trophy points
1,393
Location
Silicon Valley, California, USA (from Dhaka, Bangl
Activity points
30,545
With your code, I get a time of 998.66ms (through simulation). What issue are you facing?

After a little modification, I used this code to get a time of 998.84ms:
Code:
////////////////////////////////////////////////////////////////////////////
/////////   crystal friquncy = 20000000 Hz                         /////////
/////////                                                          /////////
/////////                      1                                   /////////
/////////   1 Sec = -------------------------  x (256-61) x 100    /////////
/////////                 (20MHz /4) / 256                         /////////
////////////////////////////////////////////////////////////////////////////

unsigned int count = 0;
//=============================================
//=============================================
void interrupt()
{
if (TMR0IF_bit)
   {
   TMR0H=0;
   if (++count==100)
      {
      count=0;
      PORTA.B0 ^= 1;
      }
   TMR0IF_bit=0;
   TMR0L=61;
   }
}
//==================================================
//==================================================
void main()
{
//--------------------
ADCON0=0x00;
ADCON1=0x07;
//--------------------
TRISA=0b11000000;
PORTA=0b00000000;
//--------------------
SWDTEN_bit=0;
//--------------------
INTCON.GIE=1;
//--------------------
T0CON = 0b11000111;
INTCON.TMR0IE=1;
INTCON1.TMR0IP=1;
TMR0H=0;
TMR0L=61;
//--------------------
while(1)
{

}
}
//=============================================
//=============================================
I noticed you are using configuration setting of HS+PLL. What is the frequency of the oscillator are you using? If you are using a 20MHz crystal, then you should use just HS instead of HS+PLL.

Hope this helps.
Tahmid.
 
Last edited:

abdoalghareeb

Member level 4
Joined
Feb 5, 2010
Messages
77
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
1,925
Code:
////////////////////////////////////////////////////////////////////////////
/////////   crystal friquncy = 20000000 Hz                         /////////
/////////                                                          /////////
/////////                      1                                   /////////
/////////   1 Sec = -------------------------  x (256-61) x 100    /////////
/////////                 (20MHz /4) / 256                         /////////
////////////////////////////////////////////////////////////////////////////

unsigned int Sec_count = 0;
unsigned int Min_count = 0;
//=============================================
//=============================================
void interrupt()
{
if (TMR0IF_bit)
   {
   TMR0H=0;
   if (++Sec_count==100)
      {
      Sec_count=0;
      PORTA.B0 ^= 1;
      if (++Min_count == 60)
         {
         Min_count=0;
         PORTA.B1 ^= 1;
         }
      }
   TMR0IF_bit=0;
   TMR0L=61;
   }
}
//==================================================
//==================================================
void main()
{
//--------------------
ADCON0=0x00;
ADCON1=0x07;
//--------------------
TRISA=0b11000000;
PORTA=0b00000000;
//--------------------
SWDTEN_bit=0;
//--------------------
INTCON.GIE=1;
//--------------------
T0CON = 0b11000111;
INTCON.TMR0IE=1;
INTCON1.TMR0IP=1;
TMR0H=0;
TMR0L=61;
//--------------------
while(1)
{

}
}
//=============================================
1- The oscillator configuration HS + PLL is the only one mode witch make the micro controller run

2- Your time calculation is correct and I use the same but the result was 0.38 Sec. because I make another led
blinking after one minute and it toggle after 23 Sec (on my JOVIAL watch)

3- What is simulation software do you use ?
 

betwixt

Super Moderator
Staff member
Joined
Jul 4, 2009
Messages
14,586
Helped
4,781
Reputation
9,579
Reaction score
4,560
Trophy points
1,393
Location
Aberdyfi, West Wales, UK
Activity points
124,317
There is nothing wrong with the program and it should be fairly accurate in timing but there are a few things you could do to optimize it. One thing you miss is the execution time of the interrupt itself which adds to the delay but this makes it slower which is the opposite of what you see. I agree the PLL should not be used and you may be seeing a combination of effects due to the PLL and other software delays.

Hints:
1. Most compilers cannot optimize a statement like "if(++sec_count==100)", try to count a variable down to zero rather than up to a value. The reason is that a decrement and check for zero will compile to a single instruction.
For example you could use something like "if (sec_count--)" or even "sec_count--; if (sec_count)" and reload your 100 only when it has passed the 'if' check.

2. The timer runs continuously, even while you are inside the interrupt routine so reload it's value as soon as possible when you enter the routine or you add the length of the routine to the interval each time.

3. Reduce the code by using 'unsigned char' rather than 'int' for the counters, otherwise the PIC has to do more calculations when the upper half of the number is always zero anyway.

I'm using a different PIC and compiler but with similar code I get an accuracy of about 10 seconds per month.

Brian.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top