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

what is different (conf. settings at 18f46J50)

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



Joined: 16 May 2006
Posts: 95

View user's profile Send private message

what is different (conf. settings at 18f46J50)
PostPosted: Fri Feb 05, 2016 4:09 pm     Reply with quote

hi;
I use multi ds18b20

my code works at this conf

Code:

#include <18F46J50.h>                       
#fuses HSPLL,NOWDT,NOXINST,PLL3,CPUDIV6
#use delay(clock=8M,crystal=12M)


but it doesn't work this conf
Code:

#include <18F46J50.h>                   
#fuses HSPLL,NOWDT,NOXINST,PLL3,CPUDIV3
#use delay(clock=16M,crystal=12M)
 

What is different?
Thanks for your answers
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Fri Feb 05, 2016 6:01 pm     Reply with quote

post the CODE and explain WHAT about it does not work.
read the data sheet. USB does NOT work with any old arbitrary clock setting.
respected



Joined: 16 May 2006
Posts: 95

View user's profile Send private message

PostPosted: Fri Feb 05, 2016 6:18 pm     Reply with quote

multi use code for ds18b20 doesn't work

main.c
Code:

#include <18F46J50.h>
#device ADC=8;                         
#fuses HSPLL,NOWDT,NOXINST,PLL3,NOCPUDIV//CPUDIV6//NOCPUDIV//,RTCOSC_T1,PROTECT
#use delay(clock=48M,crystal=12M)   
//!#include <18F46J50.h>
//!#fuses INTRC_IO, NOWDT
//!#use delay(clock=4M)
#include <flexlcd420.c>           
#include <onewire.c>



int8 i,tmp,numDev = 0;
 int8 scratch[2];
 float TEMPERATURE[2];
                                   
                                                                           
                                                                                               

 
 
  void main()                                                               
{                                                                             
    setup_oscillator(OSC_PLL_ON);
                                 
    lcd_init();

output_float(DQ);
output_high(PIN_A3);


numDev = FindDevices();

   for(i=1; i<=numDev; i++)
   {
   
      lcd_gotoxy(1,i);
      printf(lcd_putc,"S%u:",i);
      lcd_gotoxy(4,i);
      for (tmp=0; tmp<8; tmp++) 
         printf(lcd_putc,"%X",FoundROM[i][tmp]);
   
   }


signed int16 tem3;               


while (TRUE)                                                             
   {   

      if (!ow_reset())     // If a device is present and it's time to send string
      {
         
         write_byte(0xCC); // Skip Rom command
         write_byte(0x44); // Temperature convert command
         output_float(DQ);
         delay_ms(750);    // Max. conv. time is 750mS for 12 bit
         ow_reset();
         
         // read all devices on bus
         for (numRoms=1; numRoms <= numDev; numRoms++)
         {
           
            if (Send_MatchRom())
            {
               write_byte(0xBE); // Read scratch pad command 
                       
               for(i=0; i<2; i++)
               {
                  scratch[i]= read_byte();
               }           
               // raw sensor data (16bit)

               tem3 = make16(scratch[1], scratch[0]);
               TEMPERATURE[numRoms-1]=(float) tem3 / 16.0;
               
               
               
               
               
             
                       
               
            }     // if (Send_MatchRom())
           
               delay_ms(200);
               lcd_gotoxy(1,3);
               printf (lcd_putc,"PROB:%3.1f",TEMPERATURE[0]);
               lcd_gotoxy(1,4);
               printf (lcd_putc,"PROB:%3.1f",TEMPERATURE[1]);
         }     // for (numRoms=1; numRoms <= numDev; numRoms++) 
         
     
         
      }     




                       
                                                               
   } //while                                                               
                                                   
     
 }//main                                     

                                                                                 



onewire.c
Code:

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

