Страница 1 из 2
millis() Attiny13a
Добавлено: Пт дек 21, 2018 14:01:41
postal2201
Доброе время суток друзья!
Хочу перенести свой небольшой проект с рельс Arduino IDE на WinAVR.
Проект будет работать на Attiny13a. Изначально все писалось в АрдуиноИде так как очень удобно отлаживать в виртуальных симах типа тинкеркад. К иде был прикручен модуль MicroCore для поддержки Attiny13a.
При переносе в WinAVR возникла сложность с функцией millis(), так как нативно такой функции нет. В модуле MicroCore millis(), насколько я понял, реализована на основе WatchDog таймера. Вычленить её из исходников у меня пока не хватает скилла. Помогите с аналогом, либо вычленить ее из MicroCore в виде либы.
P.S. исходники моей проги для ArduinoIDE и WinAVR в аттаче.
Re: millis() Attiny13a
Добавлено: Пт дек 21, 2018 14:11:42
ARV
в вашем коде эта функция используется только для задержки при подавлении дребезга при опросе кнопок. в WinAVR есть модуль util/delay.h, подключив который, вы получите в распоряжение макрос _delay_ms(x), который выполняет задержку в миллисекундах.
чуть-чуть изменив ваш код, вы легко замените код опроса кнопок с millis() на код с _delay_ms()
Re: millis() Attiny13a
Добавлено: Чт дек 27, 2018 10:51:37
postal2201
ARV, здравствуйте!
delay не пойдет, так как вызывает остановку программы. millis используется не столько для подавления дребезга, а для отслеживания длинного нажатия кнопки. Если скажем задать длительность 5 сек от при delay прога будет ничего не делать эти 5 сек, а в это время должны отслеживаться другие события. Поэтому мне нужна реализация на таймере.
Я накидал небольшой код поковырявшись в исходниках microcore.
Код: Выделить всё
#define F_CPU = 9600000
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
volatile uint32_t wdt_interrupt_counter = 0;
ISR(WDT_vect)
{
wdt_interrupt_counter++;
}
uint32_t millis()
{
return wdt_interrupt_counter * 16;
}
int main(void)
{
cli();
wdt_reset();
WDTCR|=(1<<WDCE) | (1<<WDE);
WDTCR=(1<<WDTIF) | (1<<WDTIE) | (0<<WDP3) | (0<<WDCE) | (0<<WDE) | (0<<WDP2) | (0<<WDP1) | (0<<WDP0);
sei();
while(1)
{
uint32_t now = (uint32_t)millis();
if (now > 2000){
PORTB |= _BV(PB0);
DDRB |= _BV(PB0);
}
}
}
У меня только остался вопрос, что произойдет с переменной wdt_interrupt_counter при ее переполнении, и как долго она будет переполняться?
Re: millis() Attiny13a
Добавлено: Чт дек 27, 2018 12:43:12
ARV
поскольку вы не делаете доступ к 32-битной переменной атомарным, ваш код будет работать плохо - функция millis будет возвращать иногда совсем странные значения, причем предсказать, когда такая странность возникнет, вы не сможете.
хоть для дребезга, хоть для чего иного, _delay_ms вполне подходит. но, в принципе, я вам ничего не навязываю
Re: millis() Attiny13a
Добавлено: Чт дек 27, 2018 12:55:05
Мурик
ARV писал(а):доступ к 32-битной переменной атомарным
Одна из причин перехода на 32-ух битные МК, которые могут аппаратно работать с переменными до 32-ух бит.
Re: millis() Attiny13a
Добавлено: Чт дек 27, 2018 13:05:41
ARV
Мурик писал(а):Одна из причин перехода на 32-ух битные МК
я так понимаю, что с переменными в 64 бита или, не дай бог, больше, вы не работаете вообще, поскольку МК с такой разрядностью пока нет...
Re: millis() Attiny13a
Добавлено: Чт дек 27, 2018 13:49:26
postal2201
ARV сделал атомарной операцию возврата wdt_interrupt_counter
Код: Выделить всё
uint32_t millis()
{
ATOMIC_BLOCK(ATOMIC_RESTORESTATE){
return wdt_interrupt_counter * 16;
}
}
Операции в обработчике, ISR(WDT_vect), насколько я знаю, и так атомарны.
Так все-таки, что будет при переполнении wdt_interrupt_counter? Переменная сбросится в 0?
Re: millis() Attiny13a
Добавлено: Чт дек 27, 2018 13:50:40
ARV
сбросится, естественно
Re: millis() Attiny13a
Добавлено: Чт дек 27, 2018 14:15:20
BOB51
Вот млин "другая крайность" применения адурины...
Одни оную "в упор презирают" (
Мурик и иные МАТЕРЫЕ),
другие (большей частью начинающие, как и топикстартер
postal2201) сходу в такие ДЕБРЕГИБРИДЫ сходу лезут...
Робятки-КОТЯТКИ!
Или работайте в рамках АРДУИНО IDE (MicroCore именно к этой разновидности делался),
или делайте уж проект как полагается - на соответствующей IDE и с "стандартным" компилятором.
Иначе для начишнющего "каша" и ошибки неизбежны.
Тем более тинька 13 в коей и памяти программ... МНДЯАА... под ассемблером и то чего путнего впихнуть затруднительно.
Не говоря об "излишествах" адуринки.
Да и программу надо продумывать, а не лепить... чего.
Помимо прочего и схемка
ОБЯЗАНА БЫТЬ, а не только какой-то СКОТч.
Антидребезг можно и программный и аппаратный.
На сегодня вполне удобны и аппаратные решения (хош R-S траггер на кнопе с перекидным контактом, хош на емкостной от китаяцев) - а программе тем более проще будет.
Вот к примеру "тренировочный секундомер" с дисплейчиком и одной емкостной кнопой от китаяцев (одна и та же кнопа выполняет различные действия в режимах ожидания, счета и останова).
Однако размер результата - в 3122 байта - для адуринки наны или для дигистампа на тини85 еще впихивается, но в тини13...
Хотя там и применена millis() - но честно говоря мне абсолютно ПОФИГ на основе чего оная работает (я б для такого WDT не использовал).

