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

Ancient vs current CCS struct differences?

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



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

Ancient vs current CCS struct differences?
PostPosted: Mon Sep 10, 2018 8:25 pm     Reply with quote

About 1998 I wrote this code which compiled and ran fine under PCB version 2.213.
Code:

struct {
  short   LEDBlink;         /* 1 enables blinking of LEDs */
  short   Redbit;            /* 1 turns on Red LED */
  short   Greenbit;         /* 1 turns on Green LED */
  short   D_Trig;            /* 1 when Diver Trigger is active */
  short   PressE;             /* 1 when pressure readings are enabled */
  int     Reserved: 3;        /* make sure rest of byte is unused */
} Misc_bits;

output_bit(RedLED,~input(RedLED)& Misc_bits.Redbit);
Misc_bits &= 0b11111000;

But this code does not compile under my current PCB 5.060. The last line setting Misc_bits as a whole gives Error 36 "A numeric expression must appear here". Note that the struct is 1 byte long. I suppose I could try to install PCB version 2.213 on Windows10 but I would rather move forwards than backwards.

Reading the new manual it seems I should be using a struct in a union to access a byte either as an int8 or as bits. But if I try the union example straight out of the manual it fails to compile.
Code:

union u_tab{
   int ival;
   long ival;
   float ival;
};

Gives the Error 31 "Identifier is already used in this scope" for long ival.

Has the behavior of structs and unions changed in CCS? Do unions work in PCB 5.060? Is there a better way to do this?

Here is a short program that used to compile and run under PCB version 2.213.

Code:

#include <16C58a.H>
#include <CTYPE.H>
#fuses HS,WDT,NOPROTECT
#use standard_io(a)
#use standard_io(b)
#use delay(clock=7372800)   /* 7.3728 MHz clock */

#byte   portB = 6
#define   Sio         PIN_B0   /* Bidirectional serial line to deckbox */
#use RS232(baud= 1200, xmit=PIN_B0, rcv=PIN_B0, invert)//#use RS232(baud= 1200, xmit=PIN_B1, rcv=PIN_B0)
#define DTrig      PIN_B1   /* Diver Trigger input */
#define RedLED      PIN_B2   /* Red diver trigger LED */
#define GrnLED      PIN_B3   /* Green diver trigger LED */
#define CSGain      PIN_B4   /* Chip Select\ for Gain Control DS1804 */
#define CSAD      PIN_B5   /* Chip select\ for A/D MAX187 */
#define Dclk      PIN_B6   /* Data Clock for DS1804 and MAX187 */
#define Data      PIN_B7   /* MAX187 data and DS1804 Up/Down */

struct {
short   LEDBlink;         /* 1 enables blinking of LEDs */
short   Redbit;            /* 1 turns on Red LED */
short   Greenbit;         /* 1 turns on Green LED */
short   D_Trig;            /* 1 when Diver Trigger is active */
short   PressE;             /* 1 when pressure readings are enabled */
int     Reserved: 3;        /* make sure rest of byte is unused */
} Misc_bits;

char   comms;            /* incomming char buffer */

main() {
   Misc_bits.PressE = 0;   /* disable pressure readings until cal is read */
   setup_counters(RTCC_INTERNAL,WDT_2304MS); /* RTCC to time Thermistor */
   output_bit(Sio,Misc_bits.D_Trig);   /* Send diver trigger flag status */
   while (true) {         /* wait for input */
      if(kbhit()) {      /* start of serial message */
         comms = getch();
         comms &= 0b00000111;            /* only 3 LSBs are setable */
         Misc_bits &= 0b11111000;
         Misc_bits |= comms;
         Misc_bits.LEDBlink = Misc_bits & 0b00000010;
      }
      if (Misc_bits.LEDBlink) {         /* If Blink enabled, toggle enabled LEDS */
         output_bit(RedLED,~input(RedLED)& Misc_bits.Redbit);
         output_bit(GrnLED,~input(GrnLED)& Misc_bits.Greenbit);
      }
      delay_ms(10);
   }
}

_________________
The search for better is endless. Instead simply find very good and get the job done.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Sep 10, 2018 11:43 pm     Reply with quote

I was able to make it compile, and get apparent good results in the .LST
file by making the changes shown in bold below:
Quote:
(int8)Misc_bits &= 0b11111000;
(int8)Misc_bits |= comms;
Misc_bits.LEDBlink = (int1)((int8)Misc_bits & 0b00000010);

