по "аварийной" ссылке оба браузера у меня (хром и лиса свежие) прекрасно ходят, может ваш браузер устаревший - жаба скрипты так могут действовать. А мэйком можно и Си++ и ардуино: Создал я ардуиновский проектик (main.cpp и Makefile) подключил "Arduino.h" как в скетчах делают. Cкопипастил себе в проект ядро MiniCore (mega8 там есть). Поблинкал стандартным набортным светодиодом с помощью тупой задержки. Скопипастил себе библиотеку MsTimer2. Поблинкал с помощью асинхронного таймера2: И понял в ардуино вся сила в либах, брат, а собирать ардуиновский проект где неважно - в иде или мэйкфайлом...
Ессно под ХР х32 будут "устаревшими" - надо сие учитывать и проверять перед выкладкой ссылок. УВЫ... Не от нашего желания такие "мелки пакости" зависят...
ВОТЬ... Посему главный упор делаем на САМОСТОЯТЕЛЬНОЕ написание библиотек - это и универсальнее и понятнее (для себя) и заметно проще, чем разбираться в "чужих" библиотеках.
А в данном случае не просто "поблинкать", а создать собственную библиотечку для 4-х позиционного дисплея со 4-мя кнопами надо - это примерно половина простейшего проекта по смыслу.
как его проверять, если у меня сейчас Debian на ПК, есть вообще в виртуалке виндовс7, но ей отрублен интернет именно чтоб не нахваталась вирусни. Хорошо - да для часов ардуиновских нужен индикатор. Интересно, а есть ли ардуиновские либы для семисегментных индикаторов? Есть... тамже на аварийном сайте этот ответ нашел. У нас в каждом ларьке есть в продаже семисегментные светодиодные индикаторы для ардуино с двумя 74HC595 в виде готовой платы - дешевле намного чем самому паять. Скачал либу для такого индикатора, скопипастил к себе в проект, там и пример есть - проверил работает: Асинхронный таймер мигает светодиодом - время идет, индикатор выводит циферки, никто из разных либ никому не мешает - это уже почти готовые часы. Уйду в ардуинщики - всяких либ хоть завались . оный скетч (модное слово): Спойлер
int main() { pinMode(ledPin, OUTPUT); MsTimer2::set(500, flash); // 500ms period MsTimer2::start(); setup(); sei();
for (;;) { disp.send(LED_0F[0], 0b0001); //send digital "0" to 1st indicator _delay_ms(2000); disp.send(LED_0F[3], 0b0110); //send digital "3" to 2nd and 3rd indicator _delay_ms(2000); disp.send(LED_0F[10], 0b1111); //send simbol "A" to all indicators _delay_ms(2000);
for (int i = 0; i <= 99; i++) { disp.digit2(i, 0b0001, 50); //send counter 0-99 with delay 50 cicles int 1st and 2nd view ports }
for (int i = 0; i <= 99; i++) { disp.digit2(i, 0b0100, 50); //send counter 0-99 with delay 50 cicles int 3st and 4rd view ports }
for (int i = 0; i <= 100; i++) { disp.digit4showZero(i, 50); //send counter 0-100 with delay 50 cicles with zero }
for (int i = 0; i <= 9999; i++) { disp.digit4(i, 50); //send counter 0-9999 with delay 50 cicles and hide zero } } return 0; }
з.ы. проверил тревожный сайт онлайн антивирусами, в том числе DrWeb - все в порядке
Последний раз редактировалось oleg110592 Ср окт 21, 2020 10:56:38, всего редактировалось 1 раз.
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
С "добавками" индикаторов хош удавись... И программы там заметно проще выполняются. Да и семисегментники - также не в диковинку. Драйверки к ним можно вполне и самому написать, без влезания в "чужие библиотеки" - то уже кому как удобнее (порой вычитка библиотеки занимает больше времени, чем создание своей). Разве что когда уже никак не обойтись простыми средствами - OneWire, Adafruit_NeoPixel да эзернетовские... Там лучше таки библиотеки применить на начальном этапе.
Только вот именно без дополнительных мелкосхем надо прокрутить... Т.е. динамическая индикация с совмещенной кноподавой в автономно вертящемся режиме. В принципе под ассемблером - не проблема (вероятно и под "чистым Си также). А вот такой же по функционалу для адуринки с ее базовыми "бабочками"(меги8,186,328Р в DIP28 корпусировке) да используя только референс... Уж слишком "раздуться" может... Что и несколько напрягает...
Пока надо из имеющегося набора тест-макет соорудить... Для теста придется нанку стару использовать - а у меня там разводка макетки ... "весьма неудачная" - делалась давно и без учета возможных особенностей, что позже проявились. А переделывать все ВЛОМ...
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Только вот именно без дополнительных мелкосхем надо прокрутить...
имхо надо ближе к народу/китайпрому быть - ардуине-ардуиново, пошел и купил задешево. Но и без доп. микросхем ардуинщики все давно разжевали: https://www.circuitbasics.com/arduino-7 ... -tutorial/ (сайт проверен онлайн) несложно Эта простая программа выведет на дисплей число «4,999»:
А пчему нет аргумента resistorsOnCommons!) Зачастую ТАКИЕ дурные эти библиотеки (не конкретно эта). Давеча писал человеку для модуля на hc595. Ужас! Пришлось самому накидать.)
Скажем так "не все так гладко" - при тесте под нанкой наскочил на весьма странный эфект... И неприятный... У меня выходы сегментных ключей были выставлены рядком на D19-18-17-16-15-14-12-11... ДЫК... Попытка заменить программу после модификации - последующая загрузка СКОТча привела к ... отказу IDE - ошибки прошивки... Как будто выход из строя или ПК или адуриньи... В принципе и то и другое оказалось исправным, но нервов покушало. Отделался перепрошивкой бутлоадера из-под siProg (моей готовки) и автономной аврдудешелл. Ибо средствами IDE восстановить режим перепрошивки невозможно... Данный "ступор" продолжал повторяться до тех пор, пока не перебросил лапки с D12-D11 на D10-D9... Независимо от типа бутлоадера... После переброски сигнала на другие лапки "как пошептало" (опять же на двух разных нанках)... Однако ISP при работе бутлоадера вроде не должен быть задействован... или как-то повлиять "внешними цепями"...
.... по схеме сегментные выводы подключены к ULN2803... Проверялись две платки - поведение абсолютно одинаковое. На больше порыться пока нету настроения, как и полную схему того "странного теста" окончательно вычертить. Смотрим наброски общая схема (набор блоков без межсоединений)
Единственный плюс (помимо "заметки карандашом") - заменил бутлоадер на оптибутовский - его или в соответствующих папках найти можно или сама IDE прошивает в режиме "загрузка через программатор" (у мня в качестве оного нанка с прошивкой ардуино ISP).
Теперь можно и с кнопами да всякоэфектами демоиндикации поморочиться - интересно насколько чувствительны будут...
Не факт, что все окончательно прояснено - вполне реально какой глюк и в прожке - надо таки некоторое время на выяснение... Как одно из предположений - довольно высокочастотный сигнал tone() на D13 каким-то образом блокирует возможность работы бутлоадера после 5-6 минут работы макета. Отключение схемы на пару минут возсстанавливает работу загрузчика. Бум дальше "непутевы заметки" по ходу пыток делать...
ИТОГОВЫЙ АНАЛИЗ ("...утро вечера мудренее...") Сбой загрузки из IDE через штатный бутлоадер 1. не зависит от комбинации и назначения активных выводов платки ардуино-нано; 2. не зависит от типа бутлоадера; 3. проявляется случайным образом; 4. в зависимости от "стечения обстоятельств" может иметь место как полное самовосстановление после отключения питания от платки, так и необходимость полной перезагрузки бутлоадера через ISP программатор. 5. наблюдается некоторая зависимость частоты и тяжести последствий отказов в зависимости от частоты на выходе, используемом функцией tone(). При этом сама программа функционирует абсолютно нормально. Сбой происходит только при попытке перезагрузки средствами штатного бутлоадера. Как предположение - сбой вызывает случайное наложение с одной стороны "каскадируемого прерывания" - частично функционала tone(), частично прерывания на INT0 и его обработчика при одновременном запуске на исполнение встроенного бутлоадера. Причем то "стечение обстоятельств" возникает в разные моменты времени с точки активации бутлоадера - от того и последствия разные - от "самовосстановления" до необходимости полной перезаливки бутлоадера МК. Далее аналитика только для спецов. Оставлю себе лишь "замечание о возможном глюке и методах его(глюка) устранения".
и временно - окончательный (до проработки кноп) текст прожки в "более простонародном доступе"
Спойлер
Код:
/* * * шаблон-заготовка обработчика клавиатуры-дисплея * базовая модель МК - atmega8 * автономно-независимое исполнение по прерыванию * обмен с основной программой через буфер предподготовки данных и * буфер содержимого байта кода клавиатуры * данные в буфере предподготовки представлены * уже в виде сегментного кода * флаги - * наличие данных в буфере содержимого байта кода клавиатуры * в текущем скан-цикле * и * запрос обновления данных из буфера предподготовки в * буфер видеопамяти * */ //***************************************************************** // Секция include: здесь подключается заголовочный файл к модулю //***************************************************************** //#include "leds4.h" // заголовочный *.h файл текущего проекта // // содержимое leds4.h на этапе тестирования на симуляторе // // знакогенератор
#define s_A 0 // значение номера сегмента A #define s_B 1 // значение номера сегмента B #define s_C 2 // значение номера сегмента C #define s_D 3 // значение номера сегмента D #define s_E 4 // значение номера сегмента E #define s_F 5 // значение номера сегмента F #define s_G 6 // значение номера сегмента G #define s_H 7 // значение номера сегмента H
// определение линий интерфейса // линии интерфейса связи для программного I2C обмена
// активный уровень для сегментных ключей = 1 // режим работы OUTPUT // состояние по сбросу = все Z // состояние при инициализации = все OUTPUT = 1
#define segline_a 11 // управление сегментным ключом A на D12 #define segline_b 12 // управление сегментным ключом B на D13 #define segline_c 14 // управление сегментным ключом C на D14 #define segline_d 15 // управление сегментным ключом D на D15 #define segline_e 16 // управление сегментным ключом E на D16 #define segline_f 17 // управление сегментным ключом F на D17 #define segline_g 18 // управление сегментным ключом G на D18 #define segline_h 19 // управление сегментным ключом H на D19
// активный уровень для анодных ключей = 0 // режим работы OUTPUT // состояние по сбросу = все с внешней подтяжкой к 1 // состояние при инициализации = все OUTPUT = 1
#define sa_line0 3 // управление анодным ключом 0 на D11 #define sa_line1 6 // управление анодным ключом 1 на D10 #define sa_line2 5 // управление анодным ключом 2 на D9 #define sa_line3 4 // управление анодным ключом 3 на D8
// линия контроля ЛВК (линия возврата клавиатуры) // режим работы INPUT с внешней подтяжкой к 1 // активный уровень = 0
#define lvk_line 8 // линия контроля ЛВК на D7
// линия выходного тактового сигнала // для тактирования Контроллера Клавиатуры Дисплея
#define sdr_clco 13 // источник тактового сигнала ККД на D4 // линия входного тактового сигнала // для тактирования Контроллера Клавиатуры Дисплея
#define kkd_freq 30000 //260 // константа генератора регенерации ККД #define llq 10 // константа малого цикла (10тиков/переполнение) #define hlq 10 //26 // константа большого цикла (26циклов/переполнение)
#define nump 4 // константа для счетчика позиций (0-3)
#define mask_sa0 B00000001 // маска линии sa_line0 #define mask_sa1 B00000010 // маска линии sa_line1 #define mask_sa2 B00000100 // маска линии sa_line2 #define mask_sa3 B00001000 // маска линии sa_line3
// переменные ККД
volatile byte cntk=0; // счетчик позиций(кадров) дисплея в строке развертки volatile byte cntl=0; // счетчик малого цикла интервала текущего кадра volatile byte cnth=0; // счетчик большого цикла интервала текущего кадра
volatile byte lvk_mask=0; // буфер текущей маски ЛВК volatile byte lvk_data=0; // буфер данных ЛВК за текущий цикл развертки volatile byte lvk_dold=0; // буфер данных ЛВК за предшествующий цикл развертки volatile byte qf_sn_press=0; // флаг наличия нажатия в текущем цикле volatile byte qf_sn_stabl=0; // флаг наличия подтвержденных данных в lvk_dold volatile byte qf_refram=0; // флаг запроса перезаписи информации из // pp_ram в v_ram byte v_ram[4]={fnt_0,fnt_1,fnt_2,fnt_3}; // массив видеопамяти текущего отображения byte pp_ram[4]={fnt_4,fnt_5,fnt_6,fnt_7}; // массив буфера предподготовки данных
// Секция прототипов функций
void sdr_prog(); // основной обработчик регенерации ККД
//************************************************** // Секция создания экземпляров классов // задаем соответствие физических линий интерфейса // и передаваемых параметров // закрытым переменным членам класса //***************************************************
//анодные ключи, уровень digitalWrite(sa_line0,LOW); digitalWrite(sa_line1,LOW); digitalWrite(sa_line2,LOW); digitalWrite(sa_line3,LOW); //анодные ключи, режим pinMode(sa_line0,INPUT); pinMode(sa_line1,INPUT); pinMode(sa_line2,INPUT); pinMode(sa_line3,INPUT);
//линия контроля ЛВК digitalWrite(lvk_line,HIGH); //линия контроля ЛВК, режим pinMode(lvk_line,INPUT);
// линия выходного тактового сигнала // для тактирования Контроллера Клавиатуры Дисплея, уровень digitalWrite(sdr_clco,HIGH); // линия выходного тактового сигнала // для тактирования Контроллера Клавиатуры Дисплея, режим pinMode(sdr_clco,OUTPUT);
// линия входного тактового сигнала // для тактирования Контроллера Клавиатуры Дисплея, уровень digitalWrite(sdr_clci,HIGH); // линия входного тактового сигнала // для тактирования Контроллера Клавиатуры Дисплея, режим digitalWrite(sdr_clci,INPUT);
//*************************************************** // Секция основной программы (в обычном Си = main) //***************************************************
void loop() { // put your main code here, to run repeatedly:
}
//----------
//*************************************************** // ПОДВАЛ С ФУНКЦЯМИ //***************************************************
//----------**********************---------- // прерывание по INT0 - обработчик ККД
void sdr_prog() { if(cntl==0) { switch (cnth) { case 0: //do something when var equals 0 // гашение по анодам // пауза задержки отключения силовых ключей pinMode(sa_line0,INPUT); pinMode(sa_line1,INPUT); pinMode(sa_line2,INPUT); pinMode(sa_line3,INPUT); break; case 1: //do something when var equals 1 // загрузка текущего содержимого сегментного кода в порт вывода // согласно содержимого ячейки массива v_ram, на которую указывает // текущее значение cntk digitalWrite(segline_a,bitRead(v_ram[cntk], 0)); digitalWrite(segline_b,bitRead(v_ram[cntk], 1)); digitalWrite(segline_c,bitRead(v_ram[cntk], 2)); digitalWrite(segline_d,bitRead(v_ram[cntk], 3)); digitalWrite(segline_e,bitRead(v_ram[cntk], 4)); digitalWrite(segline_f,bitRead(v_ram[cntk], 5)); digitalWrite(segline_g,bitRead(v_ram[cntk], 6)); digitalWrite(segline_h,bitRead(v_ram[cntk], 7)); // внутренний switch (cntk) для включения соответствующего анода // и заполнения буфера маски для текущей кнопки lvk_mask switch (cntk) { case 0: //do something when var equals 0 pinMode(sa_line0,OUTPUT); lvk_mask=mask_sa0; break; case 1: //do something when var equals 1 pinMode(sa_line1,OUTPUT); lvk_mask=mask_sa1; break; case 2: //do something when var equals 2 pinMode(sa_line2,OUTPUT); lvk_mask=mask_sa2; break; case 3: //do something when var equals 3 pinMode(sa_line3,OUTPUT); lvk_mask=mask_sa3; break; default: // if nothing else matches, do the default // default is optional break; } break;
//----------
case (hlq-1): //9 //25 //do something when var equals 25 cntk++; // счетчик позиций +1
// все дальнейшее проводится только в последнем кадре строки if (cntk==nump) { cntk=0;
// анализ флага qf_refram и перезапись данных // из pp_ram в v_ram со сбросом qf_refram=0 if (qf_refram) { for (byte cnt=0; cnt<=3; cnt++) { v_ram[cnt]=pp_ram[cnt]; } qf_refram=0; }
// проверка флага наличия нажатия в строке qf_sn_press if (qf_sn_press) { if (lvk_dold==lvk_data) { qf_sn_stabl=1; // при совпадении установить // флаг наличия подтвержденных данных } else { lvk_dold=lvk_data; // при несовпадении заместить // содержимое в lvk_dold qf_sn_stabl=0; // и сбросить флаг // наличия подтвержденных данных } // сброс флага qf_sn_press, обнуление lvk_data и выход из проверки qf_sn_press=0; lvk_data=0; } // если НЕТ (qf_sn_press=0) тогда // qf_sn_press=0; lvk_data=0; по умолчанию (таковы при входе) else { if (lvk_dold==lvk_data) { qf_sn_stabl=0; // сбросить флаг наличия подтвержденных данных } else { lvk_dold=lvk_data; // антидребезг статуса "все кнопки отпущены" } } } break;
default: // if nothing else matches, do the default // default is optional // все остальные значения используются для опроса ЛВК if (!digitalRead(lvk_line)) { lvk_data = lvk_data | lvk_mask; qf_sn_press = 1; } break; } } cntl++; if (cntl == llq) //10 { cntl=0; cnth++; if (cnth == hlq) //10 //26 { cnth=0; } } }
//----------
//---------- файла/end of file---------------------
Надо будет его как-то "окультурить" в библиотечку...
В СКОТче-тесте при кратковременном нажатии - в крайней правой позиции высвечивается комбинация нажатых кноп (от 1 до F) оставшееся сдвигается влево. При длительном удержании идет непрерывный сдвиг влево номера кода комбинации. Но то уже тестовый фрагмет, а не базовый обработчик контроллера совмещенного дисплея-клавиатуры. Его можно завернуть как угодно.
На том мой интерес и завершился - ибо в теме-источнике вопрос сам-собой решился, а мне продолжать уже и не интересно - базовый результат получен. Отзыв кнопок вполне приятный (ежли контактная группа нормальная). Обработчик подразумевает поля сменных указателей на функцию...
Однако... вытянуть все в отдельный файл мозгов явно не хватает... Собственно из-за использования функций от референса как части инициализации развертки, основанной на генераторе частоты и обработчике прерывания.
Движок основан на приеме, вычитанном в одной из книж, автор которой (согласно текста в книже) сам позаимствовал его где-то тут: robotosha.ru Суть в использовании прерывания по совпадению у Т0. Однако... такой прием возможен только для МК, имеющих OCR0A - платок с МК вида мега328, мега168... Для мега8 это НЕПРИМЕНИМО. И все же... прием сам по себе весьма интересен - вроде ни на какие функции референса не влияет...
Качество отображения и реакция на нажатие кноп соответствует предыдущему варианту, но чуток поменьше и внешней перемычки не требуется.
Возможно таки его удастся и в вариант библиотечки выдернуть... Позже поглядямс...
Это уже из "дополнительных библиотек" (MsTimer2). В рамки "абсолютного референса" не входит. А мне интерес на минимуме соорудить, с тем, что ВСЕГДА под когти попадает.
такая "инициализацмя" не ардуиновый путь - проще сразу на чистом Си писать. з.ы. мега8 можно таймер0 использовать для индикации и пр. прерывание по переполнению, записывая в регистр счетчика таймера нужное значение там же в прерывании
В принципе использование незадействованных в референсе ресурсов вполне оправдано - как вариант для определенных платформ. Ибо вставка метода класса в функцию прерывания гораздо муторнее... Бибилиотека MsTimer2 делает его (Т2) непригодным для "стандартного" использования в функционале референса, а вот тот вариант, что я выше выложил вроде ни на что (со слов автора книжи) влиять не может - в том и "изюминка". Хотя тоже... я ж в "потроха" IDE настолько глубоко не лазил - верим автору книжи и его ссылкам... В принципе на меге8 (а это NG or older) регистров сравнения у Т0 не имелось - можно предположить, что посему они так и остались неиспользуемыми в "старших" моделях на 168й-328й мегах...
А в остальном - еще одно подтверждение принципа подхода к ардуиноподобным - для прикладной конкретики удобнее таки использовать внешнюю "периферию с мозгами", имеющую более/менее "стандартные" протоколы последовательного обмена.
Касательно отдельного счетчика, основанного на "системной сетке частот" ( millis() и micros() ) - удобно конечно, но там еще переполнение счетчика системных тиков отслеживать надо... а энто... ЛЕЕНЬ.... ибо "стандартное решение" и не во всех случаях оптимально...
Настраивая прерывания на Timer 0 вы теряете: перестают работать функции времени (delay(), millis()…), не работает генерация ШИМ на пинах D5 и D6, перестают работать все библиотеки, так или иначе завязанные на системном времени
Вот как раз в данном случае - ничего не теряется. Если оставить предположение, что ШИМ от Т0 делается программно (на меге 8 иначе не сделать), то использование режима "прерывание по совпадению" посредством OCR0A даст так сказать "параллельный процесс" формирования той же самой 1 миллисекундной последовательности. Но... обрабатываемой на другом векторе прерывания. Я ж сказал - "взял на веру" написанное в книже. Да и макет подтверждает правильность работы. Правда без ШИМ на D5 и D6... Проверить предположение о влиянии на ШИМ на D5 и D6 можно или перекопав начинку IDE(не моё) или задав тест на макете... МНДЯ...
использование режима "прерывание по совпадению" посредством OCR0A даст так сказать "параллельный процесс" формирования той же самой 1 миллисекундной последовательности.
все эти milis и 1 милисекунда летят в далекую даль, пока мы находимся в прерывании по совпадению (приоритетных прерываний же нет). Это прерывание будет исполнятся долгонько, судя по многократным digitalWrite и pinMode - в это время милисы это же ясно - тормозят да еще и в прерывании delayMicroseconds(5);
Как это "приоритетных прерываний нет"??? Собственно приоритет определяется положением адреса вектора в таблице векторов. Другое дело, что нет разрешения вложенных прерываний. Однако... за одну миллисекунду при 16 мегагерцах успеет выполнится как минимум 16000 команд, а прерывание по совпадению примерно в половине интервала. Т.е. между обработчиками допустимый интервал примерно в 4 тысячи команд. По сему, чтоб произошла накладка обработчиков и "снесло" сетку частот от Т0 надо уж очень постараться. Да и прерывания по переполнению и по совпадению (на одном и том же таймере) ЧЕТКО СЛЕДУЮТ ДРУГ ЗА ДРУГОМ. У меня и посложнее использование цифровых компараторов было (еще и с регулируемым периодом) - все устойчиво работает. Далее - участок инициализации это совершенно независимый от всяких прерываний фрагмент. Собственно по прерыванию отрабатывает только SIGNAL(TIMER0_COMPA_vect) А там чего-то длиннее чем на 2000 команд вряд-ли накопается при всем желании даже при помощи компилятора Си. При том, что основной таймер НЕ ОСТАНАВЛИВАЕТСЯ, а продолжает далее преспокойненько тикать и отработает свою миллисекунду по переполнению.
delayMicroseconds(5); - НЕ ИСПОЛЬЗУЕТ ТАЙМЕРЫ и прерывания - может применяться внутри прерываний.
заходим в прерывание по совпадению 1. допустим находимся там 5 мкс 2. через 1 мкс срабатывает прерывание по переполнению 3. но мы будем находится в прерывании по совпадению еще 4 мкс 4. выходим из прерывания по совпадению 5. попадаем в прерывание по переполнению 1мс+4мкс != 1мс или я AVR уже подзабыл з.ы. один digitalWrite() 5.47 microseconds. http://codius.ru/articles/%D0%A2%D1%8E% ... 1%82%D1%8B
СТОП!!! У нас же ОДИН ЕДИНЫЙ СЧЕТНЫЙ РЕГИСТР. Т.е. и совпадение и переполнение на его тиках основано. Если переполнение =226, а совпадение допустим на половине этого интервала =150, то уж никак прерывания друг на дружку не наскочат. Тут главное, чтоб длина обработчика была хотя бы не более половины интервала между прерываниями - где-то четверть миллисекунды. Ну и можно туда-сюда точку прерывания по совпадению подвигать в разумных пределах (нельзя сдвигать ближе, чем интервал исполнения обработчика предыдущего прерывания). Другое дело, когда таймеры РАЗНЫЕ - там все что угодно будет, вплоть до "пришли одновременно" и ждут окончания текущего прерывания. А вот когда оно завершится и одна команда после будет выполнена начнется соревнование - "а кому тапки"? Вот тут ранг размещения вектора (приоритет) и скажет своё МЯВ...
// the prescaler is set so that timer0 ticks every 64 clock cycles, and the // the overflow handler is called every 256 ticks. #define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256))
1) 8 МГц это 125нс умножаем на 64 = 8мкс 2) от 150 до 255 это 105 тиков 3) 8 * 105 = 840 мкс - главное не находится в прерывании по совпадению дольше. 10 digitalWrite() на 8МГц испортят картину. я б в прерывании по совпадению один одинешенек флаг бы выставил (индикация в теле), и вообще зачем на этом несчастном таймере два прерывания организовывать, согласно "референсу" одного хватает для индикации и пр. Еще и милисы прерывания вырубают, жуть
Код:
unsigned long millis() { unsigned long m; uint8_t oldSREG = SREG;
// disable interrupts while we read timer0_millis or we might get an // inconsistent value (e.g. in the middle of a write to timer0_millis) cli(); m = timer0_millis; SREG = oldSREG;
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 34
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения