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

16 bit pointer question

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



Joined: 30 Sep 2010
Posts: 38

View user's profile Send private message

16 bit pointer question
PostPosted: Thu Feb 25, 2016 10:22 am     Reply with quote

Hello All,

The following function operates normally 1st and 2nd function in. But *tensdigit value is showing 0 with function placed third function in. The function works fine if the pointers are 8 bit.

yes I am using #device *=16

Question in general: How do I know when to start using 16 bit pointers.
pic18F46k22 with 3896 RAM -- can only use 256 spots with 8-bit pointers?

ver 5.045

Code:

void dec_to_2digit(int16 *tensdigit, int16 *onesdigit, int8 int_number){
 
      *tensdigit = 0;
      *onesdigit = 0;
 
      while (int_number >= 10){
       
      int_number -= 10;
      (*tensdigit)++;
      }
     
      *onesdigit = int_number;
      return;
 }


thanks,
Davidd
temtronic



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

View user's profile Send private message

PostPosted: Thu Feb 25, 2016 10:45 am     Reply with quote

comments..
1) don't think you need the device *=16 for the 18 series PICs..

2) why int16 for *tensdigit, *onesdigit ? Int_number can only be from 0 to 255 if unsigned, -128 to 127 if signed. You also don't decode the hundreds digit so I'm at a loss to understand what you really want unless int_number is only valid for say 00-99 ?. If true 'tensdigit'can only be 0-9, so an unsigned int8.

Would appreciate more info on what you're trying to do.
input ( range) ---------> function-----------variables

I'm thinking you have 00-99--->and it gets 'parsed' to 9,9
45 parses to 4,5 ?

Jay
davidd



Joined: 30 Sep 2010
Posts: 38

View user's profile Send private message

PostPosted: Thu Feb 25, 2016 11:15 am     Reply with quote

Thanks Jay,

This particular function is servicing clock digits so yes indeed it is handling 00-59 actually.

I guess I'm not understanding the 16 bit pointer usage. I assumed that even though the actual variables are 8-bit, if the variables were stored in higher ram locations I would need to declare INT16 *ptr because the addresses wouldn't fit in INT8 *ptr.
temtronic



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

View user's profile Send private message

PostPosted: Thu Feb 25, 2016 11:22 am     Reply with quote

OK...I'm NOT a 'C' guy but why not just use 'regular' variables instead of 'pointed' ones? Heck most of my programs use global variables even though 'local' ones are supposed to be 'better'. I've never run out of RAM on the 46K22, if I was getting close, then I'd do the 'local' stuff.

The last project was an updated version of the 'monodigicron' clock using the 46K22 and a single 8" tall LED digit.Way overkill but .... it works !

Jay
asmboy



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

View user's profile Send private message AIM Address

PostPosted: Thu Feb 25, 2016 12:27 pm     Reply with quote

PCM_PROGRAMMER donated these routines to the code library.

his work is uniformly excllent IMHO and it may prove to be of benefit to you.
Code:

/----------------------------------------------
// This function converts an 8 bit binary value
// to an 8 bit BCD value.
// The input range must be from 0 to 99.

int8 bin2bcd(int8 value) {

   char retval;
   retval = 0;

   while(1)
     {
      // Get the tens digit by doing multiple subtraction
      // of 10 from the binary value.
      if(value >= 10)
        {
         value -= 10;
         retval += 0x10;
        }
      else // Get the ones digit by adding the remainder.
        {
         retval += value;
         break;
        }
      }

   return(retval);

}

//----------------------------------------------
// This function converts an 8 bit BCD value to
// an 8 bit binary value.
// The input range must be from 00 to 99.

char bcd2bin(char bcd_value) {

   char temp;

   temp = bcd_value;

   // Shifting the upper digit right by 1 is
   // the same as multiplying it by 8.
   temp >>= 1;

   // Isolate the bits for the upper digit.
   temp &= 0x78;

   // Now return: (Tens * 8) + (Tens * 2) + Ones
   return(temp + (temp >> 2) + (bcd_value & 0x0f));

}
newguy



Joined: 24 Jun 2004
Posts: 1907

View user's profile Send private message

PostPosted: Thu Feb 25, 2016 12:32 pm     Reply with quote

davidd wrote:
Thanks Jay,

This particular function is servicing clock digits so yes indeed it is handling 00-59 actually.

I guess I'm not understanding the 16 bit pointer usage. I assumed that even though the actual variables are 8-bit, if the variables were stored in higher ram locations I would need to declare INT16 *ptr because the addresses wouldn't fit in INT8 *ptr.


I'm not that well versed with pointers, but I'm pretty sure that when you declare an int8 *ptr, it just means that the pointer ptr points to a byte (int8) in RAM. Declaring int16 *ptr means that the pointer ptr points to a word (int16) in RAM. It has nothing to do with the size of the pointer itself.
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Thu Feb 25, 2016 12:39 pm     Reply with quote

