Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Help me understand syntax of C for embedded systems

Status
Not open for further replies.

air

Member level 3
Joined
Jun 6, 2002
Messages
59
Helped
1
Reputation
2
Reaction score
0
Trophy points
1,286
Activity points
557
I am learning c for embedded system programming. I have 5 questions list below. I'll appreciate it if someone can explain some of them or even all. Or can someone recommend me some references to leanr these conventions?
1 what is this convention like this: (copy from Hi-tech c)
#ifndef _PIC_H
#define _PIC_H
especially the underscore puzzles me a lot.

2. what is the signs &, *, +, @ , and the parenthesis of (unsigned) mean in the following (from Hi-tech)
static bit LCD_RS @ ((unsigned)&PORTA*8+2);

3. what does this statment mean? (from Hi-tech c)
#define LCD_STROBE ((LCD_EN = 1),(LCD_EN=0))

4. What is the underscore and < ....> mean? (from sourceboost C)
#define _LCD_Read LCD_Read <InterfaceType, UseBusy, DataPort, Data_PortTris, CtrlPort, Ctrl_PortTris, RS, RW, E>

5. who can explain
_LCD_TEMPL and template

in the part of the program as following: (from sourceboost C)
......
// These macros make susequent code more readable, but can seem a little confusing
#define _LCD_RawWriteNibble LCD_RawWriteNibble <InterfaceType, UseBusy, DataPort, Data_PortTris, CtrlPort, Ctrl_PortTris, RS, RW, E>
#define _LCD_RawWriteNibbleInline LCD_RawWriteNibbleInline <InterfaceType, UseBusy, DataPort, Data_PortTris, CtrlPort, Ctrl_PortTris, RS, RW, E>
#define _LCD_Read LCD_Read <InterfaceType, UseBusy, DataPort, Data_PortTris, CtrlPort, Ctrl_PortTris, RS, RW, E>
#define _LCD_WaitForNotBusy LCD_WaitForNotBusy <InterfaceType, UseBusy, DataPort, Data_PortTris, CtrlPort, Ctrl_PortTris, RS, RW, E>
#define _LCD_Write LCD_Write <InterfaceType, UseBusy, DataPort, Data_PortTris, CtrlPort, Ctrl_PortTris, RS, RW, E>
#define _LCD_FunctionMode LCD_FunctionMode <InterfaceType, UseBusy, DataPort, Data_PortTris, CtrlPort, Ctrl_PortTris, RS, RW, E>
#define _LCD_DataMode LCD_DataMode <InterfaceType, UseBusy, DataPort, Data_PortTris, CtrlPort, Ctrl_PortTris, RS, RW, E>
#define _LCD_RawWrite LCD_RawWrite <InterfaceType, UseBusy, DataPort, Data_PortTris, CtrlPort, Ctrl_PortTris, RS, RW, E>
#define _LCD_ClockOut LCD_ClockOut <InterfaceType, UseBusy, DataPort, Data_PortTris, CtrlPort, Ctrl_PortTris, RS, RW, E>

#define _LCD_TEMPL template < unsigned char InterfaceType,\
unsigned char UseBusy,\
unsigned int DataPort, unsigned int Data_PortTris,\
unsigned int CtrlPort, unsigned int Ctrl_PortTris,\
unsigned char RS, unsigned char RW, unsigned char E>

_LCD_TEMPL
inline void LCD_FunctionMode( void )
{
volatile bit rs@CtrlPort.RS = 0;
}

_LCD_TEMPL
inline void LCD_DataMode( void )
{
volatile bit rs@CtrlPort.RS = 1;
}
......
 

hitech eeprom_write

Learn the basics of C programming first.
 

hi-tech c eeprom_write

Yes, you must learn C language first. 'cause those symbols, which you asked, are used by C language.
 

hi-tech flash_write

I can only answer for the first qustion