//calc_CRC - INTERNAL FUNCTION
//Purpose:    To calculate an 8-bit CRC based on a polynomial and the series
//            of data bytes
//Note:       Polynomial used x^8 + x^5 + x^4 + 1 = 10001100
//Inputs:     A pointer to an array of the data bytes and an int saying how many
//            bytes there are in the data array
//Outputs:    An int8 which is the calculated CRC
int8 calc_CRC(int8* data, int8 bytes)
{
   #define CRC_POLY      0x8C
   int8 shift_register = 0, i, datab, bits;

   for(i = 0; i < bytes; ++i)
   {
      datab = *(data + i);

      for(bits = 0; bits < 12; ++bits)  //8
      {
         if(bit_test((shift_register ^ datab), 0))
         {
            shift_register = shift_register >> 1;
            shift_register ^= CRC_POLY;
         }
         else
         {
            shift_register = shift_register >> 1;
         }

         datab = datab >> 1;
      }
   }
   return shift_register;
} //calc_CRC


// Returns 0 for one wire device presence, 1 for none
int8 ow_reset(void)
{
   int8 presence;
   
   output_low(DQ);
   delay_us(488);          // 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(12);        // Read within 15uS from start of time slot
   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(60);       // 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 = calc_CRC(x,8);
   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_rom_index = 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_rom_index < lastDiscrep)
               g = ((RomBytes[n] & k) > 0);
            // If equal to last pick 1
            else
               g = (m_rom_index == lastDiscrep);  // If not then pick 0

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

         // 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_rom_index++;           // 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_rom_index < (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;

}

//******************************************************************************
int8 FindDevices(void)
{
   int8 m, cont = 0;
   if(!ow_reset())
   {

      if(First())    // Begins when at least one part found
      {
     
     
         numROMs = 0;
         do
         {
            numROMs++; 
            cont++;


            for (m=0;m<12;m++) //8
            {
               FoundROM[numROMs][m] = RomBytes[m];
            }
         } while (Next());   // Continues until no additional                             
      }
   }

   return cont;

}

//******************************************************************************
// 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;
}

float ds1820_read()
{
int8 busy=0, temp1, temp2;
signed int16 temp3;
float result;
ow_reset();
write_byte(0xCC);
write_byte(0x44);
while (busy == 0)                   
busy = read_byte();
ow_reset();
write_byte(0xCC);
write_byte(0xBE);
temp1 = read_byte();
temp2 = read_byte();
temp3 = make16(temp2, temp1);
result = (float) temp3 / 16.0;
delay_ms(200);
return(result);
}
temtronic



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

View user's profile Send private message

PostPosted: Fri Feb 05, 2016 6:24 pm     Reply with quote

If the problem is in communcating with the DS18B20 devices it might be the wrong driver.
There's 2 or 3 different variations of them and the driver must match the device. ds1820 is NOT the same as ds18B20 from what I recall.
Also the timing needs to be correct.

1st thing is to confirm the PIC will run a 1Hz LED program and is accurate.

2nd get ONE sensor to work....

3rd try a 2nd sensor.

i used them 5-6 years ago so all this is from memory.


Jay
respected



Joined: 16 May 2006
Posts: 95

View user's profile Send private message

PostPosted: Fri Feb 05, 2016 6:30 pm     Reply with quote

when I changed oscillator frequency , it works. and when i used only one sensor. it has no problem. But 2 sensors have problem with 16 or higher frequency
temtronic



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

View user's profile Send private message

PostPosted: Fri Feb 05, 2016 9:05 pm     Reply with quote

what are hardware details of your one wire bus?
value of pullup resistor
length of wires to sensors
PCB, wirewrap or ???

Jay
respected



Joined: 16 May 2006
Posts: 95

View user's profile Send private message

PostPosted: Sat Feb 06, 2016 4:03 am     Reply with quote

pull-up resistor 4K7. I use 2 sensors and i use PCB.
It works 2 sensors at 4MHz
temtronic



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

View user's profile Send private message

PostPosted: Sat Feb 06, 2016 6:47 am     Reply with quote

Does it find both sensors and display their ID numbers and then 'fail'?

Are the sensor very close to the PCB or on wires ?

I used 4k7 pullup on DQ line with 5 volt PIC.

Also my project only used 4 sensors so I used individual I/O pins for each sensor. It was a lot easier for wiring and no need for the ID routines. I used integers for temp not float.

