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

PIC18F252, CCS-IDE 3.249

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



Joined: 09 May 2019
Posts: 24

View user's profile Send private message

PIC18F252, CCS-IDE 3.249
PostPosted: Thu May 09, 2019 9:24 am     Reply with quote

In order to have at all a debug means at the extension of a Uralt system at hand, I wanted to spend in a Fifo cached debug values alternating to the temperature with the serial interface.

In a first step, I once issued two nibbles of my ms timer and already with it there is a problem:

- I output the two lower nibbles of the 16bit return value,
The two nibbles go out on the RS232 line as well.
- but I give out the middle two Nibble
(time = ((uint16_t) msTime ()) >> 4;), but goes out on the
RS232 cable only the lower nibble
- and finally I give out the top two nibbles (>> 8),
does not send out anything anymore, I permanently have the output "@ 00".


The same thing is then repeated with a local static variable (tick), with the same result - if I send the upper byte of the 16bit variable (>> 8), I see on the RS232 line only "@ 00" - I override the calculated Values with the values that I have
I expect the first run, I get as output also "@ 12", so the problem must be with shift / and / or! Does anyone see my mistake?
Code:

              static signed int tick = 0x1234;

              static uint8_t toggle = 0;

              tick += 7;

              toggle ^= 1;

              if (toggle)

              {

                  uint16_t time;

                  char h, l;
                 
                  //time = ((uint16_t) msTime()) >> 8;

                  time = ((uint16_t) tick);

                  time >>= 8;

                  h = (char) (((time >> 4) & 0xF) | 0x30);

                  l = (char) (((time >> 0) & 0xF) | 0x30);

                  //h = '1';

                  //l = '2';

                  tx_state_a[1] = '@';

                  tx_state_a[2] = h;

                  tx_state_a[3] = l;

                  //tx_state_a[2] = Conv4bitsToAscii(((char) ((time >> 4) & 0xF)));

                  //tx_state_a[3] = Conv4bitsToAscii(((char) ((time >> 0) & 0xF)));

              }


Meanwhile, I've tested the code with the TDN-GCC compiler on the PC, where it works as expected - does anyone have an idea what the CCS-PIC18 compiler does not like in my wording?
Code:

i=00000 => @12
i=00026 => @12
i=00052 => @13
i=00078 => @14
i=00104 => @15
i=00130 => @15
i=00156 => @16
i=00182 => @17
i=00208 => @17
i=00234 => @18
i=00260 => @19
i=00286 => @1:
i=00312 => @1:
i=00338 => @1;
i=00364 => @1<
i=00390 => @1<
i=00416 => @1=
i=00442 => @1>
i=00468 => @1?
i=00494 => @1?
i=00520 => @20
i=00546 => @21
i=00572 => @21
i=00598 => @22
i=00624 => @23
i=00650 => @24
i=00676 => @24
i=00702 => @25
gaugeguy



Joined: 05 Apr 2011
Posts: 303

View user's profile Send private message

PostPosted: Thu May 09, 2019 9:33 am     Reply with quote

static signed int tick = 0x1234;

This is going to be a signed 8 bit value, so only the 0x34 gets loaded into the variable.

Change to
static signed int16 tick = 0x1234;
ulg



Joined: 09 May 2019
Posts: 24

View user's profile Send private message

PostPosted: Thu May 09, 2019 9:34 am     Reply with quote

Here's what the compiler generates at shift 8, shift 4 and without shift.
shift 8:
Code:

