CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

PLL system problem

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
kmp84



Joined: 02 Feb 2010
Posts: 354

View user's profile Send private message

PLL system problem
PostPosted: Wed May 14, 2014 7:52 am     Reply with quote

Hi all friends!

I have strange problem with PLL function on pic18F2420.
When I use this:
Code:
 #fuses HS,PROTECT,NODEBUG,PUT,NOWDT,NOBROWNOUT,NOLVP,NOFCMEN,NOPBADEN,MCLR

#use delay(clock=7372800)

My code for reading 8 ds18b20 sensors work !
But when I use this fuse settings :
Code:
#fuses H4,PROTECT,NODEBUG,PUT,NOWDT,NOBROWNOUT,NOLVP,NOFCMEN,NOPBADEN,MCLR

 #use delay(clock=29491200)//7.3728Mhz x 4

code doesn't work!
My compiler version: PCH 4.140
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Wed May 14, 2014 8:46 am     Reply with quote

Step back.

Do a simpler test than 'your code'. The basic 'flash an LED', or output a square wave and test with an oscilloscope. Verify that the timing does remain the same with the two different fuse settings.
The odds are that it will.

Your problem then is most likely something else.

Though the compiler will correct serial baud rates, and delays using 'delayxx', it can't change other things. For instance, if you output_high one pin on a port, then output_low a different pin one after the other, this will happen 4* faster with the faster clock. If there is some capacitance on the first pin, the line may not have reached the required level with the faster clock, and will be reset. Also things like timings, using timers will be occurring 4* faster. Though the compiler 'helps you', by doing a lot of the donkey work, you still need to handle the other things involved with faster clocks.....
kmp84



Joined: 02 Feb 2010
Posts: 354

View user's profile Send private message

PostPosted: Wed May 14, 2014 9:02 am     Reply with quote

I made some test program :
Code:
      #include <18F2420.h>
      //#include <18F2525.h>
      #fuses HS,PROTECT,NODEBUG,PUT,NOWDT,NOBROWNOUT,NOLVP,NOFCMEN,NOPBADEN,MCLR
      //#use delay(clock=11059200)
      #use delay(clock=7372800)
      //#use delay(clock=29491200)//7.3728Mhz x 4 (PLL system)
      #use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7,errors)
     
      #define test_pin PIN_C5
     
      void main (void){
         printf("\n\r Delay ms_us Test");
         for(;;)
         {
            output_toggle(test_pin);
            delay_us(100);
         }     
      }

with different Fuse settings the different frequency is :

4.975 KHz
and
4.902 KHz
measured with my Chinese oscilloscope GDS-1052-U
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Wed May 14, 2014 9:23 am     Reply with quote

Yes, so it is correctly running at the faster rate and working right.

The difference is from exactly where your problem is going to lie. The jump back to perform the loop, is faster with the faster clock.

It is going to be some tiny difference like changing pins 'one after the other' on a port, and hitting the PIC RMW problem at the faster rate, or the use of a feature like one of the hardware timers. Also remember that things like I2C, which perhaps can't get to 400KHz using software at the lower rate, may also change speed as the clock goes up....
kmp84



Joined: 02 Feb 2010
Posts: 354

View user's profile Send private message

PostPosted: Wed May 14, 2014 10:08 am     Reply with quote

