mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Anfängerprobleme mit MEGA32


Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

Ich habe mir heute auf einem Steckbrett eine Experimentierschaltung mit 
einem Mega32 aufgebaut. Als Programmer benutze ich einen einfachen 
Parallelport Programmer und Ponyprog. Das scheint soweit auch zu 
funktioniere. Kann den Flash schreiben, auslesen und auch FuseBits 
einstellen. Leider bekomme ich es nicht hin eine einfache LED ans 
leuchten zu bekommen.

Hier mein Prog.Code:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>

//CPU Frequenz für Programm auf 1MHz einstellen(interner Takt)
#define F_CPU    4000000

//Bautrateneinstellung
#define BAUD 4800L          // Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!
 // Berechnungen
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) // Fehler in Promille 
 
#if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
#endif

//***********************
typedef unsigned char byte;
typedef unsigned int word;

typedef struct byte_str{
  unsigned b0:1;
  unsigned b1:1;
  unsigned b2:1;
  unsigned b3:1;
  unsigned b4:1;
  unsigned b5:1;
  unsigned b6:1;
  unsigned b7:1;
};


//***********************
void ioinit(void);
void delay_ms(unsigned int ms);


//***********************
// Initialisierung der IO
void ioinit(void)
{
    
    DDRA = 0xff;    // PortB als Ausgang deklarieren
    //PORTB = 0x00;   // Ports auf HIGH schalten
  
  DDRC = 0xff;
  PORTC = 0x2A;
  
  DDRD = 0xff;
  PORTD = 0x00;  
  
  sei();  //Interrupts an
  //cli(); Interrupts aus
  
}
/***********************/
//UART Funktionen

void aktiviereUART(void)
{
  UCSRB |= (1<<TXEN);               // UART TX einschalten
  UCSRB |= ( 1 << RXEN );      //UART RX einschalten
    UCSRC |= (1<<URSEL)|(3<<UCSZ0);  // Asynchron 8N1 
}
void uart_write_char(char c)
{
  while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich                   */
    {
    }
 
    UDR = c;/* schreibt das Zeichen x auf die Schnittstelle */
}
void uart_write_String (char *s)
{
    while (*s)
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
        uart_write_char(*s);
        s++;
    }
}




//********************
//Methoden

// Warteschleife
void delay_ms(unsigned int ms)
{
    unsigned int zaehler;
   
    while (ms) {
        zaehler = F_CPU / 5000;
       
        while (zaehler) {
            asm volatile("nop");
            zaehler--;
        }
        ms--;
    }
}

// Hauptprogramm
int main(void) {
    unsigned char i;   

    ioinit();  
  
   
    // Endlosschleife
    while (1) {
        
    PORTD=0xff;
    PORTA=0x00;
    
    }   

    return 0;
}

Ich habe eine LED mit minus an PD6 über 330Ohm an Vss(5V). Die LED will 
aber nicht leuchten.
Ich habe einen Externen Quarz mit 4Mhz angeschlossen. Muss ich das in 
den FuseBits irgendwie einstellen das der ext. Quarz genutzt wird? 
Welche Bits muss ich in PonyProg setzen? Wie kann ich mir sicher sein, 
das der ext. Quarz korrekt arbeitet?

Sebi

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich habe eine LED mit minus an PD6 über 330Ohm an Vss(5V). Die LED will
> aber nicht leuchten.

Warum sollte sie auch. Wenn der Minuspol an PD6 liegt, dann folglich der 
Plus an Vss (das Kürzel für Masse), also ist die LED grad verkehrt herum 
dran.

Wenn du andererseits mit Vss(5V) in Wahrheit Vcc meinst, dann ist zwar 
die LED richtig rum, aber mit PORTD=0xFF liegt der Ausgang auch auf 5V 
und die LED kriegt nix.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Led ist mit dem kurzen beinchen an dem Port und mit dem anderen über 
330Ohm an 5V. Ich nutze Port PD6. Aber es geht nicht. Muss ich noch 
irgendwas anderes im Controller einstellen?

