C CodeVision: C-Programm auf Mega32 spielen, Fuse-Bit Einstellungen

codeman

Neues Mitglied
12. März 2009
27
0
0
Sprachen
Hallo Community,
ich bin noch ziemlich neu auf dem Gebiet der ATMega Programmierung.

Ich habe mir ein I/O Board entwickelt, welches 5 Eingänge (Port B) und 24 Ausgänge (Port A, C, D) beherbergt. Verbaut ist ein externer 8MHz Quarz, welchen ich auch nutzen möchte.
Die restlichen "Eingänge" von PortB sind vom ISP belegt.

Ich habe hier jetzt ein kleines C-Programm, welches ein Port C toggeln lassen soll.

Code:
#include <io.h>
#include <delay.h>
#include <stdint.h>

//Prototypen
void sleep_ms(uint16_t ms);

//LED Defines
//Hier müssen die richtigen Angaben hin
#define LED_PORT    PORTC       //PORTA, PORTB...

void main(void){

    //Die LED die ganze Zeit an und aus schalten
    while(1){
        LED_PORT = 1;    //Den Portpin auf high setzen
        sleep_ms(2000);    //1sek warten
        LED_PORT = 0;    //Den Portpin auf low setzen
        sleep_ms(2000);    //1sek warten
    }
}

/*  Diese Funktion lässt den Controller
    "ms" Millisekunden warten.
    Die while-Schleife wird so oft durchlaufen,
    wie der Funktion übergeben wurde.
    Bei jedem Duchlauf wir noch 1ms gewartet. 
*/
void sleep_ms(uint16_t ms){
    while(ms){
        ms--;
        delay_ms(1);
    }
}

Den Code habe ich von RN.
Ich versuche jetzt den Code mit meinem USB/ISP Adapter auf den Mega32 zu spielen.
Der USB/ISP Adapter ist kompatibel zum STK500. Treiber sind installiert. Gerät ist an "COM4" angeschlossen.
CCom4 habe ich in den Programmer Einstellungen in Codevision gewählt.

Bei folgendem Fenster habe ich Probleme mit den Einstellungen:
Programmer_Einstellungen.jpg

Ich weiss nicht wirklich, was ich bei SCK Freq auswählen soll:
- 460800
- 230400
- 57600
- 28800
- 7200??

Ebenfalls bin ich mir bei den Fusebit Einstellungen unsicher.
Hab mal in bissel im Datenblatt und bei google geguckt und da unterscheiden sich die Aussagen. Bin verwirrt :confused:

Wäre nett, wenn ihr mir mal unter die Arme greifen könntet..

Ich hoffe, ich habe keine Angaben vergessen, die wichtig sind...?

Gruß und Danke für die Antworten
 
Hallo Codeman,

willkommen im AVR-PRAXiS-Forum! :ciao:

Über die Fusebits des AVR kannst du in diesem Thread Fuse-Bits der Megas und Tinys (Übersicht und Erklärung) einiges lesen. Im Datenblatt findest du Informationen im Kapitel "System Clock and Clock Options".

Der Atmega32 läuft von Werk aus mit dem internen RC-Oszillator und zwar mit 1MHz. Du musst die Fusebits also so einstellen, dass der Oszillator für den externen Quarz aktiviert und als Systemtaktquelle verwendet wird. (hier schonmal einen Hinweis: Bei manchen AVRs gibt es noch das Fusebit CKDIV8, welches ab Werk programmiert ist. Der Oszillatortakt wird dann nochmal durch 8 geteilt. Das Fusebit ist aber beim Mega32 nicht vorhanden, kannst es also erst mal ignorieren und im Hinterkopf behalten)

Die folgende Fusebiteinstellung macht das:

1 = nicht programmiert, 0 = programmiert (wichtig! Oft wird das verwechselt.)

CKSEL3..1 = 1 (externer Quarz an XTAL1/2)
CKOPT = 0 (rail-to-rail swing)
CKSEL0, SUT1..0 = 1 (Startup Time 16 CK, Delay 65ms)


SPIEN = 0 (bleibt so, SPI Programmierinterface nicht disablen!)

(Alle Angaben ohne Gewähr!)

An den Lockbits brauchst du nichts ändern.

