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

the difference between PIC18f26k22 and PIC16f1847
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Danni



Joined: 05 Mar 2016
Posts: 10

View user's profile Send private message

the difference between PIC18f26k22 and PIC16f1847
PostPosted: Sat Mar 05, 2016 1:42 am     Reply with quote

Hello.

I am new in microcontroller and has a pickit 3 and a demo print with PIC18f26k22 I've tried different things.

Now I made a print with a PIC16f1847 and can not figure out what I need to do to get code that works on demo table to work on my own prints.

I have a DS18B20 + with parasitic power and a 4k7 pullup resistor. Have found the code in here that I use.

So I think it's something with the setup of my PIC.

Is there someone who can give my a hint.

Code:


#include <16f1847.h>

#device adc=16

 #FUSES NOWDT                    //No Watch Dog Timer
 #FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
 #FUSES NOBROWNOUT               //No brownout reset
 #FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES PUT                      //Power Up Timer
#FUSES NOMCLR
#FUSES NODEBUG


#use delay(clock=4000000)



#define DQ   PIN_B3   

//-------------------------------------
void ow_reset(void)
{
output_low(DQ);
delay_us(500);          // Min. 480uS
output_float(DQ);
delay_us(500);          // Wait for end of timeslot
}

//-------------------------------------
// Read bit on one wire bus

