Atmega @ 8MHZ задерживает в 8 раз быстрее

Я очень новичок в программировании Atmegas и AVR, поэтому я надеюсь, что вы простите меня за этот нубский вопрос: у меня есть этот код, который отлично работает на частоте 1 МГц, но если я подключил Atmega к внутренней частоте 8 МГц, изменив частоту F_CPU на 8 МГц кроме того, светодиод мигает слишком быстро, кажется, что компилятор C игнорирует мою новую частоту. Может ли кто-нибудь помочь мне ;)?

#define F_CPU 8000000UL
#include <util/delay.h>
#include <avr/io.h>

int main(void)
{
  while(1)
  {
    //TODO:: Please write your application code
    /* set PC0 on PORTC (digital high) and delay for 500mS */
    PORTD &= ~_BV(PD5);
    _delay_ms(500);

    /*  PC0 on PORTC (digital 0) and delay for 500mS */
    PORTD |= _BV(PD5);
    _delay_ms(500);
  }
}

он компилируется с помощью этих команд:

avr-gcc -g -Os -mmcu=atmega8  -c test.c 
avr-gcc -g -mmcu=atmega8 -dF_CPU=8000000UL -o flash.elf test.o
avr-objcopy -j .text -j .data -O ihex flash.elf flash.hex

БОЛЬШОЕ спасибо за ваше время и помощь;) Delay.h: http://pastebin.com/wzppfma3


person user3321030    schedule 13.08.2015    source источник
comment
Вы изменили две вещи: частоту процессора и F_CPU, и вы предполагаете, что компилятор игнорирует F_CPU. Но также может случиться так, что частота вашего процессора не такая, как вы думаете.   -  person indiv    schedule 13.08.2015
comment
Сам компилятор, безусловно, игнорирует макрос. Это потому, что он не имеет представления о часах и базовой системе. Если ваши функции задержки не соблюдают это определение, вы должны проверить их.   -  person too honest for this site    schedule 13.08.2015
comment
Частота процессора должна быть 8 МГц, потому что светодиод мигает примерно 10 секунд. 8 раз быстрее, поэтому я думаю, что компилятор все еще находится в режиме 1 МГц. Я использовал предохранители LOW: 0xe4 High:0xd9 , поэтому выбрано время запуска RC 8Mhz 6ck +64ms. Функция задержки использует константу F_CPU: atmel.com/webdoc/AVRLibcReferenceManual/   -  person user3321030    schedule 13.08.2015
comment
@Olaf _delay_ms() — это встроенная функция, определенная в заголовке <util/delay.h>, и ее поведение зависит от значения макроса F_CPU.   -  person    schedule 13.08.2015
comment
@user3321030: user3321030: Пожалуйста, повторите: компилятор не заботится о системной частоте!   -  person too honest for this site    schedule 13.08.2015
comment
@duskwuff: Спасибо за разъяснение. Однако OP может проверить это, так как это объясняет проблемы.   -  person too honest for this site    schedule 13.08.2015
comment
Что вы ожидаете от -dF_CPU=8000000UL? Вы не перепутали с -DF_CPU=8000000UL который нужно было бы использовать при компиляции исходников, а не для линковки.   -  person too honest for this site    schedule 14.08.2015
comment
Юп, кажется, я перепутал, но тоже без изменений, светодиод по-прежнему мигает с частотой 8 Гц :( Компилятору плевать на системную частоту! Компилятору плевать на системную частоту! :D   -  person user3321030    schedule 14.08.2015
comment
@user3321030 user3321030 По-видимому, _delay_ms() определено в <util/delay.h>. Было бы полезно, если бы вы добавили это определение к вопросу.   -  person user3386109    schedule 14.08.2015
comment
pastebin.com/wzppfma3 это мой заголовочный файл delay.h   -  person user3321030    schedule 14.08.2015
comment
Вы превышаете максимальную задержку, которую _delay_ms() может дать на любой тактовой частоте.   -  person Dmitri    schedule 14.08.2015
comment
@Dmitri ок, спасибо, какой у меня макс. Задержка на 8 МГц?   -  person user3321030    schedule 14.08.2015
comment
На частоте 8 МГц максимальная задержка составляет около 32,768 мс.   -  person Dmitri    schedule 14.08.2015
comment
@ user3386109 <util/delay.h> является частью заголовков цепочки инструментов AVR. Это не часть проекта этого пользователя.   -  person    schedule 14.08.2015


Ответы (2)


Проблема в том, что _delay_ms имеет максимальное значение мс в зависимости от частоты вашего F_CPU. Согласно документам, этот максимум составляет:

262,14 мс/F_CPU в МГц

что составляет максимум 32 мс для ваших 8 МГц. Поэтому вместо этого напишите такой цикл, чтобы получить задержку в 500 мс:

for (uint8_t i=0; i<50; i++) _delay_ms(10);
person bobasaurus    schedule 14.08.2015
comment
Спасибо :) Это решение ;) - person user3321030; 26.08.2015
comment
Согласно документации _delay_ms переключается на более низкое разрешение, если вы запрашиваете задержки больше максимального, а затем поддерживает задержки до 6, с чем-то секунд, независимо от тактовой частоты процессора... microchip.com/webdoc/AVRLibcReferenceManual/ - person Julian F. Weinert; 17.07.2019
comment
@Julian Это должно быть новая функция, так как я опубликовал это 4 года назад, хотя похоже, что она ограничена максимум 6,5535 сек. - person bobasaurus; 18.07.2019

Вы должны изменить внутренний предохранитель AVR для работы с 8 МГц, просто написать его в коде недостаточно, установите lfuse на 0xE4, чтобы заставить AVR работать на 8 МГц.

person Nasr    schedule 14.08.2015