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 support@ccsinfo.com

Using struct and union

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



Joined: 24 Jul 2020
Posts: 62

View user's profile Send private message

Using struct and union
PostPosted: Fri Aug 14, 2020 7:22 am     Reply with quote

Hi there,

I wrote a code with struct/union. You can see below.

Code:


typedef struct{
   uint8 s_syncBYTE;
   uint8 s_THRBW;
   uint8 s_P1_THR_0;
   uint8 s_P1_THR_1;
   uint8 s_P1_THR_2;
   uint8 s_P1_THR_3;
   uint8 s_P1_THR_4;
   uint8 s_P1_THR_5;
   uint8 s_P1_THR_6;
   uint8 s_P1_THR_7;
   uint8 s_P1_THR_8;
   uint8 s_P1_THR_9;
   uint8 s_P1_THR_10;
   uint8 s_P1_THR_11;
   uint8 s_P1_THR_12;
   uint8 s_P1_THR_13;
   uint8 s_P1_THR_14;
   uint8 s_P1_THR_15;
   uint8 s_P2_THR_0;
   uint8 s_P2_THR_1;
   uint8 s_P2_THR_2;
   uint8 s_P2_THR_3;
   uint8 s_P2_THR_4;
   uint8 s_P2_THR_5;
   uint8 s_P2_THR_6;
   uint8 s_P2_THR_7;
   uint8 s_P2_THR_8;
   uint8 s_P2_THR_9;
   uint8 s_P2_THR_10;
   uint8 s_P2_THR_11;
   uint8 s_P2_THR_12;
   uint8 s_P2_THR_13;
   uint8 s_P2_THR_14;
   uint8 s_P2_THR_15;
}pga_bufs16;

typedef union{
   pga_bufs16 pgab16;
   uint8 pga_bufdizi16[sizeof(pga_bufs16)];
}pga_bufu16;

void pga460_initThresholds(BYTE thr)
{
         P1_THR_0 = 0x88;
         P1_THR_1 = 0x88;
         P1_THR_2 = 0x88;
         P1_THR_3 = 0x88;
         P1_THR_4 = 0x88;
         P1_THR_5 = 0x88;
         P1_THR_6 = 0x84;
         P1_THR_7 = 0x21;
         P1_THR_8 = 0x08;
         P1_THR_9 = 0x42;
         P1_THR_10 = 0x10;
         P1_THR_11 = 0x80;
         P1_THR_12 = 0x80;
         P1_THR_13 = 0x80;
         P1_THR_14 = 0x80;
         P1_THR_15 = 0x00;
         P2_THR_0 = 0x88;
         P2_THR_1 = 0x88;
         P2_THR_2 = 0x88;
         P2_THR_3 = 0x88;
         P2_THR_4 = 0x88;
         P2_THR_5 = 0x88;
         P2_THR_6 = 0x84;
         P2_THR_7 = 0x21;
         P2_THR_8 = 0x08;
         P2_THR_9 = 0x42;
         P2_THR_10 = 0x10;
         P2_THR_11 = 0x80;
         P2_THR_12 = 0x80;
         P2_THR_13 = 0x80;
         P2_THR_14 = 0x80;
         P2_THR_15 = 0x00;      


        pga_bufu16 pgau16;
       
      pgau16.pgab16.s_syncBYTE=syncBYTE;
      pgau16.pgab16.s_THRBW=THRBW;
      pgau16.pgab16.s_P1_THR_0=P1_THR_0;
      pgau16.pgab16.s_P1_THR_1=P1_THR_1;
      pgau16.pgab16.s_P1_THR_2=P1_THR_2;
      pgau16.pgab16.s_P1_THR_3=P1_THR_3;
      pgau16.pgab16.s_P1_THR_4=P1_THR_4;
      pgau16.pgab16.s_P1_THR_5=P1_THR_5;
      pgau16.pgab16.s_P1_THR_6=P1_THR_6;
      pgau16.pgab16.s_P1_THR_7=P1_THR_7;
      pgau16.pgab16.s_P1_THR_8=P1_THR_8;
      pgau16.pgab16.s_P1_THR_9=P1_THR_9;
      pgau16.pgab16.s_P1_THR_10=P1_THR_10;
      pgau16.pgab16.s_P1_THR_11=P1_THR_11;
      pgau16.pgab16.s_P1_THR_12=P1_THR_12;
      pgau16.pgab16.s_P1_THR_13=P1_THR_13;
      pgau16.pgab16.s_P1_THR_14=P1_THR_14;
      pgau16.pgab16.s_P1_THR_15=P1_THR_15;
      pgau16.pgab16.s_P2_THR_0=P2_THR_0;
      pgau16.pgab16.s_P2_THR_1=P2_THR_1;
      pgau16.pgab16.s_P2_THR_2=P2_THR_2;
      pgau16.pgab16.s_P2_THR_3=P2_THR_3;
      pgau16.pgab16.s_P2_THR_4=P2_THR_4;
      pgau16.pgab16.s_P2_THR_5=P2_THR_5;
      pgau16.pgab16.s_P2_THR_6=P2_THR_6;
      pgau16.pgab16.s_P2_THR_7=P2_THR_7;
      pgau16.pgab16.s_P2_THR_8=P2_THR_8;
      pgau16.pgab16.s_P2_THR_9=P2_THR_9;
      pgau16.pgab16.s_P2_THR_10=P2_THR_10;
      pgau16.pgab16.s_P2_THR_11=P2_THR_11;
      pgau16.pgab16.s_P2_THR_12=P2_THR_12;
      pgau16.pgab16.s_P2_THR_13=P2_THR_13;
      pgau16.pgab16.s_P2_THR_14=P2_THR_14;
      pgau16.pgab16.s_P2_THR_15=P2_THR_15;
   
      
   delay_us(100);
   return;
}