I'm not sure if you're doing your 3rd line correctly. By ANDing with 10
you are testing to see if Redbit is set = 1. If so, then set LEDBlink=1.
Is that really what you want to do ? If it is, then casting the expression
to a boolean (ie., True/False) with (int1) is the way to go.
SherpaDoug



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

PostPosted: Tue Sep 11, 2018 6:43 pm     Reply with quote

Thanks, that fixed things. But trying to understand the problem, I guess a struct doesn't have a data type unless you force one upon it by casting? I guess the old compiler didn't check and just did the obvious, and that worked.
_________________
The search for better is endless. Instead simply find very good and get the job done.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Sep 12, 2018 12:23 pm     Reply with quote

I think that's the best explanation.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Sat Sep 15, 2018 12:55 am     Reply with quote

As some comments to this:

The reason the union did not work, was that you are calling all three parts the same name. Once the name is used inside the union, the other parts have to have different names. The example uses ival, lval, and fval, not all called ival as you post....

About 5.050ish, CCS introduced 'strong typing' for pointers. So it'll complain if pointer types do not match. It looks as if at the same time they allocated a 'type' to the structure name (probably void *), so if used as a pointer it has to be cast. However...
Technically in C, the structure name is not a pointer to the structure. It is actually an alias for the user defined type created by the structure. So the correct way to get it's address is:

&Misc_bits

it does still seem to be accepting it as the pointer (with suitable casting), but better really to use the & syntax that will then be correct C.
SherpaDoug



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

PostPosted: Sat Sep 22, 2018 1:18 pm     Reply with quote

Ttelmah, would this be proper by-the-book and easily understood C syntax?

Code:
struct {
short   LEDBlink;         /* 1 enables blinking of LEDs */
short   Redbit;            /* 1 turns on Red LED */
short   Greenbit;         /* 1 turns on Green LED */
short   D_Trig;            /* 1 when Diver Trigger is active */
short   PressE;             /* 1 when pressure readings are enabled */
int     Reserved: 3;        /* make sure rest of byte is unused */
} Misc_bits;

union miscellanious{
   int Misc_bits;
   int Misc_byte;
};

output_bit(RedLED, Misc_bits.Redbit);
Misc_byte &= 0xF7;

_________________
The search for better is endless. Instead simply find very good and get the job done.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Sat Sep 22, 2018 1:54 pm     Reply with quote

You don't have a variable called 'Misc_byte'. You have one called miscellanious. However this does not talk to the same memory as your Misc_bits.

Code:

struct bts {
short   LEDBlink;         /* 1 enables blinking of LEDs */
short   Redbit;            /* 1 turns on Red LED */
short   Greenbit;         /* 1 turns on Green LED */
short   D_Trig;            /* 1 when Diver Trigger is active */
short   PressE;             /* 1 when pressure readings are enabled */
int     Reserved: 3;        /* make sure rest of byte is unused */
}

union {
   struct bts bits;
   unsigned int8  byte;
} Misc;

//Then

output_bit(RedLED, Misc.bits.Redbit); //Note . not _
Misc.byte &=0xF7;


This declares a union called Misc, containing an unsigned int8, and a struct bts, in the same memory space.
SherpaDoug



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

PostPosted: Mon Sep 24, 2018 9:00 pm     Reply with quote

For future readers, here is a fully compilable example of how to use a struct in a union.
Code:
#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, BRGH1OK)
#define RedLED    PIN_B2
#define GrnLED    PIN_B3

char comms;

struct bitalloctype {
   short LEDBlink;
   short Redbit;
   short Greenbit;
   int Reserved: 5;
};  //bitallocvar;

union {
   struct bitalloctype mbits;
   int8 mbyte;
} Misc;

void main(void)
{
   comms=getc();
   output_bit(RedLED, Misc.mbits.Redbit);
   Misc.mbyte &= 0xF7;
   printf(Misc.mbyte);
}

_________________
The search for better is endless. Instead simply find very good and get the job done.
jeremiah



Joined: 20 Jul 2010
Posts: 1314

View user's profile Send private message

PostPosted: Fri Sep 28, 2018 12:29 pm     Reply with quote

As an additional note, CCS does support anonymous structs, so you can change it up a bit if you like:

Code:

#define RedLED    PIN_B2
#define GrnLED    PIN_B3

union {
   struct {
      short LEDBlink;
      short Redbit;
      short Greenbit;
      int Reserved: 5;
   }; 
   int8 mbyte;
} Misc;

void main(void)
{
   output_bit(RedLED, Misc.Redbit);
   Misc.mbyte &= 0xF7;
   printf(Misc.mbyte);
}
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