Wie nutze ich den externen Quarz?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sebastian wrote:
> Die Led ist mit dem kurzen beinchen an dem Port und mit dem anderen über
> 330Ohm an 5V. Ich nutze Port PD6. Aber es geht nicht. Muss ich noch
> irgendwas anderes im Controller einstellen?
>
> Wie nutze ich den externen Quarz?

Eins nach dem anderen. Jetzt muss erstmal deine LED leuchten
und dazu ist es unerheblich ob dein Quarz jetzt aktiv ist
oder nicht. Dein Mega32 arbeitet, wenn du an den Fuses noch nichts
verstellt hast, mit dem internen Oszillator auf ca. 1Mhz.
Wichtig ist nur: Er arbeitet.

Gib doch einfach mal ein anderes Bitmuster am Port aus:
0xAA
Das ist binär 10101010, dh. immer abwechselnd eine 1 und
eine 0. Wenn deine LED also am Pin PD6 nicht leuchtet
dann versuche mal den Pin PD5. An einem der beiden muss
es gehen, ansonsten ist was an der Hardware faul.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah,Ich habs hinbekommen. Sie blinkt jetzt....*Freu*

Und wie gehts jetzt weiter?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sebastian wrote:
> Ah,Ich habs hinbekommen. Sie blinkt jetzt....*Freu*

Gut

>
> Und wie gehts jetzt weiter?

Keine Ahnung. Was willst du denn machen?


Wegen der Umstellung auf Quarz:
http://www.mikrocontroller.net/articles/AVR_Fuses

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erstmal würde ich gerne verstehen wie ich das mit der Zeit und der 
Taktfrequenz geregelt bekomme.

Ich habe ja F_CPU 4000000 wegen dem ext. Quarz. Dann ist in der delay_ms 
eine wartezeit in ms eingegeben. Wie errechnet man die exakte wartezeit 
in ms, so das die wartezeit wirklich in ms angegeben werden kann?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sebastian wrote:
> Erstmal würde ich gerne verstehen wie ich das mit der Zeit und der
> Taktfrequenz geregelt bekomme.
>
> Ich habe ja F_CPU 4000000 wegen dem ext. Quarz.

Dann solltest du dem obigen Link folgen, die Seite komplett
lesen und den Mega32 mal auf Quarz-Betrieb umstellen

> Dann ist in der delay_ms
> eine wartezeit in ms eingegeben. Wie errechnet man die exakte wartezeit
> in ms, so das die wartezeit wirklich in ms angegeben werden kann?

Gar nicht.
Du gibst einfach an, wieviele ms du haben willst und _delay_ms
macht das dann.
Aber beachte:
Die delay Funktion die du da hast, die schmeist du gleich
wieder weg und verwendest die, die mit dem Compiler mitgeliefert
wird. Kein Grund das Rad neu zu erfinden.


#define F_CPU 4000000

#include <avr/io.h>
#include <util/delay.h>

int main()
{
  ....

  _delay_ms( 10.0 );     // Warte 10 Millisekunden

  ....
}

Aber Achtung: Diese mitgelieferte Funktion hat eine Obergrenze.
Du kannst nicht beliebige Millisekunden anfordern. Die Obergrenze
ist von deiner Taktfrequenz abhängig und ist als Formel in delay.h
angegeben.
10 Millisekunden sind aber kein Problem. Wenn du daraus eine
ganze Sekunde machen willst (sowas macht man allerdings in einem
relaen Programm nicht), dann musst du halt 100 mal 10 Millisekunden
abwarten:

   for( i = 0; i < 100; ++i )
     _delay_ms( 10.0 );


(Den Optimizer des Compilers einschalten nicht vergessen, sonst
stimmen die Zeiten nicht)

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie würde man das denn in einem realen prog. machen? Sagen wir mal man 
möchte 1000ms warten. Würde man eine solche Schleife nutzen?

Gibt es irgendwo eine übersicht über die vom Compiler oder von WinAVR 
zur verfügung gestellten methoden?

Habe mal in PonyProg die FUSEBits ausgelesen. CKSEL 3-1 haben ein 
häkchen, 0 nicht. Da das anscheinend invertierte logik ist, bedeutet das 
0001 wenn ich das nach der FUSEBIT seite deute bedeutet das internal 
QuarzOsz. wie zu erwarten.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wie würde man das denn in einem realen prog. machen? Sagen wir mal man
> möchte 1000ms warten. Würde man eine solche Schleife nutzen?

