Electronics > Beginners

Odd Code Error

(1/2) > >>

Lance:
I have the following code which is supposed to control the LCD segments for an 7 segment digit. I copied the define statements from an assembly sample file, and I figured this would be okay in C:


--- Code: ---#define s1a LCDDATA2,6 //define segments for digit 1
#define s1b LCDDATA2,7
#define s1c LCDDATA8,7
#define s1d LCDDATA11,6
#define s1e LCDDATA8,6
#define s1f LCDDATA5,6
#define s1g LCDDATA5,7

--- End code ---
The compiler is fine with that. It complains when I try to do things with it:


--- Code: ---void LCDseg_digit1(short unsigned int state)
{
switch(state)
{
case 0:
s1a=1;
s1b=1;
s1c=1;
s1d=1;
s1e=1;
s1f=1;
s1g=0;
break;
                default:
s1a=0;
s1b=0;
s1c=0;
s1d=0;
s1e=0;
s1f=0;
s1g=0;
break;
}
}

--- End code ---
With this function you input a number between 0 and 9, and it controls the segments accordingly. I cut out the stuff in the middle.

I then get this error spewed at me for every like where I try to set a register:

--- Code: ---only lvalues may be assigned to or modified
--- End code ---
I tried searching around, but I don't understand why this isn't allowed. Could someone enlighten me?

johnmx:
Try replacing your definitions with the following code:


--- Code: ---#define PORTBIT(adr, bit) ((unsigned)(&adr)*8+(bit))
static bit s1a @ PORTBIT(LCDDATA2, 6);
static bit s1b @ PORTBIT(LCDDATA2, 7);
static bit s1c @ PORTBIT(LCDDATA8, 7);
static bit s1d @ PORTBIT(LCDDATA11, 6);
static bit s1e @ PORTBIT(LCDDATA8, 6);
static bit s1f @ PORTBIT(LCDDATA5, 6);
static bit s1g @ PORTBIT(LCDDATA5, 7);
--- End code ---

baljemmett:

--- Quote from: Lance on June 21, 2011, 08:36:14 pm ---I have the following code which is supposed to control the LCD segments for an 7 segment digit. I copied the define statements from an assembly sample file, and I figured this would be okay in C:


--- Code: ---#define s1a LCDDATA2,6 //define segments for digit 1

--- End code ---
The compiler is fine with that.
--- End quote ---

Yes, it will be; #defines aren't examined directly at all by the compiler, but rather simply substituted into the rest of the source by a preprocessor pass.  So you can #define anything you like; it's only when the token you've defined is used in the program that it gets expanded and the compiler has a chance to moan about it.

So to take an example from your code:


--- Quote ---It complains when I try to do things with it:


--- Code: --- s1a=1;

--- End code ---

--- End quote ---

... gets expanded into:


--- Code: --- LCDDATA2,6=1;

--- End code ---

... which in C is treated as two expressions, LCDDATA2 and 6=1 (the comma operator is a way to join several expressions together, computing all of them and evaluating to the result of the right-most, but that's by-the-by here).  And you can't assign to the literal 6, which is why:


--- Quote ---I then get this error spewed at me for every like where I try to set a register:

--- Code: ---only lvalues may be assigned to or modified
--- End code ---

--- End quote ---

There are several ways to fix it; one is to change your #defines into references to the correct single bit, if your compiler (and/or headers) support a method for doing that.  Another might be to #define a constant for each digit that represents the port value you need to set and just assign that to the port as a whole, but the specific options you have will depend on your compiler, and of course what you're running the code on!  (I see johnmx has suggested one approach whilst I was typing, for instance, which looks like it uses a compiler extension to address single bits -- the most direct translation of the original assembly approach.)

A-sic Enginerd:
Put the mouse down and step away from the keyboard.

Sorry, not trying to be harsh and bag on ya, just pointing out I think you need to take a step back and get a better handle on the basics of C and assembly before you start leaping into this kind of stuff.

My advise would be as follows:
 - spend a little time understanding what the assembly is doing that you pasted in. Meaning - ignore C for just a few and get a decent grasp on the syntax of the assembly you're dealing with. It will be CPU and assembler specific syntax (as is always the case when working in assembly) so you won't be able to look things up in a "generic" sense.
Depending on how savvy you are already with what you're working with, this may take a few hours. Refer to the docs for your part or assembler. specific doc in question will be something like "Assembler Reference Guide" or something like that. Basically gives the break down of all the assembly instructions and what their syntax looks like and means.

- next, pick up just about any C book and get a grip on the use of switch statements. This will actually be the easier of the tasks. Shouldn't take long at all. And yes, this one you could look up generically.

Also, realize that #define statements in C (especially when used in this fashion) is nothing more than an exact text replacement. Nothing magical about it. So in your code, where ever you made use of what appears in the left half of the "define" statement, replace that with what you put in the right half. At that point you should be able to look at your code and go - "what? Wait.....that doesn't look right".

Final note: accessing individual bits in C can actually be a bit of a PITA. Not super hard, but tedious. Good news is a lot of the cross compilers for microcontrollers on the market today realize this and realize that in a microcontroller you're likely to be doing bit accesses a LOT. So, they help out by providing built in - non standard or ANSI C - constructs that make the job a whole lot easier so take a look at the C language reference manual for your cross compiler as well.

Lots of digging I know, but you'll learn a helluva lot more and understand it better than just getting the short answer of how it's supposed to be done here. (I know, I'm a hardass a-hole.......just ask my kids)

Lance:
Thanks for the help everyone.

johnmx
I actually used that to define some bits back in my main.h. For some reason I decided the assembly code would work. Bit of a brain fart there.

baljemmett
That cleared a lot up for me, I didn't think defines were that straightforward. Thanks!

A-sic Enginerd
Was there something wrong with my switch statement? I'm reading some stuff on assembly on the side right now. Still have a lot to figure out. Are there any particular devices you found to be nice to someone who's new to assembly? This PIC16F917 doesn't seem too bad.

Navigation

[0] Message Index

[#] Next page

There was an error while thanking
Thanking...
Go to full version
Powered by SMFPacks Advanced Attachments Uploader Mod