Q1:
due to underscore it's meanless,it's part from the name of identifcation.
and due to #ifndef <name> if this <name> not defined befor the compiler will copmile the next line until find #endif OR #else ,
and if defined befor,the compiler will not compile this part and not get it hex file

and this question mean if not defined then define _PIC_H

simply u can search in help in the compiler u'll find it very easy to understand it.
 

what does &porta mean

Hi!

Before you write software for microcontrollers, learn
first the C programming on a PC. Use a PC with an ANSI
compliant C compiler. Write EXE programs that will run
in a MS-DOS console window. On the WEB you can find a lot
of free tutorials about C.

Example:
http://www.ericlindsay.com/applix/ctutor.pdf

(Search with Google for "C tutorial" or "Hi-tech c tutorial").

Switch to a C compiler for embedded systems once you
master the C programming for the PC.

* * *
Compiler - Borland C++ 4.52 (Also for C).

Perfect to learn C. Compiler and debugger run under Windows.
(The console for input and output is a Windows form not
MS-DOS console window).
In the project options you can set the language compliance.
(Kernighan and Ritchie, ANSI, UNIX V, Borland extensions).


* * *

Compiler - Pacific C for MS-DOS (Hi-tech)

Free MS-DOS ANSI C compiler with debugger and
a 366 pages PDF manual:

http://www.htsoft.com/products/PACIFICc.php

This compiler and debugger run also in a MS-DOS
console window under Windows.
If you create a PIF file, the program will run in
full-screen DOS mode under Windows with mouse support.


* * *

The first book about C:

The C Programming Language (Second Edition).
Brian W. Kernighan / Dennis M. Ritchie
ISBN: 0-13-110362-8

Luciano
 

flash_write in c

Remember that C macros are simply text substitution. Macros are powerful but sometimes difficult to follow, especially when the macro contains other macros.

1. In C, an underscore is an ordinary character like A through Z, so _PIC_H is simply an identifier (function name, macro name, etc) possibly defined elsewhere.

2. I don't think @ is valid C language. It may be some extension provided by your compiler, or it may be a token recognized by some other preprocessor. The expression ((unsigned)&PORTA*8+2) takes the address of PORTA, casts it to an unsigned integer, multiplies it by 8, and adds 2. That sort of thing is very common in embedded C.

3. That defines a macro named LCD_STROBE. If you use that macro in your program, it expands to the text ((LCD_EN=1),(LCD_EN=0)) which happens to contain two assignments separated by the comma operator. It sets something named LCD_EN to 1, and then clears it to 0.

4. Again, the underscore is just an ordinary character, so _LCD_Read is simply the macro name. If you use that macro in your program, it expands to all that weird text. Who knows what it does! You'll have to go find where it's being used, and puzzle out what the programmer was thinking.

5. Yuch! I think the secret is "template". It's not part of the C language, so it's probably yet another macro. Try to find its definition.

I like their comment: "... can seem a little confusing".


Here's a great book and a helpful FAQ:

https://www.eskimo.com/~scs/C-faq/top.html
 

flash_write+c programming

ahm_hassaan said:
I can only answer for the first qustion

Q1:
due to underscore it's meanless,it's part from the name of identifcation.
and due to #ifndef <name> if this <name> not defined befor the compiler will copmile the next line until find #endif OR #else ,
and if defined befor,the compiler will not compile this part and not get it hex file

and this question mean if not defined then define _PIC_H

simply u can search in help in the compiler u'll find it very easy to understand it.

I found a sentence in "c a complete reference":
"Standard C reserves identifier names beginning with an underscore and followed by either a second underscore or a capital letter for use in headers."

According to it, does it mean:
_PIC_H = __pic_h
What does _PIC_H refer to? Does _PIC_H refers to the file pic.h?
What is _PIC_H defined here? For example:
#define a 1
means that 'a' will be replaced as 1 anywhere in the program. But what dose
#define _PIC_H
define? defines null?

Added after 2 minutes:

Here is the complete pic.h file

