pic24 basic data type, uint8_t or uint16_t

Thread Starter

bug13

Joined Feb 13, 2012
2,002
Hi guys

First time using a pic24 here, I know what I should use uint8_t on a pic18 where possible, because pic18 is a 8bit mcu, and this is most efficient. It's the basic data type in 8bit mcu, eg the ALU can manipulate 8bit data in one instruction. Where if I need to use an uint16_t, it's actual combining two uint8_t, and it take more cycles.

Now if I understand correctly, pic24 is a 16bit mcu, should I be using uint16_t where possible? For the same reasons mention above, or can I use both uint8_t and uint16_t, because the MCU will just treat uint8_t as a uint16_t??

Thanks guys.
 

nsaspook

Joined Aug 27, 2009
13,312
Hi guys

First time using a pic24 here, I know what I should use uint8_t on a pic18 where possible, because pic18 is a 8bit mcu, and this is most efficient. It's the basic data type in 8bit mcu, eg the ALU can manipulate 8bit data in one instruction. Where if I need to use an uint16_t, it's actual combining two uint8_t, and it take more cycles.

Now if I understand correctly, pic24 is a 16bit mcu, should I be using uint16_t where possible? For the same reasons mention above, or can I use both uint8_t and uint16_t, because the MCU will just treat uint8_t as a uint16_t??

Thanks guys.

A little experiment:
Code:
50:                /*
51:                            Main application
52:                 */
53:                uint8_t f1 = 13, f2 = 31, res_8;
54:                uint16_t f3 = 14, f4 = 32, res_16;
55:              
56:                int main(void)
57:                {
0002F0  FA0000     LNK #0x0
58:                    // initialize the device
59:                    SYSTEM_Initialize();
0002F2  070057     RCALL SYSTEM_Initialize
60:              
61:                    while (1) {
62:                        // Add your application code
63:                        res_8 = f1 + f2;
0002F4  208201     MOV #0x820, W1
0002F6  784091     MOV.B [W1], W1
0002F8  BFC821     MOV.B 0x821, WREG
0002FA  40C000     ADD.B W1, W0, W0
0002FC  B7E826     MOV.B WREG, res_8
64:                        res_8 = f1 + f4;
0002FE  804120     MOV 0x824, W0
000300  784080     MOV.B W0, W1
000302  BFC820     MOV.B 0x820, WREG
000304  40C000     ADD.B W1, W0, W0
000306  B7E826     MOV.B WREG, res_8
65:                        res_16 = f3 + f4;
000308  804111     MOV 0x822, W1
00030A  804120     MOV 0x824, W0
00030C  408000     ADD W1, W0, W0
00030E  884140     MOV W0, res_16
66:                        res_16 = f3 + f2;
000310  BFC821     MOV.B 0x821, WREG
000312  FB8080     ZE W0, W1
000314  804110     MOV 0x822, W0
000316  408000     ADD W1, W0, W0
000318  884140     MOV W0, res_16
67:                    }
00031A  37FFEC     BRA .L2
68:              
69:                    return 1;
70:                }
 

Thread Starter

bug13

Joined Feb 13, 2012
2,002
A little experiment:
Code:
50:                /*
51:                            Main application
52:                 */
53:                uint8_t f1 = 13, f2 = 31, res_8;
54:                uint16_t f3 = 14, f4 = 32, res_16;
55:             
56:                int main(void)
57:                {
0002F0  FA0000     LNK #0x0
58:                    // initialize the device
59:                    SYSTEM_Initialize();
0002F2  070057     RCALL SYSTEM_Initialize
60:             
61:                    while (1) {
62:                        // Add your application code
63:                        res_8 = f1 + f2;
0002F4  208201     MOV #0x820, W1
0002F6  784091     MOV.B [W1], W1
0002F8  BFC821     MOV.B 0x821, WREG
0002FA  40C000     ADD.B W1, W0, W0
0002FC  B7E826     MOV.B WREG, res_8
64:                        res_8 = f1 + f4;
0002FE  804120     MOV 0x824, W0
000300  784080     MOV.B W0, W1
000302  BFC820     MOV.B 0x820, WREG
000304  40C000     ADD.B W1, W0, W0
000306  B7E826     MOV.B WREG, res_8
65:                        res_16 = f3 + f4;
000308  804111     MOV 0x822, W1
00030A  804120     MOV 0x824, W0
00030C  408000     ADD W1, W0, W0
00030E  884140     MOV W0, res_16
66:                        res_16 = f3 + f2;
000310  BFC821     MOV.B 0x821, WREG
000312  FB8080     ZE W0, W1
000314  804110     MOV 0x822, W0
000316  408000     ADD W1, W0, W0
000318  884140     MOV W0, res_16
67:                    }
00031A  37FFEC     BRA .L2
68:             
69:                    return 1;
70:                }
I don't know much about assembly, but I can count instructions. It looks like using uint8_t need 5 instructions. but uint16_t needs 4 instructions. 25% slower if using uint8_t
 

nsaspook

Joined Aug 27, 2009
13,312
I don't know much about assembly, but I can count instructions. It looks like using uint8_t need 5 instructions. but uint16_t needs 4 instructions. 25% slower if using uint8_t
That why the ANSI C int is normally the native word size (>=16-bits) of the processor.
"Plain ints have the natural size suggested by the architecture of the execution environment." Where natural is usually the accumulator size with some exceptions for 8-bit or smaller and odd processors.

In theory, everything in C and C++ depends on the compiler and only on the compiler. To be a highly efficient language hardware considerations must be taken into account.
 

Thread Starter

bug13

Joined Feb 13, 2012
2,002
That why the ANSI C int is normally the native word size (>=16-bits) of the processor.
"Plain ints have the natural size suggested by the architecture of the execution environment." Where natural is usually the accumulator size with some exceptions for 8-bit or smaller and odd processors.

In theory, everything in C and C++ depends on the compiler and only on the compiler. To be a highly efficient language hardware considerations must be taken into account.
Don't know about the natural size, good to know about that, thanks!
 
Top