Anmelden

Archiv verlassen und diese Seite im Standarddesign anzeigen : Programm probleme



Spongebob85
16.02.2007, 17:32
Moin!!!

Ich hab mir grade ein kleines Programm ausgedacht. Einzelne LEDs leuchten lassen funktioniert. Hab WinAVR und so endlich zum laufen bekommen.
Kann mir jemand sagen, was hier falsch ist? Das is echt alles voll kompliziert.

Hier das programm:

#include <avr/io.h>
#include <stdint.h>

int main (void) {

uint8_t portd; //Per int wird portd hoffentlich als Variable deklariert
portd = PIND; //portd soll immer den Zustand der Pins annehmen

DDRA = 0xff; //Das bedeutet das Port B komplett als Ausgang deklariert ist, denk ich
DDRD = 0x00; //Das bedeutet das Port D komplett als Eingang deklariert ist, denk ich

if (portd==1) //Wenn PortD 1 ist, also PD0 ein Signal "+5V" bekommt soll der komplette Porta
{
PORTA = 0x00; //auf 0V steuern
}

else
PORTA = 0xff; //wenn PortD nicht 1 ist sollen die pins des PortA 5V haben

while(1) {;}

return 0;
}


MfG Jan

vklaffehn
16.02.2007, 17:51
Moin,

da kann ich hoffentlich auch mal helfen :

erstens sollte die Routine in der While(1) -Schleife stehen, sonst wird's nur einmal ausgeführt und danach nie wieder.
Also quasi


int main(void){
while (1){
// das hier die ganze zeit wiederholen
}
}

außerdem ist

uint8_t portd; //Per int wird portd hoffentlich als Variable deklariert
portd = PIND; //portd soll immer den Zustand der Pins annehmen

irgendwie seltsam, da würde ich doch direkt PIND nehmen, um den Zustand der Eingangspins auszulesen.

Also z.B. so:


#include <avr/io.h>
#include <stdint.h>

int main (void) {

//einmalig die Ports festlegen

DDRA = 0xff; //Das bedeutet das Port B komplett als Ausgang deklariert ist, denk ich
DDRD = 0x00; //Das bedeutet das Port D komplett als Eingang deklariert ist, denk ich

while (1) {

// die folgende Abfrage funktioniert nur, wenn nur an PD0 high anliegt und an allen anderen low!! ich würd's so machen
// if ((PIND&(1<<0) !=0) ,damit ist der Zustand der anderen Pins egal

if (PIND==1) //Wenn PortD 1 ist, also PD0 ein Signal "+5V" bekommt soll der komplette Porta
{
PORTA = 0x00; //auf 0V steuern
}
else
PORTA = 0xff; //wenn PortD nicht 1 ist sollen die pins des PortA 5V haben
} //ende der While-schleife

return 0;
}

Spongebob85
16.02.2007, 18:38
Das versteh ich nicht:
if ((PIND&(1<<0) !=0) ,damit ist der Zustand der anderen Pins egal

Ich kenne daran nur eine UNGLEICH verknüpfung wieder !=
Sonst kenn ich nur kleiner als, größer als, kleinergleich etc.
Dann kenn ich noch UND, ODER, NICHT.
Aber was soll "PIND&(1<<0)" bedeuten?

vklaffehn
16.02.2007, 18:55
ganz einfach, keine panik ;-)

(a<<b) : verschiebt bitweise den wert a um b bits nach links
(1<<0) : 00000001 nullmal nach links = 00000001
damit kann man schön einzelne bits setzen, z.B. wenn man Bit 3 haben will
(1<<3) : 00000001 wird danach zu 00001000

PIND ist das byte, das den Zustand der Eingangspins von PORTD beinhaltet, das '&' ist ein bitweises 'und'

nehmen wir an, an D sieht es binär so aus:
00000000 : alle pins auf low
00000000 'bitweises und' 00000001 : ergibt '0', da im Ergebnis ein Bit nur dann gesetzt wird, wenn es in beiden Operanden gesetzt ist. Daher kriegen wir immer '0', solange Bit0 auf 0 ist, die restlichen Bits werden durch die Verknüpfung ausmaskiert, PIND kann also z.B. auch so aussehen :
11010010 : verknüpft wie oben ergibt auch 0, mann kann also später die anderen Pins auch benutzen, ohne das die Abfrage darunter leidet.

sobald Bit0 jetzt mal high ist, sieht das dann so aus:
xxxxxxx1 'bitweises und' 00000001 : ergibt 1 -> !=0

das '!=0' macht Sinn, wenn man z.B. nicht PD0 sondern PD5 abfragen will:
00100000 & (1<<5) : ergibt nämlich 1<<5=32 -> !=0

ich hoffe, das hilft dir ein wenig.

Pascal
16.02.2007, 19:49
@ Spongebob85: falls du schreibfaul bist ;-), kannst du das !=0 auch weglassen, denn das macht das if quasi schon mit
wenn PIND&(1<<0) 0 ist, entspricht das false und wenn der wert ungleich 0 ist, entspricht das einem true