#ifndef _PIC_H
#define _PIC_H

#if defined(_12F629) || defined(_12F675)
#include <pic12f6x.h>
#endif

#if defined(_16F627)
#include <pic16f6x.h>
#endif

#if defined(_16F627A)
#include <pic16f62xa.h>
#endif

#if defined(_16C84) || \
defined(_16F84) || defined(_16F84A)
#include <pic1684.h>
#endif

#if defined(_16F877)
#include <pic1687x.h>
#endif

#if defined(_16F877A)
#include <pic168xa.h>
#endif

#if defined(_16F684)
#include <pic16f684.h>
#endif

#define CLRWDT() asm("clrwdt")
#define SLEEP() asm("sleep")
#define NOP() asm("nop")

#define ___mkstr1(x) #x
#define ___mkstr(x) ___mkstr1(x)
#define __CONFIG(x) asm("\tpsect config,class=CONFIG,delta=2");\
asm("\tglobal\tconfig_word"); \
asm("config_word"); \
asm("\tdw "___mkstr(x))

#define __IDLOC(w) asm("\tpsect idloc,class=IDLOC,delta=2");\
asm("\tglobal\tidloc_word"); \
asm("idloc_word"); \
asm("\tirpc\t__arg," ___mkstr(w)); \
asm("\tdw 0&__arg&h"); \
asm("\tendm")

#if EEPROM_SIZE > 0
#define __EEPROM_DATA(a, b, c, d, e, f, g, h) \
asm("\tpsect eeprom_data,class=EEDATA,delta=2"); \
asm("\tdb\t" ___mkstr(a) "," ___mkstr(b) "," ___mkstr(c) "," ___mkstr(d) "," \
___mkstr(e) "," ___mkstr(f) "," ___mkstr(g) "," ___mkstr(h))
#endif

/***********************************************************************
**** FLASH memory read/write/erase macros and function definitions ****
***********************************************************************
* Notes:
* __FLASHTYPE == 0 defined in devices that can only read flash memory - cannot write eg. 16F777
* __FLASHTYPE == 1 defined in traditional devices that can write 1 word at a time eg. 16F877
* __FLASHTYPE == 2 defined in devices that can only write in 4 word blocks eg. 16F877A
* __FLASHTYPE == 3 defined in devices requiring 32-word block erasure before writing eg. 16F87
* __FLASHTYPE == undefined if device can neither read nor write program memory
*/
// macro FLASH_READ returns a word stored at a flash address
// global interrupt enable macros
#if defined(__FLASHTYPE)
extern unsigned char flash_read(unsigned short addr);
#if EEPROM_SIZE > 0
#define FLASH_READ(addr) \
(EEADR=(addr)&0xff, \
EEADRH=(addr)>>8, \
WREN=0, \
EECON1 |= 0x80, \
RD=1, \
DC=0, \
DC=0, \
(EEDATH << 8) | EEDATA)
#else // FLASH_READ without EEPROM
#define FLASH_READ(addr) \
(EEADR=(addr)&0xff, \
EEADRH=(addr)>>8, \
RD=1, \
DC=0, \
DC=0, \
(EEDATH << 8) | EEDATA)
#endif
#endif // end FLASH_READ

// macro FLASH_WRITE used when writing only one word of data
#if __FLASHTYPE==2 || __FLASHTYPE==3
#define FLASH_WRITE(addr,data) \
do{ \
unsigned short x=data; \
flash_copy((const unsigned char *)&x,1,addr); \
}while(0)

extern void flash_copy(const unsigned char * source_addr,unsigned char length,unsigned short dest_addr);
#elif __FLASHTYPE==1
#define FLASH_WRITE(addr, value) \
EEADR=((addr)&0xff); \
EEADRH=((addr)>>8); \
EEDATH=((value)>>8); \
EEDATA=((value)&0xff); \
EECON1 |= 0x80; \
WREN=1; \
EECON2 = 0x55; \
EECON2 = 0xaa; \
WR=1; \
asm("nop"); \
asm("nop"); \
WREN=0
#endif // end FLASH_WRITE

