PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : brauche Start-Hilfe bei C&AVR



CNC
15.02.2006, 14:38
Hallo zusammen,

ich bin schon längere Zeit passiver Mitleser hier im Forum und habe mir auf Grund einiger Vorhaben entschlossen, mich in die µC-Technik einzuarbeiten. Begrenzte C-Kenntnisse sind durch mein Studium (Maschbau) vorhanden, außerdem habe ich mir vom Shop das RN-Board und den Programmier-Dongle für den Parallelport geholt.

Zu meinen eigentlichen Problemen:
Ich habe winAVR in Kombination mit ponyprog, um den Flash des AVR mit der HEX-Datei zu füttern, nur läuft das Programm (Blinky aus dem wiki) nicht einwandfrei. Es blinken auf dem RN-Board die LED 1,2 und 8. Nur eben nicht in 2 Hz, sondern es sind die Pausen zwischen dem ca. 1 Sekunde langen Aufleuchten ca 30 Sekunden lang.

Ich würd' gerne einfach nur ein einfaches Blink-Programm rüberladen nach dem Motto
blink;
Sleep(500);
blink aus;
Sleep(500);

- hat da jemand ein paar Tipps für mich bzw. ein kleines Beispielprogramm?
- mit welchem Befehl kann ich die Ports beschreiben bzw. auslesen?
- dafür muss die Header io.h eingebunden werden (#include <avr/io.h>), oder? oder noch mehr?

hm ein Beispiel sollte möglichst simpel sein: interrupts, timer, Zusammensetzen mehrerer Module usw. ist jetzt noch nicht so wichtig

Ich wäre für euere Hilfe sehr dankbar ;)

SprinterSB
15.02.2006, 15:04
Hoi.

Das Beispiel stammt von mir.

Hast du was an der CPU-Frequenz geändert?
Welche Einstellungen verwendest du da (Fuses)?
Hast du das im Quellcode angepasst?

Es gibt auch eine etwas vereinfachte Version, die in einer einzigen Quelldatei ist.

CNC
15.02.2006, 16:12
hi,

erst mal danke für die schnelle Antwort.

Ich hab'
#define F_CPU 16000000
gesetzt, da das RN-Board mit 16MHz Quarz betrieben wird. Ohne Quarz ändert sich meiner Meinung nach nix bzw. wenn man den Wert ändert verändert sich die Blinkfrequenz nicht. Wenn der Prozessor auf 1 MHz getaktet ist dann würde das Ganze ja mit 32 Hz blinken da der AT ja 16 mal schneller betrieben wird als das Programm denkt...
Ich habe die Werte aber in jede Richtung mal verändert, es ändert sich nichts.
Meinst du mit "fuse" was anderes?

ich hätte es so gemacht


#include <avr/io.h>
#inlcude <avr/signal.h>
#define PORT_LED PORTB

int main()
{
PORT_LED =1;
Sleep(500);
PORT_LED =0;
Sleep(500);
return (0);
}

oder so ähnlich... wie würde denn der Quelltext aussehen nach meiner Idee?[/code]

SprinterSB
15.02.2006, 17:10
Nach dem Ändern den Defines muss das alles neu compiliert werden und wieder aufgespielt werden.

Dabei ist sicherzustellen, daß bei Verwendung von make auch wirklich neu erzeugt wird. Wenn so ein Define im Makefile selbst steht, das Projekt aber nicht abhängig vom Makefile ist, dann wird nicht neu generiert.

Das sieht eher so aus, als ob dein AVR mit 1MHz rennt und es deshalb langsam blinkt. Versuch doch mal die Einstellung mit F_CPU für 1MHz. Wenn sich nichts an der Blink-Frequenz ändert, ist mächtig der Wurm irgendwo. Blinkt die LED mit der angegebenen Frequenz, stimmen deine Fuse-Einstellungen nicht.

sleep() gibt es nicht, jedenfalls nicht so (avr/sleep.h dient dazu, deinen AVR schlafen zu legen: Power-Down, etc).

Eine sleep() im Sinne von wait() bräuchte eine Zeitbasis, die man sich erst besorgen muss. Dazu bildet das Beispiel die Grundlage, auf der man weiter aufbauen kann.

CNC
16.02.2006, 00:08
also beim compilieren kommt die Warnung signal.h is obsolete, use interrupt.h... und SIG_OUTPUT_COMPARE_1A appears to be a misspelled

CNC
16.02.2006, 00:24
also beim compilieren kommt die Warnung signal.h is obsolete, use interrupt.h... und SIG_OUTPUT_COMPARE_1A appears to be a misspelled signal handler

