I am trying to write general procedure with the C51, who use name that I can easily assign to a port for a specific controler. Ex: I want to replace port P4 in a procedure with a name like DATA
The original question talked about doing it within a function. Don't 'sfr' declarations have to be global?
Apparently "sfr" delarations do have to be global. I could not find any mention of this limitation in the manuals. Is the limitation intuitively obvious to everyone but me? Oh well, there's always:
#define DATA P4
Yes, that'd fix it! No, IMO, none of the restrictions, requirements, foibles, etc of any of the Keil SFR & bit-access features is at all obvious - let alone intuitive! As Keil themselves say in the C51 User Guide, Appendix F: "Some users have reported difficulties in using the bdata memory type..." From the fact that they've included that whole section, I think we can probably surmise that what they really mean is "Many users have difficulties..." ;-) It's not helped when they say things like "...sfr variables are defined just like other C variable declarations." when clearly they are not quite like other C variable declarations! And why couldn't they state the restrictions clearly and explicitly in the same place that these language extensions are introduced - instead of hiding them away in an Appendix? Sorry. End of rant.
Well SFR's are global because they're hardware of course. C knows nothing of hardware and thus it's scoping rules can't really be made to apply. However, I often put my SFR def'ns. at the top of the .c file that uses them. I do not inlcude any Keil regXXX.h files. It works well because I can give more descriptive names to the sfrs. Also, because I never put SFR's into .h files I can 'pseudo-scope' the SFR's, at least from my naming conventions, from being accidentily used somewhere else. That is, since reg51.h is not included, someone on my team cannot set RI and ruin my UART ISR since RI will not exist in my project name space. It will only be in my uart.c file as r_charReceived. For instance, with SBUF it is read and write. I like to create an SFR called r_rxReg and r_txReg (the 'r_' prefix is my convention for any CPU register). Then it just seems more readable when I read and write to the two differently named vars. My 2 cents. - Mark
Well SFR's are global because they're hardware of course. C knows nothing of hardware and thus it's (sic) scoping rules can't really be made to apply. Yes, of course that's absolutely true - it's one of those things which explains everything after you've been bitten and had to go through and work it out. My point (a gripe at Keil, not you) is, why can't Keil just explain that up-front in the documentation of their 'sfr' etc extensions - rather putting us off the track with "...sfr variables are defined just like other C variable declarations." when, as we now know, there are important differences & therefore restrictions. As an earlier post asked, is the restriction actually stated explicitly anywhere in any Keil manual? The restriction seems even more obscure with bdata.