Re: millis() Attiny13a
Добавлено: Чт дек 27, 2018 14:25:51
Мурик
ARV писал(а):я так понимаю, что с переменными в 64 бита
С ними приходится работать не очень часто и маловероятно что с такой переменной нужно работать в прерывании и в основной части программы.
BOB51 писал(а):Или работайте в рамках АРДУИНО IDE
Допустим этот код был написан в ArduinoIDE и потребовалось в прерывании и в основном коде работать с 2-ух или 4-ех байтной переменой. Чтобы это изменило? Не потребовалось получать атомарный доступ к переменной? Так что ArduinoIDE не защитит от такой ошибки.
Re: millis() Attiny13a
Добавлено: Чт дек 27, 2018 14:32:09
ARV
Мурик писал(а):и маловероятно что
то есть для 8-битной платформы вероятность применения и там и там 32-битной переменной нормальная, а для 32-битной платформы long long - невероятная?
в данной теме речь идет о attiny13, к чему вы сюда свою рекламу 32-битников суёте? забыли уже, что бывает с темами, где вопреки теме постится реклама других МК?
Re: millis() Attiny13a
Добавлено: Чт дек 27, 2018 14:32:43
postal2201
BOB51, здравствуйте.
Или работайте в рамках АРДУИНО IDE (MicroCore именно к этой разновидности делался),
или делайте уж проект как полагается - на соответствующей IDE и с "стандартным" компилятором.
А можно и комбинировать