....................           {
....................               static unsigned int tick = 0x6934;
....................               static uint8_t toggle = 0;
....................               tick += 7;
0D26:  MOVLW  07
0D28:  MOVLB  1
0D2A:  ADDWF  x02,F
....................               toggle ^= 1;
0D2C:  MOVLW  01
0D2E:  XORWF  x03,F
....................               if (toggle)
0D30:  MOVF   x03,F
0D32:  BZ    0D62
....................               {
....................                   uint16_t time;
....................                   char h, l;
....................                   time = ((uint16_t) tick);
0D34:  MOVFF  102,173
....................                   time >>= 8;
0D38:  CLRF   x73
....................                   //time = ((uint16_t) msTime()) >> 8;
....................                   h = (char) (((time >> 4) & 0xF) | 0x30);
0D3A:  SWAPF  x73,W
0D3C:  MOVWF  00
0D3E:  MOVLW  0F
0D40:  ANDWF  00,F
0D42:  MOVF   00,W
0D44:  ANDLW  0F
0D46:  IORLW  30
0D48:  MOVWF  x74
....................                   l = (char) (((time >> 0) & 0xF) | 0x30);
0D4A:  MOVF   x73,W
0D4C:  ANDLW  0F
0D4E:  IORLW  30
0D50:  MOVWF  x75
....................                   //h = '6';
....................                   //l = '9';
....................                   tx_state_a[1] = '|';
0D52:  MOVLW  7C
0D54:  MOVLB  0
0D56:  MOVWF  xCA
....................                   tx_state_a[2] = h;
0D58:  MOVFF  174,CB
....................                   tx_state_a[3] = l;
0D5C:  MOVFF  175,CC
0D60:  MOVLB  1
....................                   //tx_state_a[2] = scf4bitsToAscii(((char) ((time >> 4) & 0xF)));
....................                   //tx_state_a[3] = scf4bitsToAscii(((char) ((time >> 0) & 0xF)));
....................               }


shift 4:
Code:

....................           {
....................               static unsigned int tick = 0x6934;
....................               static uint8_t toggle = 0;
....................               tick += 7;
0D26:  MOVLW  07
0D28:  MOVLB  1
0D2A:  ADDWF  x02,F
....................               toggle ^= 1;
0D2C:  MOVLW  01
0D2E:  XORWF  x03,F
....................               if (toggle)
0D30:  MOVF   x03,F
0D32:  BZ    0D66
....................               {
....................                   uint16_t time;
....................                   char h, l;
....................                   time = ((uint16_t) tick);
0D34:  MOVFF  102,173
....................                   time >>= 4;
0D38:  SWAPF  x73,F
0D3A:  MOVLW  0F
0D3C:  ANDWF  x73,F
....................                   //time = ((uint16_t) msTime()) >> 8;
....................                   h = (char) (((time >> 4) & 0xF) | 0x30);
0D3E:  SWAPF  x73,W
0D40:  MOVWF  00
0D42:  MOVLW  0F
0D44:  ANDWF  00,F
0D46:  MOVF   00,W
0D48:  ANDLW  0F
0D4A:  IORLW  30
0D4C:  MOVWF  x74
....................                   l = (char) (((time >> 0) & 0xF) | 0x30);
0D4E:  MOVF   x73,W
0D50:  ANDLW  0F
0D52:  IORLW  30
0D54:  MOVWF  x75
....................                   //h = '6';
....................                   //l = '9';
....................                   tx_state_a[1] = '|';
0D56:  MOVLW  7C
0D58:  MOVLB  0
0D5A:  MOVWF  xCA
....................                   tx_state_a[2] = h;
0D5C:  MOVFF  174,CB
....................                   tx_state_a[3] = l;
0D60:  MOVFF  175,CC
0D64:  MOVLB  1
....................                   //tx_state_a[2] = scf4bitsToAscii(((char) ((time >> 4) & 0xF)));
....................                   //tx_state_a[3] = scf4bitsToAscii(((char) ((time >> 0) & 0xF)));
....................               }


one shift:
Code:

....................           {
....................               static unsigned int tick = 0x6934;
....................               static uint8_t toggle = 0;
....................               tick += 7;
0D26:  MOVLW  07
0D28:  MOVLB  1
0D2A:  ADDWF  x02,F
....................               toggle ^= 1;
0D2C:  MOVLW  01
0D2E:  XORWF  x03,F
....................               if (toggle)
0D30:  MOVF   x03,F
0D32:  BZ    0D60
....................               {
....................                   uint16_t time;
....................                   char h, l;
....................                   time = ((uint16_t) tick);
0D34:  MOVFF  102,173
....................                   time >>= 0;
....................                   //time = ((uint16_t) msTime()) >> 8;
....................                   h = (char) (((time >> 4) & 0xF) | 0x30);
0D38:  SWAPF  x73,W
0D3A:  MOVWF  00
0D3C:  MOVLW  0F
0D3E:  ANDWF  00,F
0D40:  MOVF   00,W
0D42:  ANDLW  0F
0D44:  IORLW  30
0D46:  MOVWF  x74
....................                   l = (char) (((time >> 0) & 0xF) | 0x30);
0D48:  MOVF   x73,W
0D4A:  ANDLW  0F
0D4C:  IORLW  30
0D4E:  MOVWF  x75
....................                   //h = '6';
....................                   //l = '9';
....................                   tx_state_a[1] = '|';
0D50:  MOVLW  7C
0D52:  MOVLB  0
0D54:  MOVWF  xCA
....................                   tx_state_a[2] = h;
0D56:  MOVFF  174,CB
....................                   tx_state_a[3] = l;
0D5A:  MOVFF  175,CC
0D5E:  MOVLB  1
....................                   //tx_state_a[2] = scf4bitsToAscii(((char) ((time >> 4) & 0xF)));
....................                   //tx_state_a[3] = scf4bitsToAscii(((char) ((time >> 0) & 0xF)));
....................               }
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu May 09, 2019 9:58 am     Reply with quote

ulg wrote:
Here's what the compiler generates at shift 8, shift 4 and without shift.
shift 8:
.................... {
.................... static unsigned int tick = 0x6934;

Do what gaugeguy told you to do. Change the above line to:
Quote:
static unsigned int16 tick = 0x6934;
Ttelmah



Joined: 11 Mar 2010
Posts: 19491

View user's profile Send private message

PostPosted: Thu May 09, 2019 10:03 am     Reply with quote

Key is this:
Code:

....................                   time = ((uint16_t) tick);
0D34:  MOVFF  102,173


That is a _single byte_ move.

As gaugeguy (and as I'm typing, PCM_Programmer), says, you need
an int16 variable to hold a 16bit value....
ulg



Joined: 09 May 2019
Posts: 24

View user's profile Send private message

PostPosted: Fri May 10, 2019 1:21 am     Reply with quote

Thanks for the quick responses.

I had still checked that in the stdint.h I created (since one of them was not supplied by the compiler) I accidentally defined the int16_t with char and then defined tick as "signed int" to exclude any errors. That this could only be 8bit, I did not get the idea!

Can someone tell me where I can find a useful stdint.h for CCS 3.249 / PIC18F252?
Where can I find the Reference Manual for 3.249?
ulg



Joined: 09 May 2019
Posts: 24

View user's profile Send private message

PostPosted: Fri May 10, 2019 1:30 am     Reply with quote

Using the 2019 CCS Reference Manual, I modified my stdint.h as below.
Does it fit with vs. 3.249?
Code:

#ifndef STDINT_H                                       
#define STDINT_H

typedef signed int8 int8_t;
typedef signed int16 int16_t;
typedef signed int32 int32_t;
typedef unsigned int8 uint8_t;
typedef unsigned int16 uint16_t;
typedef unsigned int32 uint32_t;

#endif
Ttelmah



Joined: 11 Mar 2010
Posts: 19491

View user's profile Send private message

PostPosted: Fri May 10, 2019 1:55 am     Reply with quote

Yes.

The key point is to _never_ assume sizes.

For example 'int', on CCS, is an int8. On most C's it is int16, but on things
like some of the Microsoft languages it is an int32.
It is always better/safer to explicitly use named sizes. So int16, int32 etc.
stdint, is just a way to give some shorter standard names for some of these
(so it is shorter to type uint32_t, than 'unsigned int32').
The lines shown from the 2019 manual can be used if you want in 3.249.
However use these or not, you just need to be using a type that is 16bit
to store a variable that you want to perform 16bit operations on.

Now 'C' historically in K&R, it was said that the default size for an integer
should always be the type that best fitted the processor hardware involved.
So Historically C on a PDP-8, use a 12bit integer. CCS kept to this, since
if you want to write fast code using the processor, the 'best' size is the
one that it handles as a single instruction. So they made 'int' an int8. Later
C's though generally decided to have 'int' always mean an int16, and
ANSI-C's use this as a standard. In fact you can change CCS to use this
by selecting it's 'ANSI' mode. However on 3.249, this is pretty limited.
Much better to just always be explicit on the size you are using. This
allows the best efficiency, and gives you control of the types used.
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