Die SCK Frequenz muss kleiner als 1/4 der Systemfrequenz sein. Da der AVR im Moment mit 1MHz läuft also kleiner 250kBit/s, ich würde mal 57600Hz verwenden.

Noch ein Hinweis zu deinem Programm. Du musst den IO-Pin erst als Ausgang schalten, nach Reset wird alles als Input initialisiert mit deaktivierem Pullup.

Am Beispiel PortC Pin 0:

Code:
int main(void)
{

  [B]DDRC |= (1<<PIN0);[/B]  // PIN0 ist Ausgang

  while(1)
  {
    PORTC |= (1<<PIN0);  // high
    _delay_ms(1000);
    PORTC &= ~(1<<PIN0); // low
    _delay_ms(1000);
  }

  return 0;
}
Ich hoffe, ich konnte dir weiterhelfen.

Grüße,
Dirk
 
Hi!
Danke für die schnelle Hilfe ;)

Ich lese mir grad den Thread mit den Fuse-Bit Einstellungen durch.

Ich komme bei den CKSEL0...3 nicht weiter. Im Datenblatt steht folgendes:

Device Clocking Option CKSEL3..0
External Crystal/Ceramic Resonator 1111 - 1010

Was muss ich da jetzt Einstellen für meinen 8MHz Quarz?
 
Hallo Codeman,
Was muss ich da jetzt Einstellen für meinen 8MHz Quarz?

du kannst die Einstellungen verwenden, die ich in meiner ersten Antwort schon vorgeschlagen habe.

Die Einstellung kann man für einen externen Quarz ab 1MHz verwenden. Am besten schau auch mal in das Datenblatt. Wenn du die

  • Tabelle "Crystal Oscillator Operating Modes" und die
  • Tabelle "Start-up Times for the Crystal Oscillator Clock Selection"
im Kapitel "System Clock and Clock Options" ansiehst, dann wird dir bestimmt einiges klarer.

Dirk
 
Ah, jetzt ja.
Mit dem Hinweis auf die (richtige) Tabelle im Datenblatt habe ich jetzt folgendes raus:
j6aol6of.jpg


CKSEL3...1: 1111
SUT1...0: 11
CKOPT: 1

Müsste richtig sein, oder? ;)
 
Ah, jetzt ja.
Mit dem Hinweis auf die (richtige) Tabelle im Datenblatt habe ich jetzt folgendes raus:

CKSEL3...1: 1111
SUT1...0: 11
CKOPT: 1

Müsste richtig sein, oder? ;)

Ja, die Einstellung kannst du für einen Quarz 8MHz verwenden.

CKOPT programmierst du dann, wenn der Oszillator unempfindlicher gegen EMV Störungen sein soll oder wenn XTAL2 einen anderen Eingang treiben soll. Wenn es bei dir nicht auf stromsparen ankommt (Batteriebetrieb), würde ich CKOPT programmieren.

Achtung, du deaktiviertst JTAG-Schnittstelle (brauchst du aber auch wahrscheinlich nicht).

Das Fusebit SPIEN ist in der Liste schon entfernt, wird also sicher nicht verändert (bleibt programmiert).

Du aktivierst den BrownOutDetector (BODEN), achte hier auf die Einstellung des Trigger-Levels (BODLEVEL).

Dann mal noch viel Erfolg :)

Dirk
 
@CKOPT: Batteriebetrieb
@JTAG: brauche ich nicht. Hab nur ISP
@BODEN: "The trigger level for the BOD can be selected by the fuse BODLEVEL to be 2.7V (BODLEVEL unprogrammed), or 4.0V (BODLEVEL programmed). -> also 0=programmieren.

Werde es nachher zu Hause mal testen... Danke für die Hilfe ;)
 
Code:
#include <io.h>
#include <delay.h>
#include <stdint.h>

//Prototypen
void sleep_ms(uint16_t ms);

//LED Defines
//Hier müssen die richtigen Angaben hin
#define LED_PORT    PORTC       //PORTA, PORTB...

void main(void)
{
  DDRC |= (1<<PIN0);  // PIN0 ist Ausgang

  while(1)
  {
    PORTC |= (1<<PIN0);  // high
    delay_ms(1000);
    PORTC &= ~(1<<PIN0); // low
    delay_ms(1000);
  }

}

