#define undeclared error

Go To Last Post
14 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi guys,

 

I'm actually starting with Atmel Studio programming an ATMEGA 328 and made a header file for globals_bexx.h, where I'm doing global declaration according to Deans TUT.

Everything is fine, but using the #define command for setting up my spi lcd-display I got an undeclared error only on 'DDRB1'

 

// #define PORT_SPI    PORTB
#define SPI_LCD_PORT		PORTB	    // SPI Display SS_ Port B1
#define SPI_LCD_PORT_CS		PORTB1	    // SPI Display SS_ Port B1
#define SPI_LCD_DDR		DDRB	    // SPI Display SS_ Port B1
#define SPI_LCD_DDR_BIT		DDRB1	    // SPI Display SS_ Port B1

Isn't it, that #define only replaces the first text by the second one?

Why does it say 'DDRB1' undeclared (frist use in this function) , as ther is no funtion at all?

 

Many thanks!

Bexx

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

BEXX wrote:
Isn't it, that #define only replaces the first text by the second one?

That is correct. It will replace 

SPI_LCD_DDR_BIT

with

DDRB1

 

But now there is a requirement that DDRB1 is defined somewhere. Is it?

 

There is no such symbold defined in Atmels header files.

 

There is a symbol

DDB1

in the header for mega328. 

 

Now, you might ask why they named it such - breaking the pattern that holds for e.g. PORTB/PORTBn and PINB/PINBn. I don't know. It doesn't make sense to me either.

 

On the other hand, all those pin numbers just equate to integer literals  between 0 and 8 anyway so you might as well skip that extra "layer and go for

// #define PORT_SPI    PORTB
#define SPI_LCD_PORT		PORTB
#define SPI_LCD_PORT_CS		1	
#define SPI_LCD_DDR		DDRB	

and use 

SPI_LCD_PORT_CS

to manipulate the bit in both the PORTB and DDRB register. It's always the same bit number so it makes no sense to have two different defines. If you move the CS signal to another pin you should just need to change in one place.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:
There is no such symbold defined in Atmels header files.  
Not even in the "mop up" header? I'm too sick and not near enough to a PC to check right now.

 

EDIT so I had to check and it just proves how ill  I am...

 

http://svn.savannah.gnu.org/view...

 

It "mops up" the PORTxn symbols but not DDRxn

Last Edited: Sun. Jan 7, 2018 - 11:27 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Never heard of the "mop up" header before (neither the header as such, nor the specific expression).

 

Anyway, I'll stand by my statement above. Having the specific port as part of the name for something that "just" represents a pin number within a port is redundancy in code and should be avoided.

 


 

To try to make my thinking clear to the OP:

 

If something is on PORTB pin 2 then that should be stated separately and neither fact should be "doubled". I.e.

 

#define PORT_SOMETHING PORTB
#define PIN_SOMETHING 2

Having the port stated as part of the pin stuff just risks a missed update if something is moved to another port but same pin number within that port. i.e.

#define PORT_SOMETHING PORTB
#define PIN_SOMETHING PORTB2

and then moving to PORTD but still pin 2 within that could end up

#define PORT_SOMETHING PORTD
#define PIN_SOMETHING PORTB2

which will work just fine - but someone reading the code might be very confused. Is something on PORTB or PORTD? E.g. that someone might want to measure a signal between the AVR and something and happens to see the PORTB2 first and attaches his oscilloscope to that pin. Nothing! No signal at all. Depending on luck, experience and phase of the moon it can take that person 10 seconds or several hours to discover what is the truth.

 

Using the style I prefer (first code snippet above) this ambiguity will never occur. And you get to use the same symbolic name for the pin number regardless of if you're accessing the PORT, PIN or DDR register.

 

Nice. Clean. Less risk for bugs and/or confusion.

 

Having the port name as part of the pin number symbolic name does not make anything clearer. Just say "no". ;-)

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Totally agree. Never really understood all this need for PB2 or PORTB2 or whatever. The code is surely just clearer and easier to read if you simply use 2 to mean "bit 2".

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I like the generic bit masks and bit positions as these defined in iotn1616.h.  Have often seen, and used, similar in ARM code.

// Generic Port Pins

#define PIN0_bm 0x01
#define PIN0_bp 0
#define PIN1_bm 0x02
#define PIN1_bp 1
#define PIN2_bm 0x04
#define PIN2_bp 2
#define PIN3_bm 0x08
#define PIN3_bp 3
#define PIN4_bm 0x10
#define PIN4_bp 4
#define PIN5_bm 0x20
#define PIN5_bp 5
#define PIN6_bm 0x40
#define PIN6_bp 6
#define PIN7_bm 0x80
#define PIN7_bp 7

 

"I may make you feel but I can't make you think" - Jethro Tull - Thick As A Brick

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius

Last Edited: Sun. Jan 7, 2018 - 11:03 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Many thanks for your input!

Johans suggestion sound quite fine for me.

So I tried to use this in the header file:

#define SPI_LCD_PORT		PORTB	    // SPI Display SS_ Port B1
#define SPI_LCD_PORT_CS		1	    // SPI Display SS_ Port B1
#define SPI_LCD_DDR	        DDRB	    // SPI Display SS_ Port B1

and this in the code (I hope i got this right):

// DDRB |= (1 << DDB1);        // original, sets bit DDB1 to 1 within register DDRB
SPI_LCD_DDR |= (1 << SPI_LCD_DDR SPI_LCD_PORT_CS);        // should set bit DDB1 to 1 within register DDRB

...now  there comes up an error : expected ')' before numeric constant    (on:  #define SPI_LCD_PORT_CS        1 )

Does it really make "DDB1" using "SPI_LCD_DDR SPI_LCD_PORT_CS" ?

 

Many thanks!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

...btw...

using:

#define SPI_LCD_PORT_CS		ABC			// SPI Display SS_ Port B1

there again comes up the error from the beginning of this thread:  'ABC' undeclared (first use in this function)

 

....I'm quite confused!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
SPI_LCD_DDR |= (1 << SPI_LCD_DDR SPI_LCD_PORT_CS);        // should set bit DDB1 to 1 within register DDRB

No. This should:

 

SPI_LCD_DDR |= (1 << SPI_LCD_DDR);        // should set bit DDB1 to 1 within register DDRB

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

BEXX wrote:

...btw...

using:

#define SPI_LCD_PORT_CS		ABC			// SPI Display SS_ Port B1

there again comes up the error from the beginning of this thread:  'ABC' undeclared (first use in this function)

 

....I'm quite confused!

So, show us the definition of ABC. (Is there one?)

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But where, exactly, is the error reported?

 

I think it would be a safe bet that it is reported where the macro is used - not where it is defined ...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Now, you might ask why they named it such - breaking the pattern that holds for e.g. PORTB/PORTBn and PINB/PINBn. I don't know. It doesn't make sense to me either.

Because avr-libc did before we started to generate the header files. So, we keep the compatibility (even though as you and Cliff says, doesn't make much sense in the greater picture). 

:: Morten

 

(yes, I work for Atmel, yes, I do this in my spare time, now stop sending PMs)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Look at the .i file.

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:
Look at the .i file.

See: https://www.avrfreaks.net/comment... for further details ...

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...