I debugged the code but found that it doesn't write all the bytes. When I looked to "pgau16.pga_bufdizi16" array on watch, I saw this result.

Code:
"\x 55\x 10\x 88\x 88\x 88\x 88\x 88\x 88\x 84\x 21\x 8\x 0\x 88\x 88\x 88\x 88\x 88\x 88\x 0\x 85\x 21\x 0\x 84\x 21\x 8\x 42\x 0\x 0\x 0\x 75\x 1b\x 76\x 20\x 0\x 0"


But it have to like this:
Code:
"\x 55\x 10\x 88\x 88\x 88\x 88\x 88\x 88\x 84\x 21\x 08\x 42\x 10\x 80\x 80\x 80\x 80\x 00\x 88\x 88\x 88\x 88\x 88\x 88\x 84\x 21\x 08\x 42\x 10\x 80\x 80\x 80\x 80\x 0"


Where is the problem? Why does not it write all? Why is it only writing part of it?
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Fri Aug 14, 2020 1:11 pm     Reply with quote

You don't show any variables being defined called P1_THR_0 etc., but
write to these. If these are constant initialisations, why not #define
these?.
I'd actually print the values, rather than using watch. Unfortunately, the
debugger quite often seems to give 'issues' when dealing with larger objects.
As a general comment, it always seems to be more reliable, if you keep to
the original C requirement to declare variables at the start of the code
sections rather than mid code.
What chip?.
What compiler version?.
Then we can test and see if the problem is repeatable.
L.T.



Joined: 24 Jul 2020
Posts: 62

View user's profile Send private message

PostPosted: Sun Aug 16, 2020 11:11 pm     Reply with quote

Actually, type of variables described above. I didn't write on my message, that is my fault.

Code:
   BYTE P1_THR_0 = 0x88;
   BYTE P1_THR_1 = 0x88;
   BYTE P1_THR_2 = 0x88;
   BYTE P1_THR_3 = 0x88;
   BYTE P1_THR_4 = 0x88;
   BYTE P1_THR_5 = 0x88;
   BYTE P1_THR_6 = 0x84;
   BYTE P1_THR_7 = 0x21;
   BYTE P1_THR_8 = 0x08;
   BYTE P1_THR_9 = 0x42;
   BYTE P1_THR_10 = 0x10;
   BYTE P1_THR_11 = 0x80;
   BYTE P1_THR_12 = 0x80;
   BYTE P1_THR_13 = 0x80;
   BYTE P1_THR_14 = 0x80;
   BYTE P1_THR_15 = 0x80;
   BYTE P2_THR_0 = 0x88;
   BYTE P2_THR_1 = 0x88;
   BYTE P2_THR_2 = 0x88;
   BYTE P2_THR_3 = 0x88;
   BYTE P2_THR_4 = 0x88;
   BYTE P2_THR_5 = 0x88;
   BYTE P2_THR_6 = 0x84;
   BYTE P2_THR_7 = 0x21;
   BYTE P2_THR_8 = 0x08;
   BYTE P2_THR_9 = 0x42;
   BYTE P2_THR_10 = 0x10;
   BYTE P2_THR_11 = 0x80;
   BYTE P2_THR_12 = 0x80;
   BYTE P2_THR_13 = 0x80;
   BYTE P2_THR_14 = 0x80;
   BYTE P2_THR_15 = 0x80;


