View previous topic :: View next topic |
Author |
Message |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
Question about getenv("BIT:xxx") |
Posted: Thu Oct 08, 2015 10:43 am |
|
|
This code compiles just fine in PCM vs. 5.050 (or really, any version).
Code: | #include <16F887.h>
#fuses INTRC_IO, NOWDT
#use delay(clock=4M)
#bit my_pin=GETENV("BIT:RA0")
//==========================
void main()
{
while(TRUE);
}
|
But the following code fails to compile in PCH (vs. 5.050). It gives the
following error message:
Quote: | *** Error 28 "PCH_Test.c" Line 5(29,30): Expecting an identifier Bad SFR name
|
RA0 is the name of a bit in the 18F4620. Another bit name, such as GIE
works fine. Am I missing something here, or is this a bug ?
Code: |
#include <18F4620.h>
#fuses INTRC_IO, NOWDT
#use delay(clock=4M)
#bit my_pin=GETENV("BIT:RA0")
//==========================
void main()
{
while(TRUE);
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Thu Oct 08, 2015 11:04 am |
|
|
Problem is that RA0, is not a defined bit name. It's PORTA bit 0, so has to be accessed as such:
Code: |
#byte PORTA=getenv("SFR:PORTA")
#bit RA0=PORTA.0
|
I know you don't use the IDE, but the device editor in that, if you select the register map, shows all the bit/register names actually defined. None of the individual register 'numbered' bits are given names as standard on the later chips...
I think part of the reason is that on these you have to make the decision of whether to write to the LAT registers or the PORT registers. So CCS have left it up to us to make the decision. |
|
|
Marttyn
Joined: 06 Mar 2015 Posts: 28 Location: Spain
|
|
Posted: Fri Dec 02, 2016 2:35 pm |
|
|
I was having the same issue.
How can i use the getenv("BIT:xxx")??
Like Ttelmah suggested is how i do now. But has no sense.
The purpose of getenv should be not having to look at the registers. If i want to access some bit from some register, i don't want to look which bit is it.
Even more, if somehow this bit is not the same in different parts, getenv should return the correct one for each part so the code can be ported without having to modify. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Dec 02, 2016 3:15 pm |
|
|
I did some more testing, and I found it works perfectly well with LATA0
and TRISA0. It just doesn't compile with PORTA0 or any of the ports.
I think it's a missing feature.
Ttelmah mentioned that the Port bits are not defined in the CCS
register map. Here's a screenshot that I found. It shows that the
port bits are not defined. I think CCS should fix this:
http://www.datadynamics.co.jp/ccscc/images/device_table_editor.gif
Test program:
Code: | #include <18F46K22.h>
#fuses INTRC_IO,NOWDT,PUT,BROWNOUT
#use delay(clock=4M)
#use rs232(baud=9600, UART1, ERRORS)
//#bit PORTA_0 = getenv("BIT:PORTA0")
#bit LATA0 = getenv("BIT:LATA0")
#bit LATA1 = getenv("BIT:LATA1")
#bit LATA2 = getenv("BIT:LATA2")
#bit LATA3 = getenv("BIT:LATA3")
#bit LATA4 = getenv("BIT:LATA4")
#bit LATA5 = getenv("BIT:LATA5")
#bit LATA6 = getenv("BIT:LATA6")
#bit LATA7 = getenv("BIT:LATA7")
#bit TRISA0 = getenv("BIT:TRISA0")
//======================================
void main(void)
{
LATA0 = 0;
LATA1 = 1;
LATA2 = 0;
LATA3 = 1;
LATA4 = 0;
LATA5 = 1;
LATA6 = 0;
LATA7 = 1;
TRISA0 = 1;
while(TRUE);
} |
Here's part of the .LST file for the program above. LATA is 0xF89 and
TRISA is 0xF92, so it's working very well with those register bits.
Code: |
.................... LATA0 = 0;
00032: BCF F89.0
.................... LATA1 = 1;
00034: BSF F89.1
.................... LATA2 = 0;
00036: BCF F89.2
.................... LATA3 = 1;
00038: BSF F89.3
.................... LATA4 = 0;
0003A: BCF F89.4
.................... LATA5 = 1;
0003C: BSF F89.5
.................... LATA6 = 0;
0003E: BCF F89.6
.................... LATA7 = 1;
00040: BSF F89.7
....................
.................... TRISA0 = 1;
00042: BSF F92.0
.................... |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Sat Dec 03, 2016 3:14 am |
|
|
It's interesting, it's and 'age of chip' thing. On older chips, CCS included these, but on ones for perhaps the last half dozen years they haven't. Then on some they are just omitted.
For instance the old 16F877, has these on portB, C & D, but not portA...
It is worth saying though, that to 'write' a bit directly, you really should be writing to the LAT bits, on a PIC18, not to the port bits, and these seem to be defined on most chips.
Personally, I'd just generate a macro to automatically build them for any port you want, however as it stands it is an omission by CCS, and quite amazing that it hasn't been fixed in the two years since the original thread.... |
|
|
Marttyn
Joined: 06 Mar 2015 Posts: 28 Location: Spain
|
|
Posted: Mon Dec 05, 2016 4:27 am |
|
|
Thanks for your replies!
As i say, i think "getenv" SFR and BIT are useful for making portable code.
Being able to do it with LAT its not very useful i think. As this may be the only register you may want to change when you port from one PIC to other.
The other registers are the ones that we need.
For example, i couldnt find a way to make "deep sleep" with CCS in PIC12F1840. This is achieved by setting the VREGPM bit of VREGCON register. So i have to do it manually. I would expect this to work:
Code: | #bit VREGPM = getenv("BIT:VREGPM") |
But doesnt, so i have to do this:
Code: | #byte VREGCON = getenv("SFR:VREGCON")
#bit VREGPM = VREGCON.1 |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Mon Dec 05, 2016 5:09 am |
|
|
The point about LAT, is that when you output on a PIC18/24 chip, you should only ever write to the LAT register, not the port register.
If you write to the port register you 'bring back' the PIC16 RMW problem, which giving access to the latch on the PIC18, was designed to avoid. Every chip I've looked at correctly has the LAT bits defined, so I was simply saying that if you want the bit definition for an output, you'd be much better using the lat bits.
The definitions for 'input', are no longer needed, since the current compilers have the 'input_state' instruction, which directly reads the port bits without accessing TRIS. |
|
|
Marttyn
Joined: 06 Mar 2015 Posts: 28 Location: Spain
|
|
Posted: Mon Dec 05, 2016 12:58 pm |
|
|
When i said that doing getenv with LAT register is not very useful, i meant regarding the getenv function. Sure that writing to LAT is the way to go.
My concern was oriented to the getenv BIT, that dont recognize bit names from registers, so its quite useless. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Dec 05, 2016 1:11 pm |
|
|
If you have the IDE version of the CCS compiler, you could probably
bring up the Device Table Editor and type in all those missing bit names.
If you have the command line compilers (like I do), then no. |
|
|
Marttyn
Joined: 06 Mar 2015 Posts: 28 Location: Spain
|
|
Posted: Mon Dec 05, 2016 1:24 pm |
|
|
It would be quite a shame having to tell the IDE this information... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Dec 05, 2016 4:45 pm |
|
|
It was just a suggestion. You could add the bit names, but then you would
have a modified CCS compiler that nobody else has, and you could write
code that wouldn't compile with anybody else's CCS compiler. So I think
it's not worth it to edit the Device Table. |
|
|
Marttyn
Joined: 06 Mar 2015 Posts: 28 Location: Spain
|
|
Posted: Tue Dec 06, 2016 8:44 am |
|
|
This kind of things, plus the many bugs is something I don't understand.
My 10 years experience with CCS is the only thing preventing to switch to XC8 |
|
|
|