Страница 3 из 4
Добавлено: 26 ноя 2010, 12:37
koolhatcker
delay_us(13);
Если в этот момент больше ничего делать не нужно(МК только генерит прямоугольник и больше ничем не занимается), то похоже на правду.
И ещё...
Почему TCNT0+=0x06; а не TCNT0=0x06;?
Ведь нужно загрузить в таймер новое значение, а не увеличивать имеющееся на 6.
P.S. Для флага не обязательно занимать 16 бит.
Сделайте его хотя бы Unsigned Char, если с битовым массивом возиться не хотите.
Добавлено: 26 ноя 2010, 12:52
xumuk
koolhatcker, я думал TCNT0 неприрвыно инкрементируется, даже во время обработки прерывания
А если я присвою 6, то выходит сбросится все что он
насчитал к моменту присвоения?
О, а как работать с битовым массивом? Мне для флага одного бита хватит
Добавлено: 26 ноя 2010, 13:00
Germie
xumuk писал(а):Код: Выделить всё
int light = 0;
interrupt [TIM0_OVF] void timer0_ovf_isr(void){
if(light==1){
PORTB.3=1;
delay_us(13);
PORTB.3=0;
}
TCNT0+=0x06;
}
Похоже на правду?
(light это флаг, установкой которого я включаю или выключаю генерацию импульсов. Хотел сделать его булевым, но компилятор ругется
, пришлось инт делать)
Полностью согласен с
koolhatcker.
1 Надо присвоить TCNT0 новое значение, а не прибавлять к нему 6.
2 Крайне нежелательно использовать в прерываниях какие-либо временные задержки, если МК еще чем-либо в это время должен заниматься. Я так понимаю, 13 мкс - это длительность импульса при частоте 38 кГц и скважности 2? В этом случае лучше увеличить частоту таймера в два раза. И при каждом входе в прерывание менять состояние выхода на противоположное. А если генерация последовательности не нужна, просто запрещать прерывание по таймеру или обнулять его предделитель.
xumuk писал(а):я думал TCNT0 неприрвыно инкрементируется, даже во время обработки прерывания
А если я присвою 6, то выходит сбросится все что он
насчитал к моменту присвоения?
Все верно, непрерывно инкрементируется. Поэтому нужно менять его содержимое сразу при входе в прерывание и, еще раз, не использовать в прерывании никаких временных задержек. Но, даже в этом случае, порядка четырех тактов при входе в прерывание будут потеряны и частота не будет точно соответствовать установленной. Если точность частоты генерации важна, можно воспользоваться 16-тиразрядным таймером и увеличить значение предделителя.
Удачи
.
Добавлено: 26 ноя 2010, 14:49
xumuk
Понял, спасибо, переделаю
Вот только непонятен один момент
порядка четырех тактов при входе в прерывание будут потеряны и частота не будет точно соответствовать установленной
Почему частота не будет соответствовать?
Добавлено: 26 ноя 2010, 14:55
TK-15
как работать с битовым массивом?
С битами работают с помощью логических операций
AND - для сброса бита
OR - для установки
XOR - для переключения
в unsigned char соответственно можно хранить 8 флагов
Добавлено: 26 ноя 2010, 14:58
TK-15
Почему частота не будет соответствовать?
вход в прерывание требует минимум 4 такта - почитай справочник. Лучшее из доступного ИМХО книжки по AVR Евстифеева.
Добавлено: 26 ноя 2010, 15:06
Germie
xumuk писал(а):Понял, спасибо, переделаю
Вот только непонятен один момент
порядка четырех тактов при входе в прерывание будут потеряны и частота не будет точно соответствовать установленной
Почему частота не будет соответствовать?
На вход в прерывание МК, в общем случае, тратит четыре такта. То есть, к моменту входа в прерывание твой таймер, работающий на частоте МК (без предделителя) насчитает уже четыре. Можно, в принципе вносить поправку, как ты это делал. А можно просто учитывать это дело и загружать в TCNT не 6, а 10. Но, имхо, не красиво
. И, все равно, не точно. А если в программе появятся еще прерывания, отнимающие процессорное время, погрешность установки частоты еще увеличится.
Удачи
.
Добавлено: 26 ноя 2010, 15:10
xumuk
С битовым массивом понятно, буду пользовать
вход в прерывание требует минимум 4 такта
Да, но непонятно куда эти 4 такта прицепить и почему они влияют на чатсоту
TCNT0 ведь продолжает увеличиваться пока идет вход в прерывание ? Выходит когда вход будет выполнен в TCNT0 уже будет 0х04?
Добавлено: 26 ноя 2010, 15:13
Germie
xumuk писал(а):С битовым массивом понятно, буду пользовать
вход в прерывание требует минимум 4 такта
Да, но непонятно куда эти 4 такта прицепить и почему они влияют на чатсоту
TCNT0 ведь продолжает увеличиваться пока идет вход в прерывание ? Выходит когда вход будет выполнен в TCNT0 уже будет 0х04?
Да, уже будет 4. А ты меняешь в обработчике значение TCNT0. В твоем случае, конечно же, можно просто прибавлять к TCNT0 6, но так можно сделать далеко не всегда и, обычно, так не делают.
Добавлено: 28 ноя 2010, 01:28
xumuk
Урра! Заработало
Спасибо всем за помощь, особенно
Germie, помогавшему мне исправлять ошибки вчера до часу ночи
Показать/Спрятать
Вот такой ИК пульт получился для фотокамер Nikon.
Теперь берусь за тахометр
Добавлено: 28 ноя 2010, 17:26
Dj_smart
Добавлено: 28 ноя 2010, 17:31
Germie
И я, и я... С вашего разрешения вклинюсь
.
Ардуино - ново- (почти ново-, точнее
) модное увлечение молодых западных эмбеддеров.
Особого внимания, в смысле надо ли платить за эту платформу денег, не стоит. А в качестве пособия для новичков использовать можно. В принципе, платформа не предлагает ничего принципиально нового, чего нельзя бы было сделать на любой грамотно спроектированной макетке под AVR.
Добавлено: 28 ноя 2010, 17:58
koolhatcker
Dj_smart, я согласен с
Germie, ничего там такого нет, обычная макетка. Из плюсов - язык больше похож на бейсик, чем на Си
и готовых приложений под это железо тьма написана.
Добавлено: 28 ноя 2010, 18:02
Dj_smart
Да макетка меня меньше всего... Понравилось это: Согласитесь, очень удобно начать работу с последовательным портом на
скорости 9600 бит в секунду, сделав вызов одной строчкой:
Serial.begin(9600);
Просто очень. А на бейсик действительно похоже.
Добавлено: 28 ноя 2010, 18:08
Germie
Dj_smart писал(а):Да макетка меня меньше всего... Понравилось это: Согласитесь, очень удобно начать работу с последовательным портом на
скорости 9600 бит в секунду, сделав вызов одной строчкой:
Serial.begin(9600);
Просто очень. А на бейсик действительно похоже.
Это можно будет использовать лишь в случае, когда используемый МК совпадает с тем, что используется в Ардуине. Чудес ведь не бывает - если МК другой, все равно придется ручками инициализировать. Но никто же не мешает наваять макросов, скажем, под свои МК и использовать так же.
Добавлено: 28 ноя 2010, 18:12
TK-15
Согласитесь, очень удобно начать работу с последовательным портом на
скорости 9600 бит в секунду, сделав вызов одной строчкой:
Dj_smart - "просто так" ничего не бывает
. За всю эту простоту идет оплата размером кода. В С и так полно библиотек, так что использовать ни чуть не сложнее.
в качестве пособия для новичков использовать можно
наверное это основное ....
Добавлено: 03 янв 2011, 22:20
xumuk
Не совсем в тему, но т.к. я новичок в этом деле, решил написать сюда.
Как зависит у AVR частота встроенного генератора и напряжение встроенного источника опорного напряжения (2,56 в) от напряжения питания?
Т.е. можно ли запитывать МК напрямую от Li-ion аккумулятора?
Добавлено: 03 янв 2011, 23:48
Germie
Зависимость частоты внутреннего генератора от напряжения примерно такая
.
Однако, следует заметить, что у многих МК серии AVR имеется один или несколько регистров OSCCAL (регистр калибровки частоты внутренних генераторов), которые позволять подстроить частоту при отличном от 5 В напряжении питания.
Образцовое напряжение АЦП от напряжения питания практически не зависит (на то оно же и образцовое
).
Так что, никто не мешает питать МК от твоего аккума.
Удачи
.
Добавлено: 04 янв 2011, 00:12
xumuk
Понял, спасибо
Придется повесить кварц.
Добавлено: 09 янв 2011, 15:44
xumuk
Подскажите пожалуйста как из
char сделать и вывести на экран
float в формате x.xx
Чар получаю с двух каналов АЦП. Опорное напряжение 2,56.
Пробовал так
Код: Выделить всё
sprintf(lcd_buffer,"%4u\n%4u", ((float)read_adc(0))/100, ((float)read_adc(1))/100);
На экран выводятся 4хзначные числа без точки.
Добавлено: 09 янв 2011, 15:58
okan_vitaliy
sprintf(lcd_buffer,"%1.2f %1.2f", ((float)read_adc(0))/100, ((float)read_adc(1))/100);
Добавлено: 09 янв 2011, 17:06
xumuk
okan_vitaliy, заработало!
Спасибо
Вот только пришлось помучаться с CVAVR, сначала выводило просто
2f 2f
Оказалось надо полезть в
Project -> Configure -> C Compiler ->
и в выпадающем списке
(s)printf Features выбрать "float, width, precision" (по умолчанию только "int, width").
У меня тут еще вопрос назрел - могу ли я использовать прерывания ацп (250 КГц) еще и как таймер? Хочу туда положить счетчик чтобы засекать время между появлением сигнала на первом и втором канале АЦП.
Добавлено: 09 янв 2011, 17:16
okan_vitaliy
Можно, только поделите частоту на 13(за 13 тактов происходит преобразование).
Добавлено: 23 мар 2011, 14:37
vzgherea
В контроллерах, описанных на этом сайте, сигнал STEP подаётся на ножку МК которая поддерживает внешнее прерывание. Можно ли для STEP использовать другие ноги и ловить на них изменения уровня сигнала или всё-таки первый вариант предпочтительнее?
Добавлено: 23 мар 2011, 14:44
koolhatcker
Можно, но первый вариант предпочтительнее, т.к. если длительность импульса будет меньше частоты опроса входа, то импульс пройдёт незамеченным.
Добавлено: 23 мар 2011, 14:52
vzgherea
koolhatcker писал(а):если длительность импульса будет меньше частоты опроса входа, то импульс пройдёт незамеченным
А разве при использовании других ног в качестве входа МК не вызывает обработчик прерывания как и в случае с ножкой INT?
Добавлено: 23 мар 2011, 14:59
koolhatcker
Не все МК это могут делать и не со всеми ногами.
Добавлено: 24 мар 2011, 09:18
okan_vitaliy
vzgherea писал(а):
А разве при использовании других ног в качестве входа МК не вызывает обработчик прерывания как и в случае с ножкой INT?
Все современные Меги (AVR) поддерживают прерывание по перепаду сигнала почти на всех лапках. Тут главное что бы в прерываниях почти ничего не обрабатывалось, а обрабатывалось в маине. Тогда пропусков не будет.
Добавлено: 24 мар 2011, 11:13
koolhatcker
Тут главное что бы в прерываниях почти ничего не обрабатывалось, а обрабатывалось в маине
И чтобы время обработки в маине было меньше, чем частота входных импульсов
.
Добавлено: 27 мар 2011, 08:44
okan_vitaliy
koolhatcker писал(а):
И чтобы время обработки в маине было меньше, чем частота входных импульсов
.
Это совсем не обязательно. В прерываниях задача не пропустить входные импульсы, а вот в майне Вы их обрабатывать можете как хотите. Тут все зависит от алгоритма. Причем не обязательно что бы майн выполнялся быстрее чем один импульс. Просто обработчик в майне должен быть готов к тому что в счетчике импульсов будет не один, а несколько импульсов и корректно эту ситуацию обработать. У меня в контроллере так и сделано. И помимо обработчика шагов в майне еще крутится дофига других обработчиков.