Spongebob85
17.02.2007, 02:11
Das is ja echt relativ einfach zu verstehen! Hätte ich nicht gedacht. War aber auch echt ne gute erklährung!!!

Hab mein Programm jetzt umgeschrieben. Das funzt aber irgendwie immer noch nicht.

Das Prog sieht jetzt so aus:



#include <avr/io.h>
#include <stdint.h>

int main (void) {


DDRA = 0xff; //Das bedeutet das Port B komplett als Ausgang deklariert ist, denk ich
DDRD = 0x00; //Das bedeutet das Port D komplett als Eingang deklariert ist, denk ich

while (1)
{

if (PIND&(1<<0) !=0)
{
PORTA = 0x01; //PortA0 auf 5V steuern wenn PortA ungleich 0
}

else
PORTA = 0x00; //wenn PortD0 1 ist sollen die pins des PortA 0V haben

} //ende der While-schleife

return 0;
}




Irgendwie geht das trotzdem nicht. Was hab ich denn jetzt noch falsch gemacht???

vklaffehn
17.02.2007, 07:54
Moin!
Im Prinzip richtig, allerdings hab ich nochmal die if-Zeile geändert, ich glaube, da kommt sonst auch eine Warnung vom Compiler. Also der If-Teil (setze PA0 auf high) wird ausgeführt, wenn PD0 auf high liegt, und der Else-Teil (setze PA0 auf low) bei PD0 low, das war in Deinen Kommentaren nicht ganz klar.
Und das setzen und löschen von einzelnen Ausgangsbits hab ich auch mal wie oben beschrieben umgebaut, damit das Ändern von PA0 auch funktioniert, ohne dass die anderen Bits beeinflusst werden, vorrausgesetzt, du willst mal nur einen Pin umschalten, und nicht den ganzen Port.
Ansonsten sollte es so eigentlich funktionieren.



#include <avr/io.h>
#include <stdint.h>

int main (void) {


DDRA = 0xff; //Das bedeutet das Port B komplett als Ausgang deklariert ist, denk ich
DDRD = 0x00; //Das bedeutet das Port D komplett als Eingang deklariert ist, denk ich

while (1)
{

if (PIND&(1<<0) !=0) // ruhig die bitweise Verknüpfung noch mal in Klammern, also if ((PIND & (1<<0)) != 0), konkret -> wenn PD high dann
{
PORTA |= (1<<0); //PortA0 auf 5V steuern wenn PortD0 ungleich 0, ausgeschrieben heißt das PORTA = PORTA | (1<<), wobei '|' bitweises 'oder' bedeutet
}

else
PORTA &= (1<<0); //wenn PortD0 0 ist soll PortA0 0V haben ,das heißt : ~(1<<0) setze Bit0 und invertiere das Ergebnis, danach mach eine &-Verknüpfung mit PORTA

} //ende der While-schleife

return 0;
}

Wenn man z.B. PA1 und PA3 auf high schalten möchte :

PORTA |= (1<<1)|(1<<3)

und zum wieder low schalten nur dieser beiden Pins :

PORTA &= ~( (1<<1)|(1<<3) )

Zu den Operatoren hab ich grad noch das hier gefunden :
http://www.peacesoftware.de/ckurs4.html

Spongebob85
17.02.2007, 12:16
//PortA0 auf 5V steuern wenn PortD0 ungleich 0
das sollte eigentlich andersrum sein. Wenn PortD0 ungleich 0 ist also 5V Potential anliegt soll PortA0 auf 0V steuern. Die LED liegt mit der kathode am µController, aber das kann ich ja ummodeln wie ich will :-) Die if-Anweisung is mir jetzt völlig verständlich und das (x<<y) hab ich auch begriffen. Jetzt hast du aber |= geschrieben. Das kenn ich wieder nicht. Aber ich werde mir das mit den Operatoren mal ansehen. vielleicht werde ich da ja schlauer.

Pascal
17.02.2007, 13:25
Jetzt hast du aber |= geschrieben. Das kenn ich wieder nicht.

Was genau verstehst du daran nicht? vklaffehn hat im von ihm geposteten code die ausgeschriebene Variante davon geschrieben.

Spongebob85
17.02.2007, 14:30
Ich kann mir unter diesem Bitweisem oder einfach nicht so wirklich was vorstellen.

Hab das programm jetzt genau so gemacht:



#include <avr/io.h>
#include <stdint.h>

int main (void)
{


DDRA = 0xff;
DDRD = 0x00;


while (1)
{

if ((PIND & (1<<0)) != 0) // ruhig die bitweise Verknüpfung noch mal in Klammern, also if ((PIND & (1<<0)) != 0), konkret -> wenn PD high dann
{
PORTA |= (1<<0); //PortA0 auf 5V steuern wenn PortD0 ungleich 0, ausgeschrieben heißt das PORTA = PORTA | (1<<), wobei '|' bitweises 'oder' bedeutet
}

else
PORTA &= (1<<0); //wenn PortD0 0 ist soll PortA0 0V haben ,das heißt : ~(1<<0) setze Bit0 und invertiere das Ergebnis, danach mach eine &-Verknüpfung mit PORTA

} //ende der While-schleife

return 0;
}