also entweder muss ich die signal.h updaten oder die wurde durch die interrupt.h ersetzt/erweitert 8-[ Habe ich evtl beim installieren von WINAVR was vergessen?

Was ist eigentlich jetzt die Adresse von der 1. LED? DDRB oder PORTB? wie kann ich alle LEDs an/ausschalten??

Also er die LEDs leuchten genau 2 Sekunden auf und dann ist 40 Sekunden nix, egal welche Prozessortaktung, egal ob mit quarz oder ohne... deswegen gehe ich davon aus dass er sowieso ohne externer Taktung arbeitet.

izaseba
16.02.2006, 00:41
Hallo,
Zue Deiner Warnung:
Klick (http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Anforderungen_an_Interrupt-Routinen)
und unter ISR weiterlesen
Klick (http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html)
Diese Seite sollte sowieso jeder kennen, der sich mit avr-gcc beschäftigt...

Gruß Sebastian

ogni42
16.02.2006, 10:54
Du musst das Datenrichtungsregister noch setzten.



DDRB = 0xff;
PORTB = 0x00;
while( 1 )
{
PORTB ^= 0xff;
SLEEP(500); // wo kommt denn bei Dir diese Routine her?
}

bergowitch
16.02.2006, 14:09
Die SLEEP (500) Methode hätte ich auch gerne. kannst du die mal posten?
Danke
Gruß
Stefan

ogni42
16.02.2006, 14:22
Etwas in der Art:



#include <inttypes.h>
#include <avr/delay.h>

/**
* wait for a given amount of time.
* @param timeInMs The time to wait. Accuracy is 8ms
*/
void sleep( uint16_t timeInMs )
{
uint16_t loopCnt = timeInMs>>3;

while( loopCnt )
{
_delay_ms(8);
loopCnt--;
}
}


Die Funktion kann mit einer Genauigkeit von 8ms (plus ein paar hundert ns für die Schleife) von 8ms bis 65536ms verzögern. Wenn es genauer sein soll, kann man die Funktionen aus delay.h erweitern.

bergowitch
16.02.2006, 16:47
Danke. Die Funktion in der include-Datei kannte ich nicht.
Gruß
Stefan

ogni42
16.02.2006, 17:37
Bitte bei der Verwendung der _delay_ms und _delay_us darauf achten, dass die nur eine begrenzte Zeit (F_CPU/irgendwas) warten können. Wie lange, steht im header.

CNC
16.02.2006, 18:39
nochmal zu einer meiner Anfangsprobleme:

Also den das Hello world für AVRs habe ich jetzt mal nach hinten gestellt, ich such jetzt nach einer Möglichkeit, einfach nur über Tastendruck eine LED einzuschalten. Ich habe im Netz übrigens noch eine Blinky-hex-Datei gefunden, die vom Speicher selber her um Einiges weniger belegt (ca. 1 1/2 Zeilen, im Gegensatz zu der anderen aber funktioniert.

Wenn ich jetzt an der RN-control Taster 1 drücke soll LED 1 leuchten, bei T2 LED2 usw... wie würde der Quelltext aussehen?

Ein Anfangsproblem war außerdem, dass ich nur einen ATMega16 beschreiben konnte, nicht aber den ATMega32. Schuld war meine Ponyprog-Version, da war eine Aktualisierung notwendig.
Außerdem hab' ich das mit den Fuse-bits gecheckt, die AVRs sind jetzt mit Quarz betreibbar. Schön zu sehen, wie sich die Blinkfrequenz mit der Quarzfrequenz verlangsamt. (an irgendeinem Erfolgserlebnis muss ich mich ja orientieren =P~)

vielleicht erbarmt sich jemand und hackt ein paar anschauliche Zeilen zusammen

CNC
16.02.2006, 20:01
da ich noch ganz dumm bin hab' ich mal folgendes versucht, funktioniert aber nicht... es sollten die ersten 2 LEDs des Ports leuchten... ich kann eine andere hex-file laden (Blinky von vorhin) die geht... die hier lässt sich compilieren und rüberschaufeln, funktioniert aber nicht auf dem ATMega



#include <avr/io.h>

int main(void)
{
/* Setzt das Richtungsregister des Ports C auf 0xff
(alle Pins als Ausgang): */
DDRC = 0xff;

while (1)
{
/* Setzt PortC auf 0x03, Bit 0 und 1 "high", restliche "low": */
PORTC = 0x03;
}
}


wo liegt mein Fehler?

edit: äh hab' was doof formuliert

izaseba
16.02.2006, 20:34
die hier geht compiliert aber nicht!

was heißt geht, compilliert aber nicht ?
Das Programm muß sich doch kompilieren lassen...
Der einzigste Fehler, den ich sehe ist, wenn Du eine Funktion schreibst, die ein int zückgeben soll, mußt Du das auch tun...
int main(void)

und wo ist hier ein return???

Wie gut kennst Du Dich überhaupt mit C aus ?

Gruß Sebastian

CNC
16.02.2006, 20:44
ok schmeiß noch ein return 0; nach das ist ja nicht das Problem...

c an sich kann ich schon rel. gut ( hab' darin auch Vordiplom geschrieben usw, das sagt aber wieder weniger aus :D)

Wir haben eben nur Konsolenanwendungen geschrieben, wie die Ports vom AVR geschrieben werden usw ist mir noch nicht klar. Außerdem haben wir kein einziges mal was mit Interrupts gemacht!

dass sich das Programm kompilieren lässt ist klar, auch in Hex umwandeln ist nicht das Thema, in den AT schaufeln auch nicht... nur es leuchtet keine LED auf... hab' auch schon die Ports geändert, alle 4 Ports zusammen auf high gesetzt usw... irgendwo hab' ich da einen Denkfehler drin...

izaseba
16.02.2006, 21:03
alle 4 Ports zusammen auf high gesetzt usw

Naja, soweit ich weiß sind die LEDs gegen VCC geschaltet, mithin müsstest Du die Ports auf LOW setzten, sehe Schaltplan, ich hoffe, das wars...
Gruß Sebastian

CNC
16.02.2006, 21:19
hm bleibt sich egal ob man die LEDs von vcc auf Pin oder von Masse auf Pin setzt man muss nur die Stromflussrichtung beachten... das eine mal leuchten sie halt wenn Port auf "0" und das andere mal bei "1" ... da aber am PortC nur die ersten 2 Pins anders sind als der Rest müssten die LEDs einfach unterschiedlich on oder off sein, wie ist mir jetzt noch egal, hauptsache es leuchtet irgendwas! Es tut sich aber nix! Ich hab' das Gefühl, dass ich irgendwo vom compilieren her einen Fehler drin hab... ich erstelle mit AVR-GCC ein Hex-file das ich dann mit Ponyprog in den µC lade. Ich glaube nicht, dass der Fehler an Ponyprog liegt, da ich ja das Blink-Hex auch übertragen kann und es funktioniert.

Ich geb' also in der Kommandozeile ein avr-gcc leucht.c -o leucht.hex -mmcu=atmega32 -g -Os -Wl,--oformat=ihex

Liegt da evtl der Fehler?

izaseba
16.02.2006, 21:32
Schau mal hier (http://www.nongnu.org/avr-libc/user-manual/group__demo__project.html)
So macht man das zu Fuß.

Benutze doch mal make.

Klick (http://www.sax.de/~joerg/mfile/)
Klick (http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Exkurs:_Makefiles)

Gruß Sebastian

SprinterSB
17.02.2006, 10:47
Funktioniert das Beispiel aus dem Wiki inzwischen?

Ich kann den Code ja nicht auf allen möglichen Controllern mit allen Denkbaren Compiler-Versionen testen. Evtl. müsste das Beispiel dan korrigiert werden, falls es einen Fehler gibt.

CNC
17.02.2006, 12:18
aaalso... jetzt blinken zumindest LED 1 und LED 2 im Sekundentakt, und andere Pins an verschiedenen Ports werden beliebig mitbeschaltet. (bei jedem der 8te usw...) Bei einem Reset macht er oft ganz verschiedene Sachen: ab und zu blinkt er nur ein paar mal und hört dann auf, usw.

Wenn man den Wert F_CPU im Quelltext ändert, sollte sich doch die Blinkfrequenz ändern oder nicht? macht bei mir gar nichts aus, es blinkt wie vorher

mfg Alois

CNC
17.02.2006, 12:23
hm und bei meiner einfachen Einschalt-Programmiererei geht gar nix...



#include <avr/io.h>

int main(void)
{
/* Setzt das Richtungsregister des Ports C auf 0xff
(alle Pins als Ausgang): */
DDRC = 0xff;

while (1)
{
/* Setzt PortC auf 0x03, Bit 0 und 1 "high", restliche "low": */
PORTC = 0x03;
}
}

könnte mir das jemand in eine *.hex kompilieren? Ich würde die dann vergleichen mit meiner, evtl liegt ja bei meiner compiliererei der Hund begraben...

SprinterSB
17.02.2006, 15:34
Um das zu machen, bräuchte man die Optionen (Controller-Typ, Optimierungsgrad, GCC-Version, ...)

Und selbst dann ist nicht gesagt, daß das gleiche hex rauskommt.

Hier mal für ATmega32 (gcc 3.4.1):

avr-gcc cnc.c -o cnc.hex -Os -mmcu=atmega32 -Wl,--oformat=ihex



.file "cnc.c"
.arch atmega32
__SREG__ = 0x3f
__SP_H__ = 0x3e
__SP_L__ = 0x3d
__tmp_reg__ = 0
__zero_reg__ = 1
.global __do_copy_data
.global __do_clear_bss
.text
.global main
.type main, @function
main:
/* prologue: frame size=0 */
ldi r28,lo8(__stack - 0)
ldi r29,hi8(__stack - 0)
out __SP_H__,r29
out __SP_L__,r28
/* prologue end (size=4) */
ldi r24,lo8(-1)
out 52-0x20,r24
ldi r24,lo8(3)
.L2:
out 53-0x20,r24
rjmp .L2
/* epilogue: frame size=0 */
/* epilogue: noreturn */
/* epilogue end (size=0) */
/* function main size 9 (5) */
.size main, .-main
/* File "cnc.c": code 9 = 0x0009 ( 5), prologues 4, epilogues 0 */




cnc.hex: file format ihex

Contents of section .sec1:
0000 36940000 51940000 51940000 51940000 6...Q...Q...Q...
0010 51940000 51940000 51940000 51940000 Q...Q...Q...Q...
0020 51940000 51940000 51940000 51940000 Q...Q...Q...Q...
0030 51940000 51940000 51940000 51940000 Q...Q...Q...Q...
0040 51940000 51940000 51940000 51940000 Q...Q...Q...Q...
0050 51940000 11241fbe cfe5d8e0 debfcdbf Q....$..........
0060 106000e1 b06080e1 f0e002c0 05900d92 .`...`..........
0070 0031b107 d9f71060 00e1b060 01c01d92 .1.....`...`....
0080 0031b107 e1f75394 00000c94 00001fe9 .1....S.........
0090 d8e0debf cdbf8fef 84bb83e0 85bbfecf ................

izaseba
17.02.2006, 16:33
So hier hast Du eine hex Datei.
Du mußt .txt am ende entfernen...

Gruß Sebastian

SprinterSB
17.02.2006, 17:17
Kannste mal sehen...bei mir hat die hex 515 Bytes...

izaseba
17.02.2006, 18:08
Kannste mal sehen...bei mir hat die hex 515 Bytes...

avr-gcc 3.4.4
mmcu atmega32
-Os

EDIT: Wobei ich sagen muß, daß der Assemblercode soweit gleich ist...

CNC
17.02.2006, 18:38
so, also zum compilieren bin ich also nicht zu doof... habt ihr mein Programm auch mal auf den µC geschaufelt ob sie funktioniert? meine Hex ist genauso groß, 515 bytes. Anschließend schaufel ich mit Ponyprog rüber...

Vielen Dank auf alle Fälle für alles

johannuhrmann
17.02.2006, 19:26
hm und bei meiner einfachen Einschalt-Programmiererei geht gar nix.....

Du kannst ja mal zum Test versuchen, deine Hex-Datei zu disassemblieren:
avr-objdump -D -m avr -z test.hex

Es sollte zumindest halbwegs lesbarer Assemblercode erzeugt werden. Am Ende des
Listings sollte die Endlosschleife zu sehen sein.

Grüße,

Hans

izaseba
17.02.2006, 20:00
Vielen Dank auf alle Fälle für alles

Was jetzt? Klappt es, oder steigst Du auf BASCOM um :cheesy: ??

CNC
17.02.2006, 20:41
eigentlich bin ich mitten unter'm Vordiplom und muss lernen, nur ist das Rumbasteln um Einiges interessanter als so ein BWL-Schein, der für einen Maschinenbauer sowieso der blanke Horror ist ;) . Ich werde das Ganze ein paar Tage ruhen lassen und mich dann wieder frischen Mutes an die Sache wagen.

Interessant fände ich jedoch noch, ob die Hex-Datei bei euch läuft oder ob ich noch irgendwo einen Fehler drin hab'.

Ich werde mich dann noch näher mit den makefiles auseinandersetzen, sowas bin ich als visual studio.net-Jünger von der Uni her nicht gewöhnt. Außerdem brauchen meine C-Kenntnisse eine Auffrischung usw.