/*  Diese Funktion lässt den Controller
    "ms" Millisekunden warten.
    Die while-Schleife wird so oft durchlaufen,
    wie der Funktion übergeben wurde.
    Bei jedem Duchlauf wir noch 1ms gewartet. 
*/
void sleep_ms(uint16_t ms){
    while(ms){
        ms--;
        delay_ms(1);
    }
}

Beim Kompilieren folgende Fehlermeldungen:
Error: C:\cvavreval\TLF1625\TLF1625.c(14): undefined symbol 'PIN0'
Error: C:\cvavreval\TLF1625\TLF1625.c(14): undefined symbol 'PIN0'
Error: C:\cvavreval\TLF1625\TLF1625.c(20): undefined symbol 'PIN0'

Der ist ja auch nicht definiert. Wie genau muss der definiert werden?
 
Code:
#include <io.h>
#include <delay.h>
#include <stdint.h>

//Prototypen
void sleep_ms(uint16_t ms);

//LED Defines
//Hier müssen die richtigen Angaben hin
#define LED_PORT    PORTC       //PORTA, PORTB...
#define LED_DDR		DDRC        //DDRA, DDRB...
#define LED_PORTPIN	PORTC.1         //PA0, PA1..., PB0, PB1..., ...

void main(void)
{
  DDRC |= (1<<LED_PORTPIN);  // PIN0 ist Ausgang

  while(1)
  {
    PORTC |= (1<<LED_PORTPIN);  // high
    sleep_ms(1000);
    PORTC &= ~(1<<LED_PORTPIN); // low
    sleep_ms(1000);
  }

}

/*  Diese Funktion lässt den Controller
    "ms" Millisekunden warten.
    Die while-Schleife wird so oft durchlaufen,
    wie der Funktion übergeben wurde.
    Bei jedem Duchlauf wir noch 1ms gewartet. 
*/
void sleep_ms(uint16_t ms){
    while(ms){
        ms--;
        delay_ms(1);
    }
}

SO kommen zumindet beim Kompilieren keine Fehler. Ist es so richtig?

Gruß ;)
 
Hallo,

ersetze in meinem Beispiel PIN0 durch PC0, bzw. PC1 und compiliere erneut.

Es ist auch möglich, dass es bei Codevision eine andere Schreibweise gibt, um den logischen Zustand eines Pins zu ändern, mit Codevision kenne ich mich aber leider nicht aus.

Dirk
 
Hi,
unabhängig von der Syntax haben ich beim Aufspielen gerade folgende Fehlermeldung bekommen:

fehlermeldung.jpg

Hab schon die kleinste Stufe von 7200 beim SCK Freq. genommen...?
 
Hallo Codeman,

ich gehe mal davon aus, dass der Programmer in Ordnung ist.

Stimmt der Anschluss an SPI?
PB5 = MOSI
PB6 = MISO
PB7 = SCK
RESET

Ist irgend ein Pin des SPI Interfaces durch externe Hardware belastet? Wenn ja, durch Vorwiderstand entkoppeln.

Stimmt die Betriebsspannung? (Ich gehe mal davon aus du nutzt VCC=5V aber sicherheitshalber der Hinweis: Die meisten Lowcost Programmer programmieren nur 5V Systeme. Hier ggf. in einen AVRISPmkII investieren, den gibts bei www.mikrocontroller-praxis.de oder bei Reichelt, Pollin, Conrad ...)

Hast du ggf. schon einmal versucht zu programmieren, eventuell mit falschen Fusebiteinstellungen?
Eventuell sind die Fuses verstellt, so dass du entweder SPI ausgeschaltet hast oder auf eine Systemtaktquelle gestellt hast, die nicht vorhanden ist (ext. RC-Oscillator, ext. Oscillator). Für SPI Programmierung wird ein Systemtakt benötigt.

Ansonsten fällt mir jetzt auch nichts ein, ausser dass es noch ein Problem zwischen Codevision und dem Programmer sein könnte, da kann ich aber leider nicht weiterhelfen.

Dirk
 
also ich habe den schonmal "erfolgreich" programmiert.
zumindest kam da keine fehlermeldung.