Wenn ich jetzt "Make all" drücke kommt immernoch die gleiche Fehlermeldung wie am anfang wo ich euch noch nicht gefragt hab, und zwar diese:



> "make.exe" all
MAKE Version 5.2 Copyright (c) 1987, 2000 Borland
Error makefile 451: Command syntax error
Error makefile 452: Command syntax error
Error makefile 453: Command syntax error
Error makefile 454: Command syntax error
Error makefile 457: Command syntax error
Error makefile 458: Command syntax error
Error makefile 460: Command syntax error
Error makefile 461: Command syntax error
Error makefile 463: Command syntax error
Error makefile 465: Command syntax error
Error makefile 466: Command syntax error
Error makefile 521: Colon expected
Error makefile 530: Colon expected
Error makefile 552: Too many rules for target 'obj/%.o'
Error makefile 562: Too many rules for target '%.s'
Error makefile 569: Too many rules for target 'obj/%.o'
Error makefile 598: Command syntax error
*** 17 errors during make ***

> Process Exit Code: 1
> Time Taken: 00:01


Ich kann mir das echt nicht erklähren. Hoffe es hat noch jemand ein guten tipp.

MfG Jan

Pascal
17.02.2007, 15:28
Poste mal dein makefile, so wie es aussieht, stimmt auch darin etwas nicht. Woher hast du das? Ist es selbst programmiert?

Spongebob85
17.02.2007, 16:17
Den Makefile hab ich mit "mFile" gemacht (das programm was bei WinAVR bei ist) Da hab ich nur eingestellt:

-Main file name: Testpp
-MCU Type: ATMega32
-Programmer: stk200
-Port: LPT1

Der Makefile hat aber meiner Meinung nach schon mal funktioniert.

hier nochmal der ganze Makefile:



# Hey Emacs, this is a -*- makefile -*-
#----------------------------------------------------------------------------
# WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al.
#
# Released to the Public Domain
#
# Additional material for this makefile was written by:
# Peter Fleury
# Tim Henigan
# Colin O'Flynn
# Reiner Patommel
# Markus Pfaff
# Sander Pool
# Frederik Rouleau
# Carlos Lamas
#
#----------------------------------------------------------------------------
# On command line:
#
# make all = Make software.
#
# make clean = Clean out built project files.
#
# make coff = Convert ELF to AVR COFF.
#
# make extcoff = Convert ELF to AVR Extended COFF.
#
# make program = Download the hex file to the device, using avrdude.
# Please customize the avrdude settings below first!
#
# make debug = Start either simulavr or avarice as specified for debugging,
# with avr-gdb or avr-insight as the front end for debugging.
#
# make filename.s = Just compile filename.c into the assembler code only.
#
# make filename.i = Create a preprocessed source file for use in submitting
# bug reports to the GCC project.
#
# To rebuild project do "make clean" then "make all".
#----------------------------------------------------------------------------


# MCU name
MCU = atmega32


# Processor frequency.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency. You can then use this symbol in your source code to
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
# automatically to create a 32-bit value in your source code.
# Typical values are:
# F_CPU = 1000000
# F_CPU = 1843200
# F_CPU = 2000000
# F_CPU = 3686400
# F_CPU = 4000000
# F_CPU = 7372800
# F_CPU = 8000000
# F_CPU = 11059200
# F_CPU = 14745600
# F_CPU = 16000000
# F_CPU = 18432000
# F_CPU = 20000000
F_CPU = 8000000


# Output format. (can be srec, ihex, binary)
FORMAT = ihex


# Target file name (without extension).
TARGET = testpp


# Object files directory
OBJDIR = obj


# List C source files here. (C dependencies are automatically generated.)
SRC =


# List C++ source files here. (C dependencies are automatically generated.)
CPPSRC = main.cpp


# List Assembler source files here.
# Make them always end in a capital .S. Files ending in a lowercase .s
# will not be considered source files but generated files (assembler
# output from the compiler), and will be deleted upon "make clean"!
# Even though the DOS/Win* filesystem matches both .s and .S the same,
# it will preserve the spelling of the filenames, and gcc itself does
# care about how the name is spelled on its command-line.
ASRC =


# Optimization level, can be [0, 1, 2, 3, s].
# 0 = turn off optimization. s = optimize for size.
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
OPT = s


# Debugging format.
# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
# AVR Studio 4.10 requires dwarf-2.
# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
DEBUG = dwarf-2


# List any extra directories to look for include files here.
# Each directory must be seperated by a space.
# Use forward slashes for directory separators.
# For a directory that has spaces, enclose it in quotes.
EXTRAINCDIRS =


# Compiler flag to set the C Standard level.
# c89 = "ANSI" C
# gnu89 = c89 plus GCC extensions
# c99 = ISO C99 standard (not yet fully implemented)
# gnu99 = c99 plus GCC extensions
CSTANDARD = -std=gnu99


# Place -D or -U options here for C sources
CDEFS = -DF_CPU=$(F_CPU)UL