Code:



      #include <18F2420.h>
      //#include <18F2525.h>
      #fuses H4,PROTECT,NODEBUG,PUT,NOWDT,NOBROWNOUT,NOLVP,NOFCMEN,NOPBADEN,MCLR
      //#use delay(clock=11059200)
      //#use delay(clock=20000000) //20MhZ
      //#use delay(clock=16000000) //16MhZ
      #use delay(clock=29491200)//7.3728Mhz x 4 (PLL system)
      //#use delay(clock=7372800)
      #use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7,errors)
     
      #define  DQ    PIN_A0      // One Wire Bus pin assignment
      #include "onewire.c"
     
      int8 i;
      //signed int16 temperature;
      float temperature;
      int8 scratch[9];
         
      void main (){
     
         //int8 i;
         //signed int16 temperature;
         //float temperature;
         //int8 scratch[9];       
         delay_ms(1);
         printf("18b20 Thermo Controller.:)\n\r");
         output_float(DQ);       // Set as input. 4k7 pullup on bus.
         FindDevices();
         
         for(;;)
         { 
            if (!ow_reset())     // If a device is present
            {
               write_byte(0xCC); // Skip Rom command                        //105 us //
               write_byte(0x44); // Temperature convert command             //105 us //
               output_float(DQ);
               delay_ms(750);    // Max. conv. time is 750mS for 12 bit     //750 ms//
               ow_reset();                                                  //488us,72us,424us//
       
               // Now get the device raw temperature data using Match ROM with the
               // addresses obtained with FindDevices().
               // If the received crc is same as calculated then data is valid.
               // Scale and round to nearest degree C.
               // Scaling is 0.0625 (1/16) deg.C/bit with default 12 bit resolution.
               // Round by adding half denominator for positive temperatures and
               // subtracting half denominator for negative temperatures.
                           
               for (numRoms=1;numRoms<=8;numRoms++)
               {
                  if (Send_MatchRom())
                  {
                     write_byte(0xBE); // Read scratch pad command           //105us//
                     dowcrc = 0;       
                     
                     // Get the data bytes
                     
                     for (i=0;i<=7;i++)
                     {
                         scratch[i] = read_byte();                           //120us//
                         ow_crc(scratch[i]);     
                     }
         
                     scratch[8] = read_byte();   // Get crc byte             //120us//
                     ow_reset();                                             //488us,72us,424us//
         
                     // If calculated crc from incoming bytes equal to crc byte
                     // then data is valid.
                                               
                     if (scratch[8] == dowcrc)
                     {
                        temperature = (signed int16) make16(scratch[1],scratch[0]);
                       
                        if (temperature >= 0)
                           temperature = (temperature + 8)/16;                                   
                       
                        else
                           temperature = (temperature - 8)/16;
                                                       
                        printf("%3.3f \n\r",temperature);
                        //lcd_init();
                        //printf(lcd_putc,"TEMP:%3.3f ",temperature);
                     }
                     
                     else
                        printf("Error in data\n\r");
                        //lcd_init();
                        //printf(lcd_putc,"Error in data");
                  }
               }
               
               putc('\n'); putc('\r');
            }   
         }   
      }