aber an der SPI fuse habe ich nicht geschraubt. höchstens an den cksel
 
... höchstens an den cksel

Das reicht ja eventuell schon aus. Eventuell ist kein Systemtakt vorhanden, den du aber für SPI Programmierung benötigst.

Du könntest versuchen an XTAL1 einen Takt anzulegen zum Beispiel durch einen anderen AVR (Katze beisst sich in den Schwanz ;)) oder einen Timer 555 oder rückgekoppelte Invertergates ... verwenden. Oder besser einen neuen ATmega32 verwenden und erst mal prüfen, ob die Programmierung nun funktioniert.

Dirk
 
Einfach meine Schaltung unter Spannung setzen und mit einem Taktgenerator an XTAL1 und GND und dann 5V SS? Was für eine Frequenz? Ein Sinus oder ein Rechteck?

Gruß ;)
 
Ideal wäre etwas zwischen 100kHz und 1MHz, Rechteck oder Sinus. Darauf achten dass die SPI Frequenz kleiner 1/4 der Frequenz an XTAL1 ist.

Danach Fuses einlesen, wenn möglich und schauen was verstellt ist. CKSEL3..0, SUT1..0, CKOPT so einstellen, dass der richtige Oszillator gewählt wird und Fuses erneut programmieren.

Ob du damit erfolgreich bist, kann ich nicht sagen. Es kommt eben darauf an, was verstellt ist und ob was verstellt ist.

Du kannst auch mal im Forum suchen, eventuelle mit "XTAL2, 555" o.ä.

Dirk
 
Aus dem Beitrag hier:

http://www.avr-praxis.de/forum/showpost.php?p=11762&postcount=7

Hier hab ich mal ein Bild von einer Wiederbelebung ...
Clock-Rescue.JPG
Ich habe die Taktquelle auf externen Takt eingestellt. Dadurch läuft natürlich
mit dem angeschlossenen Quarz überhaupt nichts mehr. Alles tot. Um dem
Atmel (ATmega8) jetzt wieder Leben einzuhauchen habe ich einen externen
Quarzoszillator (die Blechkanne rechts vom Atmel) an den Pin XTAL1 gesetzt
(über den grünen Draht). Damit zwinge ich dem internen Oszillator des Atmels
den externen Takt auf. Und schon läuft er wieder und man kann ihn
umprogrammieren Über die braunen Drähte habe ich den ISP-Progger mit
dem Atmel verbunden. Diese Wiederbelebung geht bei jeder Takteinstellung.
Also auch wenn man aus Versehen auf Extern-RC gestellt hat.

So werde ich es mal probieren. Wenn ich das so angeschlossen habe, wie kann ich die Fuse-Bits auslesen?
Bei CodeVision habe ich keine Funktion dafür gefunden...


BTW:
Guck mal, was ich eben gefunden habe...
AVR Fuse Calculator

Gruß
 
Wenn ich das so angeschlossen habe, wie kann ich die Fuse-Bits auslesen?
Bei CodeVision habe ich keine Funktion dafür gefunden...

Es ist möglich, dass du Fusebits bei Codevision nicht auslesen kannst. Das ist auch nicht unbedingt notwendig. Am besten dann einfach alle Fusebits durchgehen und richtig einstellen, dann versuchen zu programmieren.

BTW:
Guck mal, was ich eben gefunden habe...
AVR Fuse Calculator

Das ist schon mal eine Hilfe. Ich habe auch schon daran gedacht, soetwas für Windows zu programmieren, bisher aber wegen zu wenig Zeit nicht gemacht. :rolleyes:

Dirk
 
Danke für die Hilfe. Ich werde es ausprobieren und dann Rückmeldung geben...

Gruß und frohe Ostern ;)
 
Hi!
Ich dreh hier gleich durch. Hab mir nen neuen bestellt, da ich keine Lust hatte den alten Mega wiederzubeleben.
Jetzt will ich den programmieren... ich bekomme die Fehlermeldung:

"The FLASH buffer is empty. Do you want to load a file?"

Was muss ich denn da machen? Hab irgendwo gelesen, dass da nicht richtig kompiliert wurde. Das hatte ich aber vor dem senden gemacht...

Gruß und Danke ;)
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)