# Place -D or -U options here for C++ sources
CPPDEFS = -DF_CPU=$(F_CPU)UL
#CPPDEFS += -D__STDC_LIMIT_MACROS
#CPPDEFS += -D__STDC_CONSTANT_MACROS



#---------------- Compiler Options C ----------------
# -g*: generate debugging information
# -O*: optimization level
# -f...: tuning, see GCC manual and avr-libc documentation
# -Wall...: warning level
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns...: create assembler listing
CFLAGS = -g$(DEBUG)
CFLAGS += $(CDEFS)
CFLAGS += -O$(OPT)
#CFLAGS += -mint8
#CFLAGS += -mshort-calls
CFLAGS += -funsigned-char
CFLAGS += -funsigned-bitfields
CFLAGS += -fpack-struct
CFLAGS += -fshort-enums
#CFLAGS += -fno-unit-at-a-time
CFLAGS += -Wall
CFLAGS += -Wstrict-prototypes
CFLAGS += -Wundef
#CFLAGS += -Wunreachable-code
#CFLAGS += -Wsign-compare
CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
CFLAGS += $(CSTANDARD)


#---------------- Compiler Options C++ ----------------
# -g*: generate debugging information
# -O*: optimization level
# -f...: tuning, see GCC manual and avr-libc documentation
# -Wall...: warning level
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns...: create assembler listing
CPPFLAGS = -g$(DEBUG)
CPPFLAGS += $(CPPDEFS)
CPPFLAGS += -O$(OPT)
#CPPFLAGS += -mint8
#CPPFLAGS += -mshort-calls
CPPFLAGS += -funsigned-char
CPPFLAGS += -funsigned-bitfields
CPPFLAGS += -fpack-struct
CPPFLAGS += -fshort-enums
CPPFLAGS += -fno-exceptions
#CPPFLAGS += -fno-unit-at-a-time
CPPFLAGS += -Wall
#CPPFLAGS += -Wstrict-prototypes
CFLAGS += -Wundef
#CPPFLAGS += -Wunreachable-code
#CPPFLAGS += -Wsign-compare
CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst)
CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
#CPPFLAGS += $(CSTANDARD)


#---------------- Assembler Options ----------------
# -Wa,...: tell GCC to pass this to the assembler.
# -ahlms: create listing
# -gstabs: have the assembler create line number information; note that
# for use in COFF files, additional information about filenames
# and function names needs to be present in the assembler source
# files -- see avr-libc docs [FIXME: not yet described there]
ASFLAGS = -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs


#---------------- Library Options ----------------
# Minimalistic printf version
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min

# Floating point printf version (requires MATH_LIB = -lm below)
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt

# If this is left blank, then it will use the Standard printf version.
PRINTF_LIB =
#PRINTF_LIB = $(PRINTF_LIB_MIN)
#PRINTF_LIB = $(PRINTF_LIB_FLOAT)


# Minimalistic scanf version
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min

# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt

# If this is left blank, then it will use the Standard scanf version.
SCANF_LIB =
#SCANF_LIB = $(SCANF_LIB_MIN)
#SCANF_LIB = $(SCANF_LIB_FLOAT)


MATH_LIB = -lm



#---------------- External Memory Options ----------------

# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# used for variables (.data/.bss) and heap (malloc()).
#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff

# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# only used for heap (malloc()).
#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff

EXTMEMOPTS =



#---------------- Linker Options ----------------
# -Wl,...: tell GCC to pass this to linker.
# -Map: create map file
# --cref: add cross reference to map file
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
LDFLAGS += $(EXTMEMOPTS)
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
#LDFLAGS += -T linker_script.x



#---------------- Programming Options (avrdude) ----------------

# Programming hardware: alf avr910 avrisp bascom bsd
# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500
#
# Type: avrdude -c ?
# to get a full listing.
#
AVRDUDE_PROGRAMMER = stk200

# com1 = serial port. Use lpt1 to connect to parallel port.
AVRDUDE_PORT = lpt1

AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep


# Uncomment the following if you want avrdude's erase cycle counter.
# Note that this counter needs to be initialized first using -Yn,
# see avrdude manual.
#AVRDUDE_ERASE_COUNTER = -y

# Uncomment the following if you do /not/ wish a verification to be
# performed after programming the device.
#AVRDUDE_NO_VERIFY = -V

# Increase verbosity level. Please use this when submitting bug
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
# to submit bug reports.
#AVRDUDE_VERBOSE = -v -v

AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)



#---------------- Debugging Options ----------------

# For simulavr only - target MCU frequency.
DEBUG_MFREQ = $(F_CPU)

# Set the DEBUG_UI to either gdb or insight.
# DEBUG_UI = gdb
DEBUG_UI = insight

# Set the debugging back-end to either avarice, simulavr.
DEBUG_BACKEND = avarice
#DEBUG_BACKEND = simulavr

# GDB Init Filename.
GDBINIT_FILE = __avr_gdbinit

# When using avarice settings for the JTAG
JTAG_DEV = /dev/com1

# Debugging port used to communicate between GDB / avarice / simulavr.
DEBUG_PORT = 4242

