Topics Topics Edit Profile Profile Help/Instructions Help Member List Member List  
Search Last 1|3|7 Days Search Search Tree View Tree View  

C code gotcha

:: EPE Chat Zone ­:: ­Radio Bygones Message Board :: » EPE Chat Zone » Archive through 20 February, 2016 » C code gotcha « Previous Next »

  Thread Last Poster Posts Pages Last Post
  ClosedClosed: New threads not accepted on this page        

Author Message
Top of pagePrevious messageNext messageBottom of page Link to this message

hackinblack
Frequent Contributor
Username: hackinblack

Post Number: 669
Registered: 09-2006

Rating: N/A
Votes: 0 (Vote!)

Posted on Tuesday, 05 January, 2016 - 12:59 pm:   Edit Post Delete Post Print Post    Move Post (Moderator/Admin Only)

thinking in assembly;when a 1 is written to a port it sets the pins Hi and vice-versa.Then writing in C,the following code 'looks' OK;but it won't work properly...
code:

PORTC = 0;
Delay_ms(10000);
PORTC = 1;
Delay_ms(10000);

although it looks OK the 0 and 1 are interpreted as DECIMAL 0 and 1....or 0b00000000 0b00000001
this will only set bit 0 of portC high!
NOT THE WHOLE PORT!!!

