avr attiny84: falsche Verzögerung

Ich bin ziemlich neu in der AVR-Programmierung. Ich stehe vor einem seltsamen Problem, das ich bisher nicht lösen kann.

Ich habe einen einfachen Code geschrieben:

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

int main(void) {

    DDRA = 0XFF;

    for (;;){
        PORTA = 0xFF;
        _delay_ms(1000);
        PORTA = 0x00;
        _delay_ms(1000);
    }

    return 0x00;
}

Ich setze die F_CPU (den von _delay_ms() verwendeten Wert) über das Makefile, das ich zum Kompilieren und Hochladen des Codes verwende:

DEVICE     = attiny84
CLOCK      = 20000000
PROGRAMMER = -c usbasp -P /dev/tty.usb* -b 19200 
OBJECTS    = main.o dallas_one_wire.o
FUSES      = -U lfuse:w:0x62:m -U hfuse:w:0xdf:m -U efuse:w:0xff:m


######################################################################
######################################################################

# Tune the lines below only if you know what you are doing:

AVRDUDE = avrdude $(PROGRAMMER) -p $(DEVICE)
COMPILE = avr-g++ -Wall -Os -DF_CPU=$(CLOCK) -mmcu=$(DEVICE)

# symbolic targets:
all:    main.hex

.c.o:
    $(COMPILE) -c $< -o $@

.S.o:
    $(COMPILE) -x assembler-with-cpp -c $< -o $@
# "-x assembler-with-cpp" should not be necessary since this is the default
# file type for the .S (with capital S) extension. However, upper case
# characters are not always preserved on Windows. To ensure WinAVR
# compatibility define the file type manually.

.c.s:
    $(COMPILE) -S $< -o $@

flash:  all
    $(AVRDUDE) -U flash:w:main.hex:i

fuse:
    $(AVRDUDE) $(FUSES)

install: flash fuse

# if you use a bootloader, change the command below appropriately:
load: all
    bootloadHID main.hex

clean:
    rm -f main.hex main.elf $(OBJECTS)

# file targets:
main.elf: $(OBJECTS)
    $(COMPILE) -o main.elf $(OBJECTS)

main.hex: main.elf
    rm -f main.hex
    avr-objcopy -j .text -j .data -O ihex main.elf main.hex
# If you have an EEPROM section, you must also create a hex file for the
# EEPROM and add it to the "flash" target.

# Targets for code debugging and analysis:
disasm: main.elf
    avr-objdump -d main.elf

cpp:
    $(COMPILE) -E main.c

In Bezug auf das Datenblatt des attiny84 sollte es mit 20 MHz unter 5 Volt laufen.

Leider blinkt die LED nicht jede Sekunde mit einer Rate von 1, sondern etwas wirklich länger mit einer Rate von 10 Sekunden.

Durch Einstellen des F_CPU-Werts habe ich die 1-Sekunden-Blinkrate erreicht, indem ich F_CPU = 1000000 (1 MHz) verwendet habe.

Bedeutet das, dass der attiny84 mit 1 MHz läuft oder irre ich mich woanders?

Standardmäßig läuft der Attiny mit seinem internen Oszillator, der 8 MHz beträgt, und standardmäßig gibt es auch einen Takt, der durch 8-Sicherungssatz geteilt wird. Wie Sie auf die harte Tour herausgefunden haben, läuft es mit 1 MHz. Sie können die Division-durch-8-Sicherung deaktivieren, um 8 MHz zu erhalten, aber für alles, was höher ist, müssen Sie einen externen Kristall hinzufügen. Außerdem sind die internen Oszillatoren nicht sehr genau, in diesem Fall spielt es keine Rolle, aber es ist gut zu wissen.

Antworten (2)

Annahme: Sie betreiben den ATTiny84 mit seiner internen RC-Uhr.

Damit der ATTiny84 mit 20 MHz läuft, muss der Mikrocontroller mit einem externen 20-MHz-Takt versorgt werden, der normalerweise durch einen 20,0-MHz-Quarz oder -Resonator und zwei Lastkondensatoren erreicht wird. Aus dem Datenblatt :

Kristalloszillator

Außerdem müssen Sie die Sicherungen entsprechend einstellen, damit der Mikrocontroller einen externen Oszillator anstelle des internen verwendet.

Sie können die Sicherungseinstellungsbits berechnen, die Sie für einen externen Quarz benötigen, indem Sie hier den spezifischen AVR auswählen . Zusätzliche nützliche Informationen in dieser Antwort auf eine verwandte Frage auf dieser Website.

Der ATtiny läuft tatsächlich mit (ungefähr) 1 MHz.

Aus dem Datenblatt :

6.2.6 Standarduhrquelle

Das Gerät wird mit CKSEL = „0010“, SUT = „10“ und CKDIV8 programmiert ausgeliefert. Die Standardeinstellung für die Taktquelle ist daher der interne Oszillator, der bei 8,0 MHz mit der längsten Startzeit und einer anfänglichen Vorskalierung des Systemtakts von 8 läuft, was zu einem Systemtakt von 1,0 MHz führt . Diese Standardeinstellung stellt sicher, dass alle Benutzer ihre gewünschte Taktquelleneinstellung mit einem systeminternen oder Hochspannungsprogrammierer vornehmen können.

Kapitel 6.2 erklärt, wie die Taktauswahl für dieses ATtiny funktioniert, aber seien Sie vorsichtig, die Auswahl einer zu langsamen Taktfrequenz (z. B. 128 kHz) kann Sie daran hindern, das Gerät neu zu programmieren, es sei denn, Sie verwenden einen "Hochspannungs" -Programmierer. Die Sicherungen verwenden negative Logik, lesen Sie das Kapitel sorgfältig durch, bevor Sie sie programmieren.

Tabelle 19-5 erklärt, dass „Fuse Low Byte“ einen Standardwert von 0x62 hat, wobei Bit7 0 ist, aber anzeigt, dass der 8-MHz-Takt durch 8 geteilt wird (daher negative Logik).

Viele Anwendungen laufen perfekt mit dem niedrigeren Takt, was den Vorteil eines geringeren Stromverbrauchs hat. Es hängt ganz von Ihrer Anwendung ab, ob Sie wirklich einen höheren Takt benötigen oder nicht. Setzen Sie einfach F_CPU auf den zutreffenden Wert. F_CPU informiert den Compiler darüber, wie schnell die Steuerungsuhr ist, es stellt nicht die Steuerungsuhr.

Danke, Ihre Erklärung ist wirklich wert und geht über meine Frage hinaus! Hochgeschätzt