# Debugging host used to communicate between GDB / avarice / simulavr, normally
# just set to localhost unless doing some sort of crazy debugging when
# avarice is running on a different computer.
DEBUG_HOST = localhost



#================================================= ===========================


# Define programs and commands.
SHELL = sh
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
SIZE = avr-size
NM = avr-nm
AVRDUDE = avrdude
REMOVE = rm -f
REMOVEDIR = rm -rf
COPY = cp
WINSHELL = cmd


# Define Messages
# English
MSG_ERRORS_NONE = Errors: none
MSG_BEGIN = -------- begin --------
MSG_END = -------- end --------
MSG_SIZE_BEFORE = Size before:
MSG_SIZE_AFTER = Size after:
MSG_COFF = Converting to AVR COFF:
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
MSG_FLASH = Creating load file for Flash:
MSG_EEPROM = Creating load file for EEPROM:
MSG_EXTENDED_LISTING = Creating Extended Listing:
MSG_SYMBOL_TABLE = Creating Symbol Table:
MSG_LINKING = Linking:
MSG_COMPILING = Compiling C:
MSG_COMPILING_CPP = Compiling C++:
MSG_ASSEMBLING = Assembling:
MSG_CLEANING = Cleaning project:
MSG_CREATING_LIBRARY = Creating library:




# Define all object files.
OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o)

# Define all listing files.
LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst)


# Compiler flags to generate dependency files.
GENDEPFLAGS = -MD -MP -MF .dep/$(@F).d


# Combine all necessary flags and optional flags.
# Add target processor to flags.
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS)
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)





# Default target.
all: begin gccversion sizebefore build sizeafter end

# Change the build target to build a HEX file or a library.
build: elf hex eep lss sym
#build: lib


elf: $(TARGET).elf
hex: $(TARGET).hex
eep: $(TARGET).eep
lss: $(TARGET).lss
sym: $(TARGET).sym
LIBNAME=lib$(TARGET).a
lib: $(LIBNAME)



# Eye candy.
# AVR Studio 3.x does not check make's exit code but relies on
# the following magic strings to be generated by the compile job.
begin:
@echo
@echo $(MSG_BEGIN)

end:
@echo $(MSG_END)
@echo


# Display size of file.
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
ELFSIZE = $(SIZE) -A $(TARGET).elf
AVRMEM = avr-mem.sh $(TARGET).elf $(MCU)

sizebefore:
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
$(AVRMEM) 2>/dev/null; echo; fi

sizeafter:
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
$(AVRMEM) 2>/dev/null; echo; fi



# Display compiler version information.
gccversion :
@$(CC) --version



# Program the device.
program: $(TARGET).hex $(TARGET).eep
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)


# Generate avr-gdb config/init file which does the following:
# define the reset signal, load the target file, connect to target, and set
# a breakpoint at main().
gdb-config:
@$(REMOVE) $(GDBINIT_FILE)
@echo define reset >> $(GDBINIT_FILE)
@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
@echo end >> $(GDBINIT_FILE)
@echo file $(TARGET).elf >> $(GDBINIT_FILE)
@echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE)
ifeq ($(DEBUG_BACKEND),simulavr)
@echo load >> $(GDBINIT_FILE)
endif
@echo break main >> $(GDBINIT_FILE)

debug: gdb-config $(TARGET).elf
ifeq ($(DEBUG_BACKEND), avarice)
@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
@$(WINSHELL) /c pause

else
@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
$(DEBUG_MFREQ) --port $(DEBUG_PORT)
endif
@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)




# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
COFFCONVERT = $(OBJCOPY) --debugging
COFFCONVERT += --change-section-address .data-0x800000
COFFCONVERT += --change-section-address .bss-0x800000
COFFCONVERT += --change-section-address .noinit-0x800000
COFFCONVERT += --change-section-address .eeprom-0x810000



coff: $(TARGET).elf
@echo
@echo $(MSG_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof


extcoff: $(TARGET).elf
@echo
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof



# Create final output files (.hex, .eep) from ELF output file.
%.hex: %.elf
@echo
@echo $(MSG_FLASH) $@
$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@

%.eep: %.elf
@echo
@echo $(MSG_EEPROM) $@
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 -O $(FORMAT) $< $@

# Create extended listing file from ELF output file.
%.lss: %.elf
@echo
@echo $(MSG_EXTENDED_LISTING) $@
$(OBJDUMP) -h -S $< > $@

# Create a symbol table from ELF output file.
%.sym: %.elf
@echo
@echo $(MSG_SYMBOL_TABLE) $@
$(NM) -n $< > $@



# Create library from object files.
.SECONDARY : $(TARGET).a
.PRECIOUS : $(OBJ)
%.a: $(OBJ)
@echo
@echo $(MSG_CREATING_LIBRARY) $@
$(AR) $@ $(OBJ)


# Link: create ELF output file from object files.
.SECONDARY : $(TARGET).elf
.PRECIOUS : $(OBJ)
%.elf: $(OBJ)
@echo
@echo $(MSG_LINKING) $@
$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)


