Только в этом месяце - скидки на паяльники и электронику с нашими кодами (123avr.com) :
![]() |
|
Совет - умейте правильно находить информацию!
|
Задача 9. Электронный вольтметр, измеритель вибрации. Цель задачи: разработать устройство и программу для МК ATmega16 для измерения напряжения и частоты сигнала от датчика вибрации и отображения результата на 2-х разрядном 7-ми сегментном светодиодном индикаторе. Что нужно для выполнения этой задачи:
Параметры сигнала от датчика вибрации: Датчик выдает синусоидальное переменное напряжение с частотой вибрации не превышающей 50 Гц и максимальным действующим значением 150 мВ. Значит амплитуда (это максимальное отклонение от нуля) сигнала будет: 150 * (корень из 2) = 212 (мВ) Виброперемещение вычисляется по формуле: (мкм) = U (мВ) / (0,03 * F (Гц)) Результат выводится на двухразрядный светодиодный индикатор - это два индикатора TDSL5150 с общим анодом - это значит что все 8 светодиодов (7 сегментов цифры и точка) соединены "тупыми сторонами" вместе и это соединение нужно подключить к "+" питания. А для включения сегмента нужно создать на соответствующей ножке ток 2 мА на "землю" при этом падение напряжение на светодиоде составит примерно 1.8 вольт это данные и график из ДШ на индикатор. Давайте подумаем над схемой и алгоритмом работы устройства. Нам надо измерить амплитуду и частоту входного сигнала - первое что приходит на ум это подать его на вход АЦП (Аналоговый сигнал в Цифровой Преобразователь) МК ATmega16 - оцифровывая сигнал с частотой значительно превышающей максимальную частоту входного сигнала - например 1000 раз в секунду - мы можем найти его максимальную положительную величину обнаружив что результат следующего измерения стал меньше, затем аналогично обнаружим следующий максимум и время между этими максимумами будет периодом сигнала. Так как вывод
осуществляется на индикатор для
зрительного восприятия человеком, то
обновлять результат чаще трех раз в
секунду не стоит - получится мелькание -
при этом Т.е. вычисление виброперемещения можно проводить несколько раз между каждым обновлением показаний на индикаторе. А на индикатор выводить максимальный результат из этих нескольких вычислений. Теперь
нужно посмотреть описание АЦП ATmega16. В моей версии ДШ это стр. 202 Мы видим что встроенный в МК АЦП имеет возможность усиливать сигнал в 10 и 200 раз но при этом разрешение составит 8 бит и по примечанию 1 реализована эта функция только в квадратных корпусах для поверхностного монтажа! Учтем это! Значит при использовании усиления х10 мы будем оцифровывать положительные полуволны сигнала в диапазоне от 0 до 2,12 вольт. Опять смотрим ДШ и видим, что МК имеет внутренний калиброванный источник опорного напряжения на 2,56 вольт. Определить на какой вход подавать входной сигнал можно по таблице Table 84. Input Channel and Gain Selections Я предлагаю воспользоваться примером расчета на стр. 215 Example: ADMUX = 0xED Voltage on ADC3 is 300 mV, ADCR = 512 * 10 * (300 - 500) / 2560 = -400 = 0x270 ADCL will thus read 0x00, and ADCH
will read 0x9C. ADCL = 0x70, ADCH = 0x02.
или 1 единица соответствует 0.5 мВ. К сожалению дифференциальное включение АЦП и доп. усиление не доступны в 40-ка выводном DIP-корпусе и в симуляторе VMLAB. А вот PROTEUS это симулирует !
бит ADLAR = 0 - выравнивание в право:
Так
записывается результат по умолчанию ! Внимание! CodeVisionAVR позволяет использовать в программе виртуальный 16 битный регистр ADCW:
это
бывает удобно ! Запускаем компилятор CVAVR (CodeVisionAVR или CV) и затем генератор начального кода программы: Прекрасный помошник для начинающего эмбедера! 1) выбираем ATmega16 и частоту 8 МГц 2) откроем ярлык АЦП - ADC: -
включили АЦП 3) теперь настройте Timer 0 -
источник тактового сигнала - системный
такт - т.е. та Мы хотим мерить 1000 раз в секунду, а счет идет 125000 раз в секунду, значит нам надо чтоб таймер считал 125 "тик"ов, выдавал прерывание (и выше в п.2 мы настроили чтоб запускал АЦП) и начинал опять считать. но таймер переполняется при "тик"е когда уже содержит 255 значит он должен считать не с 0 а с 256 -125 = 131 а 131 в 16-ричном виде будет 0х83 или 83h - вот я его и вписал в окошко. Если не понятно - перечитайте! 4) Всегда полезно иметь возможность вывести отладочную либо еще какую информацию через адаптер rs232 на ПК - для этого активируем передатчик USART -
включить передатчик
5) можно
указать некоторую информацию о проекте
-
6) Теперь надо сгенерировать начальный текст программы и сохранить. Так как я планирую дальнейшую отладку в симуляторе VMLAB то создал папку для этого проекта c:\VMLAB\z09 Сохраните файлы с такими именами:
Сохраняйте ...
Вы
увидите сгенерированный по сделанным
Включите
поддержку кириллицы и удобный для вас
Давай те слегка структурируем программу, а именно уберем текст конфигурации инициализации "железа" МК из главной функции main в специально созданную функцию: init_avr 1) Выделите и вырежьте текст из программы со строки:
до строки:
2) на месте вырезанного напишите вызов функции:
добавленный код я написал и буду писать синим ! 3) после текста:
напишите объявление функции:
Причем функция может быть и пустой т.е. ничего не содержать между скобками {} - это удобно при написании скелета программы, а далее по мере проработки алгоритма в скобках появляется текст того, что делает функция.
Итак, что делает эта программа? По задуманному при включении МК с кварцем на 8 МГц (конечно с конденсаторами по 22 пФ с ног на землю и соответственно прошитыми фьюзами!) тамер 0 должен 1000 раз в секунду переполнятся и будет возникать соответствующее прерывание - т.е. мы будем попадать в функцию обработчик прерывания от timer 0. Добавим в нее код запускающий АЦП входного напряжения:
А здесь, в прерывании, мы сделали бит_6 = "1" это запускает АЦ преобразование. ВНИМАНИЕ! бит_6 станет "0" автоматически при завершении АЦП - программно сделать его "0" нельзя!
По завершении АЦП должно возникать прерывание и мы должны попадать в процедуру = функцию обработки прерывания:
Как нам
проверить что программа работает Давайте их использовать. Проверка и отладка программы Нужно создать файл-проект для симулятора. В любом текстовом редакторе создайте файл vmlab9.prj и поместите его в папку c:\VMLAB\z09 Не советую использовать кириллицу ! VMLAB тупит порой по этому поводу. Давайте наполнять файл vmlab9.prj содержанием. Все
что я буду туда записывать вы можете
найти Ищите их поиском Vindows в папке c:\VMLAB\ и вложенных.
Во-первых указываем тип МК, затем файл прошивки z09.hex которую даст компилятор, затем файл z09.cof в котором содержится привязка данных прошивки к тексту программы на Си
Теперь логично добавить источник напряжения V_in для измерения, пусть пока это будет не генератор синусоиды а переменный резистор - одна нога на "землю" другая на 2.5 вольт а средний вывод пойдет на вход АЦП - ADC3 (ножка PA3 МК)
Еще нам надо подать
0 на ADC2 (ножка PA2 МК) поэтому
используем резистор R1 на 1 Ом от
ножки PA2
VDD - это "земля" или 0 вольт VSS - это питание, по умолчанию +5 вольт Чтоб принимать данные от USART МК как бы через подключенный к ножке PD1 rs232 адаптер на COM-порт ПК включим симулятор терминала:
Момент возникновения различных событий удобно наблюдать в окне виртуального осциллографа SCOPE симулятора. Я думаю двух ножек МК будет достаточно для этого. Подключим ножки МК: PB0, PB1 и ножку вывода информации с USART PD1 к осциллографу и вход PA3 для V_in
Теперь мы увидим напряжения на этих четырех ножках при симуляции. При включении МК или после сброса (замыкания вывода reset на землю и создания на нем лог. "1") все выводы МК становятся входами. Чтобы
вывести на ножки МК нужные нам сигналы (логические
уровни "0" или "1") - нужно
сделать соответствующие ножки
вЫходами. Для этого соответствующие биты в регистре направления работы выводов порта DDRx нужно сделать "1" = "ножка вЫход" соответственно "0" = "ножка вход" В текст нашей программы на Си в созданную нами функцию нужно добавить после строк:
такой код:
после исполнения МК этих строк программы ножки PB0 и PB1 станут ВЫХОДАМИ и на них появятся напряжения (= уровни) определяемые содержимым соответствующих бит регистра PORTB - у нас это будут логические "0" (см. код программы чуть выше!)
Всё просто! При включении каких либо устройств (периферии МК) ножки относящиеся к ним автоматически конфигурируются так как это нужно для правильной работы этого устройства. Однако я рекомендую вам уточнять это всегда в ДШ или проверочной симуляцией тестовой программы! Теперь давайте обозначим какие события будут вызывать изменения уровней на PB0 и PB1 и вывод сообщений на симулятор терминала ПК. Пусть ножка PB0 изменяет свой логический уровень при каждом переполнении таймер 0:
дословно на Си добавленная синяя строчка означает: взять значение бит_0 регистра PORTB сделать XOR (исключающее или) этого значения с числом 1 (а проще = инвертировать бит) и результат записать опять в бит_0 регистра PORTB. Старайтесь думать над значением каждой строки программы и четко проговаривать выполняемые операции ! Теперь после переполнения таймера 0 мы попадем в эту функцию обработчик прерывания, в ней мы восстановим значение начала отсчета, затем изменим логический уровень на ножке PB0 и увидим это в окне SCOPE симулятора и еще запустим АЦП. Обязательно и подробно комментируйте свою программу! не откладывайте на потом... потом не сделаете! PB1 будет менять свой уровень при завершении АЦП - напишем строчку соответствующего кода:
на ПК пока через USART выведем обычную строчку начинающих :
Кстати если вы помните генератор начального текста программы - он не спрашивал нас на какой вход мы будем подавать измеряемое напряжение V_in и какой коэф. усиления будем использовать. Нужно указать это в программе самим! По ДШ и примеру гораздо выше - видно что этими вопросами ведает регистр МК ADMUX - в нашем тексте программы уже есть кое что по этому регистру:
и вот это:
Строку #define удалите совсем, а значение которое нужно записать в регистр ADMUX определим сами, по ДШ
Table
83. Voltage Reference Selections
for ADC - из неё мы видим что бит_5 ADLAR оставляем "0" - результат выравнивается нормально, по правому краю. бит4_0 для нашей конфигурации (выше я объяснил подробно) должны быть по табл. 84 01101 итак в регистр нужно записать:
А пока, так как симулятор не симулирует дифференциальное включение, мы будем подавать сигнал просто без усиления на ножку PA3 - это 3-й канал АЦП и значит его номер - число 3 нужно вписать в биты_4_0 Итак для симуляции в регистр ADMUX нужно записать:
Записываем число в двоичном виде:
Еще я бы хотел сделать переменную для результата АЦП глобальной - т.е. доступной для использования в любом месте программы. Вырежьте вот эти строки из программы:
и
вставьте после строки
Компилируем. 1) Кликните эту иконку в CodeVisionAVR: 2) если вы сделали все аккуратно то получите вот такое: а в вашей
папке C:\VMLAB\z09 появится множество файлов,
но нас интересуют три файла: z09__.c
z09.hex z09.cof Симулируем ... Подробно и с картинками симуляция в VMLAB описана в задаче 3 1) запустите VMLAB 2) откройте проект - vmlab9.prj 3) нажмите F9 чтоб "отбилдить" проект. Должна выскочить такая надпись - Успешно! все готово к забегу! в противном случае начните с 1) и повнимательней. 4) На панели "peripherals" - "переферия МК" кликните плюсики у АЦП и Таймер 0 чтоб развернуть их. Должно получится вот так:
5) для запуска симуляции нажимайте светофор до тех пор пока симулятор наругается: и пойдет нормальная, непрерывная симуляция... При симуляции вы можете менять положение движка левого резистора на Control Panel и видеть в цифровом виде (рисунок над предыдущим) напряжение V_in и одновременно результат его оцифровки в регистрах ADCH и ADCL. Я померил в симуляторе время между переполнениями таймер 0 и оно очень точно равно 1 мС - вот картинка измерения. А вот замер времени передачи сообщения по USART: оно составило 3.4 мС Мы
передали 12 символов и символ "LF" -
значит всего 13. Еще важный момент ! Благодаря осциллографу SCOPE мы можем увидеть электрические сигналы! Посмотрите внимательно этот рисунок: На осциллограмме видно, что в начале, после включения МК и до выполнения программы функции инициализации уровни на трех ножках были по 2,5 вольта - так симулятор показал что они являются высоко-омными входами.
2,5 вольта симулятор показал просто для определенности - на самом деле напряжения на ножках реального МК будут определятся тем что к ним подключено!
Затем программа выполнила строку:
и на ножках PB0 и PB1сразу стали логические "0" (что соответствует 0 вольт) потому, что ранее была выполнена вот такая строчка:
По истечении 4.1 мкС выполняется эта строка:
она включает USART и, как я писал выше, конфигурирует вывод PD1 для правильной работы этого устройства - т.е. делает его выходом. Но - опять внимание! делает PD1 выходом с уровнем "1" несмотря на то, что ранее в программе была выполнена строчка:
"1" появилась на PD1 потому что включился USART - а при отсутствии передачи данных на его выходе высокий логический уровень! Далее, через некоторое время (рисунок разорван!) началась передача текста со спада "1-0" на PD1 - это "старт бит".
Погоняйте симуляцию программы. У вас не должно остаться вопросов без ответа! Если вопросы останутся, то запишите их и ищите ответ по методике описанной на первой странице курса!
|
|
Copyright 2009-2019 123avr.com