View previous topic :: View next topic |
Author |
Message |
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
Ancient vs current CCS struct differences? |
Posted: Mon Sep 10, 2018 8:25 pm |
|
|
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
|
|
Posted: Mon Sep 10, 2018 11:43 pm |
|
|
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
|
|
Posted: Tue Sep 11, 2018 6:43 pm |
|
|
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
|
|
Posted: Wed Sep 12, 2018 12:23 pm |
|
|
I think that's the best explanation. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Sat Sep 15, 2018 12:55 am |
|
|
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
|
|
Posted: Sat Sep 22, 2018 1:18 pm |
|
|
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: 19520
|
|
Posted: Sat Sep 22, 2018 1:54 pm |
|
|
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
|
|
Posted: Mon Sep 24, 2018 9:00 pm |
|
|
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: 1349
|
|
Posted: Fri Sep 28, 2018 12:29 pm |
|
|
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);
}
|
|
|
|
|