# Compile: create object files from C source files.
$(OBJDIR)/%.o : %.c
@echo
@echo $(MSG_COMPILING) $<
$(CC) -c $(ALL_CFLAGS) $< -o $@


# Compile: create object files from C++ source files.
$(OBJDIR)/%.o : %.cpp
@echo
@echo $(MSG_COMPILING_CPP) $<
$(CC) -c $(ALL_CPPFLAGS) $< -o $@


# Compile: create assembler files from C source files.
%.s : %.c
$(CC) -S $(ALL_CFLAGS) $< -o $@


# Compile: create assembler files from C++ source files.
%.s : %.cpp
$(CC) -S $(ALL_CPPFLAGS) $< -o $@


# Assemble: create object files from assembler source files.
$(OBJDIR)/%.o : %.S
@echo
@echo $(MSG_ASSEMBLING) $<
$(CC) -c $(ALL_ASFLAGS) $< -o $@


# Create preprocessed source for use in sending a bug report.
%.i : %.c
$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@


# Target: clean project.
clean: begin clean_list end

clean_list :
@echo
@echo $(MSG_CLEANING)
$(REMOVE) $(TARGET).hex
$(REMOVE) $(TARGET).eep
$(REMOVE) $(TARGET).cof
$(REMOVE) $(TARGET).elf
$(REMOVE) $(TARGET).map
$(REMOVE) $(TARGET).sym
$(REMOVE) $(TARGET).lss
$(REMOVEDIR) $(OBJDIR)
$(REMOVE) $(SRC:.c=.s)
$(REMOVE) $(SRC:.c=.d)
$(REMOVEDIR) .dep


# Create object files directory
$(shell mkdir $(OBJDIR) 2>/dev/null)


# Include the dependency files.
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)


# Listing of phony targets.
.PHONY : all begin finish end sizebefore sizeafter gccversion \
build elf hex eep lss sym coff extcoff \
clean clean_list program debug gdb-config

Spongebob85
17.02.2007, 19:03
Ich hab grade echt was krasses rausgefunden!!!
Wenn ich auf "make all" drücke steht da, wo der bericht steht in der 1. Zeile "MAKE Version 5.2 Copyright (c) 1987, 2000 Borland". Ich hab grade vor 2 Tagen Delphi 2005 von Borland installiert. Jetzt hab ich delphi einfach mal gelöscht und alles funktioniert wieder. Das finde ich ganz schön scheiße, weil ich delphi für die schule brauch und WinAVR Programmers notepad für meinen Roboter. Das is ganz schön scheiße das die sich stöhren, und ganzschöner zufall das ich´s rausgefunden hab.

SprinterSB
17.02.2007, 20:20
Wenn du mehrere maked ainstalliert hast und nur "make" aufrufst, dann führt dein OS das erste make aus, daß es im Pfad (%PATH% oder $PATH) findet.
Üblicherweise hängen neue Programme beim Installieren ihr Verzeichnis vorne an PATH an. Dann kannst du einfach das make, das du haben willst, explizit aufrufen, also *mit* kompletem Pfad. c:\winavr-gedöns\util\make.exe oder so.

Spongebob85
18.02.2007, 01:54
Ich hab das mit dem Makefile jetzt ja wie gesagt endlich hinbekommen und schon kommt das nächste problem. Im Programers Notepad klicke ich [WinAVR] Programm an und dann steht bei "Output" das hier:

> "make.exe" program
avrdude -p atmega32 -P lpt1 -c stk200 -U flash:w:testpp.hex

avrdude: AVR device not responding
avrdude: initialization failed, rc=-1
Double check connections and try again, or use -F to override
this check.


avrdude done. Thank you.

make.exe: *** [program] Error 1

> Process Exit Code: 2
> Time Taken: 00:01

Was kann das denn schon wieder sein? Ich hab alle verbindungen mehrere male kontrolliert. Hab sogar meine ganze schaltung noch mal neu gesteckt und es kommt immer diese meldung.

Wäre für jede Hilfe dankbar. Schönen Abend noch!

SprinterSB
18.02.2007, 11:54
Wie gesagt, der Duse schafft es nicht, sich über dein an LPT1 angeschlossenes STK200 mit dem ATmega32 zu unterhalten...

Am wahrscheinlichsten:
- Progger funzt nicht
- fehlerhafte Parallelport-Konfiguration (muss bidirektional sein)
- falsche Fuses/Takteinstellung am AVR
- µC ist gelockt, erlaubt kein ISP, ...
- falsche Parameter an avrdude angegeben (du hast garkein STK200, ...)
- keine Zugriffsberechtigung auf den Parallelport
- Passt der Anschluss des STK200 an den Parallelport zu der Pindefinition des Parallelports in avdrdude.conf?

Spongebob85
20.02.2007, 16:07
Moin!!! Ich hab jetzt endlich mal wieder Zeit mit dem µC rumzuspielen. Hab das Problem auf die reihe bekommen (konnte doch nicht mehr programmieren). Nachdem mir mein Steckbrett runtergefallen ist, und ein loch ins laminat gemacht hat, hatte ein Beinchen keinen Kontakt mehr...naja, jetzt funzt ja wieder alles. Bis auf das Programm.

