Проблема компиляции DigiSpark AT Tiny85?
Друг попросил меня найти проблему с компиляцией для его DigiSpark НА плате Tiny85. Мы пытаемся составить скетч отсюда: https://forum.arduino.cc/index.php?topic=314773.0
Но не повезло - что-то смешалось в заголовках или конфигурации, и я не знаю, что именно.
Этот ISR не компилируется:
ISR(TIMER1_OVF_vect) { //переполнение timer1
Сначала были некоторые ошибки, такие как TCR1 = 0; не определено в этом скетче, затем после игры с #define __ AVR_ATtiny85__, #undef _AVR_IOXXX_H_ и замены avr/io.h на iotn85.h пришли ошибки, такие как множественное определение __vector_x (?). Закомментируйте эту строку:
//attachInterrupt(0,zeroCrossingInterrupt, ПАДЕНИЕ)
помогло, но теперь даже это работает, а ИСР-нет.
Я знаю, что там много тайников и вы не видите, что происходит за занавесками, но я еще совсем потерялся...
Может быть, есть также проблема, у меня есть несколько установок в разных dirs, но я не знаю, как очистить старые (1.6.5-r2), и в конце концов оба работают одинаково, моя последняя свежая установка-1.8.9.
Есть ли у кого-нибудь опыт работы с демо-скетчом или какой-нибудь рабочий демо-скетч, использующий как compare match, так и overflow ISR ?
Обновлено
Информация о настройке
Эта плата выбрала (...\AppData\Roaming\Arduino15\packages\digistump\hardware\avr\1.6.7\boards.txt):
digispark-tiny.name=Digispark (Default - 16.5mhz)
digispark-tiny.upload.using=micronucleusprog
digispark-tiny.upload.protocol=usb
digispark-tiny.upload.tool=micronucleus
digispark-tiny.upload.maximum_size=6012
digispark-tiny.build.mcu=attiny85
digispark-tiny.build.f_cpu=16500000L
digispark-tiny.build.board=AVR_DIGISPARK
digispark-tiny.build.core=tiny
digispark-tiny.build.variant=digispark
digispark-tiny.upload.wait_for_upload_port = false
digispark-tiny.upload.use_1200bps_touch = false
digispark-tiny.upload.disable_flushing = false
И они доступны:
(...\AppData\Roaming\Arduino15\package_digistump_index.json)
...
"boards": [
{
"name": "Digispark (Default - 16.5mhz)"
},
{
"name": "Digispark Pro (Default 16 Mhz)"
},
{
"name": "Digispark Pro (16 Mhz) (32 byte buffer)"
},
{
"name": "Digispark Pro (16 Mhz) (64 byte buffer)"
},
{
"name": "Digispark (16mhz - No USB)"
},
{
"name": "Digispark (8mhz - No USB)"
},
{
"name": "Digispark (1mhz - No USB)"
}
],
...
Правка 2
Новая попытка установки на W10
Еще несколько ссылок - 2-е руководство здесь:
https://www.electronicshub.org/getting-started-with-attiny85/
http://digistump.com/package_digistump_index.json
должны быть переведены на
https://raw.githubusercontent.com/digistump/arduino-boards-index/master/package_digistump_index.json
https://downloads.arduino.cc/arduino-1.8.9-windows.zip
W10
При установке отображается ошибка загрузки (тайм-аут?):
http://downloads.arduino.cc/tools/avr-gcc-4.8.1-arduino5-i686-mingw32.zip
Скачал вручную (там был пустой файл с таким именем):
...\AppData\Local\Arduino15\staging\packages\
avr-gcc-4.8.1-arduino5-i686-mingw32.zip
...\AppData\Local\Temp\arduino_build_139604\core\core.a(wiring.c.o): В функции `__vector_4':
...\AppData\Local\Arduino15\packages\digistump\hardware\avr\1.6.7\core\tiny/wiring.c:93: множественное определение `__vector_4'
...\AppData\Local\Temp\arduino_build_139604\sketch\sketch_jun28a.ino.cpp.o:...\arduino-1.8.9\SketchBook\sketch_jun28a/sketch_jun28a.ino:60: впервые определено здесь
collect2.exe: ошибка: ld вернул 1 статус выхода
статус выхода 1 Ошибка компиляции для платы Digispark (по умолчанию - 16,5 МГц).
...\AppData\Local\Arduino15\packages\digistump\hardware\avr\1.6.7\core\tiny\core_build_options.h (не нашел этот файл в arduino dir):
/*=============================================================================
Build options for the ATtiny85 processor
=============================================================================*/
#if defined( __AVR_ATtiny25__ ) || defined( __AVR_ATtiny45__ ) || defined( __AVR_ATtiny85__ )
#define __AVR_ATtinyX5__
#endif
#if defined( __AVR_ATtinyX5__ )
/*
For various reasons, Timer 1 is a better choice for the millis timer on the
'85 processor.
*/
#define TIMER_TO_USE_FOR_MILLIS 1
@Tom, 👍0
Обсуждение3 ответа
Лучший ответ:
Проблема заключается в следующем:
Ядро digispark уже реализует ISR TIMER1_OVF_vect (прерывание переполнения Timer1). Поскольку у вас есть
1
для #define TIMER_TO_USE_FOR_MILLIS
, Timer1 будет использоваться для подсчета значения millis()
в фоновом режиме. Для этого необходимо прерывание переполнения таймера 1.
Код, который вы скопировали с этого сайта, не предполагает, что вы можете использовать ядро, которое уже реализует прерывания. Он написан для общего ATtiny85, а не специально для версии Digispark.
Что вы можете сделать, чтобы решить эту проблему:
Вы можете использовать Timer0 для своего кода, сохраняя ядро Digispark нетронутым. Вы можете изменить все регистры с Timer1 на Timer0 (заменив
1
на0
). Кроме того, вам нужно заменитьTCR1
наTCR0B
, потому что для Timer0 это регистр, который устанавливает прескалер (и отключает таймер, если в него записан ноль). Также нужно учитывать, что Timer0 имеет другие настройки прескалера. Таким образом, строкаTCR1 = B00001011;
вzeroCrossingInterrupt()
должна быть изменена наTCR0B = B00000101;
. Это установит прескалер на 1024, как упоминалось в комментарии. Полученный код отлично компилируется для меня с ядром digispark (хотя я не тестировал его функциональность).Вы можете настроить ядро Digispark на использование Timer0 для
millis()
, изменив определениеTIMER_TO_USE_FOR_MILLIS
в разделе Attiny85 файлаarduino_folder/packages/digistump/hardware/avr/1.6.7/core/tiny/core_build_options.h
на значение0
вместо1
. Если вы сделаете это, исходный скетч будет скомпилирован нормально. Хотя в комментарии перед этим build options говорится, что Timer1 лучше дляmillis()
"по разным причинам", что не очень конкретно. Вы можете попробовать, если это работает хорошо для вас.Вы можете использовать другое ядро Attiny. Хотя вам, возможно, придется изменить его, чтобы приспособиться к необычной тактовой частоте fo 16,5 МГц (большинство ядер, которые я видел, имеют 16, 8 и 1 МГц). Это может быть так же просто, как изменить значение определенной тактовой частоты в файлах ядер, но я в этом не уверен.
Отлично ! Попробую, надеюсь и он поймет это как непрофессиональный программист и примет ваш ответ. Вы можете научить, как бороться с этой безумной системой 4 чайников ;-) Вы знаете, что простые вещи часто запутывают их..., @Tom
Кстати, если вам нужно будет уменьшить размер шрифтов GFX в два раза и ускорить печать или скомпилировать и запустить код Arduino + LCD на ПК, проверьте, что мои сопровождающие Github - lib защищаются от улучшений., @Tom
Когда я изменил значение millis с 1 на 0, ошибка компиляции исчезла, но программа не загрузилась должным образом. Я попытался загрузить простой blink blink sketch, он больше не может загружаться. Кажется, он больше не общается ! Во всяком случае, это, вероятно, "особенность", а не концепция плохой архитектуры..., @Tom
Загрузка не имеет ничего общего с компиляцией. Вы просто видите еще одну проблему. Я думаю, вы видите какую-то ошибку "программист не отвечает". Попробуйте погуглить, потому что на эту распространенную ошибку ответили несколько раз на этом сайте, @chrisl
Еще один простой вариант - переписать или удалить ISR в проводке.: ...\AppData\Local\Arduino15\packages \ digistump\hardware\avr\1.6.7\core\tiny\wiring.c
Например, после такого изменения удалось скомпилировать без проблем.
Самым простым решением было бы поместить этот код в мой ISR или вызвать его из другого.
#ifdef nothing
// bluebie изменил isr на noblock, чтобы он не испортил USB-библиотеки
ISR(MILLISTIMER_OVF_vect, ISR_NOBLOCK)
{
// скопируйте их в локальные переменные, чтобы они могли храниться в регистрах
// (изменчивые переменные должны считываться из памяти при каждом обращении)
unsigned long m = millis_timer_millis;
unsigned char f = millis_timer_fract;
/* rmv: The code below generates considerably less code (emtpy Sketch is 326 versus 304)...
m += MILLIS_INC;
f += FRACT_INC;
if (f >= FRACT_MAX) {
f -= FRACT_MAX;
m += 1;
}
...rmv */
f += FRACT_INC;
if (f >= FRACT_MAX)
{
f -= FRACT_MAX;
m = m + MILLIS_INC + 1;
}
else
{
m += MILLIS_INC;
}
millis_timer_fract = f;
millis_timer_millis = m;
millis_timer_overflow_count++;
}
#endif
Если вы переименуете wiring.c и перезапустите редактор, вы получите main.cpp:5: неопределенная ссылка на ошибку `init', есть это "дерьмовое" сердце arduino:
#include <WProgram.h>
int main(void)
{
init();
setup();
for (;;)
loop();
return 0;
}
WProgram.h начинается с:
#ifndef WProgram_h
#define WProgram_h
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <avr/interrupt.h>
#include "core_build_options.h"
#include "core_pins.h"
#include "wiring.h"
...
И init этого ATtiny85 (внутренняя проводка.c) evn выглядит так:
void init(void)
{
// калибровка часов
// перекалибровать часы, если они были откалиброваны загрузчиком (например, micronucleus)
#if F_CPU != 16500000L
if (OSCCAL != read_factory_calibration()) {
// отрегулируйте калибровку с 16,5 МГц до 16,0 МГц
if (OSCCAL >= 128) {
// может быть, 8 лучше? ну да ладно - в любом случае только около 0,3%
OSCCAL -= 7;
} else {
OSCCAL -= 5;
}
}
#endif
// TODO: определите, установлены ли предохранители на PLL, обычный внутренний генератор или внешний, и измените поведение в следующем разделе...
#if F_CPU < 16000000L
cli();
CLKPR = 0b10000000;
#if F_CPU == 8000000L
CLKPR = 1; // div 2
#elif F_CPU == 4000000L
CLKPR = 2 // div 4
#elif F_CPU == 2000000L
CLKPR = 3; // div 8
#elif F_CPU == 1000000L
CLKPR = 4; // div 16
#elif F_CPU == 500000L
CLKPR = 5; // div 32 = 500khz
#elif F_CPU == 250000L
CLKPR = 6; // div 64 = 250 кГц
#elif F_CPU == 125000L
CLKPR = 7; // div 128 = 125 кГц тактовая частота процессора
#else
#warning "Cannot prescale chip to specified F_CPU speed"
#endif
#endif
// это нужно вызвать перед setup (), иначе некоторые функции там не будут работать
sei();
// На случай, если загрузчик плохо оставил наш миллисекундный таймер
#if defined( HAVE_BOOTLOADER ) && HAVE_BOOTLOADER
MillisTimer_SetToPowerup();
#endif
// Используйте таймер Millis для быстрого ШИМ
MillisTimer_SetWaveformGenerationMode( MillisTimer_(Fast_PWM_FF) );
// Millis timer-это всегда часы процессора, разделенные на MillisTimer_Prescale_Value (64)
MillisTimer_ClockSelect( MillisTimer_Prescale_Index );
// Включить прерывание overlow (это базовый системный tic-toc для millis)
MillisTimer_EnableOverflowInterrupt();
// Инициализация таймера, используемого для тонального сигнала
#if defined( INITIALIZE_SECONDARY_TIMERS ) && INITIALIZE_SECONDARY_TIMERS
initToneTimerInternal();
#endif
// Инициализация АЦП
#if defined( INITIALIZE_ANALOG_TO_DIGITAL_CONVERTER ) && INITIALIZE_ANALOG_TO_DIGITAL_CONVERTER
ADC_PrescalerSelect( ADC_ARDUINO_PRESCALER );
ADC_Enable();
#endif
}
У меня была похожая проблема. Я удалил функции loop() и setup (), использовал классическую конструкцию C с функцией main (), и она начала работать. (Я думаю, что loop() и setup() позволяют использовать другие функции, такие как delay() - и он использует таймер - только моя гипотеза).
- Ошибка компиляции кода для Arduino/Genuino Uno
- Собственное определение типа с использованием структуры не дает имени типу
- ошибка компиляции при изменении переменной с char на String
- UECIDE: ошибка компоновщика с библиотекой U8g2
- Ошибка: expected unqualified-id before 'if'
- Связь последовательного порта Digispark
- Ошибка : заблудиться '\' в программе
- Ошибка: invalid application of 'sizeof' to incomplete type 'int []' при попытке вычислить размер массива в библиотеке
Btw сделал лучшее сжатие и ускорение шрифтов Adafruit (примерно на 1/2 лучше, чем LZW) и C++ .Net simulator for old AT Mega project setup если кому интересно (он компилирует код Arduino напрямую, но мало файлов издевается и работает не во всех версиях - движок "черной магии" часто меняется., @Tom
Код с сайта кажется нормальным. Из сообщения об ошибке кажется, что вы не выбираете правильный тип платы в Arduino IDE. Поскольку ATtiny85 нет в стандартной библиотеке ядра: Какое ядро для ATtiny вы установили?, @chrisl
Он прислал мне ссылку https://www.instructables.com/id/Digispark-DIY-The-smallest-USB-Arduino/?%EF%BB%BF как настроить, думал, что я использовал то же самое, но помню, что я выбрал по умолчанию 16,5 МГц - может быть, из руководства с другой страницы, и теперь я вижу, что там упоминается Крошечное ядро ?? Проверю и это позже - не уверен, что был такой вариант. Не устанавливал драйверы, так как у меня нет модуля, и в этом zip-файле не было ничего связанного., @Tom
Больше информации добавлено к вопросу, проверено все платы, Tiny85 упомянул также @all 3 non-pro версии., @Tom
Пожалуйста, загляните в файл "arduino folder/packages/digistump/hardware/avr/1.6.7/core/tiny/core_build_options.h". Какое число используется для
#define TIMER_TO_USE_FOR_MILLIS
?, @chrislНе уверен, что в файле выбран правильный раздел, но в теории 1 есть только 0/1 для 3 разных групп процессоров (информация от 1-й установки сейчас)., @Tom