Внешнее преравание и запуск по нему таймера
- Войдите на сайт для отправки комментариев
Втр, 03/03/2015 - 14:52
проблемка выходит с таймером
#include <CyberLib.h> volatile boolean i = 0; void setup() { D3_In; D9_Out; attachInterrupt(1,impuls,FALLING); //прерывание по 3 пину } void loop() { if(i==1){StartTimer1(obrobotchik, 1000);i = 0;};} //запуск таймера о обнуление флага void obrobotchik() {D9_High;delay_ms(1);D9_Low;StopTimer1();} //после отсчета таймера void impuls() { i=1;} //установка флага
пробовал запускать таймер в interrup, но ничего не дает
желтый - вход D3, синий - выход D9
dmitriykisliy, а что вы хотели получить?
по описанию таймера понял, что по истечении времени (1000 мкс)
программа переходит к
т.е. после LOW на D2, на D9 возникнет HIGH через 1000 мкс, но или я туплю, или ATmega328 меня не понимает.
Голову ломаю 2 недели, delay не подходит, частота входа меняется (датчик Холла автомобиля) и void loop сбивается
Если есть варианты, подскажите)
dmitriykisliy, т.е. вам нужно, что б ежели кто-то дёрнет ногу порта d2 на ноль, то через 1мс поднять ногу d9, а ещё через 1мс её опустить, так?
да, верно.
кто-то - это датчик Холла трамблера авто, 1 мс - это пробная величина, далее она будет функцией оборотов мотора
http://arduino.ru/forum/programmirovanie/takhometr-0#comment-35202
http://arduino.ru/forum/programmirovanie/takhometr-0#comment-35142
подсчет внешних прерываний это не сложнл, а как по внешнему прерыванию запустить таймер и с выдержкой времени выполнить действие?
вы что делаете - электронный регулятор угла опережения зажигания от оборотов движка ?
верно, со своим алгоритмом работы, выложу когда заработает. сейчас езжу на ардуине, лучше, чем было на штатном трамблере, но угол опережения нестабилен (из за delaymicroseconds думаю)
http://arduino.ru/forum/proekty/fuoz-takhometr
реализация через счётчики МК и таблицу пересчёта - быстрее и точнее, чем производить матрассёты
верно, со своим алгоритмом работы, выложу когда заработает. сейчас езжу на ардуине, лучше, чем было на штатном трамблере, но угол опережения нестабилен (из за delaymicroseconds думаю)
алгоритм у всех ФУОЗов одинаков - разные только кривые зависимости "обороты-времяОпережения" :)
про счетчик МК можно поподробнее?
ATmega48PA/88PA/168PA/328P
14. 8-bit Timer/Counter0 with PWM
15. 16-bit Timer/Counter1 with PWM
16. Timer/Counter0 and Timer/Counter1 Prescalers
17. 8-bit Timer/Counter2 with PWM and Asynchronous Operation
это видел,
а как ПРАВИЛЬНО запустить таймер 1 после прерывания? в этом и есть проблема (рис 1 пост)
в Ассемблере я 0, с библиотекой проще, но не работает(
dmitriykisliy, тут не много тех, кто в ассемблере !=0 ;-) У меня был похожий шаблончик, подкорректировал под ваши данные. Вроде всё как надо, снял осциллограмку -одна клетка пол миллисекунды. Синий график -кнопка, подтянута к HIGH, при нажатии соответссно ноль. Жёлтый график -выход с D9 ардуины.
Управление сделал через ещё одно прерывание от таймера, иначе не знаю как.. Сам скетч:
RESPECT! спасибо, попробую на работе,
как я понял выдержки времени можно менять строкой 15 (это предделитель?), ну и строками 21 и 22. Верно?
dmitriykisliy, да в 15 строке задаёте период вызова прерывания (8000 попугаев = 1мс учитывая и прочие настройки таймера) но не более 65535, а в прерывании таймера делаете что нужно..
12 строка (вектор внешнего прерывания) значит, что если на d3 falling, то запускается таймер?
не совсем так - посмотрите все биты управляющих регистров одного счётчика
всяко нужно два счётчика - один постоянно измеряет t оборота коленвала, второй создаёт задержку искрообразования в зависимости от t оборота коленвала ( или из таблицы(быстрее и проще - но кривая зависимости ступенчатая) , или по формуле пересчёта(помедленне - но кривая зависимости непрерывная)
счётчик rpm -
1) прерывание по ризинг ( или фаллинг ) от сигнала с датчика Холла
2) обработчик прерывания - захват значения счётчика в глобальную волатильную переменную, обнуление счётчика
итого: система на каждом обороте КВ знает период или частоту, или rpm ( что по сути меры одного и того же )
......здесь рассчёт/формирование значения установки для второго счётчика, который формирует задержку искрообразования
счётчик задержки - ...........
примерно так...
машина времени ещё не создана, поэтому говорить об опережении зажигания на Х гр от ВМТ можно как о задержке на 360-Х гр от ВМТ ( или на 180-Х гр от НМТ ) , НО в следующем обороте КВ
счётчик задержки - ...........
....должен сформировать временные значения и сами фронты сигнала на коммутатор бабины
апгрейд системы будет заключаться в изменении таблицы соответствия "обороты-УОЗ" ( все зависимости в авто построены на этом ) , или изменением коэффициентов в формуле пересчёта "обороты-УОЗ"
построение системы хардварное или софтовое - вопрос философский и вкуса.... моя за хардвар - хватит и Attyni85 :)
если на d3 falling, то запускается таймер?
тут два варианта
1 - ст обнулён, счёт запрещён коэффициентом деления = 0 ( STOP ) , по прерыванию устанавливаем коэффициентом деления = 1, 64, ...... нужный
2 - по прерыванию обнуляем ст
......результат одинаков - запускается таймер на отсчёт чего-либо от момента начала прерывания
уважаемые dmitriykisliy и dimax, есть у вас время и желание вступить в симбиоз ?
....и создать адаптированную систему под вкус-цвет и потребности любого пользователя ?
кто-то логику, кто-то коды, кто-то свою машинку для испытаний :)
....моя корысть - модуль управления УОЗ старенького ( но очень распространённого ) дизелька :)
SU-27-16, увы, я в автомобильной тематике полный ноль. Да и с таймерами буквально две недели как начал разбираться :)
SU-27-16, увы, я в автомобильной тематике полный ноль. Да и с таймерами буквально две недели как начал разбираться :)
на то и симбиоз :)-
понял.... вы согласен ! :)
сорри, до нета только добрался
с расчетом прерываний проблем 0, на работе делали датчики тока и напряжения с цифровой опторазвязкой (преобразование ток-частота и напряжение-частота)
по поводу машины времени +1, это приближенный расчет, но факт то, что он лучше штатного трамблеровского с грузами и вакуумом, да и проблемы с запуском пропали...
по поводу функции или массива (таблицы) - по быстродействию, да и ступенчатости массив рулит (составлял на 100 элементов - 50 об/мин +на вакууме висит датчик холла (корректор))
скетч не опробовал, планирую на завтра
su-27-16 спс за рекомендации
в чем вопрос по дизельку? есть наработки
Ну заработало)
Готовый скетч
Строки 28 - 30 переделаю на многоискровой запуск
на холостых оборотах
чуть больше 3000 об/мин
частота около 5500 об/мин, уоз 36 градусов
очень хорошо, что заработало :)
критика
- неоптимальное использование коммутатора и "бабины", т.е. - лишний расход ЭлЭн....
накопление энергии в "бабине" - const по времени.... и не должно зависеть от оборотов движка.....
- процессы в лупе и прерываниях "относительно" синхронны
есть предложения - позже обосную
за дизелёк - спасибо, всё решено - тока код надо допилить без рассчётов в коде, только через таблицы ( желание заказчика :( )
по коду - волатильными переменные стоит ( нужно ) объявлять только те, которые изменяются в прерываниях - может кто поправит ?
т.е. - 01, 03, 04 - могут быть неволатильными
Чтобы не плодить новую ветку вопрос задам тут.
Меня интересует, что происходит при повторном запуске таймера 1 по команде TCCR1B=(1<<CS10)|(1<<WGM12) ? Один запуск делаю сначала в "void loop()", а повторный в int 0. Таймер считает количество тактов генератора в течении 1 секунды по внешнему прерыванию. Вроде по теории не должно быть разницы. Поскольку сбрасываю регистр таймера по прерыванию.
Если запускаю таймер только в "void loop()" - то количество тактов 16000000 +/- 3 такта
Если запускаю таймер в "void loop()" и затем по "int 0" - то количество тактов 16000000 +/- 1 такта
вот 1 вариант:
void loop()
{TCCR1B=(1<<CS10)|(1<<WGM12);} //Запускаем Таймер 1
ISR (INT0_vect)
{if (start_timer_1==1 && flag_LED==0){TCNT1=0;} }
вот 2 вариант:
void loop()
{TCCR1B=(1<<CS10)|(1<<WGM12);} //Запускаем Таймер 1
ISR (INT0_vect)
{if (start_timer_1==1 && flag_LED==0){TCNT1=0;TCCR1B=(1<<CS10)|(1<<WGM12);} }
интересно. кто вам сказал. что строчка
"запускает таймер" ?
Эта строчка у вас в loop(). если бы она действительно ЗАПУСКАЛА таймер - он бы у вас перестартовывался тысячи раз в секунду.
Эта строка ВСЕГО ЛИШЬ устанавливает значение регистра TCCR1B. А если регистр уже установлен - строка не меняет состояние таймера. Помещать ее в ЛУП или в обработчик - бессмысленно, ей место в setup()
Вот от таких Булдаковых и непонятно какие дети рождаются.(
Поместил эту строчку в setup все перестало работать. Работает только первый раз. А потом ничего не меняется. Код рабочий. У меня был только вопрос почему добавление строчки TCCR1B=(1<<CS10)|(1<<WGM12); в прерывание улучшает стабильность счета таймера?
специально нашел описание регистра TCCR1B. Если TCCR1B=0 - то таймер не считает. Если TCCR1B=(1<<CS10)|(1<<WGM12) - то таймер считает без деления частоты.
Было так:
дел
давайте код целиком, с описанием переменных
специально нашел описание регистра TCCR1B. Если TCCR1B=0 - то таймер не считает. Если TCCR1B=(1<<CS10)|(1<<WGM12) - то таймер считает без деления частоты.
и как из этого следует, что ваша строчка "запускает таймер"? Она запускает, только если до того TCCR1B=0. А если TCCR1B у вас уже настроен - последующее "добление" этой строкой в лупе НЕ МЕНЯЕТ НИЧЕГО.
А если TCCR1B у вас уже настроен - последующее "дробление" этой строкой в лупе НЕ МЕНЯЕТ НИЧЕГО.
Правильно. И я так думал. А оказывается - ошибался. Поэтому я и спросил почему такое может быть.
Скорее всего все упирается в длительность исполнения участков кода.