// macro FLASH_ERASE used to clear a 32-Byte sector of flash
#if __FLASHTYPE==3
#define FLASH_ERASE(addr) \
while(WR)continue; \
EEADR=((addr)&0xFF); \
EEADRH=((addr>>8)&0xFF); \
EECON1=0x94; \
CARRY=0;if(GIE)CARRY=1;GIE=0;\
EECON2=0x55;EECON2=0xAA;WR=1; \
asm("\tNOP"); \
if(CARRY)GIE=1

// library function version
extern void flash_erase(unsigned short addr);
#endif // end FLASH_ERASE

/***********************************************************************/
/****** EEPROM memory read/write macros and function definitions *******/
/***********************************************************************/
#if EEPROM_SIZE > 0
#ifdef __FLASHTYPE
// macro versions of EEPROM write and read
#define EEPROM_WRITE(addr, value) \
while(WR)continue;EEADR=(addr);EEDATA=(value); \
EECON1&=0x7F;CARRY=0;if(GIE)CARRY=1;GIE=0; \
WREN=1;EECON2=0x55;EECON2=0xAA;WR=1;WREN=0; \
if(CARRY)GIE=1

#define EEPROM_READ(addr) ((EEADR=(addr)),(EECON1&=0x7F),(RD=1),EEDATA)

#else // else doesn't write flash
#define EEPROM_WRITE(addr, value) \
while(WR)continue;EEADR=(addr);EEDATA=(value); \
CARRY=0;if(GIE)CARRY=1;GIE=0; \
WREN=1;EECON2=0x55;EECON2=0xAA;WR=1;WREN=0; \
if(CARRY)GIE=1

#define EEPROM_READ(addr) ((EEADR=(addr)),(RD=1),EEDATA)
#endif

/* library function versions */
extern void eeprom_write(unsigned char addr, unsigned char value);
extern unsigned char eeprom_read(unsigned char addr);
#endif // end EEPROM routines


/****************************************************************/
/****** Global interrupt enable/disable macro definitions *******/
/****************************************************************/

#ifndef ei
#define ei() (GIE = 1) // interrupt enable bit
#endif ei

#ifndef di
#define di() { do { GIE = 0; } while ( GIE == 1 ); } // disable interrupt bit
#endif di

#endif /* _PIC_H */

Added after 21 minutes:

echo47 said:
Remember that C macros are simply text substitution. Macros are powerful but sometimes difficult to follow, especially when the macro contains other macros.

1. In C, an underscore is an ordinary character like A through Z, so _PIC_H is simply an identifier (function name, macro name, etc) possibly defined elsewhere.

2. I don't think @ is valid C language. It may be some extension provided by your compiler, or it may be a token recognized by some other preprocessor. The expression ((unsigned)&PORTA*8+2) takes the address of PORTA, casts it to an unsigned integer, multiplies it by 8, and adds 2. That sort of thing is very common in embedded C.

3. That defines a macro named LCD_STROBE. If you use that macro in your program, it expands to the text ((LCD_EN=1),(LCD_EN=0)) which happens to contain two assignments separated by the comma operator. It sets something named LCD_EN to 1, and then clears it to 0.

4. Again, the underscore is just an ordinary character, so _LCD_Read is simply the macro name. If you use that macro in your program, it expands to all that weird text. Who knows what it does! You'll have to go find where it's being used, and puzzle out what the programmer was thinking.

5. Yuch! I think the secret is "template". It's not part of the C language, so it's probably yet another macro. Try to find its definition.

I like their comment: "... can seem a little confusing".


Here's a great book and a helpful FAQ:
h**p://
h**p://www.eskimo.com/~scs/C-faq/top.html
Thanks for your explanation. But I still have something to argue.
part of the code is:

