Noob: C port - Page 1
Forum section: electronics / general

author: PerranOak
author_rank: Frequent Contributor
timestamp: October 01, 2019, 04:06:34 pm
content: In my PIC C programming course I've come across a command that is not explained:static bit button @ (unsigned) &PORTA*8+1;What I think I know is:the code is to assign the name "button" to RA1,staticmeans that the value of "button" is to be retained between functions,unsignedmeans that the value of "button" has no mathematical sign andPORTAis port A(!)I don't understand what these are doing:bit,@,&(though I believe this is "logical .AND."),*8,1(I guess this refers to bit 1 of PORTA).I'm not necessarily looking for descriptions (though all help is welcome) but where do I look to understand these things? I have Kernighan & Ritchie but this is not really a reference.Cheers.

author: ledtester
author_rank: Super Contributor
timestamp: October 01, 2019, 04:39:28 pm
content: The @-sign is a compiler extension which allows you to specify the address of a global variable:https://stackoverflow.com/questions/15955856/sign-in-c-variable-declarationIn this case it looks like a bit-variable is being defined at a specific bit-address - hence the PORTA*8+1 expression.

author: sokoloff
author_rank: Super Contributor
timestamp: October 01, 2019, 04:45:38 pm
content: & is "address of"(&& is "logical AND")Read that as roughly:Take the address of PORTA (&PORTA), multiply by 8 (*8), add 1 (+1) to get to the bit you want.

author: SiliconWizard
author_rank: Super Contributor
timestamp: October 01, 2019, 06:06:58 pm
content: Additionally, '&' has two forms, unary and binary. Reminds me of another thread...

author: PerranOak
author_rank: Frequent Contributor
timestamp: October 03, 2019, 01:08:57 pm
content: Cheers all.So, why is it "*8"? Does each bit have an address?

author: ledtester
author_rank: Super Contributor
timestamp: October 03, 2019, 01:40:57 pm
content: Yes - it's a bit address not a byte address. The first byte (byte address 0) contains bit addresses 0 through 7, the second byte contains bit addresses 8 through 15, etc.

author: PerranOak
author_rank: Frequent Contributor
timestamp: October 03, 2019, 01:54:05 pm
content: Oh no! Another thing!Thank you.

author: Ian.M
author_rank: Super Contributor
timestamp: October 03, 2019, 02:08:15 pm
content: Its hard to be specific when you are discussing non-standard extensions to a C compiler and the O.P. hasn't specified *which* compiler! However that looks like HiTech PIC C or older XC8 syntax, so I'm going to assume that's whats being used. If you are using something else, ignore this and post the actual compiler make and version you are using.No, a HiTech PIC C or XC8 variable ofbittype does *NOT* have an address in the C sense of address - you cant make a pointer to a bit or have an array of them. However the compiler needs some way of locating which bit in which byte to use when defining them at an absolute address so when applied to abit, the@addressing attribute takes a parameter of 8 times the byte address + the bit number within the byte. Its only usable for@- *NOTHING* else uses bit 'addresses' and they must always evaluate to a compile-time constant expression.N.B. thebittype is very non-portable. The modern way of declaring that input bit under later HiTech C versions or XC8 would be:Code:#define BUTTON PORTAbits.RA1which relies on you having #included the compiler's standard headers. BUTTON is in caps because that's the convention for a name that's a #defined alias. You'd need to make all other instances of it the same case. If you need single bit flag variables, you'd do best to pack them as bitfields in a struct.XC8 CCI syntax has depreciatedbitand@, and that's the default (for C99 compatibility) from XC8 2.0 onwards. You can however enable backwards compatibility, and still use it.

author: PerranOak
author_rank: Frequent Contributor
timestamp: October 03, 2019, 02:39:04 pm
content: Cheers for that.You were right, it is XC8 and the version used by my course manual is v1.35 though I have a later version.Is "bit" a variable type like "int" and "long"? You don't see it in those lists.PSI still don't get why it's "*8".

author: Siwastaja
author_rank: Super Contributor
timestamp: October 03, 2019, 03:23:39 pm
content: Quote from: PerranOak on October 03, 2019, 02:39:04 pmNo, and not even close.You need to understand that you arenotwriting C, but a C-like custom language. It's more than extensions or attributes; it has fundamental differences in basics.You need to refer to the documentation of the language.

author: SiliconWizard
author_rank: Super Contributor
timestamp: October 03, 2019, 03:47:58 pm
content: Quote from: Siwastaja on October 03, 2019, 03:23:39 pmExactly.

author: ledtester
author_rank: Super Contributor
timestamp: October 03, 2019, 04:23:02 pm
content: Quote from: PerranOak on October 03, 2019, 02:39:04 pmIt's a single bit - i.e. either a 0 or 1.It's intended to be used like this:Code:static bit LCD_RS @ ((unsigned)&PORTB*8+1); // RB1 -> LCD_RS...LCD_RS =1; // Set RB1 to 1The compiler will generate code to set the RB1 bit to 1 (without affecting any of the other bits in the RB register.)However, it is not standard C and there are alternatives which are compatible with the C standard:https://www.microchip.com/forums/m1088415.aspxQuoteHave a look at the data memory map of the PIC16F684:Each file address contains a byte. The file address of PORTA is 0x05, so the 0-th bit of PORTA is the 5*8+0 = 40-th bit of the data file. The 1st bit of PORTA is the 41-st bit of the file, etc.To find the bit-offset you have to multiply the byte-address by 8 and add which bit you want to address.

author: PerranOak
author_rank: Frequent Contributor
timestamp: October 04, 2019, 09:53:33 am
content: Thank you ledtester that is very clear. So the effect of "bit" is to treat the memory addresses not as bytes but as bits.So, if the address you want is 5 bytes in, then (with 8-bits per byte) it's 5*8=40 bits in. Got it!Of course, my problem is that (since I'm at the beginning) I don't know what is standard C and what is uC specific.Siwastaja: the "documentation of the language"; where would I find this? I have C books but these are no good since, as you pointed out, this is not C and I've looked in the XC8 manual but couldn't really get it - not like I do now thanks to ledtester.

author: sokoloff
author_rank: Super Contributor
timestamp: October 04, 2019, 01:43:30 pm
content: I think K&R you cited is a great reference. It’s how I learned the formal part of C. Then, lots of coding teaches you the practical application while you occasionally need the reference material.As far as I can see, most of what you’re going to see is bog standard C. The @ bit addressing is compiler-specific.

author: Ian.M
author_rank: Super Contributor
timestamp: October 04, 2019, 05:54:19 pm
content: +1 for K&R, 2nd ed. but that only covers C up to ANSI C89 standard. Prior to the release of XC8 v2.0, that was fine for 8 bit PICs as the XC8 v1.x compiler was a C89 one with *some* C99 extensions. However XC8 v2.0 upwards defaults to full ISO C99 mode.You'll probably also want a copy of the applicable C standards. The ANSI C89/ISO C90, and ISO C99 standards are payware but as they have been superceeded by ISO C11 and C18, you can probably find free eBook or PDF copies floating around. The drafts of the standards are freely available and unless you are a C language lawyer are plenty good enough for everyday use.Seehttp://port70.net/~nsz/c/for indexed HTML versions of the drafts.

author: SiliconWizard
author_rank: Super Contributor
timestamp: October 04, 2019, 06:30:59 pm
content: Yes.My additional tip: don't learn a language by fiddling with MCUs first. That will yield to improper learning, wrong notions, bad style, quirks, incomplete knowledge, etc.It's like willing to learn architecture by playing with Lego.