and 1-Wire function (#include "onewire.c")

Code:

// One Wire bus functions - from Dallas publication AN162
// "Interfacing DS18x20/DS1822 1-wire Temperature Sensor in a Microcontroller
// Environment". Delays calculated from values given for 8051.
// Changed variable name ROM[] to RomBytes[] because ROM is a reserved word
// in version 4 of the CCS compiler.

// Global variables
int8 RomBytes[8];     
int8 lastDiscrep = 0;
short doneFlag = 0;
int8 FoundROM[8][8];    // Table of found ROM codes, 8 bytes for each
int8 numROMs;
int8 dowcrc;            // crc is accumulated in this variable

// crc lookup table
int8 const dscrc_table[] = {
   0,94,188,226,97,63,221,131,194,156,126,32,163,253,31,65,
   157,195,33,127,252,162,64,30,95,1,227,189,62,96,130,220,
   35,125,159,193,66,28,254,160,225,191,93,3,128,222,60,98,
   190,224,2,92,223,129,99,61,124,34,192,158,29,67,161,255,
   70,24,250,164,39,121,155,197,132,218,56,102,229,187,89,7,
   219,133,103,57,186,228,6,88,25,71,165,251,120,38,196,154,
   101,59,217,135,4,90,184,230,167,249,27,69,198,152,122,36,
   248,166,68,26,153,199,37,123,58,100,134,216,91,5,231,185,
   140,210,48,110,237,179,81,15,78,16,242,172,47,113,147,205,
   17,79,173,243,112,46,204,146,211,141,111,49,178,236,14,80,
   175,241,19,77,206,144,114,44,109,51,209,143,12,82,176,238,
   50,108,142,208,83,13,239,177,240,174,76,18,145,207,45,115,
   202,148,118,40,171,245,23,73,8,86,180,234,105,55,213,139,
   87,9,235,181,54,104,138,212,149,203,41,119,244,170,72,22,
   233,183,85,11,136,214,52,106,43,117,151,201,74,20,246,168,
   116,42,200,150,21,75,169,247,182,232,10,84,215,137,107,53
};

// Returns 0 for one wire device presence, 1 for none
int8 ow_reset(void)
{
   int8 presence;

   output_low(DQ);
   delay_us(480);          // Min. 480uS
   output_float(DQ);
   delay_us(72);           // Takes 15 to 60uS for devices to respond
   presence = input(DQ);
   delay_us(424);          // Wait for end of timeslot
   return(presence);
}
//******************************************************************************
// Read bit on one wire bus
int8 read_bit(void)
{
   output_low(DQ);
   delay_us(1);         // Added, 1uS min. Code relied on 8051 being slow.
   output_float(DQ);
   delay_us(15);        // Read within 15uS from start of time slot///12
   return(input(DQ));   
}                       
//******************************************************************************
void write_bit(int8 bitval)
{
   output_low(DQ);

   if(bitval == 1) {
      delay_us(1);      // 1uS min. Code relied on 8051 being slow.
      output_float(DQ);
   }
   delay_us(105);       // Wait for end of timeslot
   output_float(DQ);
}
//******************************************************************************
int8 read_byte(void)
{
   int8 i;
   int8 val = 0;

   for(i=0;i<8;i++)
   {
      if(read_bit()) val |= (0x01 << i);
      delay_us(120);  // To finish time slot
   }

   return val;
}
//******************************************************************************
void write_byte(int8 val)
{
   int8 i;
   int8 temp;

   for (i=0;i<8;i++)
   {
      temp = val >> i;
      temp &= 0x01;
      write_bit(temp);
   }

   delay_us(105);
}
//******************************************************************************
// One wire crc
int8 ow_crc(int8 x)
{
   dowcrc = dscrc_table[dowcrc^x];
   return dowcrc;
}
//******************************************************************************
// Searches for the next device on the one wire bus. If there are no more
// devices on the bus then false is returned.
int8 Next(void)
{
   int8 m = 1;             // ROM Bit index
   int8 n = 0;             // ROM Byte index
   int8 k = 1;             // Bit mask
   int8 x = 0;
   int8 discrepMarker = 0;
   int8 g;                 // Output bit
   int8 nxt;               // Return value
   short flag;


   nxt = FALSE;            // Reset next flag to false

   dowcrc = 0;             // Reset the dowcrc

   flag = ow_reset();

   if (flag||doneFlag)     // If no parts return false
   {
      lastDiscrep = 0;     // Reset the search
      return FALSE;
   }

   write_byte(0xF0);       // Send SearchROM command

   do
   {
      x = 0;
      if (read_bit() == 1) x = 2;
      delay_us(120);
      if (read_bit() == 1) x |= 1;   // And it's complement

      if (x == 3)                   // There are no devices on the one wire bus
      break;
      else
      {
         if (x > 0)                 // All devices coupled have 0 or 1
            g = x >> 1;             // Bit write value for search

         // If this discrepancy is before the last discrepancy on a previous
         // Next then pick the same as last time.
         else
         {
            if (m < lastDiscrep)
               g = ((RomBytes[n] & k) > 0);
            // If equal to last pick 1
            else
               g = (m == lastDiscrep);  // If not then pick 0

               // If 0 was picked then record position with mask k
               if (g == 0) discrepMarker = m;
         }

         // Isolate bit in ROM[n] with mask k
         if (g == 1) RomBytes[n] |= k;
         else RomBytes[n] &= ~k;

         write_bit(g);  // ROM search write

         m++;           // Increment bit counter m
         k = k << 1;    // and shift the bit mask k
         // If the mask is 0 then go to new ROM
         if (k == 0)
         {  // Byte n and reset mask
            ow_crc(RomBytes[n]);      // Accumulate the crc
            n++;
            k++;
         }
      }
   } while (n < 8);  // Loop through until through all ROM bytes 0-7

   if (m < (65||dowcrc))   // If search was unsuccessful then
      lastDiscrep = 0;     // reset the last Discrepancy to zero

   else  // Search was successful, so set lastDiscrep, lastOne, nxt
   {
      lastDiscrep = discrepMarker;
      doneFlag = (lastDiscrep == 0);
      nxt = TRUE; // Indicates search not yet complete, more parts remain
   }

   return nxt;
}
//******************************************************************************
// Resets current state of a ROM search and calls Next to find the first device
// on the one wire bus.
int8 First(void)
{
   lastDiscrep = 0;
   doneFlag = FALSE;
   return Next();    // Call Next and return it's return value;
}
//******************************************************************************
void FindDevices(void)
{
   int8 m;

   if(!ow_reset())
   {
      if(First())    // Begins when at least one part found
      {
         numROMs = 0;

         do
         {
            numROMs++;

            for (m=0;m<8;m++)
            {
               FoundROM[numROMs][m] = RomBytes[m];
            }

            printf("Device No.%u address ",numROMs);

            printf("%X%X%X%X%X%X%X%X\n\r",
            FoundROM[numROMs][7],FoundROM[numROMs][6],FoundROM[numROMs][5],
            FoundROM[numROMs][4],FoundROM[numROMs][3],FoundROM[numROMs][2],
            FoundROM[numROMs][1],FoundROM[numROMs][0]);

         } while (Next() && (numROMs<8));   // Continues until no additional
                                             // devices found.
      }
   }
   //putc('\n'); putc('\r');
   //printf("Debug point_1");
}
//******************************************************************************
// Sends Match ROM command to bus then device address
int8 Send_MatchRom(void)
{
   int8 i;
   if (ow_reset()) return FALSE;          // 0 if device present
   write_byte(0x55);                      // Match ROM

   for (i=0;i<8;i++)
   {
      write_byte(FoundRom[numROMs][i]);   // Send ROM code
   }

   return TRUE;
}
temtronic



Joined: 01 Jul 2010
Posts: 9243
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed May 14, 2014 12:06 pm     Reply with quote

Have to ask..
What value pullup are you using? Did you calculate for the 8 sensors and line loss due to length?

hth
jay
kmp84



Joined: 02 Feb 2010
Posts: 354

View user's profile Send private message

PostPosted: Wed May 14, 2014 12:42 pm     Reply with quote

temtronic wrote:
Have to ask..
What value pullup are you using? Did you calculate for the 8 sensors and line loss due to length?

hth
jay
Yes, I tried with 4K7 and lower resistors, and with 1 ,2,3 or 4 sensors . Problem is not pullup resistor ! I suppose problem is time based (function delay_us (xx)), but what is different in this function at 7.3728Mhz and 29.4912 Mhz (x4 ->PLL) in this stupid compiller! Smile Rolling Eyes
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Wed May 14, 2014 2:47 pm     Reply with quote

I have to say it.

The compiler is not being stupid. You are....

There are so many little places where things are going to happen quicker with a faster clock (after all that is why you are using the faster clock...). Any one of them could be the problem.

The point is that the operations 'between' the delays will be four times faster, and as such timings will change.

Now, if you look in the code library, you will find an alternative faster version of the onewire routines, and in the thread for these, are tweaks to the timings to make them run correctly at a faster clock:

<http://www.ccsinfo.com/forum/viewtopic.php?t=41878&highlight=onewire>
kmp84



Joined: 02 Feb 2010
Posts: 354

View user's profile Send private message

PostPosted: Wed May 14, 2014 3:35 pm     Reply with quote

Ttelmah wrote:
I have to say it.

The compiler is not being stupid. You are....

There are so many little places where things are going to happen quicker with a faster clock (after all that is why you are using the faster clock...). Any one of them could be the problem.

The point is that the operations 'between' the delays will be four times faster, and as such timings will change.

Now, if you look in the code library, you will find an alternative faster version of the onewire routines, and in the thread for these, are tweaks to the timings to make them run correctly at a faster clock:

<http://www.ccsinfo.com/forum/viewtopic.php?t=41878&highlight=onewire>


Sorry "Ttelmah" if you have been hurt,and thanks for your help! Smile
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Thu May 15, 2014 1:54 am     Reply with quote

I don't care at all, but I did think it rather 'inane' to be talking about the compiler being stupid. Smile

It's a bit like the driver who goes and has his car tuned up, to go faster, and then comes back and complains to the garage that he is having to brake earlier...

If the compiler adjusted everything so it ran at the same speed whatever clock you used, there would be no point in switching to a faster clock.
You are changing to a faster clock so the chip runs faster. Just as with the driver who has to then adjust his driving to suit the extra speed, you have to adjust the code, looking at every point where events happen, but don't use 'times' as such, and the change in speed might affect how things work in the real world.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group