Lässt sich so allgemein nicht beantworten. In einfachen Programmen ja, 
in komplexen Programmen arbeitet man eher mit Timer-Interrupts und 
dadurch gesetzten Erinnerungen.

> Gibt es irgendwo eine übersicht über die vom Compiler oder von WinAVR
> zur verfügung gestellten methoden?

Mit ein bischen Suche nach dem passenden Icon bei dir auf der Platte. 
Oder http://www.nongnu.org/avr-libc/user-manual/index.html.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann ich mit dem Internen Osz. auch höhere Frequenzen machen? Habe 
gerade gesehen das man beim AVR Fuse Calc
http://palmavr.sourceforge.net/cgi-bin/fc.cgi
auch 8MHz wählen kann. Geht das dann ohne ext. Quarz?

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Kann ich mit dem Internen Osz. auch höhere Frequenzen machen?

Wie wär's mit einem Blick ins Datasheet? Dein Text über die Fuses deutet 
an, dass du immerhin mal reingesehen hast. Sowas steht da drin.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jagut, also scheint der sogar 8MHz intern zu können. Man kann das ja 
sogar noch irgendwie kllibrieren wenn ichs richtig verstehe. Dann muss 
ich die bits jetzt auf 0100 für 8MHz setzen. Das wäre in Ponyprog X0XX 
bei CKSEL3-0 (X=Häkchen).

Autor: Tracer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
was hast du denn an material benutzt um das obige progeamm zu schreiben? 
bin nämlich auch noch anfänger und muss mich erstmal reinfitzen deshlab 
bin ich für jeden vorschlag dankbar. hab schon tutorial gelesen aber der 
prinzipiele programmaufbau und wie ich an sowas rangeh ist mir noch 
nicht wirklich klar

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe WinAVR installiert. Damit kannst du die make-Files und den 
Programmcode erstellen und dann auch kompilieren. Zum programmieren 
nutze ich PonyProg und einen einfachen ParallelPort Programmer. Das 
findest du alles kostenlos im Internet, bzw beim Programmer die 
Bauanleitung. Der Parallelport Programmer geht sogar nur mit 2 
Widerständen.
Programmcode habe ich mir einfach aus dem avr-gcc tutorial hier auf der 
seite zusammengesucht. Mein Code enthält viel was man erstmal nicht 
braucht, ich hab einfach nur alles, was ich interessant fand mit rein 
kopiert.

Autor: Christoph Erstmalegal (gluema)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wie lange hast du gesessen für alles?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christoph Erstmalegal wrote:
> wie lange hast du gesessen für alles?

Die Frage klingt so nach: Ich muss auf die Schnelle programmieren
lernen und möchte das so schnell wie möglich hinter mich bringen.

Ins Stammbuch geschrieben:
Für die ersten Schritte kann man schon ein paar Tage rechnen,
je nach persönlicher Eignung. Einen etwas fotgeschritteneren
Anfängerstatus erreicht man erst nach ein paar Wochen. So
einigermassen la-la wird man in der Programmierung erst nach
ein paar Monaten. Um mal eine Zahl zu nennen: sagen wir mal
6 - 9 Monate. Gut wird man nicht unter einem Jahr und wenn man
zu einem Experten aufsteigen will, dann reden wir von Jahren
(nicht unter 3).

Die Zahlen mögen je nach persönlicher Eigung und dem Willen
sich zu quälen variieren aber die Proportionen bleiben
erhalten.

Das soll jetzt aber niemanden abhalten, Softwareentwicklung
zu betreiben. Nur so, wie Lieschen Müller sich die Programmierung
vorstellt, so ist das nicht. Das mussten auch die Arbeitsämter
lernen, als sie vor Jahren Unsummen in 2 Monats Schnellsiederkurse
zur Umschulung auf Programmierer investierten. Rausgeschmissenes
Geld.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christoph Erstmalegal wrote:
> wie lange hast du gesessen für alles?
Wie, kommt man jetzt sogar in den Knast dafür;-? Vorbestraft wegen 
AVR-Vergewaltigung?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.