Зачем ограничивать себя такими условностями. Я например для своего же удобства накидал сначала "говнокод" в Arduino IDE, погонял в виртуальном симе. Подправил, убрав костыли в виде digitalwrite и прочего. Все бы хорошо, можно так и оставить но мне нужна максимальная скорость, поэтому перенес под WinAvr.
Ничего сверх сложного для себя не увидел. Хотя я ни разу не программист. Радиолюбительство и отчасти программирование это просто мое хобби.
По поводу схемы, она конечно есть, но не заслуживает внимания, поскольку готовое устройство будет очень простое и узкоспециализированное.
Re: millis() Attiny13a
Добавлено: Чт дек 27, 2018 14:44:03
Мурик
ARV писал(а):то есть для 8-битной платформы вероятность применения и там и там 32-битной переменной нормальная, а для 32-битной платформы long long - невероятная?
Скажите, насколько часто вам приходилось использовать 64-ех битные переменные в МК используемые в прерывании и в основном коде? Если такое было, то из-за чего была такая необходимость?
ARV писал(а):к чему вы сюда свою рекламу 32-битников суёте?
Это не реклама, а реальность. 32-ух битные МК столько же как 8-ми битные и при этом намного лучше.
ARV писал(а):забыли уже, что бывает с темами, где вопреки теме постится реклама других МК?
Помню, приходит ARV и из-за него тему отправляют в МЯЯЯЯУ.
postal2201 писал(а):мне нужна максимальная скорость, поэтому перенес под WinAvr.
Тогда берите 32-ух битный МК. У него тактовая часта от 48 до 400 МГц в зависимости от модели. Сравнение скорости выполнения кода 8-ми и 32-ух битными МК. Посмотрите если хотите.
http://purebasic.mybb.ru/viewtopic.php?id=717
Re: millis() Attiny13a
Добавлено: Чт дек 27, 2018 14:49:58
postal2201
[uquote="Мурик",url="/forum/viewtopic.php?p=3536221#p3536221"]Тогда берите 32-ух битный МК. У него тактовая часта от 48 до 400 МГц в зависимости от модели. Сравнение скорости выполнения кода 8-ми и 32-ух битными МК. Посмотрите если хотите.
http://purebasic.mybb.ru/viewtopic.php?id=717[/uquote]
Зачем? Для управления 3 светодиодами и ногой внешней EEPROM? не жирно ли 32-ух битный МК?
Re: millis() Attiny13a
Добавлено: Чт дек 27, 2018 14:52:42
BOB51
postal2201
Разница весьма болезненно может сказаться.
У ардуино начальная конфигурация и необходимая инициализация программных и аппаратных модулей выполняется автоматически.
В "стандартных" компиляторах это задача программиста.
В случае с "непродуманной смесью" и симулятор от ошибок не избавит.
Просто "ВСЕМУ СВОЕ ВРЕМЯ"
Ну а "МАКСИМАЛЬНАЯ СКОРОСТЬ" - это УДЕЛ АССЕМБЛЕРА.
Мурик
Для простейшего "выключателя на два положения с памятью" мне и PIC12F508 ЖАЛКО будет,
не говоря уже об АРМе.

Re: millis() Attiny13a
Добавлено: Чт дек 27, 2018 14:53:19
ARV
Мурик писал(а):Помню, приходит ARV и из-за него тему отправляют в МЯЯЯЯУ
первая часть фразы - верно. вторая часть - ложь: не из-за ARV, а из-за того, кто влезает в тему, целиком посвященной одной архитектуре МК, с рекламой другой архитектуры, тем самым нарушая правила форума размещать сообщения по соответствующим темам.
Re: millis() Attiny13a
Добавлено: Чт дек 27, 2018 15:09:10
Мурик
postal2201 писал(а):Зачем? Для управления 3 светодиодами и ногой внешней EEPROM?
Тогда зачем нужна большая скорость работы?
postal2201 писал(а):не жирно ли 32-ух битный МК?
Когда МК стоит 0.5$, то есть около 30 рублей, не жирно.
ARV писал(а):вторая часть - ложь: не из-за ARV
Именно из-за ARV была отправлена в МЯЯЯЯУ тема "ARM или не ARM ", а она напрямую касалась 32-ух битных МК. Так что не ложь, а правда - из-за вас тему отправляют в МЯЯЯЯУ.

Re: millis() Attiny13a
Добавлено: Чт дек 27, 2018 15:18:55
ARV
Мурик писал(а):Так что не ложь, а правда - из-за вас тему отправляют в МЯЯЯЯУ
эта тема уйдет в МЯЯЯУ тоже по моей вине? так и будете передергивать и изворачиваться, или все-таки угомонитесь и оставите кесарю кесарево?
Re: millis() Attiny13a
Добавлено: Чт дек 27, 2018 15:20:25
postal2201
Тогда зачем нужна большая скорость работы?
МК будет установлен на сторонний девайс. При включении МК должен "быстро определиться" куда ему нужно подтянуть старший адрес EEPROM внешнего девайса, пока девайс не начал читать данные из EEPROM. Тем самым реализуется электронное переключение двух разных прошивок в одной EEPROM.
Re: millis() Attiny13a
Добавлено: Чт дек 27, 2018 15:24:43
BOB51
Такая задача только свиду проста...
Это не простой переключатель, а синхронизируемое устройство.
Помимо прочего должно быть связано с явно определяемым процессом в основном блоке (кудыть его впихеривать собираются).
Да и на "рассыпухе" также вполне решаемо.

Так что и схема и диаграммы с описанием работы (на уровне хотелок) ОБЯЗАТЕЛЬНЫ.