int8 read_bit(void)
{
output_low(DQ);
delay_us(1);         
output_float(DQ);
delay_us(12);        // Read within 15uS from start of time slot
return(input(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 power_on)
{
int i;

for(i=0; i<8; i++)
   {
    output_low(DQ);
    delay_us( 2 ); 
    output_bit(DQ, shift_right(&val,1,0)); 

    delay_us(60);
 
    if((i == 7) && (power_on == 1))
      {
       output_high(DQ);
      }
    else
      {
       output_float(DQ);
       delay_us( 2 ); 
      }
   }

}

//==========================================
void main(void)
{
int8 i;
signed int16 temperature;
signed int8 scratch[9];
   
output_float(DQ);


while(1)
  {
   ow_reset();
   write_byte(0xCC, 0); // Skip Rom command
   write_byte(0x44, 1); // Temperature Convert command

   delay_ms(750);    // Max. time for conversion is 750mS
   
   
   ow_reset();
   write_byte(0xCC, 0); // Skip Rom command
   write_byte(0xBE, 0); // Read scratch pad command
   
   // Get the data bytes
   for(i=0; i < 8; i++)
      {
       scratch[i] = read_byte(); 
      }
   
   ow_reset();
   
temperatur = scratch[1];   
   
   temperature = (signed int16) make16(scratch[1],scratch[0]);
         
   if(temperature >= 0)
      temperature = ((temperature + 8)/16)*10;
   else
      temperature = ((temperature - 8)/16)*10;
   


                }
                 
             }




Regards Danni..
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Sat Mar 05, 2016 3:47 am     Reply with quote

I haven't looked at the code. Just the fuses. Big problems.

'HS' says use an _external_ crystal running faster than 4MHz.
'INTRC_IO', then says to use the internal osclliator.

You can't have both. Use:
Code:

#include <16f1847.h>

#device adc=10

#FUSES NOWDT               //No Watch Dog Timer
#FUSES NOBROWNOUT    //No brownout reset
#FUSES NOLVP                //No low voltage prgming
#FUSES INTRC_IO           //Internal RC Osc, no CLKOUT
#FUSES PUT                    //Power Up Timer
#FUSES NOMCLR             //MCLR pin disabled
#FUSES NODEBUG          //'Run' mode.

#use delay(INTERNAL=4000000)

Your chip then has a chance of working.

Then always start _one step at a time_.
With these fuses use a simple program to just flash an LED on one pin. Verify this does flash, and flashes at the expected speed. You then know your chip is working, before trying to debug problems with your code....
Danni



Joined: 05 Mar 2016
Posts: 10

View user's profile Send private message

PostPosted: Sat Mar 05, 2016 5:37 am     Reply with quote

I think it's something with the setup but it has not solved the problem yet.

I have made two flashing diodes and they worked fine and 1 second seems to fit.
Also before i removed #fuses hs :-)
temtronic



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

View user's profile Send private message

PostPosted: Sat Mar 05, 2016 6:44 am     Reply with quote

The 1Hz LED test is a 'rough' - OK I'm working test NOT very accurate.
You should use an oscilloscope and check the actual timings if possible. The internal RC clock may not be 4.000000000 MHz so your 1us won't be 1us.
These DS chips need precise timings.
So you may need to adjust the delays either more or less.
Whenever using 'time critical' code like timers, UARTs, DS chips it's best to use a real xtal/2caps.

Jay

also this..
temperatur = scratch[1];

looks like 'old code', needs to be deleted.
Danni



Joined: 05 Mar 2016
Posts: 10

View user's profile Send private message

PostPosted: Sat Mar 05, 2016 8:01 am     Reply with quote

Yes sorry forgot to remove it.

The only thing i changed is i could not complie int8 scratch[9];

So changed it to Signed int8 scratch[9]; but isn't that the same or?
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Sat Mar 05, 2016 9:06 am     Reply with quote

No, they are not the same.

One has 8bits and accepts values from 0 to 255.The other has one bit reserved for the sign, and has values from -128 to +127.

What do you mean "i could not complie int8 scratch[9];". Why not?.

It'll change things when any maths, or logic operations are performed on the variable.
Danni



Joined: 05 Mar 2016
Posts: 10

View user's profile Send private message

PostPosted: Sat Mar 05, 2016 1:21 pm     Reply with quote

when i use int8 scratch[9];
i get the error Unable to resolve identifier scratch

I read somewhere that signed int is the same as int :-S
temtronic



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

View user's profile Send private message

PostPosted: Sat Mar 05, 2016 1:48 pm     Reply with quote

It sounds like you've made a few changes to your code so it would be best to post your current version.


Jay
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Mar 05, 2016 1:49 pm     Reply with quote

Quote:
when i use int8 scratch[9];
i get the error Unable to resolve identifier scratch

That's an MPLAB X message. See this thread on the Microchip forum:
http://www.microchip.com/forums/m775535.aspx
Danni



Joined: 05 Mar 2016
Posts: 10

View user's profile Send private message

PostPosted: Sat Mar 05, 2016 2:30 pm     Reply with quote

I use this now:

Code:


#include <16f1847.h>

#device adc=10

 #FUSES NOWDT               //No Watch Dog Timer
 #FUSES NOBROWNOUT    //No brownout reset
 #FUSES NOLVP                //No low voltage prgming
 #FUSES INTRC_IO           //Internal RC Osc, no CLKOUT
 #FUSES PUT                    //Power Up Timer
 #FUSES NOMCLR             //MCLR pin disabled
 #FUSES NODEBUG          //'Run' mode.

 #use delay(INTERNAL=4000000)



#define DQ   PIN_B3   


//-------------------------------------
void ow_reset(void)
{
output_low(DQ);
delay_us(500);          // Min. 480uS
output_float(DQ);
delay_us(500);          // Wait for end of timeslot
}

//-------------------------------------
// Read bit on one wire bus

int8 read_bit(void)
{
output_low(DQ);
delay_us(1);         
output_float(DQ);
delay_us(12);        // Read within 15uS from start of time slot
return(input(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 power_on)
{
int i;

for(i=0; i<8; i++)
   {
    output_low(DQ);
    delay_us( 2 ); 
    output_bit(DQ, shift_right(&val,1,0)); 

    delay_us(60);
 
    if((i == 7) && (power_on == 1))
      {
       output_high(DQ);
      }
    else
      {
       output_float(DQ);
       delay_us( 2 ); 
      }
   }

}


//==========================================
void main(void)
{
int8 i;
signed int16 temperature;
int8 scratch[9];
   
output_float(DQ);
   
while(1)
  {
         
         
   ow_reset();
   write_byte(0xCC, 0); // Skip Rom command
   write_byte(0x44, 1); // Temperature Convert command

   delay_ms(750);    // Max. time for conversion is 750mS
   
   
   ow_reset();
   write_byte(0xCC, 0); // Skip Rom command
   write_byte(0xBE, 0); // Read scratch pad command
   
   // Get the data bytes
   for(i=0; i < 8; i++)
      {
       scratch[i] = read_byte(); 
      }
   
   ow_reset();
   
   
   temperature = (signed int16) make16(scratch[1],scratch[0]);
         
   if(temperature >= 0)
      temperature = ((temperature + 8)/16)*10;
   else
      temperature = ((temperature - 8)/16)*10;
   
 
                }
                 
             }


with changed #fuses as Ttelmah told me to.
But the Unable to resolve identifier scratch is there but can download without any problem.
But still not working...[/code]
temtronic



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

View user's profile Send private message

PostPosted: Sat Mar 05, 2016 2:43 pm     Reply with quote

OK... I don't see anything like a print statement to display the reading ??

Also if you have a spare I/O pin, add a resistor and LED and 'toggle' it in the 'forever loop' to confirm the program is running.

Jay
Danni



Joined: 05 Mar 2016
Posts: 10

View user's profile Send private message

PostPosted: Sat Mar 05, 2016 2:54 pm     Reply with quote

I use a red/green led to blink the binary temperature out.
I used that on my demo board too, because its easy to see whats 1 and 0:
and a blink at the end.

Code:


#include <16f1847.h>

#device adc=10

 #FUSES NOWDT               //No Watch Dog Timer
 #FUSES NOBROWNOUT    //No brownout reset
 #FUSES NOLVP                //No low voltage prgming
 #FUSES INTRC_IO           //Internal RC Osc, no CLKOUT
 #FUSES PUT                    //Power Up Timer
 #FUSES NOMCLR             //MCLR pin disabled
 #FUSES NODEBUG          //'Run' mode.

 #use delay(INTERNAL=4000000)



#define DQ   PIN_A7   
#define LEDGRON PIN_A1
#define LEDROD PIN_A0

//-------------------------------------
void ow_reset(void)
{
output_low(DQ);
delay_us(500);          // Min. 480uS
output_float(DQ);
delay_us(500);          // Wait for end of timeslot
}

//-------------------------------------
// Read bit on one wire bus

int8 read_bit(void)
{
output_low(DQ);
delay_us(1);         
output_float(DQ);
delay_us(12);        // Read within 15uS from start of time slot
return(input(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 power_on)
{
int i;

for(i=0; i<8; i++)
   {
    output_low(DQ);
    delay_us( 2 ); 
    output_bit(DQ, shift_right(&val,1,0)); 

    delay_us(60);
 
    if((i == 7) && (power_on == 1))
      {
       output_high(DQ);
      }
    else
      {
       output_float(DQ);
       delay_us( 2 ); 
      }
   }

}






void truebit()
{
      output_high(LEDGRON); // 1 bit
      delay_ms(81);  //20 pc bruger kun en kort puls til at tælle low tid
      output_low(LEDGRON);
      delay_ms(41);  //50
}

void falsebit()
{
      output_high(LEDROD); // 0 bit
      delay_ms(41);  //20 pc bruger kun en kort puls til at tælle low tid
      output_low(LEDROD);
      delay_ms(81); //80
}









//==========================================
void main(void)
{
int8 i;
signed int16 temperature;
int8 scratch[9];
   
output_float(DQ);
   
while(1)
  {
         
         
   ow_reset();
   write_byte(0xCC, 0); // Skip Rom command
   write_byte(0x44, 1); // Temperature Convert command

   delay_ms(750);    // Max. time for conversion is 750mS
   
   
   ow_reset();
   write_byte(0xCC, 0); // Skip Rom command
   write_byte(0xBE, 0); // Read scratch pad command
   
   // Get the data bytes
   for(i=0; i < 8; i++)
      {
       scratch[i] = read_byte(); 
      }
   
   ow_reset();
   
   
   temperature = (signed int16) make16(scratch[1],scratch[0]);
         
   if(temperature >= 0)
      temperature = ((temperature + 8)/16)*10;
   else
      temperature = ((temperature - 8)/16)*10;
   
 



                   
    if((temperature & 0x0800) != 0x00)truebit();else falsebit();
    if((temperature & 0x0400) != 0x00)truebit();else falsebit();
    if((temperature & 0x0200) != 0x00)truebit();else falsebit();
    if((temperature & 0x0100) != 0x00)truebit();else falsebit();
    if((temperature & 0x0080) != 0x00)truebit();else falsebit();
    if((temperature & 0x0040) != 0x00)truebit();else falsebit();
    if((temperature & 0x0020) != 0x00)truebit();else falsebit();
    if((temperature & 0x0010) != 0x00)truebit();else falsebit();
    if((temperature & 0x0008) != 0x00)truebit();else falsebit();
    if((temperature & 0x0004) != 0x00)truebit();else falsebit();
    if((temperature & 0x0002) != 0x00)truebit();else falsebit();
    if((temperature & 0x0001) != 0x00)truebit();else falsebit();
       

 
       output_high(LEDROD);
       output_high(LEDGRON);
       delay_ms(1000);  //20 pc bruger kun en kort puls til at tælle low tid
       output_low(LEDROD);
       output_low(LEDGRON);

                }
                 
             }

Danni



Joined: 05 Mar 2016
Posts: 10

View user's profile Send private message

PostPosted: Sun Mar 06, 2016 1:33 pm     Reply with quote

But how does this work??

Code:

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


For me it looks like a counter that calls read_bit 8 times and puts a 0 or 1 in each of the int8 bits.

It looks like that it only reads read_bit one time in every scan. and it should read it 8 times?? or am i wrong??
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Mar 06, 2016 2:22 pm     Reply with quote

Quote:
It looks like that it only reads read_bit one time in every scan

Make a test program to study the read_bit() routine.
The output of the test program is shown below. This output comes
from running the program in MPLAB vs. 8.92 simulator.
It shows that read_bit() is called 8 times by the read_byte() function:
Quote:

read_bit() was called.
read_bit() was called.
read_bit() was called.
read_bit() was called.
read_bit() was called.
read_bit() was called.
read_bit() was called.
read_bit() was called.
Value read = 55 hex


The test program is shown below. Instead of the normal read_bit()
function, a test function is substituted, which displays the
message "read_bit() was called". This allows us to see the number of
times it was called (Answer: 8 times).
Code:
#include <18F4620.h>
#fuses INTRC_IO,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4M)
#use rs232(baud=9600, UART1, ERRORS)


int8 read_bit(void)
{
static int8 temp = 0;

printf("read_bit() was called. \r");

temp ^= 1;  // Flip the return value to 0 or 1.

return(temp);
}

//-----------------------
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 main()
{
int8 value;

value = read_byte();

printf("Value read = %x hex \r", value);

while(TRUE);
}
temtronic



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

View user's profile Send private message

PostPosted: Sun Mar 06, 2016 2:50 pm     Reply with quote

To understand what's going on you really need to read the Dallas Semi datasheets on 'one-wire' operations. It will explain the 'how and why' of the one wire communications bus that they developed.
The short answer.. as PCM P points out, is that they 'create' a byte from 8 reads of the bus.
It is important to read their data sheets as timing is critical in using this bus unlike 'RS232' where it's all done 'behind the scene' in a UART.

Jay
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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