более низкая тактовая частота, чем ожидалось на attiny202
Я программирую attiny202 согласно datasheet может работать на частоте до 20 МГц, но после компиляции/загрузки этого простого кода в attiny202 и наблюдения за выводом PA2 на осциллографе я вижу, что вывод колеблется с частотой ~ 2,5 МГц, что составляет около 10x. медленнее, чем я ожидал, даже если я отключил предварительное масштабирование, я что-то упустил? (я новичок в программировании микроконтроллеров)
Примечание: VCC составляет 5 В (от блока питания лабораторного стола)
main.c
#include <avr/io.h>
int main(void)
{
// без предскейлинга (если меньше 4.5В, то это разгон)
_PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, 0);
PORTA_DIR = _BV(2);
while(1)
{
PORTA_OUTTGL = _BV(2);
}
}
Создать файл
PRG = main
CC = avr-gcc
MCU_TARGET = attiny202
OPTIMIZE = -Os
OBJCOPY = avr-objcopy
UART = /dev/ttyUSB0
all: $(PRG).elf $(PRG).hex
$(PRG).elf: $(PRG).c » $(CC) -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(PRG).c -o $(PRG).elf
%.hex: %.elf
» $(OBJCOPY) -j .text -j .data -O ihex $< $@
clean:
» rm *.elf *.hex
burn: $(PRG).hex
» pymcuprog -t uart -d $(MCU_TARGET) -u $(UART) write -f $(PRG).hex --erase --verify
растровые изображения с осциллографа:
-
то же изображение с дополнительной информацией об измерениях:
@Joe Cabezas, 👍0
Обсуждение2 ответа
Лучший ответ:
Как дополнение к ответу Крисла, если вы разберете скомпилированный программы, вы должны увидеть, что ваш бесконечный цикл выглядит так:
1: sts 0x0407, r24 ; write to PORTA_OUTTGL
rjmp 1b ; jump back to previous instruction
Каждая из этих инструкций выполняется по два цикла, всего четыре цикла на каждую. итерация цикла. Таким образом, ожидается, что цикл будет работать на частоте F_CPU÷4 = 5 МГц. Поскольку цикл выходного сигнала занимает два переключателя, вы ожидаете увидеть 2,5 МГц на осциллографе.
Вы можете ускорить это, написав в виртуальный порт.
зарегистрируйте VPORTA_IN
вместо PORTA_OUTTGL
. Регистры виртуального порта
эквивалентны обычным регистрам портов, но отображаются в
Пространство ввода/вывода микроконтроллера. Это позволяет компилятору заменить
инструкцию sts
на более короткую и быструю инструкцию out
.
цикл должен завершиться всего за 3 цикла ЦП и вывести сигнал в
3,33 МГц.
о, спасибо за это объяснение !, в чем тогда преимущество использования только не виртуального порта, если vports «лучше»? (конечно, есть причина, но я нуб), не хочешь объяснить? Большое спасибо за ваше время, @Joe Cabezas
@JoeCabezas: Обычные порты имеют дополнительные функции: устанавливать, очищать и переключать адреса регистров для каждого базового регистра. Кроме того, адресное пространство, доступное для виртуальных портов, крошечное, поэтому большинство периферийных устройств имеют только обычные порты., @Edgar Bonet
спасибо, тогда я буду больше изучать vports, очень полезно!, @Joe Cabezas
Вы постоянно переключаете вывод в программе. Это включает в себя копирование данных регистра в рабочий регистр, переключение бита и запись результата обратно.
Это занимает больше, чем 1 такт. Таким образом, результирующая частота намного ниже. Только с программным обеспечением вы просто не сможете приблизиться к тактовой частоте микроконтроллера.
Код записывает в регистр «переключателя вывода», что более эффективно, чем выполнение последовательности чтения-изменения-записи полностью в программном обеспечении., @Edgar Bonet
@EdgarBonet спасибо, но все же кажется, что для уменьшения с 20 МГц до 2,5 МГц требуется много циклов, 10 циклов? Я действительно думаю, что что-то упускаю: /, @Joe Cabezas
@JoeCabezas: 20 МГц / 2,5 МГц = 8 циклов, а не 10. Это две итерации цикла (поскольку выходной сигнал переключается дважды) при 4 циклах ЦП на итерацию. Смотрите мой ответ для подробного подсчета циклов., @Edgar Bonet
- Поскольку double и float представляют один и тот же тип данных (обычно), что предпочтительнее?
- Прерывание переполнения таймера AVR не работает
- Заменить предохранители Arduino Uno (может ли Arduino Uno заменить свои собственные предохранители?)
- _delay_ms() работает намного медленнее, чем ожидалось (в 6 раз) на tinyAVR 0/1 (ATTiny1604)
- программирование ардуино на чистом с
- Attiny85 не распознается при запуске Windows
- Как передать нестатический член класса для обратного вызова на платформах avr?
- Используйте Arduino Uno для программирования встроенной Atmega328 на C
Итак, вы переключаете контакт в коде и ожидаете, что он будет меняться с той же частотой, что и часы? Это не сработает, так как даже такое простое действие занимает больше тактовых импульсов, чем один. Я не настолько увлекаюсь этим, чтобы сказать вам, сколько циклов необходимо, но я уверен, что это значительно больше, чем 1., @chrisl
конечно, он не будет работать на той же частоте, что и основные часы!, переключение значения в reg занимает более 1 цикла, я чувствую себя глупо, извините, я мало спал последние 48 часов из-за волнения, увидев, как это работает , это мой первый SOP8!, пожалуйста, опубликуйте свой ответ, чтобы я мог принять его, иду спать, прежде чем я задам больше вопросов, прежде чем думать ..., @Joe Cabezas