Also, you have a 200ms delay after reading, not sure why .


My PIC 18F46K22 is running at 16MHz .

edit: Need to know HOW you are connecting to the DS18B20 devices !!

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19546

View user's profile Send private message

PostPosted: Sat Feb 06, 2016 1:49 pm     Reply with quote

A bit of searching here, finds that the driver you have has problems at higher speeds. Following thread has a fix for this:

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

Problem is that once speed goes up two of the bit transactions are done too quickly.
respected



Joined: 16 May 2006
Posts: 95

View user's profile Send private message

PostPosted: Sat Feb 06, 2016 2:17 pm     Reply with quote

I think My problem is speed. I decided to use low speed (4 or 8 MHz) I use 2 sensors and normal mode not powered mode.
temtronic



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

View user's profile Send private message

PostPosted: Sat Feb 06, 2016 6:00 pm     Reply with quote

Here's the driver I've used for a few years. It might be of some help ?

Code:
// Reset one wire bus ,#1
void ow1_reset(void)
{
output_low(OW1);
delay_us(500); // Min. 480uS
output_float(OW1);
delay_us(500); // Wait for end of timeslot
}

//-------------------------------------
// Reset one wire bus, #2
void ow2_reset(void)
{
output_low(OW2);
delay_us(500); // Min. 480uS
output_float(OW2);
delay_us(500); // Wait for end of timeslot
}

//-------------------------------------
// Read bit on one wire bus ,#1
int8 ow1_read_bit(void)
{
output_low(OW1);
delay_us(1);
output_float(OW1);
delay_us(12); // Read within 15uS from start of time slot
return(input(OW1));
}

//-------------------------------------
// Read bit on one wire bus ,#2
int8 ow2_read_bit(void)
{
output_low(OW2);
delay_us(1);
output_float(OW2);
delay_us(12); // Read within 15uS from start of time slot
return(input(OW2));
}

//-------------------------------------
// read a byte from device
int8 ow1_read_byte(void)
{
int8 i;
int8 val = 0;
for(i=0 ; i<8 ; i++)
{
if(ow1_read_bit()) val |= (0x01 << i);
delay_us(120); // To finish time slot
}
return val;
}

//-------------------------------------
// read a byte from device,bus #2
int8 ow2_read_byte(void)
{
int8 i;
int8 val = 0;
for(i=0 ; i<8 ; i++)
{
if(ow2_read_bit()) val |= (0x01 << i);
delay_us(120); // To finish time slot
}
return val;
}

//-------------------------------------
// Write a byte to device,bus #1
void ow1_write_byte(int8 val, int8 power_on)
{
int i;
for(i=0; i<8; i++)
{
output_low(OW1);
delay_us( 2 );
output_bit(OW1, shift_right(&val,1,0));
delay_us(60);
if((i == 7) && (power_on == 1))
{
output_high(OW1);
}
else
{
output_float(OW1);
delay_us( 2 );
}
}
}

//-------------------------------------
// Write a byte to device,bus #2
void ow2_write_byte(int8 val, int8 power_on)
{
int i;
for(i=0; i<8; i++)
{
output_low(OW2);
delay_us( 2 );
output_bit(OW2, shift_right(&val,1,0));
delay_us(60);
if((i == 7) && (power_on == 1))
{
output_high(OW2);
}
else
{
output_float(OW2);
delay_us( 2 );
}
}
}

// first device read temperature...
signed int16 ow1_read_temp(){
ow1_reset();
ow1_write_byte(0xCC, 0); // Skip Rom command
ow1_write_byte(0xBE, 0); // Read scratch pad command
// Get the data bytes
for(i=0; i < 8; i++)
{
scratch[i] = ow1_read_byte();
}
ow1_reset();
t1 = (signed int16) make16(scratch[1],scratch[0]);
if(t1 >= 0)
   t1 = (t1 + 8)/16;
else
   t1 = (t1 - 8)/16;
return(t1);
}

