Blinkende LED mit ATMega8 blinkt nicht

Da ich ein absoluter Neuling bin, dachte ich, ich würde mit etwas wirklich Einfachem beginnen: eine LED zum Blinken bringen. Laut mehreren Websites sollte das jeder können ... Hmmm ... In meinem Fall macht die LED nichts. Es bleibt dunkel. Warum?

Dies ist das Programm, das ich geschrieben habe (auf einem Ubuntu 12.04-Computer):

#define F_CPU 1000000UL

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

void sleep(int milliseconds)
{
while (milliseconds > 0)
{
    _delay_ms(1);
    milliseconds--;
}
}

int main()
{
// set lowest bit to output in DDRB register
DDRB |= 0x01;

while(1)
{
    // switch led on
    PORTB &= 0x01;
    sleep(500);

    // switch led off
    PORTB &= 0x00;
    sleep(500);
}

return 0;
}

Dann habe ich diese Schritte befolgt:

  1. Kompiliert mein Programm:

    avr-gcc -mmcu=atmega8 test-001-blinkende LED.c -o test-001-blinkendeLED.o -Os

  2. Verhexen

    avr-objcopy -j .text -j .data -O ihex test-001-blinkendeled.o test-001-blinkendeled.hex

  3. Auf den Mikrocontroller hochgeladen (mit einem AVRISPmkII):

    sudo avrdude -p m8 -P usb -c avrispv2 -U flash:w:test-001-blinkingled.hex -F -v

mit folgendem Ergebnis:

avrdude-Ausgabe

Dies ist ein Bild meiner sehr einfachen Schaltung: (Ich verwende einen alten 9-V-Adapter für die Stromversorgung, also habe ich 2 Widerstände verwendet, um die Spannung auf 4,95 V zu regeln)

Meine Steckbrettschaltung

Was mache ich falsch? Wenn Sie andere seltsame oder dumme Dinge sehen, informieren Sie mich bitte!

Verwenden Sie niemals Widerstände, um die Spannung zu "regulieren". Sie tun es nicht. Verwenden Sie einen geeigneten Spannungsregler. Dies ist wahrscheinlich ein Teil Ihres Problems.
Hat es eine interne Uhr? Sie benötigen zusätzlich zur Verwendung eines geeigneten Reglers Netzteil-Entkopplungskappen.
Du bist ein Zauberer! Wo ist die Verbindung zwischen Ihrem Computer und dem ATMEGA8-Chip?

Antworten (3)

Vier Probleme

  1. Sie verwenden einen Widerstandsspannungsteiler, um Ihre MCU mit Strom zu versorgen. Schlecht. Schlecht schlecht. Du brauchst einen richtigen Regler. Oder ein USB (IE 5v) Netzteil. Heck, verwenden Sie 3 AA-Batterien anstelle von 9 V, wenn Sie keinen Regler haben. Die ATMega-Leitung kann was aufnehmen, 2,5 bis 5 V im normalen Bereich? Sie haben nichts, was wirklich von vollen 5 V abhängt, keinen taktempfindlichen / abhängigen Code.

  2. Sie versorgen nur eine Seite des ATMega mit Strom. Es gibt zwei Power- und zwei Ground-Pins. Sie sind NICHT überflüssig. Ein Satz ist Digital VCC und GND, der andere ist Analog VCC und GND. Idealerweise sollten Sie für rauschempfindliche analoge Schaltungen eine Induktivität zwischen den DVCC- und AVCC-Pins verwenden, aber zumindest sollten DVCC und AVCC verbunden sein, ebenso wie DGnd und AGnd.

  3. Eine Entkopplungskappe für beide (~0,1uf) wird ebenfalls empfohlen, aber Sie könnten nur eine für DVCC/DGnd verwenden.

  4. Sie verwenden ein bitweises Und (&). Nur bereits gesetzte Bits werden gesetzt. [0 & 1 = 0] [1 & 0 = 0] [0 & 0 = 0] [1 & 1 = 1]
    Ihr Code wird die LED niemals einschalten. Sie benötigen ein bitweises ODER | (der vertikale Balken oder das Rohr), um es einzuschalten. Ein bitweises And mit einem invertierten Bit schaltet es aus (PortB &= ~0x01). Alternativ kann ein bitweises XOR ^ (Caret-Symbol) zum Umschalten verwendet werden.

PORTB |= 0x01;
sleep(500);

PORTB &= ~0x01;
sleep(500);

PORTB ^= 0x01;
sleep(500);

AVR Freaks hat hier ein großartiges Tutorial zu bitweisen Operationen , für allgemeines C, aber sie konzentrieren sich auch auf AVR/Atmega/Attiny, einschließlich Port/Bit-Manipulation.

Hallo.. Können Sie mir ein gutes und leicht verständliches Tutorial zu dieser bitweisen Adressierung von IO-Ports zeigen? Vielen Dank
// switch led on
PORTB &= 0x01;
sleep(500);

// switch led off
PORTB &= 0x00;
sleep(500);

Nicht ganz. Da Ihre LED niedrig gebunden ist, müssen Sie das Port-Bit hoch setzen, um es einzuschalten.

PORTB |= _BV(PB0);

Und Sie müssen es niedrig einstellen, um es auszuschalten.

PORTB &= ~_BV(PB0);
#define F_CPU 1000000UL

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



void main() 
{
DDRB |= 0x01;

while(1)
{
  // switch led on
   PORTB |= 0x01 ; ///
   _delay_ms(500) ;      

  // led off
   PORTB  &= ~0x01; 
  _delay_ms(500) ;
 }
Beachten Sie, dass die Frage eine Antwort hat, die vor drei Jahren akzeptiert wurde.
Und niemand hat abgedeckt, dass keine Widerstände in Reihe für ATMega8 verwendet werden, sie können direkt fahren?