Hab dieses Programm auf den µC geladen:


#include <avr/io.h>
#include <stdint.h>

int main (void)
{


DDRA = 0xff;
DDRD = 0x00;


while (1)
{

if ((PIND & (1<<0)) != 0) // ruhig die bitweise Verknüpfung noch mal in Klammern, also if ((PIND & (1<<0)) != 0), konkret -> wenn PD high dann
{
PORTA |= (1<<0); //PortA0 auf 5V steuern wenn PortD0 ungleich 0, ausgeschrieben heißt das PORTA = PORTA | (1<<), wobei '|' bitweises 'oder' bedeutet
}

else
PORTA &= (1<<0); //wenn PortD0 0 ist soll PortA0 0V haben ,das heißt : ~(1<<0) setze Bit0 und invertiere das Ergebnis, danach mach eine &-Verknüpfung mit PORTA

} //ende der While-schleife

return 0;
}


Wenn ich auf [WinAVR] Programm drücke, geht sofort die LED an, die an PA0 hängt (Anode an µC, kathode über Widerstand an Masse).
Eine änderung des Signals 0V oder 5V ändert daran gar nichts.

Hoffe ihr könnt helfen.

MfG Jan

vklaffehn
20.02.2007, 16:24
Hallo!!
Fast gut, es fehlt, soweit ich das sehe, nur eine fiese Kleinigkeit, nämlich das '~' in 'PORTA &= (1<<0)'

nach dem IF passier bei Dir folgendes:
00000000
or
00000001
ergibt
00000001
-> LED geht an, der Zustand der anderen Bits ändert sich nicht/ist egal.
beim 'ELSE'
00000001
and
00000001
ergibt
00000001
-> LED bleibt an, allerdings werden alle anderen Bits auf 0 gesetzt
d.h., sobald die LED einmal an war, bleibt Sie an.
macht man vor das '(1<<0)' noch ein '~', wird das ganze invertiert, es passiert also folgendes :
00000001
and
11111110 (1.Bit gesetzt und Ergebnis invertiert)
ergibt 00000000
-> LED aus, Zustand der anderen Bits ändert sich nicht

MfG
Volker

SprinterSB
20.02.2007, 16:26
Lies mal sorgfältig deinen vorletzten Kommentar und was da zu dem Schniedel (~) steht, und dir geht ein Licht auf! Und der LED auch...

Spongebob85
20.02.2007, 17:52
Funktioniert. Nur scheint es wie bei TTL-Gattern zu sein, das offene eingänge als 1 verarbeitet werden. Die LED ist nämlich so lange an, bis ich den eingang auf Masse ziehe. Das heißt externer oder interner Pulldown Widerstand, interner wär mir lieber. Damit bin ich beim nächsten Problem.
Es fällt mir voll schwer zu verstehen, was da im Programm miteinander logisch verknüpft wird...
00000000
or
00000001 (steht sicher für PortA)
ergibt
00000001 (steht sicher für (1<<0))

klingt logisch aber warum muß das nochmal verknüpft werden, wenn da schon steht:
if ((PIND & (1<<0)) != 0).

Naja, werde weiter drüber nachdenken :-)

MfG Jan

Spongebob85
22.02.2007, 14:54
Moin!!! Ich hab nur rausgefunden, wie man Pullupwiderstände programmiert.
Für meinen Fall wäre das PORTA |= (1<<PA0); oder? Kann ich um einen Pulldown widerstand zu bekommen einfach PORTA |= ~(1<<PA0); schreiben?

Und kann mir bitte noch jemand diese Anweisung erklären?
Das andere ist mir klar geworden, muss zwar jedes mal noch ein bisschen grübeln aber denke ich habs verstanden.
Dieser Anweisung ist doch auch eine Logische Verknüpfung, aber soll das ausgeschrieben heißen:
PORTA = PORTA | (1<<PA0) ? Dann würde das ja heißen PortA endspricht PortA oder eine 1 verschoben um 0 stellen (Also an PA0) ??? Das verstehe ich nicht!!!

Pascal
22.02.2007, 17:14
Das funktioniert aber nur, wenn der Pin als Eingang definiert ist.

Mit PORTA |= ~(1<<PA0) setzt du alle Bits außer dem durch PA0 festgelegten in PORTA. Das wird nicht das sein, was du willst. Außerdem gibt es im AVR keine pulldown-Widerstände.

PORTA = PORTA | (1<<PA0)
entspricht exakt dem
PORTA |= (1<<PA0)
Das bedeutet nicht, dass PortA einem anderen PortA ENTSPRICHT, sondern dem PortA ein Wert ZUGEWIESEN bekommt. Beim Berechnen dieses Werts kommt das Zielregister halt auch drin vor.

Spongebob85
22.02.2007, 17:31
Aber weiter oben haben die von "Bitweises Oder" gesprochen. Und das steht nun mal zwischen PORTA und (1<<PA0) . Echt eigenartig. Muss ich den eingang dan extern auf masse ziehen? Wenn ich das nämlich nicht mache, und den eingang meines µC nicht beschalte verarbeitet er das in diesem Programm nämlich als 1.


