|
|
View previous topic :: View next topic |
Author |
Message |
ulg
Joined: 09 May 2019 Posts: 24
|
PIC18F252, CCS-IDE 3.249 |
Posted: Thu May 09, 2019 9:24 am |
|
|
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
|
|
Posted: Thu May 09, 2019 9:33 am |
|
|
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
|
|
Posted: Thu May 09, 2019 9:34 am |
|
|
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
|
|
Posted: Thu May 09, 2019 9:58 am |
|
|
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: 19520
|
|
Posted: Thu May 09, 2019 10:03 am |
|
|
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
|
|
Posted: Fri May 10, 2019 1:21 am |
|
|
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
|
|
Posted: Fri May 10, 2019 1:30 am |
|
|
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: 19520
|
|
Posted: Fri May 10, 2019 1:55 am |
|
|
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. |
|
|
|
|
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
|