NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Support Forum » Unable to get 328p to upload - PD7 undeclared

July 10, 2011
by konakat
konakat's Avatar

Able to program 168 initialload OK, but get the following error "lcd.c:22: error: 'PD7' undeclared (first use in this function)" when using the 328p. Followed the steps to convert to the 328p and used the same code (initialload) with changes per Nerdkits. Removed the 328p changes and the 168 chip programmed fine. The 328p chip purchased from Nerdkits so expect it to have the correct bootloader. Checked lcd.c file and it appears the same as when downloaded. Help please...make it simple as I am very new to this stuff.

July 10, 2011
by konakat
konakat's Avatar

Forgot to attach pix of command prompt

1 ![PD7 Error]

July 13, 2011
by hevans
(NerdKits Staff)

hevans's Avatar

Hi Konakat,

This seems like you missed the #include in the C file as described in the Nano guide, and possibly the modification for the Makefile. Note when you modify the makefile make does not automatically know that something changed, so you need to remove all .o and .hex files from both the working project directory, and the libnerdkits directory.

Make sure you have the io_328p.h file in your libnerdkits directory, and make sure you are including it in your .c fle. Wipe all .o and .hex files, and give that a try. Let us know what you find.


July 14, 2011
by konakat
konakat's Avatar

Still getting same message - triple checked all files and they appear to be correct. The io_328p.h file is in the libnerdkits folder and all "o" and "hex" files deleted. The hardware is working as I see the congratulations message. Here are the files:

libnerdkits makefile:

GCCFLAGS=-g -Os -Wall -mmcu=atmega328p

all: delay.o lcd.o uart.o

delay.o: delay.c
    avr-gcc ${GCCFLAGS} -o delay.o -c delay.c

lcd.o: lcd.c
    avr-gcc ${GCCFLAGS} -o lcd.o -c lcd.c

uart.o: uart.c
    avr-gcc ${GCCFLAGS} -o uart.o -c uart.c


// initialload.c
// for NerdKits with ATmega328p

#define F_CPU 14745600

#include <stdio.h>

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>
#include "../libnerdkits/io_328p.h"
#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"

// PC4 -- LED anode