However,this WILL work:-
PORTC = 0;
TRISC = 0;
while(1)
{
PORTC = ~PORTC;
Delay_ms(1000);

as decimal 0 is binary '0b00000000' (all OFF) and its value when toggled
by the ~ switch is 0b11111111 (all ON)
Top of pagePrevious messageNext messageBottom of page Link to this message

billy
Frequent Contributor
Username: billy

Post Number: 82
Registered: 12-2012

Rating: N/A
Votes: 0 (Vote!)

Posted on Tuesday, 05 January, 2016 - 01:21 pm:   Edit Post Delete Post Print Post    Move Post (Moderator/Admin Only)

Yes exactly. You need to write
PORTC = 0xff;
Top of pagePrevious messageNext messageBottom of page Link to this message

alexr
Frequent Contributor
Username: alexr

Post Number: 269
Registered: 02-2008

Rating: N/A
Votes: 0 (Vote!)

Posted on Tuesday, 05 January, 2016 - 04:45 pm:   Edit Post Delete Post Print Post    Move Post (Moderator/Admin Only)

Better yet would be;

#define Hi 0xFF
#define Lo 0x00

PORTC = Lo;
Delay_ms(10000);
PORTC = Hi;
Delay_ms(10000);

(Message edited by alexr on 05 January, 2016)
Alex
Top of pagePrevious messageNext messageBottom of page Link to this message

741
Frequent Contributor
Username: 741

Post Number: 739
Registered: 08-2005


Rating: N/A
Votes: 0 (Vote!)

Posted on Tuesday, 05 January, 2016 - 06:08 pm:   Edit Post Delete Post Print Post    Move Post (Moderator/Admin Only)

 
Maybe:

PORTC = ((uint8_t)(0x01)) << SOME_BIT_POS; //8-bit PORT, PIC16F etc

PORTC = ((uint16_t)(0x0001)) << SOME_BIT_POS; //16-bit PORT, PIC24F etc

You can even wrap it in a macro.

If you use PIC, I think you can use
// 76543210 To aid code reading
MOVLW PORTC, 0b10110001 //Set bits 7,5,4,0
Top of pagePrevious messageNext messageBottom of page Link to this message

bowden_p
Frequent Contributor
Username: bowden_p

Post Number: 478
Registered: 01-2006

Rating: N/A
Votes: 0 (Vote!)

Posted on Tuesday, 05 January, 2016 - 08:52 pm:   Edit Post Delete Post Print Post    Move Post (Moderator/Admin Only)

Hi 741,
If you are talking MPASM for the 'MOVLW' statement, the operand 'PORTC,0b10110001' woun't be much liked by the assembler, it's expecting a value which is between 0 and 255 decimal!!
Maybe :-
movlw b'10110001' ; Set bits 7,5,4,0.
movwf PORTC

It's surprising what looks sensible in code, may or may not be acceptable to the assembler, then does something rather different in practice.

With regards, Paul.
Top of pagePrevious messageNext messageBottom of page Link to this message

741
Frequent Contributor
Username: 741

Post Number: 741
Registered: 08-2005


Rating: N/A
Votes: 0 (Vote!)

Posted on Tuesday, 05 January, 2016 - 09:35 pm:   Edit Post Delete Post Print Post    Move Post (Moderator/Admin Only)

Hi Paul,

It is a good while since I used assembler, but -

From "16-Bit Assembler, Linker and Utilities User’s Guide" (DS52106A-page 38)

3.5.1.1 INTEGERS
A binary integer is ‘0b’ or ‘0B’ followed by zero or more of the binary digits ‘01’.
An octal integer is ‘0’ followed by zero or more of the octal digits ‘01234567’.
A decimal integer starts with a non-zero digit followed by zero or more decimal digits
‘0123456789’.
A hexadecimal integer is ‘0x’ or ‘0X’ followed by one or more hexadecimal digits
‘0123456789abcdefABCDEF’.
To denote a negative integer, use the prefix operator ‘-’.


Regards,
Stephen
Top of pagePrevious messageNext messageBottom of page Link to this message

basementboy
Frequent Contributor
Username: basementboy

Post Number: 286
Registered: 05-2012

Rating: N/A
Votes: 0 (Vote!)

Posted on Tuesday, 05 January, 2016 - 10:52 pm:   Edit Post Delete Post Print Post    Move Post (Moderator/Admin Only)

Depending on the PIC, you must use LAT, not port otherwise you get read-modify write errors. If the data sheet shows LAT, use it!
Top of pagePrevious messageNext messageBottom of page Link to this message

cjay
Frequent Contributor
Username: cjay

Post Number: 266
Registered: 10-2013

Rating: N/A
Votes: 0 (Vote!)

Posted on Wednesday, 06 January, 2016 - 11:50 am:   Edit Post Delete Post Print Post    Move Post (Moderator/Admin Only)

I wouldn't have expected PORTC=1 to work in any language.

Similarly if you had typed PORTC=2 I'd only ever expect RC1 to be set.

Convert it to binary and you'll see why.
Top of pagePrevious messageNext messageBottom of page Link to this message

basementboy
Frequent Contributor
Username: basementboy

Post Number: 287
Registered: 05-2012

Rating: N/A
Votes: 0 (Vote!)

Posted on Wednesday, 06 January, 2016 - 12:59 pm:   Edit Post Delete Post Print Post    Move Post (Moderator/Admin Only)

@cjay - that's what I thought too!
I must have misunderstood the OP
Top of pagePrevious messageNext messageBottom of page Link to this message

hackinblack
Frequent Contributor
Username: hackinblack

Post Number: 670
Registered: 09-2006

Rating: N/A
Votes: 0 (Vote!)

Posted on Wednesday, 06 January, 2016 - 11:52 pm:   Edit Post Delete Post Print Post    Move Post (Moderator/Admin Only)

methinks i got a brain-fade moment when i wrote that!confusing setting ports for input or output,with setting the PINS hi or Lo.my internet has been on-off yes-no and i think my head has joined in
an intersting fact,or not,is that the second 'working' code compiles to about 10 words less than the first.
Top of pagePrevious messageNext messageBottom of page Link to this message

hackinblack
Frequent Contributor
Username: hackinblack

Post Number: 671
Registered: 09-2006

Rating: N/A
Votes: 0 (Vote!)

Posted on Thursday, 07 January, 2016 - 10:14 pm:   Edit Post Delete Post Print Post    Move Post (Moderator/Admin Only)

well, i was 'partly' right!;just found a snippet for HiTech-C/XC-8 compiler aimed at a baseline 10/12F PIC on my computer.

GPIObits.GP1 = 1;
OR
GPIO = 0b000010
both set GPIO bit 1 ONLY high.
this was my error (wrong format)

BUT:-
GPIObits.GP1 = 0; //clears just bit1
whereas
GPIO = 0 //clears ALL of GPIO
i was this close
oh well; garbage in,garbage out...

the subject of read-modify-write came up; i also found away of using shadow registers to send the values indirectly to the ports,and avoid this problem.

#include <xc.h>
#include <stdint.h> //standard integer library

uint8_t sGPIO = 0; //shadow copy of GPIO to write a value to

//then, to toggle the required bits:-

sGPIO ^= 0b000010;
GPIO = sGPIO; //copy value to port safely

Administration Administration Log Out Log Out   Previous Page Previous Page Next Page Next Page