I'm using PIC16F18346 and CCS C Compiler v5.076 and MPLABX IDE v5.05. And I dont know how can I print values to computer's screen? How do I connect the UART pins to the computer? I am using the PIC16F18346 microcontroller on the Microchip Curiosity test board.
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Mon Aug 17, 2020 2:32 am     Reply with quote

Right, several things here:

First, what you post is incredibly wasteful of memory space. You have fixed
initialisation values, that you copy into RAM, and then copy to the structure.
Why?. Just #define the initialisation values and then write them directly
to the structure. Saves 32 bytes of RAM straight away.
Then there is a big issue. You do realise that declaring pgau16 as you
do in the function, means it only 'exists' as a variable, while you are inside
the pga460_initThresholds subroutine. As soon as you exit this routine,
this variable ceases to exist, and the memory it uses can be re-used?.
So the bytes being 'wrong' outside this routine, will be totally correct.
If this variable needs to be re-accessed later, then it needs to be declared
as 'static' (which then means it will still exist after the function exits). If
it is to be used anywhere else, it needs to be globally declared.

The curiosity board has RX and TX on J34. For standard serial print, you
would need either a RS232 port on your PC, with suitable level translator
circuitry, or one of the little USB to TTL serial modules, and connect the
pins from this to these pins on the board.
However assuming you are using ICD, it may also be possible to print via
the ICD. This depends on what actual debugger you are using to connect
to the chip.
L.T.



Joined: 24 Jul 2020
Posts: 62

View user's profile Send private message

PostPosted: Mon Aug 17, 2020 5:45 am     Reply with quote

PGA's register names is described as byte firstly. And default settings is loaded to registers at the same time. Then, I used these registers in different places. I have functions more than one and the same register can be used in more than one function. Different values can be loaded in each different function. When you think this way, do you still think I misidentified? Is the cause of the error due to this? Did it work when you experimented with the code I sent?
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Mon Aug 17, 2020 6:59 am     Reply with quote

If you want to use variables in multiple locations, they need to be globally
declared. As you currently show, they are not, which means the RAM they
contain can and will be re-used for other things as soon as you leave the
function. This will result in bytes containing the wrong values.
This almost certainly is what is causing the 'problem' you have....
L.T.



Joined: 24 Jul 2020
Posts: 62

View user's profile Send private message

PostPosted: Mon Aug 17, 2020 8:38 am     Reply with quote

Ttelmah wrote:
If you want to use variables in multiple locations, they need to be globally
declared. As you currently show, they are not, which means the RAM they
contain can and will be re-used for other things as soon as you leave the
function. This will result in bytes containing the wrong values.
This almost certainly is what is causing the 'problem' you have....


Could you please show me how to define it on my code as an example?
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Mon Aug 17, 2020 12:01 pm     Reply with quote

Read a basic C book:

Code:

//processor setup

type name; //this variable is global

void function(someything)
{
    type name; //this variable is local and only exists while the function
    //exists

    static type name; //this variable is also local, but exists all the time

}
L.T.



Joined: 24 Jul 2020
Posts: 62

View user's profile Send private message

PostPosted: Mon Aug 17, 2020 11:12 pm     Reply with quote

Ttelmah wrote:
Read a basic C book:

Code:

//processor setup

type name; //this variable is global

void function(someything)
{
    type name; //this variable is local and only exists while the function
    //exists

    static type name; //this variable is also local, but exists all the time

}


In the beginning, I defined all the registers globally in byte type. I wrote these definitions under processor setup.
Then, I changed it by reassigning values in functions. I think, it is local. Are you telling me to make the changes I made here as static? Do I get it right?
I don't understand what you want me to change. Can you show me where you mean on the codes I sent?
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Tue Aug 18, 2020 1:21 am     Reply with quote

The correct thing to do is:
1) All 'global' things (anything accessed in more than one location), should
be global.
2) Everything that is only used inside a single routine should be declared
locally to the routine.
3) Any 'local'' variables that need to maintain their contents between
successive calls to the routines, or values that are referenced (by pointer)
from outside the routine, should be declared as 'static'.
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