#include <pic.h>
#include "lcd.h"
#include "delay.h"

static bit LCD_RS @ ((unsigned)&PORTA*8+2); // Register select
static bit LCD_EN @ ((unsigned)&PORTA*8+3); // Enable

#define LCD_STROBE ((LCD_EN = 1),(LCD_EN=0))

I still can not see anything from your 2nd explanation. Obviously, from the code, it means that LCD's RS control pin is connecting to the PORTA pin 2, but how does it get there by this kind syntax?
 

hi-tech preprocessor sentences #ifdef

You are quickly moving towards the deep end of the swimming pool!

An identifier such as _PIC_H begins with an underscore and a capital letter. The C standard says, if I'm reading it correctly, that such names are to be used only by the guys who created the compiler. Your program should not create such names or try to use them in your program. That rule helps compiler writers and compiler users from accidentally stepping on each other's toes. (I probably mis-stated something there - reading section 7.1.3 of the standard gives me a headache.)

Now I'll try to guess why the compiler guys created _PIC_H. It looks like a flag that prevents all the other stuff in the header from accidentally being defined twice, in case somebody tries to include the header file twice. That's a common problem when a header file includes other header files. The reason they named it _PIC_H is probably because it's easy to remember that it is a flag for a file named pic.h.

I still can not see anything from your 2nd explanation. Obviously, from the code, it means that LCD's RS control pin is connecting to the PORTA pin 2, but how does it get there by this kind syntax?
I don't quite understand your question. Please rephrase. Perhaps you are wondering how PORTA is defined, and where. That's a good question! PORTA is not a standard C identifier. Look around in some other header files.
 

define in c _12f675

echo47 said:
You are quickly moving towards the deep end of the swimming pool!

An identifier such as _PIC_H begins with an underscore and a capital letter. The C standard says, if I'm reading it correctly, that such names are to be used only by the guys who created the compiler. Your program should not create such names or try to use them in your program. That rule helps compiler writers and compiler users from accidentally stepping on each other's toes. (I probably mis-stated something there - reading section 7.1.3 of the standard gives me a headache.)

Now I'll try to guess why the compiler guys created _PIC_H. It looks like a flag that prevents all the other stuff in the header from accidentally being defined twice, in case somebody tries to include the header file twice. That's a common problem when a header file includes other header files. The reason they named it _PIC_H is probably because it's easy to remember that it is a flag for a file named pic.h.

I still can not see anything from your 2nd explanation. Obviously, from the code, it means that LCD's RS control pin is connecting to the PORTA pin 2, but how does it get there by this kind syntax?
I don't quite understand your question. Please rephrase. Perhaps you are wondering how PORTA is defined, and where. That's a good question! PORTA is not a standard C identifier. Look around in some other header files.

What I want to say is that how can I interpret this line:
static bit LCD_RS @ ((unsigned)&PORTA*8+2); // Register select
to get what it suppose to tell. It seems that your previous explaination can not lead me to the point, i.e LCD's RS is connecting to PORTA pin 2. PORTA usually equals to the address of the PORTA register.
 

c compiler ___mkstr

static bit LCD_RS @ ((unsigned)&PORTA*8+2); // Register select

Well, that @ symbol is not valid C, as I already mentioned. I don't know what "bit" is either. Maybe that's where you are stuck.

Let's dissect ((unsigned)&PORTA*8+2)

PORTA
Unknown definition. Maybe it's in another header file.

&PORTA
That is the "address of" operator. It generates a pointer to PORTA.

(unsigned)&PORTA
That casts (converts) the address to an unsigned integer.

(unsigned)&PORTA*8
Times 8.

((unsigned)&PORTA*8+2)
Plus 2.

Did that help? ;-)
 

__eeprom_data expression

static bit LCD_RS @ ((unsigned)&PORTA*8+2); // Register select

HERE BIT MIGHT BE A DATA TYPE WHICH MIGHT BE TYPE CASTED USING TYPEDEF
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top