#include <avr/io.h>
#include <stdint.h>

int main (void)
{


DDRA = 0xff; //Das ganze Register A, also PA0...PA7, als Ausgang deklarieren
DDRD = 0x00; //Das genze Register D, also PD0...PD7, als Eingang deklarieren


while (1)
{

if ((PIND & (1<<0)) != 0) // ruhig die bitweise Verknüpfung noch
// mal in Klammern, also
// if ((PIND & (1<<0)) != 0), konkret ->
//wenn PD high dann
{
PORTA |= (1<<0); //PortA0 auf 5V steuern wenn PortD0 ungleich 0,
// ausgeschrieben heißt das
//PORTA = PORTA | (1<<), wobei '|'
//bitweises 'oder' bedeutet
}

else
PORTA &= ~(1<<0); //wenn PortD0 0 ist soll PortA0 0V haben,
//das heißt : ~(1<<0) setze Bit0 und invertiere
//das Ergebnis, danach mach eine &-Verknüpfung
// mit PORTA

} //ende der While-schleife

return 0; //starte neu
}



Also könnt ich mir auch den internen Pull-Up schenken.
Habt ihr am anfang auch solche Probleme gehabt?

vklaffehn
22.02.2007, 17:49
Noch mal zum Verständnis:
PORTA = PORTA | (1<<PA0)

'PORTA = ' -> weise PORTA den folgenden Wert zu:
'PORTA' -> Nimm den aktuellen Wert von PORTA
'|' -> und verknüpfe diesen bitweise oder mit
'(1<<PA0') -> 00000001

Und noch zu den Ports generell:
Wenn man einen Port als Ausgang schaltet, also z.B.

DDRA = 0xff

(das ist übrigens quasi ein DDRA=(1<<PA0)|(1<<PA1)|(1<<PA2)|(1<<PA3)|(1<<PA4)|(1<<PA5)|(1<<PA6)|(1<<PA7), setzt also alle 8 Bit im Richtungsregister)

dann schaltet man über die Bits in PORTA die Ausgänge High oder Low.

definiert man den Port per DDRA=0x00 als Eingang, kann man mit PORTA Pullup-Widerstände für die einzelnen Eingänge aktivieren,d.H. ist nichts angeschlossen, zieht der Pullup-Widerstand den Pin auf High, um das zu ändern, muß der Pin auf GND gezogen werden.
Will man ´den Zustand der Eingangspins abfragen, benutzt man PINA, in PORTA steht nur, für welchen Pin die Pullups aktiviert sind.

Ich hoffe, das hilft Dir noch weiter.

AlKI
01.03.2007, 17:44
Hi, bin neu hier und versuch auch grade die 8 Pins D0 bis D7 des Druckerports lpt zu schalten. Ich nutze DevC++ als Compiler und will das Programm dann auf nem win95er-PC laufen lassen.
der Compiler mault immer wegen dem ende rum, da wo was nicht stimmt steht auch n kommentar, dass der Compiler n Problem mit dem "="hat. auch mit { und }, welche früher mal drin waren nach "void lib_laden ()" hat der Compi 'n Problem. :-k 8-[

Könnte sich biddebidde jemand mir erbarmen und mir erklären, was da nicht stimmt? und ob das Programm danach auch macht, was es soll? [-o<

viiiiiiiiiiiiiiiiielen dank schomal im vorraus

AlKi

vklaffehn
01.03.2007, 20:33
so auf die schnelle :
hlib ist nicht deklariert, soweit ich das sehe, außerdem fehlt eine geschweifte Klammer '{' davor, und ich glaube, dass mit inp32 und oup32 muß auch irgendwie anders aussehen. Ich hab das auch mal irgendwo benutzt, ich such nacher mal ein beispiel ruas. Überigens braucht man unter Win95 die dll nicht, da kann man noch direkt auf den Ports rumorgeln.

AlKI
02.03.2007, 12:59
Danke, ich hab jetzt das problem gefunden:
ich Trottel hab die Definition in das main() programm geschrieben, was natürlich falsch ist ](*,) 8-[ #-o

dann macht mein Compiler keine Faxen mehr, und richtig isses auch :-P

AlKI
02.03.2007, 13:37
ich muss jetzt nur noch kleine sleep-Funktionen einbauen, weil ich mit den impulsen eine Ansteuerelektronik für schrittmotoren ansteuern will. Weiß irgendjemand wie man das bei C++ macht?

(Header= #include <time.h> und dadurch kann man dann irgendn Befehl nutzen, oder so)

schomal THX für jede antwort!

Gruß

AlKi

AlKI
02.03.2007, 17:14
nach etwa 2 Stunden hab ichs gefunden:
Sleep([Zahl]);
in irgendeinem von den Headern:
#include <iostream>
#include <stdio.h>
#include <conio.h>
#include <dos.h>
#include <windows.h>
#include <time.h>

Sollte sowohl bei C++ als auch C gehen.

Danke, falls sich wer schon die Arbeit gemacht hat, und rumgegrübelt hat.

AlKi


EDIT: war wohl in windows.h