Question regarding File Structure and AS7

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

Hi,

 

I am trying to create a project that includes some LCD code.  The structure is like many of the LCD.c, LCD.h construction that is found on the internet

 

I'm using AS7

 

I've added my version of the LCD.c file as  LCD_USART.c   and the LCD.h as LCD_USART.h and is included in the main.c file.  When I compile the solution it seems the LCD_USART.c compiles first, as a result I get errors that the register names are not defined.   To cure this I needed to put #include <avr/io.h> in the LCD_USART.C file.  This seems wrong but I can't find another way to make the files work.

 

Below is my code.   Any suggestions as to how this happens?   I'm thinking it has to do with how I added the files to AS.  BTW all files are in the same directory as the main.c  all in a standard AS project.

 

 

 

Thanks

 

JohnRob

 

main.c




#define F_CPU 2000000UL		// this is after the prescaler and must be before the #includes
#include <avr/io.h>
#include <util/delay.h>
//#include <stdio.h>
#include "LCD_USART.h"

#define RS232				// comment out if RS232 is not required
#define USART_BAUDRATE 9600
#define BAUD_PRESCALE ((F_CPU + USART_BAUDRATE * 8L) / (USART_BAUDRATE * 16L) - 1)

//#define PWM					// comment out if PWM is not required
#define Timer1TopCount 6500		// period ~0.001 ms per
#define Timer1ONCounts 60		// ~1µSec per count



//*** global declarations ********************************************

	// no globals defined

//*** Function Prototypes ********************************************

void Init(void);
void Init_Timer1PWM(void);
void Init_RS232(void);

LCD_USART.c

/*
 * LCD to USART Subroutines
 *
 * LCD_USART.c
 *
 */ 
#include <avr/io.h>     <--------------------------this needed to be added.  I think it should not need to be included here.

//Send char to USART:

void LCD_putByte(char c)
	{
		while ((UCSR0A & (1 << UDRE0)) == 0) {}; // Wait until UDR is ready for data
		UDR0 = c;
	}

void LCD_putstr(const char * s)
	{

		LCD_putByte(0x1B);
		LCD_putByte(0x01);		// initiate text mode
		while(*s)
			LCD_putByte(*s++);
		LCD_putByte(0x00);		// terminate text mode
	}
	
void LCD_Clear(void)
	{
		LCD_putByte(0x1B);
		LCD_putByte(0x1E);
	}
blah..blah....

		
// *** END of code **************************************************
//*******************************************************************

 

and 

 

LCD_USART.h

/*
 * LCD to USART Subroutines
 *
 *	USART to LCD interface header file
 *	See LCD_USART.c for more info
 *
 */ 


// Send char/byte to LCD, used by below routines
extern void LCD_putByte(char c);

// Send string to LCD
extern void LCD_putstr(const char * s);

// Clear LCD display	
extern void LCD_Clear(void);

// Cursor On	
extern void LCD_CursorOn(void);

// Cursor Off
extern void LCD_CursorOff(void);

// Backlight ON
extern void LCD_BacklightOn(void);
	
// Backlight OFF
extern void LCD_BacklightOff(void);

// Move cursor to row, column
extern void LCD_RowCol(char x, char y);

// Set LCD configuration (i.e. 4 rows, 20 columns)
// used to initialize only		
extern void LCD_SetRowColConfig(void);


	
// *** END of code *****************

 

Last Edited: Tue. Apr 25, 2017 - 09:01 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohnRob wrote:
I needed to put #include <avr/io.h> in the LCD_USART.C file

Yes - that is perfectly normal and correct.

 

Any and every .c file that uses definitions from avr/io.h needs to  #include <avr/io.h> 

 

Just like any and every .c file that uses definitions from stdio.h needs to  #include <stdio.h> - it's nothing specifically to do with Atmel Studio or AVR

 

This seems wrong

How so?

 

 

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...
Last Edited: Mon. Apr 24, 2017 - 11:29 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks awneil,

 

I thought it was wrong because I was always under the belief that things should be defined only in one place.  While the #include is not a definition, I felt I was using a crutch that would eventually bite me.

 

Thanks for the clarification.

 

JohnRob

 

 

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

Defined in one place only, yes.
Declared in all places (files) where it is needed, yes.

A header file normally contains declarations, not definitions.

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:
A header file normally contains declarations, not definitions.

And people who break that rule end up getting "multiple definition" errors from the Linker.

 

http://c-faq.com/decl/decldef.html

 

Again, this is standard 'C' stuff - nothing specific to Atmel Studio or AVR - so should be moved to General Programming

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...
Last Edited: Tue. Apr 25, 2017 - 06:10 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#include <avr/io.h>     <--------------------------this needed to be added.  I think it should not need to be included here.

The rule is generally that you need to #include all the headers that will document all the symbols in the following following that are not declared locally.

 

So in the LCD_USART.c you have symbols such as:

		while ((UCSR0A & (1 << UDRE0)) == 0) {}; // Wait until UDR is ready for data
		UDR0 = c;

The compiler has to be told about what those are from somewhere!

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

Again thanks to all for the clarification.   Just so you know,  for right or wrong, MPLAB does not required the declaration in the supporting c files.  This is why I though this board was the best choice.

 

Re-reading the KR book I now see in the description of header files they show declarations in each c file.

 

 

 

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

Is MPLAB, then, one of those ones that doesn't have a (proper) linker - it effectively just #includes all the .c files into one big Translation Unit ... ?

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

I'm not sure about the linker details.  However supporting c files are included in a project under a group called "other".   It would be logical they are creating the one big file you suggest.

 

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

hmmm I'm sure I had moved this thread to general programming yesterday, moving again.

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

JohnRob wrote:
Just so you know, for right or wrong, MPLAB does not required the declaration in the supporting c files.

"Beauty is in the eye of the beholder", right?

 

It wasn't that unusual for a toolchain to have a "Globally include" option or similar.  Implementations varied, but typically all the source code could "see" the listed parameter files.  [I purposefully didn't specifically say "C" or ".h", as I recall toolchains for other languages having the facility.]

 

I don't know if any of the mature AVR8 toolchains have that facility.  But I wouldn't be surprised even if a 'legacy' option.  (Could a "legacy deprecated" feature be called a "leprechaun"? )

 

 

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.