int main() {
  // LED as output
  DDRC |= (1<<PC4);

  // turn on LED
  PORTC |= (1<<PC4);

  // fire up the LCD

  // print message to screen
  //             20 columns wide:
  //                     01234567890123456789
  lcd_write_string(PSTR("  Congratulations!  "));
  lcd_write_string(PSTR("  Your USB NerdKit  "));
  lcd_write_string(PSTR("      is alive!     "));

  // turn off that LED
  PORTC &= ~(1<<PC4);

  // busy loop
  while(1) {
    // do nothing

  return 0;

initialload makefile:

GCCFLAGS=-g -Os -Wall -mmcu=atmega328P
LINKFLAGS=-Wl,-u,vfprintf -lprintf_flt -Wl,-u,vfscanf -lscanf_flt -lm
AVRDUDEFLAGS=-c avr109 -p m328P -b 115200 -P com5
LINKOBJECTS=../libnerdkits/delay.o ../libnerdkits/lcd.o ../libnerdkits/uart.o

all:    initialload-upload

initialload.hex:    initialload.c
    make -C ../libnerdkits
    avr-gcc ${GCCFLAGS} ${LINKFLAGS} -o initialload.o initialload.c ${LINKOBJECTS}
    avr-objcopy -j .text -O ihex initialload.o initialload.hex

initialload.ass:    initialload.hex
    avr-objdump -S -d initialload.o > initialload.ass

initialload-upload: initialload.hex
    avrdude ${AVRDUDEFLAGS} -U flash:w:initialload.hex:a
July 14, 2011
by hevans
(NerdKits Staff)

hevans's Avatar

Hi konakat,

I believe the p at the end of atmega328p has to be lower case. That could be the root cause of this problem.


July 14, 2011
by konakat
konakat's Avatar

The "P" didn't make any difference but got the trafficlight to program by adding the #include "../libnerdkits/io_328p.h" statement to the lcd.c file.

// lcd.c // for NerdKits // // // PIN DEFINITIONS: // // // PD2-5 -- LCD DB4-7 (pins 11-14) (was PB3-6) // PD6 -- LCD E (pin 6) (was PA5) // PD7 -- LCD RS (pin 4) (was PA4)

include "../libnerdkits/io_328p.h"

include <avr/io.h>

include <avr/pgmspace.h>

include <inttypes.h>

include <stdio.h>

include "lcd.h"

include "delay.h"

// lcd_set_type_data() void lcd_set_type_data() { PORTD |= (1<<PD7); }

// lcd_set_type_command() void lcd_set_type_command() { PORTD &= ~(1<<PD7); }

// lcd_write_nibble(...) void lcd_write_nibble(char c) {

// NOTE: only 2 or 3 work in the delays here.

// set data PORTD &= ~(0x0f << 2); PORTD |= (c&0x0f) << 2;

// E high PORTD |= (1<<PD6); delay_us(1); // E low PORTD &= ~(1<<PD6); delay_us(1);


void lcd_write_byte(char c) { lcd_write_nibble( (c >> 4) & 0x0f ); lcd_write_nibble( c & 0x0f ); delay_us(80); }

void lcd_clear_and_home() { lcd_set_type_command(); lcd_write_byte(0x01); delay_ms(50); lcd_write_byte(0x02); delay_ms(50); }

void lcd_home() { lcd_set_type_command(); lcd_write_byte(0x02); delay_ms(50); }

void lcd_write_data(char c) { lcd_set_type_data(); lcd_write_byte(c); }

// lcd_write_int16 void lcd_write_int16(int16_t in) { uint8_t started = 0;

uint16_t pow = 10000;

if(in < 0) { lcd_write_data('-'); in = -in; }

while(pow >= 1) { if(in / pow > 0 || started || pow==1) { lcd_write_data((uint8_t) (in/pow) + '0'); started = 1; in = in % pow; }

pow = pow / 10;



// lcd_write_int16_centi // assumes that its measured in centi-whatevers void lcd_write_int16_centi(int16_t in) { uint8_t started = 0;

uint16_t pow = 10000;

if(in < 0) { lcd_write_data('-'); in = -in; }

while(pow >= 1) { if(in / pow > 0 || started || pow==1) { lcd_write_data((uint8_t) (in/pow) + '0'); started = 1; in = in % pow; }

if(pow == 100) {
  if(!started) {
  started = 1;

pow = pow / 10;



void lcd_write_string(const char *x) { // assumes x is in program memory while(pgm_read_byte(x) != 0x00) lcd_write_data(pgm_read_byte(x++)); }

void lcd_goto_position(uint8_t row, uint8_t col) { lcd_set_type_command();

// 20x4 LCD: offsets 0, 0x40, 20, 0x40+20 uint8_t row_offset = 0; switch(row) { case 0: row_offset = 0; break; case 1: row_offset = 0x40; break; case 2: row_offset = 20; break; case 3: row_offset = 0x40+20; break; }

lcd_write_byte(0x80 | (row_offset + col)); }

void lcd_line_one() { lcd_goto_position(0, 0); } void lcd_line_two() { lcd_goto_position(1, 0); } void lcd_line_three() { lcd_goto_position(2, 0); } void lcd_line_four() { lcd_goto_position(3, 0); }

// lcd_init() void lcd_init() { // set pin driver directions // (output on PD7,PD6, and PD3-6) DDRD |= 0xfc;

// wait 100msec delay_ms(100); lcd_set_type_command();

// do reset lcd_write_nibble(0x03); delay_ms(6); lcd_write_nibble(0x03); delay_us(250); lcd_write_nibble(0x03); delay_us(250);

// write 0010 (data length 4 bits) lcd_write_nibble(0x02); // set to 2 lines, font 5x8 lcd_write_byte(0x28); // disable LCD //lcd_write_byte(0x08); // enable LCD lcd_write_byte(0x0c); // clear display lcd_write_byte(0x01); delay_ms(5); // enable LCD lcd_write_byte(0x0c); // set entry mode lcd_write_byte(0x06);

// set cursor/display shift lcd_write_byte(0x14);

// clear and home lcd_clear_and_home(); }

int lcd_putchar(char c, FILE *stream) { lcd_write_data(c); return 0; }

June 16, 2012
by raildoc
raildoc's Avatar

I'm bugged! My "control" program is based on tempsensor with digital logic led and lcd outputs. It works fine on a 168, but I was running out of memory-so I switched to a 328p. After making all the Nanoguide changes, I pre-checked it with led-blink and two-line lcd scroll programs-no problem. I loaded my control program on the 328p, and the logic portions for the leds worked OK-but the lcd was garbage. All I get is a line4 string on line 1 and nothing else. I am missing all the ADC and voltage outputs and other text. I am literally double-checking everything: the programs are exact (I think) line and syntax copies (except for the 328p mods); I have two new re-wired USB-powered boards, two working 328s, two program headers-even two lcds. Nada. I've gone through the Forums. The lcd works with the 328 scrolling program, but not my larger control program? Help, please!

June 16, 2012
by Ralphxyz
Ralphxyz's Avatar

raildoc, you really should not just randomly hijack on going threads.

Start a new question.

By starting a new question your chances of getting answered increase as "Unable to get 328p to upload - PD7 undeclared" might no longer be followed by everyone but a new question "might" get their attention.


Post a Reply

Please log in to post a reply.

Did you know that you can make a spooky Halloween Jack-O-Lantern with a microcontroller? Learn more...