Odd Code Error - Page 1
Forum section: electronics / beginners

author: Lance
author_rank: Frequent Contributor
timestamp: June 21, 2011, 08:36:14 pm
content: 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,7The 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;}}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 modifiedI tried searching around, but I don't understand why this isn't allowed. Could someone enlighten me?

author: johnmx
author_rank: Frequent Contributor
timestamp: June 21, 2011, 08:57:36 pm
content: 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);

author: baljemmett
author_rank: Unknown
timestamp: June 21, 2011, 09:09:40 pm
content: Quote from: Lance on June 21, 2011, 08:36:14 pmYes, 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... gets expanded into:Code:LCDDATA2,6=1;... 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:QuoteThere 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.)

author: A-sic Enginerd
author_rank: Regular Contributor
timestamp: June 21, 2011, 09:25:40 pm
content: 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)

author: Lance
author_rank: Frequent Contributor
timestamp: June 21, 2011, 09:30:40 pm
content: Thanks for the help everyone.johnmxI 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.baljemmettThat cleared a lot up for me, I didn't think defines were that straightforward. Thanks!A-sic EnginerdWas 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.

author: A-sic Enginerd
author_rank: Regular Contributor
timestamp: June 21, 2011, 09:53:51 pm
content: Quote from: Lance on June 21, 2011, 09:30:40 pmYou just answered your own question. You're mixing C and assembly. It is possible to do this in C, but it takes special attention to do so. baljemmett spelled out what the effect is of the syntax you're trying to employ.99.9% of the time a compiler complains about how you're doing something - it's a basic syntax problem. That's why I suggested what I did. If it's a functional problem, I'd be a lot more apt to give specific help (those can be painful to find and it's why software engineers get paid), but since this is a syntax problem and a pretty basic one at that, I leave it to the user to educate themselves so they may see the error of their ways. And having someone simply spell out what the code is supposed to look like is not how one learns. Go learn the basics of the "things" you're working with and the answer will become crystal clear and obvious.

author: Lance
author_rank: Frequent Contributor
timestamp: June 21, 2011, 10:11:50 pm
content: Quote from: A-sic Enginerd on June 21, 2011, 09:53:51 pmWell that works, I guess. Now that the confusion is out of the way I can work on it some more.

author: Mechatrommer
author_rank: Super Contributor
timestamp: June 22, 2011, 09:23:01 am
content: a-sic got a point there. you dont have a clear view what #define is doing. it simply like doing shortform in your programming (direct translation, baljammet described it precisely in detail), or at least you have that figured out by nowalso be carefull if you are doing complex macro (#define). i was caught by this #define error like#define myShort 1+1(pseudo code warning!). when i put it in complex math it reported error. the safer way is enclosed by bracket eg#define myShort (1+1). my 2cntsps: you are lucky if you get caught by syntantic error like this. semantics error can cost you several pieces of your hair