Стало быть, необходимо инициализировать пин D28, а не D37.
Так это получается, что при написании программы необходимо ориентироваться не на пины камня, а на фактические пины платы, к которым подводятся пины камня..?
И как мне задействовать незадействованные в Ардуино пины камня, если я хочу их использовать..Те же тактирующие сигналы для Т1, Т3, Т4...
step962, подскажите, можно ли определить форму сигнала с помощью Ардуино..?
На рисунке приведена идеальная форма под №1, но могут быть и разные сигналы(№2 и №3)..
Период, скважность, смещение(один относительно другого) -- это все можно вычислить с помощью прерываний и таймеров..А вот что еще можно определить с помощью Ардуино и что для этого потребуется..?
Частота может быть до 33кГц, но я буду использовать шаговик и постараюсь максимально уменьшить частоту..И буду надеяться, что он будет вращаться с мин.постоянной скоростью..
Это вам в сторону АЦП смотреть надо. Для более-менее достоверного определения формы импульсов потребуется 5-10 преобразований на период. Учитывая скорострельность встроенных АЦП (максимум 80 kSPS на низком разрешении), вам едва ли удастся охватить 33 кГц. Стало быть, необходимо либо внешний АЦП использовать, либо аппетиты умерять (килогерц до 10-15)
В начале обработчика вы присваиваете переменной t1 значение регистра ICR4.
Далее (но во время одного и того же вызова обработчика) вы присваиваете одной из переменных t2/t3 результат выражения ICR4-t1. Но t1=ICR4, стало быть, переменным t2/t3 всегда присваивается 0.
Попробуйте просто:
t2 (t3)= t1;
Кроме того, в одной из ветвей (скажем, в момент прихода спада) следует сбрасывать TCNT4 в нуль.
Так мне переконфигурацию таймера на захват фронта(спада) нужно делать в основном цикле программы, а не в прерывании..?
Тогда обработчик будет выглядеть так
ISR (TIMER4_CAPT_vect) {
void_fron_1t();
void_spad();
void_front_2(); }
И затем после основного цикла описать циклы обработки прерываний
void_fron_1t()
void_spad();
void_front_2();
Правильно я понял..??
И еще..Можно ли использовать pulseIn() для этих же целей..Я вроде вписываюсь в 10ms, если поставлю частоту импульсов 50кГц(10 об/сек).. 1оборот=2500 Гц = 2500 импульсов.
Да нет - все это можно в ISR сделать. Просто дополнить одну петлю сбросом счетчика. Тогда у вас при очередных срабатываниях прерывания в счетчике TCNT4 (ну и в регистре ICR4) будет содержаться число тактов системного генератора (деленное на 64) с момента обнуления счетчика. То есть с последнего захваченного заднего фронта исследуемого сигнала. А таймер/счетчик4 будет считать не от нуля до переполнения, а от предыдущего заднего фронта до следующего заднего фронта (=спада).
PulseIn() в принципе можно использовать, например, для сравнения с результатами, выдаваемыми ISR-методом. Однако, это имеет смысл только при условии стабильного входного сигнала. Сигнал от пульта ДУ, например, таким способом весьма сложно сканировать.
Одним вызовом определяем длительность импульса, следующим вызовом определяем длительность паузы. Сумма этих длительностей дает период. Отношение периода к длительности импульса даст значение скважности.
Вот так Вы имели ввиду..?? Или эту строчку надо после следующей перенастройки вставить..??
Но при таком раскладе мне придется складывать время t3 и t2, что бы вычислить период, т.к. регистр таймера обнулиться и при поступлении события захвата t3 и t2 будет содержать значение от фронта до спада и наоборот..Ну а вычисление длительности так и останется t2=ICR4-t1..Или я уже окончательно запутался..:(
Я имел ввиду прежде всего то, что присвоение t1=ICR4; с последующим как-бы вычислением длительности t2=ICR4-t1; всегда будет давать в результате 0 по той причине, что t1 содержит значение из регистра ICR4, а стало быть t2=ICR4-t1; то же самое, что и t2=ICR4-ICR4;
Вот переделал обработчик прерывания, но не пойму, как вычислить период импульса
ISR (TIMER4_CAPT_vect) { // обработчик прерывания
if (TCCR4B==0x43 && TIFR4 &(1<<ICF4)){ // если по фронту и установлен флаг прерывания
t1=ICR4; // сохраняем значение
TCCR4B &=~((1<<CS42)|(1<<CS41)|(1<<CS40)); // останавливаем таймер
TIFR4 &= ~ (1<<ICF4); // сбрасываем флаг
TCCR4B=0x03;} // переключаем на спад с запуском таймера
if (TCCR4B==0x03 && TIFR4 &(1<<ICF4)){ // если стоит по спаду и установлен флаг прерывания
t2=ICR4-t1; // вычисляем длительность
TCCR4B &=~((1<<CS42)|(1<<CS41)|(1<<CS40)); // останавливаем таймер
TIFR4 &= ~ (1<<ICF4); // сбрасываем флаг
TCCR4B=0x43;} }
хотел настроить прерывание по таймеру Т2 через каждые 0.5 секунд, но так как в Normal режиме счетчик считает до FF вроде, это значит что он переполнится через 1,6E-5 секунд. вот прочитав даташит я попытался настроить режим СТС , т.е выставив число в OCR2A я хотел тем самым увеличить количество тактов))
а если 9 и 10 строку я запишу таким вот образом это на правильную работу счетчика не повлияет?
Это легко проверяется соответствующим экспериментом: выводите в COM-порт состояние регистра в битовом формате до изменения, выполняете преобразования, снова выводите состояние порта.
DimaP. пишет:
и еще вопрос в обработчике прерывания мы также будим находится 4мсек?
скорее уж 4 мксек, если не меньше.
В прерывании вы будете находиться ровно столько времени, сколько требуется на загрузку/выгрузку из стека служебной информации и на собственно исполнение определенных в теле обработчика кодов. А их там будет не более десятка ассемблерных инструкций. Стало быть, исполняться они будут меньше микросекунды.
Кстати, для еще большего ускорения можно изменить тип счетчика с int на byte - диапазон его счета позволяет сделать это.
PS: еще раз взглянул на тело: таки нет, скорее всего десятком инструкций вы не отделаетесь - функции digitalRead/digitalWrite слишком расточительны в этом плане. Итоговая длина кода может и к сотне операций подобраться:
void digitalWrite(uint8_t pin, uint8_t val)
{
uint8_t timer = digitalPinToTimer(pin);
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
volatile uint8_t *out;
if (port == NOT_A_PIN) return;
// If the pin that support PWM output, we need to turn it off
// before doing a digital write.
if (timer != NOT_ON_TIMER) turnOffPWM(timer);
out = portOutputRegister(port);
if (val == LOW) {
uint8_t oldSREG = SREG;
cli();
*out &= ~bit;
SREG = oldSREG;
} else {
uint8_t oldSREG = SREG;
cli();
*out |= bit;
SREG = oldSREG;
}
}
int digitalRead(uint8_t pin)
{
uint8_t timer = digitalPinToTimer(pin);
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
if (port == NOT_A_PIN) return LOW;
// If the pin that support PWM output, we need to turn it off
// before getting a digital reading.
if (timer != NOT_ON_TIMER) turnOffPWM(timer);
if (*portInputRegister(port) & bit) return HIGH;
return LOW;
}
Так шта-а-а... Хотите быстрого исполнения - переходите на прямую манипуляцию портами.
Впринципе быстрого исполнения не требуется обработчике прерывания я буду считывать значения с аналогового порта возводить в квадрат и суммировать, гланая задача это чтобы значения с аналогового порта я получал примерно 20мсек(1 полный период переменного тока) Вот теперь буду думать как находится в обработчике 20 мсек!
Сильно не пинайте за вопрос. Суть такова - взял код из первого поста
volatile unsigned int tcnt2;
volatile unsigned int flag;
void setup()
{
flag=true;
TIMSK2 &= ~(1<<TOIE2); //разрешения прерывания по переполнению таймера/счетчика Т2
TCCR2A &= ~((1<<WGM21) | (1<<WGM20));// Режим работы таймера/счетчика
TCCR2B &= ~(1<<WGM22);// Режим работы таймера/счетчика
ASSR &= ~(1<<AS2); //Выбор источника синхронизации таймера если AS2=0 от системного генератора
tcnt2 = 1; // 16000000/64/f=tcnt2
TIMSK2 |= (1<<TOIE2);//Разрешение прерывания по переполнению Т2.
}
void loop()
{
}
void MyInterupt()
{
if (flag) {
flag=false;
}
else{
flag=true;
}
//обработчик вашего прерывания
}
//****************обработчик прерывания********************
ISR(TIMER2_OVF_vect)
{
TCNT2 = tcnt2;
MyInterupt();
}
Все работает как надо. Почти как надо. Есть лишь два вопрос:
1. Где и как изменить частоту вызова прерывания? Мне надо сделать что бы вызывалось почаще, но вобще знать бы что и куда писать и в каких пределах
1.1 Как правильно изменять эту частоту "на лету" - т.е. в коде программы? Надо ли останавливать или перезапускать прерывание и т.д. или просто поменять параметр и всё?
2. Как запустить еще один аналогичный таймер, который будет работать независимо от первого - т.е. вызывать еще одно прерывание по таймеру?
3. Как остановить прерыване таймера, когда нам оно не надо?
Мне бы все эти ответы просто кусками кода, если кому не сложно! Плииииз!!!
Да я понимпю. Просто на данный момент еще с кучей информации разбираюсь
Я выше приводил код, который делает все, что мне надо. Все, чего я прошу - дописать в него три комментария вида:
- вот тут выбирается гомер прерывания - может быть от..и до
- вот тут выбирается время, через которое оно сработает - может быть от..и до
- вот тут (где вызывается обработчик прерыаания) надо поменять ххх что бы он вызывался на другое прерыапгия -ххх или yyy или zzz - в зависимости от того, какое прерывание указали в первом пункте.
Я буду очень признателен за Всего три комментария таких в коде, который я приводил выше
Пытаюсь разобраться с таймерами, и столкнулся с непонятной для меня информацией.
Цель: нужно вызывать функцию 1 раз в секунду (по сути это часы, только назначение другое). Решил все это делать на таймере. Залез в даташит: 0-й и 2-й таймеры 8-мибитные, значит отпадают, остается 1-й таймер. По настройке немного сложно, делаю в первый раз, но в принципе разобраться можно.
Вот примерно что я собираюсь делать, Так правильно? И нужно ли делать сброс таймера?:
TCCR1B |= (1<<WGM12);
TCCR1B |= (1<<CS12); // делитель 256
TIMSK |=(1<<OCIE1A); // прерывание по совпадению
OCR1AH = 0b11110100; // число для сравнения 62500
OCR1AL = 0b00100100;
....
ISR (TIMER1_COMPA_vect)
{
// какое-то действие
}
Потому как millis() будет выполнятся только тогда, когда ее решат проверить (а совпало или нет??) а мне при этом нужно еще другой, основной код программы выполнять. По этому вызов millis() может происходить не стабильно, с разбросом по сремени. В коде мне очень важно отмерять точно 1-3 часа (+- пару скунд).
В общем millis() не спасет. Либо RTC (что не вариант) либо таймер
Ноги заняты все до одной (точнее одна свободная "на всякий случай"), переменные и так память забили на 85%... подключать еще две библиотеки (SPI + RTC) + ее обработка.... флеш занята на 50%
К тому же устройство должно быть легко повторяемым, без всяких дополнительных моделей. RTC к тому же настроить заранее нужно, а это еще лишняя возня.... RTC вещь хорошая, но в данном случае она не будет выполнять своих функций, так как я даже не время измерять буду (дата -время) а промежуток времени. В общем применение RTC в данном конкретном случае не оправдано. Это все равно что системник использовать в качестве подставки под цветы...
Все почему, зачем, придирки какие-то... зря вы так... я ведь не школьник понимаю что такое "обучение". Я не прошу разжевать мне что и как по мелочам. Может как говорится "глаз замылился" и не вижу элементарного.
Спросил у вас у вас совета, как у знающих людей, а вы... просто промолчали бы да и все. раз уж не хотите помогать.
Да банально. Если у вас возможно прерывание к примеру раз в 1 миллисек. В обработчике прерывания надо провести инкремент 999 раз и ретурнутся , а на 1000 вызвать главный и нужный вам обработчик. Надеюсь пару байт в ОЗУ для счетчика прерывания у вас найдется.
Так какой вывод платы соответствует 37-му выводу камня (т.е. PL2)?
на 28 выводе Ардуино..
Стало быть, необходимо инициализировать пин D28, а не D37.
И к нему же подводить те импульсы, которые вы собираетесь считать.
Стало быть, необходимо инициализировать пин D28, а не D37.
Так это получается, что при написании программы необходимо ориентироваться не на пины камня, а на фактические пины платы, к которым подводятся пины камня..?
И как мне задействовать незадействованные в Ардуино пины камня, если я хочу их использовать..Те же тактирующие сигналы для Т1, Т3, Т4...
Если используются функции Arduino - то таки да.
Но всегда есть возможность писать напрямую.
Например, чтобы объявить какой-нибудь пин выходом (OUTPUT), необходимо в соответствующий бит соответствующего регистра DDRx загнать единичку.
В нашем случае (27 вывод камня или PL2, т.е. второй бит порта L) это:
DDRL |= (1<<2);
step962, подскажите, можно ли определить форму сигнала с помощью Ардуино..?
На рисунке приведена идеальная форма под №1, но могут быть и разные сигналы(№2 и №3)..
Период, скважность, смещение(один относительно другого) -- это все можно вычислить с помощью прерываний и таймеров..А вот что еще можно определить с помощью Ардуино и что для этого потребуется..?
Частота может быть до 33кГц, но я буду использовать шаговик и постараюсь максимально уменьшить частоту..И буду надеяться, что он будет вращаться с мин.постоянной скоростью..
Это вам в сторону АЦП смотреть надо. Для более-менее достоверного определения формы импульсов потребуется 5-10 преобразований на период. Учитывая скорострельность встроенных АЦП (максимум 80 kSPS на низком разрешении), вам едва ли удастся охватить 33 кГц. Стало быть, необходимо либо внешний АЦП использовать, либо аппетиты умерять (килогерц до 10-15)
step962, подскажите, правильны ли эти шаги программы для вычисления скважности и длительности импульсов..
1.Объявляем переменные для счета t1, t2, t3.
и скважности S
2.Setup
Настраиваем Т4 для захвата по фронту с предделителем 1:64 и обнуляем маску
TCCR4A=0x00;
TCCR4B=0x43;
TIMSK4=0x00;
Разрешаем глобальные прерывания и инициализируем вход захвата Т4
SREG=0x80;
pinMode(49,INPUT);
3.Цикл
Если поступило событие на вычисление(допустим нажата кнопка), то
разрешаем прерывание по захвату, установив бит
TIMSK4|=(1<<ICIE5);
4.Обработчик прерывания
ISR (TIMER4_CAPT_vect) {
t1=ICR4; сохраняем значение
если вкл. по фронту TCCR4B==0x43, то
переключаем на спад TCCR4B=0x03
сбрасываем флаг TIFR4 &= ~ (1<<ICF4)
сохраняем значение t2=ICR4-t1
иначе переключаем на фронт TCCR4B=0x03;
сбрасываем флаг TIFR4 &= ~ (1<<ICF4);
и высчитываем период t3=ICR4-t1
и скважность S=t3/t2.
4.Обработчик прерывания
ISR (TIMER4_CAPT_vect) {
t1=ICR4; сохраняем значение
если вкл. по фронту TCCR4B==0x43, то
переключаем на спад TCCR4B=0x03
сбрасываем флаг TIFR4 &= ~ (1<<ICF4)
сохраняем значение t2=ICR4-t1
иначе переключаем на фронт TCCR4B=0x03;
сбрасываем флаг TIFR4 &= ~ (1<<ICF4);
и высчитываем период t3=ICR4-t1
и скважность S=t3/t2.
В начале обработчика вы присваиваете переменной t1 значение регистра ICR4.
Далее (но во время одного и того же вызова обработчика) вы присваиваете одной из переменных t2/t3 результат выражения ICR4-t1. Но t1=ICR4, стало быть, переменным t2/t3 всегда присваивается 0.
Попробуйте просто:
t2 (t3)= t1;
Кроме того, в одной из ветвей (скажем, в момент прихода спада) следует сбрасывать TCNT4 в нуль.
Так мне переконфигурацию таймера на захват фронта(спада) нужно делать в основном цикле программы, а не в прерывании..?
Тогда обработчик будет выглядеть так
ISR (TIMER4_CAPT_vect) {
void_fron_1t();
void_spad();
void_front_2(); }
И затем после основного цикла описать циклы обработки прерываний
void_fron_1t()
void_spad();
void_front_2();
Правильно я понял..??
И еще..Можно ли использовать pulseIn() для этих же целей..Я вроде вписываюсь в 10ms, если поставлю частоту импульсов 50кГц(10 об/сек).. 1оборот=2500 Гц = 2500 импульсов.
Да нет - все это можно в ISR сделать. Просто дополнить одну петлю сбросом счетчика. Тогда у вас при очередных срабатываниях прерывания в счетчике TCNT4 (ну и в регистре ICR4) будет содержаться число тактов системного генератора (деленное на 64) с момента обнуления счетчика. То есть с последнего захваченного заднего фронта исследуемого сигнала. А таймер/счетчик4 будет считать не от нуля до переполнения, а от предыдущего заднего фронта до следующего заднего фронта (=спада).
PulseIn() в принципе можно использовать, например, для сравнения с результатами, выдаваемыми ISR-методом. Однако, это имеет смысл только при условии стабильного входного сигнала. Сигнал от пульта ДУ, например, таким способом весьма сложно сканировать.
Одним вызовом определяем длительность импульса, следующим вызовом определяем длительность паузы. Сумма этих длительностей дает период. Отношение периода к длительности импульса даст значение скважности.
4.Обработчик прерывания
ISR (TIMER4_CAPT_vect) {
t1=ICR4; сохраняем значение
если вкл. по фронту TCCR4B==0x43, то
сбрасываем TCNT4=0;
переключаем на спад TCCR4B=0x03
сбрасываем флаг TIFR4 &= ~ (1<<ICF4)
сохраняем значение t2=ICR4-t1
иначе переключаем на фронт TCCR4B=0x03;
сбрасываем флаг TIFR4 &= ~ (1<<ICF4);
и высчитываем период t3=ICR4-t1
и скважность S=t3/t2.
Вот так Вы имели ввиду..?? Или эту строчку надо после следующей перенастройки вставить..??
Но при таком раскладе мне придется складывать время t3 и t2, что бы вычислить период, т.к. регистр таймера обнулиться и при поступлении события захвата t3 и t2 будет содержать значение от фронта до спада и наоборот..Ну а вычисление длительности так и останется t2=ICR4-t1..Или я уже окончательно запутался..:(
Я имел ввиду прежде всего то, что присвоение t1=ICR4; с последующим как-бы вычислением длительности t2=ICR4-t1; всегда будет давать в результате 0 по той причине, что t1 содержит значение из регистра ICR4, а стало быть t2=ICR4-t1; то же самое, что и t2=ICR4-ICR4;
То есть нуль.
Вот переделал обработчик прерывания, но не пойму, как вычислить период импульса
Вот статейка, в которой как раз применяется обработчик прерывания CAPT. Пусть и не для четвертого таймера, но переделать на нужный вполне реально.
Вот статейка, в которой как раз применяется обработчик прерывания CAPT...
Не Ваша, случайно, статейка..??
Спасибо за ссылку..
Добрый день прошу помощи в найстройке таймера
Хотелось настроить таймер который вызывал бы прерывание каждые 0.5 секунды
Прочитал несколько постов думал все понял, начал проверять но ничегошеньки не работает
Дуина у вас какая?
И что это за строка
OCR2A = 15624;
? Контроллер у вас скольки разрядный? размер регистра какой? byteatmega 328.
прерывание по таймеру Т2, 8 разрядный счетчик
я руководствовался вот чем
хотел настроить прерывание по таймеру Т2 через каждые 0.5 секунд, но так как в Normal режиме счетчик считает до FF вроде, это значит что он переполнится через 1,6E-5 секунд. вот прочитав даташит я попытался настроить режим СТС , т.е выставив число в OCR2A я хотел тем самым увеличить количество тактов))
Добрый день прошу помощи в найстройке таймера
Хотелось настроить таймер который вызывал бы прерывание каждые 0.5 секунды
Прочитал несколько постов думал все понял, начал проверять но ничегошеньки не работает
Ну, коль скоро вы маскируете прерывание по совпадению таймера (канал A), то может быть и обработчик стоит другой попробовать:
... 8 разрядный счетчик
... счетчик считает до FF
11
OCR2A = 15624;
Ничего не замечаете?
Подытоживая сказанное мной и maxim'ом - вносим некоторые изменения в скетч:
спасибо, вроде чтото начал понимать!
а если 9 и 10 строку я запишу таким вот образом это на правильную работу счетчика не повлияет?
и еще вопрос в обработчике прерывания мы также будим находится 4мсек?
а если 9 и 10 строку я запишу таким вот образом это на правильную работу счетчика не повлияет?
Это легко проверяется соответствующим экспериментом: выводите в COM-порт состояние регистра в битовом формате до изменения, выполняете преобразования, снова выводите состояние порта.
и еще вопрос в обработчике прерывания мы также будим находится 4мсек?
скорее уж 4 мксек, если не меньше.
В прерывании вы будете находиться ровно столько времени, сколько требуется на загрузку/выгрузку из стека служебной информации и на собственно исполнение определенных в теле обработчика кодов. А их там будет не более десятка ассемблерных инструкций. Стало быть, исполняться они будут меньше микросекунды.
Кстати, для еще большего ускорения можно изменить тип счетчика с int на byte - диапазон его счета позволяет сделать это.
PS: еще раз взглянул на тело: таки нет, скорее всего десятком инструкций вы не отделаетесь - функции digitalRead/digitalWrite слишком расточительны в этом плане. Итоговая длина кода может и к сотне операций подобраться:
Так шта-а-а... Хотите быстрого исполнения - переходите на прямую манипуляцию портами.
Понятно полезная инфа!!!
Впринципе быстрого исполнения не требуется обработчике прерывания я буду считывать значения с аналогового порта возводить в квадрат и суммировать, гланая задача это чтобы значения с аналогового порта я получал примерно 20мсек(1 полный период переменного тока) Вот теперь буду думать как находится в обработчике 20 мсек!
Может присмотрется к 16 разрядному таймеру Т1 ?
Сильно не пинайте за вопрос. Суть такова - взял код из первого поста
Все работает как надо. Почти как надо. Есть лишь два вопрос:
1. Где и как изменить частоту вызова прерывания? Мне надо сделать что бы вызывалось почаще, но вобще знать бы что и куда писать и в каких пределах
1.1 Как правильно изменять эту частоту "на лету" - т.е. в коде программы? Надо ли останавливать или перезапускать прерывание и т.д. или просто поменять параметр и всё?
2. Как запустить еще один аналогичный таймер, который будет работать независимо от первого - т.е. вызывать еще одно прерывание по таймеру?
3. Как остановить прерыване таймера, когда нам оно не надо?
Мне бы все эти ответы просто кусками кода, если кому не сложно! Плииииз!!!
Ау, люди! Ну помогите же плииизз!!!
http://samou4ka.net/page/tajmer-schetchik-mikrokontrollerov-avr
Спасибо, но как то много информации, голова не переваривает пока что ((((
Изучайте и рано или поздно все встанет на свои места и все поймете.
Да я понимпю. Просто на данный момент еще с кучей информации разбираюсь
Я выше приводил код, который делает все, что мне надо. Все, чего я прошу - дописать в него три комментария вида:
- вот тут выбирается гомер прерывания - может быть от..и до
- вот тут выбирается время, через которое оно сработает - может быть от..и до
- вот тут (где вызывается обработчик прерыаания) надо поменять ххх что бы он вызывался на другое прерыапгия -ххх или yyy или zzz - в зависимости от того, какое прерывание указали в первом пункте.
Я буду очень признателен за Всего три комментария таких в коде, который я приводил выше
П.с. могу и финансово отбагодарить - просто реально нет времени разбираться
В общем поскольку никто толком не помог - вот решение нашел
https://github.com/carlosrafaelgn/ArduinoTimer/
библиотека на каждый таймер - всё понятно там в описании
Друзья, всем привет.
Пытаюсь разобраться с таймерами, и столкнулся с непонятной для меня информацией.
Цель: нужно вызывать функцию 1 раз в секунду (по сути это часы, только назначение другое). Решил все это делать на таймере. Залез в даташит: 0-й и 2-й таймеры 8-мибитные, значит отпадают, остается 1-й таймер. По настройке немного сложно, делаю в первый раз, но в принципе разобраться можно.
Вот примерно что я собираюсь делать, Так правильно? И нужно ли делать сброс таймера?:
А чем вам millis() не устраивает. Там может быть и интервал от 1 милисек до 48 день.
Потому как millis() будет выполнятся только тогда, когда ее решат проверить (а совпало или нет??) а мне при этом нужно еще другой, основной код программы выполнять. По этому вызов millis() может происходить не стабильно, с разбросом по сремени. В коде мне очень важно отмерять точно 1-3 часа (+- пару скунд).
В общем millis() не спасет. Либо RTC (что не вариант) либо таймер
Пробую но что-то ничего не получается. Код:
В общем millis() не спасет. Либо RTC (что не вариант) либо таймер
"Хуже дурака только дурак с инициативой".
Просто интересно, что не так с RTC? Путин запретил?
Просто интересно, что не так с RTC? Путин запретил?
Я запретил. мой раб Путин в Очакове американскую базу строит.
Пожалуйста, не надо рассуждать, на счет того "нужно - не нужно, что не так"... Незачем мне RTC.
Просто помогите понять почему у меня не запускается таймер. Где я допустил ошибку или может что-то не дописал. Просто направьте на путь.
Если Кла разрешит - укажу на твою ошибку... только в обмен на тайну запрета RTC! :)
в обмен на тайну запрета RTC! :)
delay(100);
в обмен на тайну запрета RTC! :)
delay(100);
Делай раз! Делай два! Делай три!... Делай девяносто девять! delay(100);
Ноги заняты все до одной (точнее одна свободная "на всякий случай"), переменные и так память забили на 85%... подключать еще две библиотеки (SPI + RTC) + ее обработка.... флеш занята на 50%
К тому же устройство должно быть легко повторяемым, без всяких дополнительных моделей. RTC к тому же настроить заранее нужно, а это еще лишняя возня.... RTC вещь хорошая, но в данном случае она не будет выполнять своих функций, так как я даже не время измерять буду (дата -время) а промежуток времени. В общем применение RTC в данном конкретном случае не оправдано. Это все равно что системник использовать в качестве подставки под цветы...
1.если программировать не членом, а руками, то есть без "делай раз...", то реально нужно юзать миллис, ее для этого и придумали.
2. ошибка твоя найдется читая даташит на стр. 184. Если не дойдет с этого намека, то ты безнадежен.
так, чего не так с миллис? - почему ега нельзя проверять в каждом лупе?
У меня Мега168, на странице 184 описание TWI интерфейса... TIMSK1 у меня описан на 117 странице.
Что именно я прогладел? Я, кстати, пробовал разные варианты, TIMSK1 |= 1<<OCIE1A | 1<<ICIE1; не дает никакого результата.
Все почему, зачем, придирки какие-то... зря вы так... я ведь не школьник понимаю что такое "обучение". Я не прошу разжевать мне что и как по мелочам. Может как говорится "глаз замылился" и не вижу элементарного.
Спросил у вас у вас совета, как у знающих людей, а вы... просто промолчали бы да и все. раз уж не хотите помогать.
япона мать!
1.Еще раз - в таймере нужно выставлять все биты, а не только те, которые нравятся.
2. Главное - для отсчета времени сделана миллис. Погляди свой wiring.c. И не строй из себя дурака. Ты вторую миллис пишешь, только хуже.
Функция миллис возвращает значение счетчика, как ты пытаешься i = i+1 написать.
Да банально. Если у вас возможно прерывание к примеру раз в 1 миллисек. В обработчике прерывания надо провести инкремент 999 раз и ретурнутся , а на 1000 вызвать главный и нужный вам обработчик. Надеюсь пару байт в ОЗУ для счетчика прерывания у вас найдется.
Не работает, уже проверял....