//second device read temperature...
signed int16 ow2_read_temp(){
ow2_reset();
ow2_write_byte(0xCC, 0); // Skip Rom command
ow2_write_byte(0xBE, 0); // Read scratch pad command
// Get the data bytes
for(i=0; i < 8; i++)
{
scratch[i] = ow2_read_byte();
}
t2 = (signed int16) make16(scratch[1],scratch[0]);
if(t2 >= 0)
   t2 = (t2 + 8)/16;
else
   t2 = (t2 - 8)/16;
return(t2);
}



OW1 refers to the 'One Wire bus #1'
OW2 refers to the 'One Wire bus #2'
I used the parasitic mode for the devices, as it only requires 2 wires per sensor, making it for simpler hardware. used on 16F877, 16F88 and 18F46K22 at up to 16MHz with no problems. As the driver controls the timing it might be a good idea to put an oscilloscope on the bus and see what the actual timing is for the PIC.

As each sensor is on it's own I/O pin I didn't need the CRC or ID functions. The datalogger got a 1Hz interrupt from an RTC device that told main() to read the chips,display,log, then trigger a convert command.


Jay

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19546

View user's profile Send private message

PostPosted: Sun Feb 07, 2016 2:38 am     Reply with quote

As a general comment, more devices on the bus will inherently imply more capacitance. So edges (rising in particular) will be slower. Anything that is tight on timing, can then fall 'over the edge'. Now the chip has specified 'minima' for the bit timings, of 1uSec. The code has this as a delay, while the thread I point to, extends this to 5uSec, when working at a higher clock rate.
I'd suggest extending these times to 2uSec, and slightly reducing the pull up resistor (the thermometer can pull down a maximum of 4mA - a lower resistance will improve the rising edges, and improve the power available for the chip). I'd suggest 3KR.
The code is working for 'one device per bus', and it is only failing with multiple devices. Obviously the solution does exist of having multiple busses as Temtronic does (this brings the big advantage of not having to scan for ID's etc.). However it should be possible to get multiple devices to work.
respected



Joined: 16 May 2006
Posts: 95

View user's profile Send private message

PostPosted: Sun Feb 07, 2016 4:20 am     Reply with quote

In fact I tried 2K2 Pull-up resistor. It works only find devices function. so It found 2 chips and serial number but it has problem reading temp. while reading operations, it didn't any answer

@temtronic
thanks. good idea. but I want to use only one wire. Because of I have to use low speed
Ttelmah



Joined: 11 Mar 2010
Posts: 19546

View user's profile Send private message

PostPosted: Sun Feb 07, 2016 4:25 am     Reply with quote

2K2, is getting rather low. The chip only has every limited pull down capability. Hence my suggestion to just reduce a _little_.

Key thing though is have you extended the times as shown in the post?.

Running at 8MHz (say), with a 1uSec delay, the actual 'time' between the clock, and testing, will be the 1uSec, plus two instruction times. Another micro second. So 2uSec. However at 16MHz, this drops to just 1.5uSec. It only takes the rise time of the signal to be perhaps 3/4uSec with the standard pull-up, for this to then fail.....
respected



Joined: 16 May 2006
Posts: 95

View user's profile Send private message

PostPosted: Wed Feb 24, 2016 2:12 pm     Reply with quote

I tried but it doesn't work at 16MHz or higher. maybe driver is wrong.

This is great!! It works now. at 48MHz

Code:
#fuses HSPLL,NOWDT,NOXINST,DSBOR,RTCOSC_T1,PROTECT,PLL3,NOCPUDIV//CPUDIV3
#use delay(clock=48M,crystal=12M) 



Code:
int8 read_bit(void)
{
   output_low(DQ);
   delay_us(5);         // Added, 1uS min. Code relied on 8051 being slow.
   output_float(DQ);
   delay_us(20);        // Read within 15uS from start of time slot
   return(input(DQ));   
}   

//******************************************************************************
void write_bit(int8 bitval)
{
   output_low(DQ);

   if(bitval == 1) {
      delay_us(5);      // 1uS min. Code relied on 8051 being slow.
      output_float(DQ);
   }
   delay_us(60);       // Wait for end of timeslot
   output_float(DQ);
}
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