Newguy is right.
Declaring a pointer as int16*, just means that when you write a value, it'll be written to where the pointer points, and to the next location in memory. So if the pointers are to 8bit variables, the code will destroy the next location/variable in memory as well.... Not what you want.
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Fri Feb 26, 2016 2:27 am     Reply with quote

He is just splitting an int8, into two digits. In a horribly complex way...

Code:

//ensure <stdlib.h> is included before using this

void dec_to_2digit(int8 *tensdigit, int8 *onesdigit, int8 int_number)
//The declaration here does _[u]not[/u]_ affect the size of the pointer
//It changes what the pointer is deemed to point 'to'.
//These are single digits, so only need/use int8 storage
{
    div_t idiv;
    idiv=div(int_number,10);
    *onesdigit=idiv.rem;
    *tensdigit=idiv.quot;
}

The div function is specifically 'there' to do exactly this type of thing, giving you access to the quotient and remainder from a division.
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Fri Feb 26, 2016 2:57 am     Reply with quote

To try to get this clear, I've put together a crude demo program:
Code:

#include <18F4520.h>
#device ADC=10
#fuses INTRC_IO,NOWDT,NOLVP,NOXINST

#use delay(Internal=4MHz)
#use rs232(UART1, ERRORS, baud=9600) //Basic UART setup

void demo_function8(int8 * data)
{
   //write a value to an 8bit variable pointed to by 'data'
   *data = 0x55;
}

void demo_function16(int16 * data)
{
   //write a value to a 16bit variable pointed to by 'data'
   *data = 0x55;
}
#define INIT_ARRAY()    for (ctr=0;ctr<4;ctr++) test_array[ctr]=ctr+1
//initialise array with 1 to 4
#define PRINT_ARRAY() printf("%2x %2x %2x %2x\n\r",test_array[0],test_array[1],test_array[2],test_array[3])

void main()
{
   int8 test_array[4];
   int8 ctr;
   int8 *ptr8;
   int16 *ptr16;

   INIT_ARRAY(); //initilise the array to 1 to 4
   
   //Now watch what using a pointer to a 8bit value does
   demo_function8(test_array);
   PRINT_ARRAY();
   //Print the four bytes. Note only one has changed
   
   //Now repat with a pointer to a 16bit variable
   INIT_ARRAY(); //initilise the array to 1 to 4
   
   //Now watch what using a pointer to a 16bit value does
   demo_function16(test_array);
   PRINT_ARRAY();
   //Print the four bytes from the array. Note _2_ bytes have changed.
   
   //Now display the _size_ of the pointers
   printf("8bit pointer size is %2x\n\r",sizeof(ptr8));
   printf("16bit pointer size is %2x\n\r",sizeof(ptr16));   
   
   while(TRUE)
   {
   }
}


Running this, you get:
Code:

55 02 03 04
55 00 03 04
8bit pointer size is 02
16bit pointer size is 02


When you declare the pointer to be to an int16, the routine writes 'to' an int16, so 0x0055 gets transferred to the buffer. When it points to an int8, only '0x55' gets transferred. The size of the pointer is the same in both cases.
davidd



Joined: 30 Sep 2010
Posts: 38

View user's profile Send private message

PostPosted: Fri Feb 26, 2016 6:35 am     Reply with quote

very good explanation!
Thanks Ttelmah, Thanks everyone!
avatarengineer



Joined: 13 May 2013
Posts: 51
Location: Arizona

View user's profile Send private message Visit poster's website

pointers
PostPosted: Mon Feb 29, 2016 10:21 am     Reply with quote

It seems to me that using pointers "now-a-days" is akin to peek and poke of the "olden-days".
Unless I'm managing large amounts of dynamic memory that I've mapped and need to reallocate during runtime,
it's difficult to find code advantages in using them.

CCS has many built-ins and so I rarely find pointers that helpful.
In the original example above, I might have just used a union of a word + 2 bytes + 16bits within and played swap games or bit shifts.
It all depends on the goal.
asmboy



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

View user's profile Send private message AIM Address

PostPosted: Mon Feb 29, 2016 12:17 pm     Reply with quote

pointers IMHO, while perhaps not obviously useful with SIMPLE vars,
can be a great help when dealing with strings, and more complicated data structures such as multi-element arrays where passing by direct reference is awkward or inefficient in use of scratch ram AND CPU cycles

as an example look at the MEM** family OR the two ROTATE_() functions in the CCS manual --
and show how passing by direct reference would be better for any of these..
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Mon Feb 29, 2016 3:19 pm     Reply with quote

and (of course), if you are using arrays, you are actually using pointers all the time.
Pointers are a fundamental part of C.
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