Здравствуйте! Друзья помогите разобраться с причиной того, почему не работает, АЦП и внешнее прерывание в tiny13? Возможно я, что-то напортачил с настройкой.
При подключении переменника и вращении в определенный момент должен появляться высокий лог. уровень на PB4, тоже самое и с внешним прерыванием, при нажатии на кнопку.
За такое (и за отсутствие форматирования в целом) по рукам бить надо. Хотя прерывание Int0 настроено по-человечески (случайность?). Переменная RezultatACP (почему не назвать по-нормальному, adc_result хотя бы?..) объявлена глобальной, но используется только в прерывании. Логичнее было ее сделать локальной. Переменная s (офигеть информативное название) объявлена глобально, используется в прерывании и в основной программе, но не объявлена volatile. Это ошибка! Из описания непонятно чего вы пытаетесь добиться и что именно не получается. Вчитываться в этот неформатированный ужас особого желания нет, но, похоже, дребезг не обрабатывается. Если так, у вас программа на пограничных значениях будет постоянно в прерывание заходить.
За такое (и за отсутствие форматирования в целом) по рукам бить надо. Хотя прерывание Int0 настроено по-человечески (случайность?). Переменная RezultatACP (почему не назвать по-нормальному, adc_result хотя бы?..) объявлена глобальной, но используется только в прерывании. Логичнее было ее сделать локальной. Переменная s (офигеть информативное название) объявлена глобально, используется в прерывании и в основной программе, но не объявлена volatile. Это ошибка! Из описания непонятно чего вы пытаетесь добиться и что именно не получается. Вчитываться в этот неформатированный ужас особого желания нет, но, похоже, дребезг не обрабатывается. Если так, у вас программа на пограничных значениях будет постоянно в прерывание заходить.
Какая разница как назвать переменные от этого по другому они работать не станут? Просто назвал как удобнее))
Тогда как правильно (форматированно) обработать дребезг в прерывании?
Форматирование, комментарии и осмысленные названия переменных нужны не непосредственно для правильной работы программы, а чтобы упростить себе и другим анализ кода - где какой блок начинается и заканчивается, какая переменная для чего предназначена, чего автор хотел добиться тем или иным блоком кода. Туда же использование именованных битов в том же ADCSRA - я, например, не помню какой за что отвечает, но если бы было написано, скажем, ADCSRA = (1<<ADIE | 0b001<<ADPS0) была бы сразу заметна ошибка, а то и не одна. Кажется, у Макконела было что-то вроде "если мне принесут посмотреть вот такой код я скажу сначала привести его в читаемый вид. Если вот сякой - посмотрю по настроению, поскольку глаза не режет, а если вот эдакий - прочитаю обязательно". Потому что можно сконцентрироваться на логике, а не на подробностях реализации.
Цитата:
Тогда как правильно (форматированно) обработать дребезг в прерывании?
А нужно ли в прерывании? Опрос кнопок (хоть одной, хоть всех) проще делать по таймеру с интервалом 10 - 500 мс, либо в бесконечном цикле с тем же периодом: точность времени тут не важна. Впрочем, я пока не представляю задачу в которой одновременно измеряется напряжение с помощью АЦП и приближенно оценивается его уровень с помощью внешнего прерывания. Требуется реакция на пересечение порога (угу, на IO выводе с неизвестным уровнем срабатывания и гистерезисом) со задержкой менее 30 мкс (что обеспечивается АЦП)? Даже если так, аналоговый компаратор точнее обычного прерывания.
Цитата:
PS а намек понял...спасибо!)
А зря, потому что в зависимости от настроек диапазон меняется: (0...255), (0...1023), (0...65472) и даже (0...3). Кстати, может вам и не надо все 10 бит, а хватит и 8? Работа с 8-битными переменными проще и быстрее. Ну и не стоит использовать магические числа, берущиеся непонятно откуда. Лучше объявить константу или макрос (в gcc-avr макрос обычно удобнее), например
Код:
#define MAX_TEMPERATURE_C 100 //максимальная температура, в градусах Цельсия #define Temp2ADC(t) (1024*(t+273)) //например, такая формула. Взята от балды так что физический смысл коэффициентов не знаю, но в реальном коде его стоит расписать ... if( ADC > Temp2ADC(MAX_TEMPERATURE) ){...}
В последнем проекте у меня фигурирует вот такой макрос
У всех входящих в него констант есть физический смысл - сопротивления резисторов (в Омах или миллиОмах), опорное напряжение АЦП (в милливольтах), разрядность каналов. Все их можно напрямую или косвенно измерить для конкретной платы и контроллера. Более правильно было бы хранить эту константу в EEPROM'e, но для одиночного изделия и так неплохо.
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Форматирование, комментарии и осмысленные названия переменных нужны не непосредственно для правильной работы программы, а чтобы упростить себе и другим анализ кода - где какой блок начинается и заканчивается, какая переменная для чего предназначена, чего автор хотел добиться тем или иным блоком кода. Туда же использование именованных битов в том же ADCSRA - я, например, не помню какой за что отвечает, но если бы было написано, скажем, ADCSRA = (1<<ADIE | 0b001<<ADPS0) была бы сразу заметна ошибка, а то и не одна. Кажется, у Макконела было что-то вроде "если мне принесут посмотреть вот такой код я скажу сначала привести его в читаемый вид. Если вот сякой - посмотрю по настроению, поскольку глаза не режет, а если вот эдакий - прочитаю обязательно". Потому что можно сконцентрироваться на логике, а не на подробностях реализации.
Цитата:
Тогда как правильно (форматированно) обработать дребезг в прерывании?
А нужно ли в прерывании? Опрос кнопок (хоть одной, хоть всех) проще делать по таймеру с интервалом 10 - 500 мс, либо в бесконечном цикле с тем же периодом: точность времени тут не важна. Впрочем, я пока не представляю задачу в которой одновременно измеряется напряжение с помощью АЦП и приближенно оценивается его уровень с помощью внешнего прерывания. Требуется реакция на пересечение порога (угу, на IO выводе с неизвестным уровнем срабатывания и гистерезисом) со задержкой менее 30 мкс (что обеспечивается АЦП)? Даже если так, аналоговый компаратор точнее обычного прерывания.
Цитата:
PS а намек понял...спасибо!)
А зря, потому что в зависимости от настроек диапазон меняется: (0...255), (0...1023), (0...65472) и даже (0...3). Кстати, может вам и не надо все 10 бит, а хватит и 8? Работа с 8-битными переменными проще и быстрее. Ну и не стоит использовать магические числа, берущиеся непонятно откуда. Лучше объявить константу или макрос (в gcc-avr макрос обычно удобнее), например
Код:
#define MAX_TEMPERATURE_C 100 //максимальная температура, в градусах Цельсия #define Temp2ADC(t) (1024*(t+273)) //например, такая формула. Взята от балды так что физический смысл коэффициентов не знаю, но в реальном коде его стоит расписать ... if( ADC > Temp2ADC(MAX_TEMPERATURE) ){...}
В последнем проекте у меня фигурирует вот такой макрос
У всех входящих в него констант есть физический смысл - сопротивления резисторов (в Омах или миллиОмах), опорное напряжение АЦП (в милливольтах), разрядность каналов. Все их можно напрямую или косвенно измерить для конкретной платы и контроллера. Более правильно было бы хранить эту константу в EEPROM'e, но для одиночного изделия и так неплохо.
О форматировании кода вы меня убедили, будем стараться))
Конечно можно было проще использовать и компаратор, и опрос кнопок в прерываниях, но это просто эксперимент и изучение attiny13 на будущее. Жаль мало информации на русском об этом МК, надо курить даташит на заграничном, а времени совсем мало, видать в этом-то и проблема
Как при 10 бит может быть (0...65472) (0...3)...? И о каких магические числах вы имеете в виду?
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Вся информация из даташита переведена Евстифеевым "Микроконтроллеры AVR семейства tiny" Магические числа - 2048 с которым вы сравниваете результат АЦП, инициализирующие значения для ADCSRA и т.п. Про разрядность АЦП - бит ADLAR, выравнивание либо по старшему, либо по младшему биту. При выравнивании по младшему, можно использовать только ADCH - будет 2 значащих бита, диапазон (0...3), если выравнивание по старшему - парный регистр ADC принимает значения (0...65472) - 10 старших битов. Не особо представляю, где эти диапазоны могут пригодиться, но теоретически - возможно.
Невнимательно читаете: речь шла про режимы с выравниванием младшего бита и считыванием ADCH - диапазон (0...3) и с выравниванием по старшему с использованием обоих регистров - диапазон (0...65472). Впрочем, последнее может и пригодиться если где-то в вычислениях нужно умножение на 16-64.
Сейчас этот форум просматривают: Adagumer и гости: 40
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения