Разработка устройства для электросна
Разработка функциональной и принципиальной схемы прибора, ее структура и элементы. Источник тока, управляемый напряжением, схема подключения кнопок. Разработка основной программы и применяемые подпрограммы, оценка эффективности проектируемой системы.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | курсовая работа |
Язык | русский |
Дата добавления | 14.03.2015 |
Размер файла | 401,3 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
Размещено на http://www.allbest.ru/
Курсовая работа
Разработка устройства для электросна
1. Разработка функциональной схемы прибора
программа напряжение схема
На основе постановки задачи с учётом указанных требований, разработаем функциональную схему устройства.
Для реализации поставленной задачи следует в первую очередь реализовать схему управляемого генератора тока - источника тока управляемого напряжением (ИТУН). Генератор тока в данном случае должен быть достаточно прецизионным. Напряжение стимуляции при любом заданном значении тока должно быть до 20 Вольт, следовательно, в устройстве должен быть предусмотрен вторичный источник питания на величину напряжения, которая несколько превышает указанную. Для питания схемы источника тока будем применять ВИЭП на 24 Вольта. Генерацию импульсов можно осуществлять например с помощью широтно-импульного модулятора (PWM). Значения параметров должны сохраняться в энергонезависимой памяти каждый раз при регулировке и считываться при включении питания, следовательно, в устройстве должен быть предусмотрен блок энергонезависимой памяти - РПЗУ. Информация относительно параметров и состояния генерации должна выводиться на алфавитно-цифровой LCD-индикатор, следовательно, необходимо предусмотреть и данный блок. В схеме должны быть предусмотрены кнопки управления стимуляцией: «+» и «-» - для регулировки значений параметров, «param.» - для выбора регулируемого параметра, «gen. - включение / отключение генерации то есть должен быть предусмотрен блок клавиатуры. Логикой работы всего прибора должно управлять цифровое устройства управления. Укажем функции устройства управления в разрабатываемом устройстве: 1) осуществлять управление генератором тока: подавать периодические импульсы напряжения, преобразуемые в ток, управлять величиной тока; 2) сканировать клавиатуру: при нажатии на соответствующие кнопки менять значение тока стимуляции, включать / отключать стимуляцию; 3) управлять модулем LCD - выводить на него информацию о величине тока стимуляции, о включении самого процесса стимуляции. Для устройства управления, LCD, РПЗУ должен быть предусмотрен источник питания с напряжением, которое значительно ниже того, которое требуется для источника тока - 5 Вольт. Источники напряжения для разных частей схемы должны быть стабилизированными. Питание всего устройства должно осуществляться от сети переменного тока 220 Вольт.
На основе всего описанного выше была разработана функциональная схема устройства, которая изображена на рисунке 1.
Рисунок 1 - Функциональная схема устройства
Некоторые обозначения на функциональной схеме: 1) «ВИЭП 24V», «ВИЭП 5V» - вторичные источники электропитания на указанные величины напржения; 2) ИТУН - источник тока управляемый напряжением. На данный блок от устройства управления подаётся сам информационный сигнал и управляющее напряжение; 3) РПЗУ - энергонезависимая память.
2. Разработка принципиальной схемы прибора
2.1 Устройство управления
В современных малогабаритных цифровых устройствах в качестве устройства управления обычно применяют микроконтроллер (МК). При выборе микроконтроллера для определённого устройства обычно исходят из следующих соображений: 1) МК должен иметь достаточный объём памяти программ, памяти данных, набор периферийных устройств для решения поставленной; 2) ресурсы МК должны быть максимально задействованы, периферийные устройства должны максимально замещать функциональные узлы схемы; 3) не менее важными факторами является доступность аппаратных и программных средств программирования, отладки, цена самого МК.
Для выполнения поставленной задачи хорошим выбором будет микроконтроллер ATTiny2313 фирмы Atmel.
Укажем основные особенности выбранного МК [1]:
- flash-память программ объёмом 2 кБ;
- EEPROM-память данных объёмом 128 байт;
- оперативная память данных SRAM объёмом 128 байт;
- максимальная тактовая частота - 20 МГц при тактировании от внешнего кварцевого резонатора; 4 или 8 МГц при тактировании от внутреннего генератора;
- максимум 18 линий ввода-вывода (если PA0/XTAL1, PA1/XTAL2, PA2/Reset сконфигурированы как линии ввода-вывода), иначе 15 линий ввода-вывода;
- несколько источников внешних прерываний: прерывание по изменению состояния любой линии PORTB, прерывания по PD2, PD3;
- один восьмибитный таймер T0 с двумя модулями сравнения;
- один шестнадцатибитный таймер - T1 с двумя модулями сравнения, которые могут работать в режиме PWM, модулем захвата;
- полнодуплексный синхронный / асинхронный последовательный интерфейс USART;
- последовательный интерфейс USI;
- аналоговый компаратор;
- возможность внутрисхемного последовательного программирования по SPI-интерфейсу.
Графическое изображение данного микроконтроллера в PDIP-корпусе показано на рисунке 2.1.
Рисунок 2.1 - Графическое изображение микроконтроллера ATTiny2313
Как видно из данного описания, МК имеет достаточный объём памяти, достаточное кол-во линий ввода-вывода. Все функциональные блоки схемы могут подключаться непосредственно к микроконтроллеру. А в качестве блока «РПЗУ» может применяться встроенная энергонезависимая память данных EEPROM.
В данном случае требуется формирование коротких импульсов с достаточно большой точностью по частоте и длительности. Значительно увеличить точность можно при использовании высокочастотного кварцевого резонатора. Поэтому в данном случае будем применять кварцевый резонатор на частоту близкую к максимальной частоте данного контроллера - 16 МГц.
Fuse-биты МК должны быть запрограммированы следующим образом: CKSEL3…0=1111 - тактирование от внешнего ВЧ кварцевого / керамического резонатора; CKDIV8=1 - внутренний делитель частоты на 8 отключен; BODLEVEL2…0 = 101 - сброс МК при снижении напряжения питания до 2,7 Вольт, для дополнительной защиты flash и EEPROM от случайного стирания.
2.2 Источник тока управляемый напряжением
В данном подразделе будет описана разработка источника тока управляемого напряжением - блока, к которому подключён сам канал стимуляции. В начале ещё раз укажем некоторые требуемые параметры стимуляции, которые одновременно являются параметрами управляемого источника тока. Ток должен регулироваться в диапазоне от 0,2 до 3 мА с шагом 0,2 мА, импульсы тока - однополярные, напряжение стимуляции должно составлять величину до 20 Вольт при неизменной величине тока.
Регулируемый источник тока можно реализовать на транзисторах. Но транзистор является нелинейным элементом, и его характеристики сильно зависят от внешних факторов, например от температуры. По указанным причинам в данном случае будем применять источник тока на операционных усилителях. Структурная схема генератора тока на ОУ со следящей обратной ООС [2] изображена на рисунке 2.2.
Рисунок 2.2 - Структурная схема генератора тока на ОУ со следящей ООС
Укажем обозначения в схеме на рисунке 2.2: OP1 - токозадающий ОУ; OP2 - некоторая схема дифференциального усилителя, включенного в обратную связь; Ri - токозадающий резистор; Rн - сопротивление нагрузки.
Опишем принцип работы данной схемы. В случае если ОУ включён с отрицательной обратной связью, потенциалы на входах ОУ стремятся быть равными, т.е. потенциал на инверсном входе должен быть равен потенциалу на неинверсном, т.е. потенциалу на выходе цифровой линии МК. Дифференциальный усилитель OP2 усиливает падение напряжения на токозадающем резисторе Ri до величины Uвх:
, (2.1)
где G - коэффициент усиления дифференциального усилителя.
Падение напряжение на Ri рассчитывается по формуле:
, (2.2)
где IRi - ток через токозадающий резистор Ri, и, так как входное сопротивление дифференциального усилителя очень большое, то можно считать что ток IRi соответствует току через нагрузку Iн.
Подставив (2.2) в (2.1) получим:
(2.3)
Отсюда ток через резистор:
(2.4)
Как видим из соотношения (2.4), в данном случае получили источник тока, величина тока которого прямо пропорциональна входному напряжению и обратно пропорциональна сопротивлению токозадающего резистора. Так как вход данной схемы подключается непосредственно к цифровой линии МК, то входное напряжение может иметь 2 уровня: уровень логического нуля - около потенциала земли и уровень логической единицы - в данном случае около 5 Вольт. Исходя из этих соображений и будем производить дальнейшие расчёты.
Так как входное напряжение схемы имеет только 2 уровня, то представленная на рисунке 2.2 схема имеет существенный недостаток: данный источник тока нерегулируемый.
Усовершенствуем схему на рисунке 2.2 с целью получения регулируемого источника тока. Усовершенствованный вариант схемы представлен на рисунке 2.3.
Рисунок 2.3 - Структурная схема регулируемого источника тока
В случае схемы на рисунке 2.3 усилитель OP2 усиливает относительно входного опорного напряжения Uref.
Формула (2.3) для входного напряжения в этом случае принимает вид:
, (2.5)
и формула для тока через нагрузку:
(2.6)
Как видим из (2.6), чем большее опорное напряжение усилителя OP2, тем меньше ток через нагрузку. При Uref = 0 формула (2.6) сводится к виду (2.4), т.е. в этом случае будет максимально возможный ток через нагрузку. При Uref = Uвх = 5 Вольт ток через нагрузку будет равен нулю.
Перейдём непосредственно к принципиальной схеме источника тока. Принципиальная схема изображена на рисунке 2.4.
Рисунок 2.4 - принципиальная схема источника тока
Дифференциальный усилитель реализован на операционных усилителях OP2, OP2 и резисторах включённых в их обратную связь. Примечание: в данном случае для упрощения расчётов в некоторых случаях резисторы имеют равные номиналы - на схеме на рисунке 2.4 одинаковые резисторы имеют одинаковые позиционные обозначения. Коэффициент усиления дифференциального усилителя, реализованного на указанных элементах, рассчитывается по формуле:
(2.7)
В данном случае желательно обеспечить минимальное падение напряжение на токозадающем резисторе, то есть максимальное падение на нагрузке. То есть желательно повысить его коэффициент усиления за счёт подбора соответствующих номиналов резисторов. Выбираем коэффициент усиления G=10. Для обеспечения указанного коэффициента усиления из стандартного ряда номиналов резисторов выбираем значения: R1 = 20 кОм, R2 = 180 кОм.
Рассчитаем требуемое значение токозадающего резистора для максимально заданной величины тока 3 мА.
Из формулы (2.4) выразим требуемое значение резистора Ri для заданного тока:
(2.8)
Подставив в (2.8) Uвх = 5 В, IRi = 3 мА, G = 10 найдём требуемое значение токозадающего резистора: Ri ? 167 Ом. Из прецизионного ряда номиналов резисторов E96 выберем ближайший к указанному: Ri = 165 Ом.
В качестве операционных следует выбрать такие, которые удовлетворяют требованиям по напряжению питания, частоте, и т.д. В качестве усилителей выбираем микросхемы прецизионных операционных усилителей OPA277, которые обладают следующими основными параметрами [3]: напряжение смещения: 10 мкВ; дрейф нуля: 0,1 мкВ/°C; входной ток: 1 нА; максимальная рабочая частота: 1 МГц; максимальное напряжение питания при однополярном питании: 36 Вольт.
Далее рассмотрим схему регулировки опорного напряжения дифференциального усилителя. В качестве элемента регулировки можно применить потенциометр. Но так как схема с управлением от микроконтроллера, то простой потенциометр было бы применять нерационально, хорошим решение в данном случае будет применение цифрового потенциометра с цифровым интерфейсом управления от микроконтроллера.
В качестве микросхемы цифрового потенциометра применим микросхему AD5241BR100 фирмы Analog Devices [4]. Данная микросхема управляется по шине I2C, имеет сопротивление между выводами 100 кОм, 256 позиций для регулировки. Структурная схема микросхемы цифрового потенциометра показано на рисунке 2.5.
Рисунок 2.5 - Структурная схема микросхемы цифрового потенциометра AD5290BR100
Как видим из схемы, микросхема помимо потенциометра имеет в своём составе 2 выходных цифровых линии общего назначения: O1, O2, в данном случае эти линии не задействованы. Также микросхема имеет 2 адресных входа: AD0, AD1, т.е. есть возможность применения в системе до четырёх таких микросхем. Имеется также вход SHDN, который практически отключает микросхему при подаче на него напряжения низкого логического уровня - ток потребления снижается до нескольких микроампер, W замыкается с B.
Средняя точка внутреннего резистора - W; крайние точки - A, B. Потенциал средней точки определяется как: VW = (VA-VB)·pos/256, где pos - позиция потенциометра, отправляется на потенциометр по шине I2C. В данной схеме для удобства управления вывод B подключаем к общему проводу, вывод A - к напряжению питания +5 Вольт. Выходное сопротивление цифрового потенциометра имеет тот же порядок что входное сопротивление входа опорного напряжения дифференциального усилителя, то есть если выход W подключать напрямую к входу опорного напряжения, то будет значительное взаимное влияние потенциометра и входа усилителя. То есть в данном случае необходима развязка выхода потенциометра с входом опорного напряжения усилителя. Развязку лучше всего реализовать через операционный усилитель, включённый по схеме неинвертирующего повторителя между выходом W и входом опорного напряжения.
2.3 Схема подключения кнопок
Как уже было указано, в устройстве для управления должны быть предусмотрены следующие кнопки: кнопка включения / отключения генерации «gen», кнопка выбора регулируемого параметра «param.», кнопки регулировки тока стимуляции «+» и «-».
Выбранная модель МК имеет возможность включения внутренних подтягивающих резисторов на любой линии ввода-вывода [1]. При подключении внутреннего подтягивающего резистора кнопку можно подключить следующим образом: первый вывод кнопки - к линии ввода-вывода, а второй - к общему проводу. В этом случае при чтении состояния линии ввода-вывода, если кнопка отпущена будет прочитана «1», если нажата - «0». Кнопки подключены к следующим линиям ввода-вывода: кнопка «gen.» - PB0; кнопка «param.» - PB1; кнопка «+» - PB2; кнопка «-» - PB3.
2.4 Устройство индикации
В задании было указано, что в качестве устройства индикации должен применяться LCD-индикатор. В данном случае не требуется вывода большого количества информации, поэтому достаточно будет применить алфавитно-цифровой LCD-индикатор с числом знакомест 16x2.
Подходящим выбором будет алфавитно-цифровой LCD-индикатор LM016L фирмы Hitachi. Выбранный индикатор обладает следующими основными особенностями:
- число знакомест: 16x2;
- знакогенератор: английский, европейский;
- встроенный контроллер LCD HD44780 [5];
- напряжение питания: 5 Вольт;
- положительное напряжение регулировки контрастности, то есть не требуется дополнительного источника отрицательного напряжения. Подключение вывода регулировки контрастности V0 показано на рисунке 2.5.
Рисунок 2.5 - Подключение вывода регулировки контрастности LCD - индикатора
В схеме на рисунке 2.5 резисторы R, VR должны иметь номиналы 10…22 кОм. Подстроечный резистор VR, как правило, регулируется однократно, после сборки устройства.
В таблице 2.1 приведено назначение выводов индикатора и их подключение в схеме.
Таблица 2.1 - Назначение и подключение выводов индикатора
№ |
Название |
Назначение вывода в схеме |
|
1 |
Vss |
Общий провод |
|
2 |
Vdd |
Вывод питания |
|
3 |
V0 |
Вывод регулировки контрастности. Подключаться должен таким образом, как изображено на рисунке 2.5 |
|
4 |
RS |
Вход управления LCD - выбор регистра, подключён к линии PD1 микроконтроллера |
|
5 |
R/W |
Вход выбора направления шины LCD (запись / чтение), в данном случае применяем только чтение, поэтому вывод подключаем к общему проводу |
|
6 |
E |
Вход стробирования LCD. Подключён к линии PD2 |
|
7…14 |
DB0…DB7 |
Шина данных LCD-индикатора. Подключается по четырёхбитному интерфейсу [5] к линиям PD3…PD6 микроконтроллера |
Согласно рекомендации производителя [5], отправку команды / данных на LCD производим следующей последовательностью действий:
1) устанавливаем требуемый логический уровень на линии RS (PD1): «0» - команда, «1» - данные;
2) выводим в линии PD6…PD3 значение старшего полубайта;
3) на линии E (PD2) формируем синхроимпульс «0»> «1»> «0»;
4) выводим в линии PD6…PD3 значение младшего полубайта;
5) на линии E (PD2) формируем синхроимпульс «0»> «1»> «0»;
6) формируем задержку порядка 64 мкс в случае отправки любых данных и всех команд кроме команды очистки индикатора = 0x01, и 1,5 мс в случае команды очистки индикатора.
2.5 Разработка схемы питания
Питание всего устройства осуществляется от сети переменного тока 220 Вольт, а для различных блоков устройства требуются различные величины постоянного стабилизированного напряжения питания: 24 Вольта для схемы источника тока и 5 Вольт для других частей схемы. Для тех частей схемы, где требуется 5 Вольт напряжение должно быть максимально стабилизированным. Схема блока питания, которая для различных частей устройства обеспечивает требуемые величины стабилизированного напряжения, изображена на рисунке 2.6.
Рисунок 2.6 - Схема питания устройства
Роль стабилизаторов напряжения на 24 Вольт и 5 Вольт соответственно выполняют интегральные стабилизаторы напряжения 78L24 и 78L05, включённые по стандартной схеме включения: между выходом стабилизатора и общим проводом включены фильтрующие конденсаторы. Кроме того, напряжение 5 Вольт стабилизируем дополнительным LC-фильтром. Для меньших потерь энергии стабилизаторы на 24 и 5 Вольт включены последовательно друг другу. Питание от сети переменного тока 220 Вольт подключается на первичную обмотку трансформатора TV1, далее переменное напряжение выпрямляется диодным мостом VD1-VD4. Согласно требованиям к входному напряжению микросхемы 78L24, выпрямленное напряжение не должно превышать величину 35 Вольт, что должно быть учтено при выборе трансформатора. Так как токопотребление всего устройства относительно небольшое, то трансформатор TV1 и диоды можно выбрать относительно маломощные.
3. Разработка программного обеспечения
3.1 Разработка основной программы
При разработке устройств на базе микроконтроллеров разработка программного обеспечения для управляющего МК является не менее важной задачей, чем разработка принципиальной схемы устройства. В данном подразделе будет подробно описана разработка основной программы.
В начале выполнения программы - при включении питания устройства должна быть произведена инициализация, которую можно разделить на 2 части: 1) инициализация портов МК, применяемой периферии, периферия инициализируется в соответствии со значениями параметров, прочитанными из EEPROM; 2) инициализация LCD-индикатора в четырёхбитном режиме [5]. Порты МК должны быть настроены следующим образом. Линии управления LCD: RS - PD1, E - PD2 должны быть настроены на вывод; в данном случае применяем только вывод на LCD с последующими задержками в зависимости от команды / данных, поэтому линии МК, подключённые к линиям данных LCD PD6…PD3, должны быть настроены на вывод. Как уже было указано, линии, к которым подключены кнопки: PB3…PB0, должны быть настроены на ввод с включением внутреннего подтягивающего резистора. Генерация сигнала для источника тока в данном случае будет производиться с линии канала PWM PB4/OC1B - очевидно, что данная линия должна быть настроена на вывод. Управление цифровым потенциометром производится по шине I2C. Линия синхроимпульса I2C (SCL) соответствует линии PB7 - должна быть настроена на вывод; линия данных I2C (SDA) должна быть настроена на ввод без внутреннего pull-up, к данной линии должен быть подключен внешний подтягмвающиё резистор номиналом 10 кОм. В данном МК отсутствует аппаратный интерфейс I2C, поэтому он будет реализован программно. В данном случае для формирования различных временных задержек будут применяться различные таймеры. Для формирования заданной частоты сигнала и длительности импульса будем применять таймер T1, для генерации импульсов будем применять канал PWM данного таймера OC1B. Чтобы точно сформировать частоту, следует выбрать один из режимов работы таймера, где он считает до значения регистра OCR1A: изменением значения данного регистра меняем и частоту. В то же время OC1B должен работать как канал PWM. Подходящим режимом работы таймера для выполнения указанных условий является режим Fast PWM с коэффициентом деления счётчика равным значению регистра OCR1A: биты WGM13…0 = 1111 [5].
Рассмотрим подробно применение таймера T1 в данной программе. Значение OCR1A, необходимое для получения данной частоты рассчитываем по формуле:
, (3.1)
где CK = 16 MHz - тактовая частота МК, F - частота генерации импульсов, F - коэффициент деления прескалера таймера. Значение N следует выбирать таким образом, чтобы значение OCR1A было меньше максимально возможного значения = 65535. Для получения частот в заданном диапазоне 5…160 Герц оптимальное значение N будет составлять 64: биты CS12…CS10 регистра TCCR1B = 011. В этом случае формула (3.1) приводится к виду:
(3.2)
Так как выбранный МК не поддерживает на аппаратном уровне операций деления с многобайтными числами, то необходимо и формулу (3.2) упростить для применения в программе МК. В данном случае на уровне программы МК при расчётах применяем значение частоты, делённое на 5, и только на дисплей выводим реальное значение частоты. В этом случае (3.2) приводится к виду:
, (3.3)
где F' = F/5. В этом случае для программы МК необходимо будет только реализовать относительно подпрограмму беззнакового деления двухбайтного числа на однобайтное.
Как уже было указано, для формирования импульсов заданной длительносити применяем канал PWM OC1B. Значение регистра OCR1B для формирования длительности ф рассчитывается по формуле:
, (3.4)
значения CK и N определены ранее; ф по заданию должно составлять от 0,2 до 0,5 мс с шагом 0,1 мс, при подстановке в (3.4) должно быть выражено в секундах. При указанных значениях CK и N во всём диапазоне значений ф получаем целые значения OCR1B - от 50 до 125 с шагом 25, то есть возможно формировать очень точные по длительности импульсы.
Канал PWM можно включать / отключать также изменением соответствующих битов в регистре. Так как в данном случае применяем режим неинвертирующего PWM, то включить / отключить его выход можно установкой / сбросом бита COM1B1 в регистре TCCR1A [1].
Для формирования задержек для сканирования клавиатуры применяем таймер T0 в следующем режиме: CTC - обнуление при TCNT0 = OCR0A = 250, F = CK/64. При указанном режиме работы таймера получаем прерывания с интервалом 1 мс.
Помимо инициализации частоты и длительности, необходимо также установить требуемый ток нагрузки, который имеет обратную зависимость от напряжения на выходе W цифрового потенциометра. Напряжение на выходе W рассчитывается по формуле:
, (3.5)
где pos - позиция цифрового потенцирметра.
Будем считать, что при значении pos=0 ток будет максимальным=3 мА, при значении pos=255 ток будет равен нулю. В этом случае для изменения тока на минимальный шаг = 0,2 мА позицию потенциометра требуется изменить на 17. Значение тока, также как значение частоты и длительности также изначально читается из EEPROM. И далее, после чтения из EEPROM рассчитывается цифровой код для отправки на потенциометр.
После инициализации переходим к выполнению основного цикла программы. В основном цикле производим следующую последовательность действий: 1) ожидаем прихода прерывания по модулю OC1A таймера T0, инкрементируем счётчик прерываний; 2) если счётчик прерываний = 100 - прошло 100 мс, вызываем подпрограмму сканирования клавиатуры «keybscan», иначе возвращаемся к пункту 1; 3) после вызова подпрограммы сканирования клавиатуры инкрементируем счётчик 100 мс-интервалов. Если счётчик = 100 - более 10 с не было нажатий после изменения значения параметра, производится перезапись изменённого параметра в EEPROM, данный счётчик обнуляется внутри подпрограммы сканирования клавиатуры при нажатии клавиш изменения значения параметра.
На основе всего описанного выше был составлен алгоритм основной программы, который показан на рисунке 2.
Рисунок 3.1 - Алгоритм основной программы
Примечание к алгоритму на рисунке 3.1: действия по результатам нажатий на клавиши производятся внутри подпрограммы сканирования клавиатуры «keybscan». Но для наглядности указанные действия были показаны в алгоритме основной программы.
3.2 Применяемые подпрограммы
В данном подразделе перечислим и кратко опишем все применяемые подпрограммы.
1) Подпрограммы для LCD-индикатора:
LCD_init - подпрограмма стандартной инициализации LCD-индика-тора в четырёхбитном режиме [5];
LCD_sym_gen - подпрограмма генерации символа в области знакогенератора LCD. Начальный адрес в области знакогенератора задаётся в R16, начальный адрес таблицы кодов для знака - в регистровой паре ZH:ZL;
LCD_send_string - подпрограмма отправки на индикатор строки, записанной в flash-память МК. Начальный адрес строки в flash определяется регистром указателя Z. Строка должна заканчиваться кодом 0x00. Начальная позиция на LCD определяется в регистре R16;
LCD_send_command - подпрограмма отправки на LCD команды, которая определяется значением записанным в регистр R16;
LCD_send_data - подпрограмма отправки на LCD байта данных, который определяется значением записанным в регистр R17;
LCD_strobe - подпрограмма нижнего уровня для формирования синхроимпульса для LCD;
LCD_strobe_delay - подпрограмма формирования синхроимпульса LCD с последующей задержкой, длительность которой определяется отпрвленной командой / данными.
2) Подпрограммы нижнего уровня для шины I2C
I2C_start - подпрограмма формирования старт-состояния на шине I2C;
I2C_send - подпрограмма отправки байта, содержащегося в tmpL (R16) по шине I2C;
I2C_stop - подпрограмма формирования стоп-состояния на шине I2C;
I2C_delay - подпрограмма короткой задержки для I2C, вызывается внутри указанных выше подпрограмм.
3) Другие подпрограммы нижнего уровня:
short_delay1 - общая подпрограмма короткой задержки, вызывается внутри подпрограмм нижнего уровня для LCD и I2C.
EERead - подпрограмма чтения в регистр tmpL (R16) из адреса EEPROM, записанного в tmpH (R17);
EEWrite - подпрограмма записи данных из регистра tmpL (R16) по адресу EEPROM, записанному в tmpH (R17);
div16to8 - подпрограмма деления 16-ти битного числа в регистровой паре tmpH:tmpL на восьмибитное в регистре divisor (R20): результат - в tmpH:tmpL, остаток - в rest (R21);
div10 - подпрограмма деления регистра tmpL на 10: результат от деления в tmpL, остаток - в rest.
4) Подпрограммы верхнего уровня
set_current - подпрограмма установки тока через нагрузку. В качестве входного параметра применяется переменная Current, в которую записано относительное значение тока. Использует внутри подпрограммы более нижнего уровня - mul_to_17 и set_resistance;
mul_to_17 - подпрограмма умножения относительного кода тока на 17, используется для вычисления значения, отправляемого на цифровой потенциометр. Первоначальное значение тока должно быть записано в tmpH;
set_resistance - подпрограмма установки потенциала в средней точке цифрового потенциометра. Код, определяющий относительную вличину напряжения должен быть записан в tmpH. Использует внутри все подпрограммы нижнего уровня для I2C;
ind_current - подпрограмма индикации значения тока: относительное значение тока изначально записано в tmpH;
set_freq - подпрограмма установки частоты генерации импульсов. В качестве входного параметра использует переменную Freq;
ind_freq - подпрограмма индикации частоты. Рассчитывает абсолютное значение частоты, выводит на LCD. В качестве входного параметра использует переменную Freq;
set_width - подпрограмма установки длительности импульса и индикации. В качестве входного параметра использует переменную width;
Device_init - подпрограмма общей инициализации прибора. При включении питания считывает из EEPROM значения параметров, перезаписывает в соответствующие ячейки памяти в SRAM, в соответствии со считанными значениями инициализирует таймер T1 прибора - частота и длительность, цифровой потенциометр - ток;
keybscan - подпрограмма сканирования клавиатуры. Сканирует линии клавиш PB0…PB3, в случае если какая-либо клавиша нажата, и не было нажатия при предыдущем сканировании, выполняет действия в соответствии с функциями этой клавиши;
Заключение
В курсовой работе было разработано простое устройство для электросна. Разработанное устройство обеспечивает электросон воздействием на головной мозг периодическими импульсами тока регулируемой величины с напряжением до 20 Вольт. В разработанном устройстве регулируются следующие параметры: 1) ток воздействия - от 0 до 3 мА с шагом 0,2 мА; 2) частота следования импульсов тока - от 5 до 160 Герц с шагом 5 Герц; 3) длительность импульсов тока - от 0,2 до 0,5 мс с шагом 0,1 мс. Все указанные параметры сохраняются в энергонезависимой памяти устройства. Для включения / отключения генерации импульсов предусмотрена отделтная кнопка.
Перечень ссылок
1. ATMega8 Datasheet - 8bit AVR RISC microcontroller
2. П. Хоровиц, У. Хилл Искусство схемотехники, том 1 - издание 3-е, стереотипное - в двух томах с дополнением - Москва «Мир», 1986
3. OPA277 Datasheet - High precision operational amplifier
4. AD5241_5242 - I2C compatible 256-positions digital potentiometers
5. HD44780 - 16COM / 40SEG Driver and controller for DOT matrix LCD
Приложение
Текст программы
include «tn2313def.inc»
def ZERO = R15
def tmpL = R16
def tmpH = R17
def cnt1 = R18
def cnt2 = R19
def divisor = R20
def rest = R21
def T0_int_countL = R22
def T0_int_countH = R23
def predvalue = R24
def Maxvalue = R25
; port lines
equ key_stim = PORTB0
equ key_param = PORTB1
equ key_plus = PORTB2
equ key_minus = PORTB3
equ stim_line = PORTB4
equ SDA = PORTB5
equ SCL = PORTB7
equ LCD_RS_line = PORTD1
equ LCD_E_line = PORTD2
equ Device_adr = 0x58
equ keypressed = 0
ESEG
org 0x20
EEFreq: .BYTE 1
EEWidth: .BYTE 1
EECurrent: .BYTE 1
DSEG
Freq: .BYTE 1
Width: .BYTE 1
Current: .BYTE 1
Menu_pos: .BYTE 1
DigBuf: .BYTE 3
flags: .BYTE 1
; СЕГМЕНТ КОДА
CSEG
rjmp init; вектор сброса, переход к инициализации
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
rjmp T0_COMPA_handle;
вектор прерывания по срабатыванию модуля OC0A таймера T0, переход на соответствующий обработчик прерывания
reti
reti
reti
reti
reti
init: ldi tmpL, low(RAMEND)
out SPL, tmpL; инициализация стека
; инициализация портов
ldi tmpL, 1<<SCL|1<<key_minus|1<<key_plus|1<<key_param|1<<key_stim
out PORTB, tmpL
ldi tmpL, 1<<SCL|1<<stim_line
out DDRB, tmpL
ser tmpL
out DDRD, tmpL
; обнуление счётчиков
clr T0_int_countL
clr T0_int_countH
clr ZERO
sts flags, ZERO; обнуление регистра флагов
sts Menu_pos, ZERO; и текущей позиции меню
rcall LCD_init; вызов подпрограммы инициализации LCD - стандартная процедура инициализации в четырёхбитном режиме
clr tmpL
ldi ZH, high (sym_right<<1)
ldi ZL, low (sym_right<<1)
rcall LCD_sym_gen; вызов подпрограммы генерации символа стрелки вправо в области знакогенератора LCD по адресу в области знакогенератора = 0x40
rcall Device_init; вызов подпрограммы инициализации меню прибора
ldi tmpL, 1<<WGM11|1<<WGM10
out TCCR1A, tmpL
ldi tmpL, 1<<WGM13|1<<WGM12|1<<CS11|1<<CS10
out TCCR1B, tmpL; настройка режима работы T1: F=CK/64, счёт вверх от 0 до OCR1A, fast PWM при подключении какого-либо канала
ldi tmpL, 250
out OCR0A, tmpL
ldi tmpL, 1<<WGM02|1<<CS01|1<<CS00
out TCCR0B, tmpL; настройка режима T0: F=CK/64, счёт от 0 до OCR0A = 250 - прерывание каждую 1 мс
ldi tmpL, 1<<OCIE0A
out TIMSK, tmpL; разрешение прерывания по срабатыванию модуля OC0A
ldi tmpL, 1<<OCF0A
out TIFR, tmpL; на всякий случай сброс флага данного прерывания
sei; глобальное разрешение прерываний
; ОСНОВНОЙ ЦИКЛ ПРОГРАММЫ
loop:
ldi tmpL, 1<<SE
out MCUCR, tmpL
sleep; перевод МК в Idle-режим в начале основного цикла, выводится из данного режима при возникновении прерывания по срабатыванию модуля сравнения OC0A
cpi T0_int_countL, 0x64; после выхода из обработчика прерывания инкремент счётчика прерываний (1 мс-интервалов)
brlo loop; если счётчик < 100 (100 мс не прошло), переход на начало основного цикла
rcall keybscan; иначе вызов подпрограммы сканирования клавиатуры
clr T0_int_countL; обнуление счётчика 1 мс-интервалов
inc T0_int_countH; инвремент счётчика 100 мс-интервалов (обнуляется если при сканировании клавиатуры не была нажата какая-либо клавиша)
cpi T0_int_countH, 0x64
brlo loop; если счётчик < 100 (10 с не прошло), переход на начало основного цикла
clr T0_int_countH; иначе обнуление счётчика 100 мс-интервалов
ld tmpL, X
cp tmpL, predvalue; сравнение текущего значения выбранного параметра с предыдущим
breq loop; если значения равны, переход на начало основного цикла
mov predvalue, tmpL; иначе запись текущего значения в регистр предыдущего
mov tmpH, XL
subi tmpH, 0x60-0x20; переход к адресу EEPROM, соответствующему выбранному параметру
rcall EEWrite; вызов подпрограммы перезаписи параметра в EEPROM
rjmp loop; и переход на начало основного цикла
; подпрограмма сканирования клавиатуры
keybscan:
in tmpL, PINB
andi tmpL, 0x0F; чтение состояния линий кнопок
clr cnt1; очистка счётчика нажатой клавиши
lds tmpH, flags; загрузка данных из регистра флагов
next_key:
lsr tmpL; сдвиг временного регистра состояния порта вправо з записью состояния младшего бита в C
brcc pressed; если C=0 (клавиша нажата), переход на метку нажатой клавиши
inc cnt1; иначе инкремент счётчика нажатой клавиши
cpi cnt1,0x04
brne next_key; если счётчик<4, переход на метку чтения следующей линии клавиатуры
andi tmpH,~(1<<keypressed)
sts flags, tmpH; иначе (ни одна клавиша не нажата) сброс флага нажатия в регистре флагов
ret; и выход из подпрограммы
; метка нажатой клавиши
pressed:
sbrc tmpH, keypressed
ret; если флаг нажатия при предыдущем сканировании установлен, выход из подпрограммы
ori tmpH, 1<<keypressed
sts flags, tmpH; иначе установка флага нажатия
ldi ZH, high (key_handlers<<1)
ldi ZL, low (key_handlers<<1)
lsl cnt1
add ZL, cnt1
adc ZH, ZERO; вычисление адреса обработчика нажатия в таблице адресов
lpm R0, Z+
lpm R1, Z
movw ZH:ZL, R1:R0; загрузка адреса в регистр указателя
ijmp; и относительный переход по данному адресу
; обработчик нажатия клавиши включения / отключения стимуляции
stim_pressed:
in tmpL, TCCR1A
ldi tmpH, 1<<COM1B1
eor tmpL, tmpH
out TCCR1A, tmpL; инверсия бита COM1B1 в регистре TCCR1A - включение / отключения неинвертирующего PWM на линии OC1B
mov tmpH, tmpL
ldi tmpL, 0xC7; переход к позиции на LCD начиная с которой выводится состояние стимуляции: on/off
sbrs tmpH, COM1B1
rjmp PC+4
ldi ZH, high (str_on<<1); если PWM включен, запись в регистр указателя начального адреса строки «on»
ldi ZL, low (str_on<<1)
rjmp PC+3
ldi ZH, high (str_off<<1); иначе запись в регистр указателя начального адреса строки «off»
ldi ZL, low (str_off<<1)
rcall LCD_send_string; вызов подпрограммы отправки выбранной строки на LCD
ret; и выход из подпрограммы сканирования клавиатуры
; обработчик нажатия клавиши выбора параметра
param_pressed:
lds tmpH, Menu_pos
inc tmpH; инкремент регистра позиции меню
cpi tmpH, 0x03
brlo PC+2
clr tmpH; если позиция меню > 3, обнуление позиции меню
sts Menu_pos, tmpH
ld tmpL, X
cp tmpL, predvalue; сревнение текущего значения выбранного параметра с предыдущим значением
breq m7; если равно, то переход на метку выбора следующей позиции меню
; иначе действия по перезаписи изменённого значения параметра в EEPROM
push tmpH
mov tmpH, XL
subi tmpH, 0x60-0x20
out EEAR, tmpH; переход к соответствующему адресу в EEPROM
out EEDR, tmpL
rcall EEWrite; и вызов подпрограммы перезаписи параметра в EEPROM
pop tmpH
; действия по переходу к следующему параметру
m7: ldi ZH, high (Menu_handlers<<1)
ldi ZL, low (Menu_handlers<<1)
lsl tmpH
add ZL, tmpH
adc ZH, ZERO
lpm R0, Z+
lpm R1, Z; извлечение из таблицы адреса метки перехода к данному параметру
movw ZH:ZL, R1:R0
ijmp; и условный переход по данной метке
; метка перехода к регулировке частоты следования импульсов
Param1sel:
ldi Maxvalue, 0x1F
ldi XL, Freq
ldi tmpL, 0x80; сохранение адреса вывода символа стрелки вправо
push tmpL
ldi tmpL, 0xC0; сохранение адреса вывода пробела
push tmpL
rjmp m8; и переход на метку обновления информации на индикаторе
; метка перехода к регулировке длительности импульса
Param2sel:
ldi Maxvalue, 0x03
ldi XL, Width
ldi tmpL, 0x88; сохранение адреса вывода символа стрелки вправо
push tmpL
ldi tmpL, 0x80; сохранение адреса вывода пробела
push tmpL
rjmp m8; и переход на метку обновления информации на индикаторе
; метка перехода к регулировке тока (напряжения в средней точке цифрового потенциометра)
Param3sel:
ldi Maxvalue, 0x0F
ldi XL, Current
ldi tmpL, 0xC0; сохранение адреса вывода символа стрелки вправо
push tmpL
ldi tmpL, 0x88; сохранение адреса вывода пробела
push tmpL
m8: pop tmpL; извлечение в tmpL адреса вывода пробела
rcall LCD_send_command; его отправка на индикатор
ldi tmpL, ' '
rcall LCD_send_data; отправка пробела на индикатор
pop tmpL; извлечение в tmpL адреса вывода символа стрелки вправо
rcall LCD_send_command; его отправка на индикатор
clr tmpL
rcall LCD_send_data; отправка символа стрелки вправо на индикатор
ret; и выход из подпрограммы сканирования клавиатуры
; обработчик нажатия клавиши увеличения значения выбранного параметра
plus_pressed:
ld tmpL, X; извлечение из SRAM значения выбранного параметра
cp tmpL, Maxvalue
brsh ret1; если значение превышает максимально допустимое, переход на метку выхода из подпрограммы
inc tmpL; иначе инкремент значения параметра
st X, tmpL; его сохранение в SRAM
rjmp Param_change; и переход на метку изменения значения пареметра
; обработчик нажатия клавиши уменьшения значения выбранного параметра
minus_pressed:
ld tmpL, X; извлечение из SRAM значения выбранного параметра
tst tmpL
breq ret1; если значение = 0, переход на метку выхода из подпрограммы
dec tmpL; иначе декремент значения выбранного параметра
st X, tmpL; его сохранение в SRAM
; общая метка изменения значения параметра
Param_change:
lds tmpH, Menu_pos; мзвлечение текущей позиции меню
ldi ZH, high (Change_handlers<<1)
ldi ZL, low (Change_handlers<<1)
lsl tmpH
add ZL, tmpH
adc ZH, ZERO
lpm R0, Z+
lpm R1, Z
movw ZH:ZL, R1:R0; извлечение из таблицы адреса подпрограммы изменение выбранного параметра
icall; и относительный вызов данной подпрограммы
ret1:
clr T0_int_countH; обнуление счётчика 109 мс-интервалов
ret; и выход из подпрограммы
; подпрограмма инициализации меню прибора
Device_init:
ldi tmpL, 0x81
ldi ZH, high (str_freq<<1)
ldi ZL, low (str_freq<<1)
rcall LCD_send_string
ldi tmpL, 0x86
ldi ZH, high (str_HZ<<1)
ldi ZL, low (str_HZ<<1)
rcall LCD_send_string
ldi tmpL, 0x89
ldi ZH, high (str_Ti<<1)
ldi ZL, low (str_Ti<<1)
rcall LCD_send_string
ldi ZH, high (str_current<<1)
ldi ZL, low (str_current<<1)
ldi tmpL, 0xC1
rcall LCD_send_string
ldi ZH, high (str_off<<1)
ldi ZL, low (str_off<<1)
ldi tmpL, 0xC7
rcall LCD_send_string; вывод строк, содержащих названия параметров на индикатор
ldi tmpH, EEFreq
rcall EERead; чтение относительного значения частоты из EEPROM
cpi tmpL, 0x32
brlo m1; если частота в пределах допустимой, переход на m1
clr tmpL
rcall EEWrite; иначе перезапись минимального относительного значения частоты в EEPROM
m1: sts Freq, tmpL
rcall set_freq; вызов подпрограммы установки частоты
ldi tmpH, EEWidth
rcall EERead; чтение относительного длительности частоты из EEPROM
cpi tmpL, 0x04
brlo m2; если длительность в пределах допустимой, переход на m2
clr tmpL
rcall EEWrite; иначе перезапись минимального относительного значения длительности в EEPROM
m2: sts Width, tmpL
rcall set_width
ldi tmpH, EECurrent
rcall EERead; чтение относительного значения тока стимуляции из EEPROM
cpi tmpL, 0x10
brlo m3; если значение в пределах допустимого, переход на m3
clr tmpL
rcall EEWrite; иначе перезапись минимального относительного значения длительности в EEPROM
m3: sts Current, tmpL
rcall set_current; вызов подпрограммы установки тока стимуляции
rcall Param1sel; вызов подпрограммы выбора параметра 1 (частоты импульсов)
ret; и выход из подпрограммы
; подпрограмма установки частоты: регистр Freq в области SRAM - относительное значение частоты
set_freq:
ldi tmpH, high(50000)
ldi tmpL, low(50000)
lds divisor, Freq
inc divisor
rcall div16to8; вычисление значение регистра сравнения OC1A, необходимого для формирования данной частоты: OC1A = 50000/Freq
out OCR1AH, tmpH
out OCR1AL, tmpL; и перезапись результата в OC1A
rcall ind_freq; вызов подпрограммы индикации частоты
ret; и выход из подпрограммы установки частоты
; подпрограмма индикации частоты
ind_freq:
ldi tmpL, 0x83
rcall LCD_send_command; переход к начальному адресу индикации
lds tmpL, Freq
ldi ZL, digbuf+3
lds tmpL, Freq
inc tmpL
mov tmpH, tmpL
lsl tmpL
lsl tmpL
add tmpL, tmpH; вычисление из регистра относительного значения частоты Freq абсолютного значения частоты в Герцах: Hz = (Freq+1)*5
m4: rcall div10; вызов подпрограммы деления на 10
st - Z, rest; запись остатка от деления по текущему адресу в буфере выводимых цифр с преддекрементом адреса
cpi ZL, digbuf
brne m4; если адрес превышает начальный, переход на m4
m5: ld tmpL, Z+
subi tmpL,-0x30
rcall LCD_send_data; последовательный вывод цифр из буфера выводимых цифр
cpi ZL, digbuf+3
brlo m5; пока не выведены единицы, переход на m5
ret; дале выход из подпрограммы
; подпрограмма установки длительности из относительного значения в регистре Width: T = (Width+2)*0.1 мс
set_width:
ldi tmpL, 0x8E
rcall LCD_send_command; переход на LCD к адресу вывода длительности
lds cnt1, Width
inc cnt1
push cnt1
ldi tmpL, 25
clr tmpH
m6: subi tmpL, - 25
dec cnt1; вычисление значения канала PWM OC1B для формирования данной длительности: OC1B = 25*(2+Width)
brne m6
out OCR1BH, tmpH
out OCR1BL, tmpL; перезапись вычисленного значения в OC1B
pop cnt1
inc cnt1
mov tmpL, cnt1
subi tmpL,-0x30
rcall LCD_send_data; вывод десятых долей мс значения длительности на индикатор
ret; и выход из подпрограммы
; подпрограмма установки напряжения в средней точке потенциометра - установка тока
set_current:
ldi tmpH, 0x0F
lds tmpL, Current; извлечение относительного значения тока
push tmpL
sub tmpH, tmpL
rcall mul_to_17; вычисление отправляемого на цифровой потенциометр байта для установки требуемого значения
rcall set_resistance; вызов подпрограммы установки напряжения в средней точке потенциометра
pop tmpH
lsl tmpH
rcall ind_current; вызов подпрограммы индикации значения тока
ret; и выход из подпрограммы
; подпрограмма индикации значения тока: относительное значение тока = tmpH = Current<<1
ind_current:
push tmpH
ldi tmpL, 0xC3
rcall LCD_send_command; переход к адресу вывода значения тока
pop tmpL
rcall div10; деление относительного значения тока на 10
subi tmpL,-0x30
rcall LCD_send_data; вывод на индикатор результата деления - единиц милиампер
ldi tmpL, '.'
rcall LCD_send_data; вывод на индикатор десятичной точки
mov tmpL, rest
subi tmpL,-0x30
rcall LCD_send_data; вывод на индикатор остатка от деления - десятых долей милиампера
ret; и выход из подпрограммы
; вспомогательная подпрограмма умножения на 17: применяется для вычисления байта регулировки напряжения в средней точке цифрового потенциометра
mul_to_17:
mov tmpL, tmpH
lsl tmpH
lsl tmpH
lsl tmpH
lsl tmpH
add tmpH, tmpL
ret
;подпрограмма установки потенциала в средней точке цифрового потенциометра
set_resistance:
rcall I2C_start; формирование старт-состояния на шине I2C
ldi tmpL, Device_adr
rcall I2C_send; отправка слейв-адреса цифрового потенциометра
clr tmpL
rcall I2C_send; отправка байта конфигунации
mov tmpL, tmpH
rcall I2C_send; отправка значения байта установки напряжения в средней точке U0: U0 = VCC*value/256
rcall I2C_stop; формирование стоп-состояния на шине I2C
ret; и выход из подпрограммы
; подпрограмма стандартной инициализации LCD в четырёхбитном режиме
LCD_init:
ldi tmpL, 0x18
out PORTD, tmpL; вывод в PORTD байта команды = 0x30
ldi tmpL, 0x0A
m0: ldi cnt1,0x40
rcall next_del
dec tmpL
brne m0; задержка около 40 мс
rcall LCD_strobe; подача на LCD синхроимпульса
ldi cnt1,0x40
rcall next_del; задержка около 4 мс
rcall LCD_strobe; подача на LCD синхроимпульса
ldi cnt1,0x04
rcall next_del; задержка около 256 мкс
rcall LCD_strobe_delay; вызов подпрограммы тактирования LCD с последующей задержкой
ldi tmpL, 0x10
out PORTD, tmpL; вывод в PORTD байта команды = 0x20
rcall LCD_strobe_delay; вызов подпрограммы тактирования LCD с последующей задержкой - инициализация четырёхбитного режима
ldi tmpL, 0x28
rcall LCD_send_command; отправка на LCD команды инициализации двустрочного режима LCD
ldi tmpL, 0x0C
rcall LCD_send_command; отправка команды включения матрицы LCD без видимого курсора, без подчёркиваний
ldi tmpL, 0x06
rcall LCD_send_command; отправка команды сдвига вправо после отправки символа
ldi tmpL, 0x01
rcall LCD_send_command; отправка команды очистки индикатора
ret; и выход из подпрограммы
;подпрограмма генерации символа в области знакогенератора LCD: начальный адрес в области знакогенератора = 0x40+(tmpL&0x07)<<3, начальный код символа в flash по адресу ZH:ZL
LCD_sym_gen:
andi tmpL, 0x07
swap tmpL
lsr tmpL
subi tmpL,-0x40; tmpL = 0x40+((tmpL&0x07)<<3) - начальный адрес символа
rcall LCD_send_command; отправка на LCD команды начального адреса символа
clr R20; обнуление счётчика
next_sym_code:
lpm tmpL, Z+; загрузка из flash текущего кода с постинкрементом адреса
rcall LCD_send_data; отправка на LCD загруженного байта данных
inc R20; инкремент счётчика отправленных байт
cpi R20,0x08
brlo next_sym_code; если счётчик < 8, переход на метку отправки на LCD следующего байта
ret; и выход из подпрограммы
; подпрограмма отправки строки на LCD: строка расположена в flash начиная с адреса ZH:ZL, должна заканчиваться байтом = 0x00, начальная позиция на LCD задана в tmpL
LCD_send_string:
rcall LCD_send_command; отправка на LCD команды перехода к начальному адресу вывода строки
next_sym:
lpm tmpL, Z+; загрузка из текущего адреса в flash байта данных с постинкрементом адреса
tst tmpL
brne PC+2
ret; если извлечённое значение = 0 (конец строки), выход из подпрограммы
rcall LCD_send_data; иначе оправка извлечённого байта данных на LCD
rjmp next_sym; и переход к метке вывода следующего символа
; подпрограмма отправки на LCD байта команды, содержащегося в tmpL в четырёхбитном режиме
LCD_send_command:
cbi PORTD, LCD_RS_line; вывод логического «0» в линию, соответствующую LCD RS
rjmp PC+2; и переход к последующим действиям по отправке байта
; подпрограмма отправки на LCD байта данных, содержащегося в tmpL в четырёхбитном режиме
LCD_send_data:
sbi PORTD, LCD_RS_line; вывод логической «1» в линию, соответствующую LCD RS
rcall LCD_short_delay; вызов короткой задержки
push tmpL; временное сохранение отправляемого байта в стеке
andi tmpL, 0xF0
lsr tmpL
in tmpH, PORTD; запись состояния выходных линий PORTD во временный регистр
andi tmpH, 0x07; запись в биты временного регистра, соответствующего линиям данных LCD нулей
or tmpL, tmpH; логическое ИЛИ регистра, содержащего старший полубайт отправляемого значения с битами временного регистра состояния выходных линий PORTD
out PORTD, tmpL; вывод результата в PORTD
rcall LCD_short_delay; вызов короткой задержки
rcall LCD_strobe; вызов подпрограммы тактирования LCD
pop tmpL; извлечение сохранённого в стеке значения отправляемого значения
push tmpL
swap tmpL; обмен извлечённых полубайт в извлечённом регистре - вывод младших байт отправляемого значения в старшие
andi tmpL, 0xF0
lsr tmpL
in tmpH, PORTD; запись состояния выходных линий PORTD во временный регистр
andi tmpH, 0x07; запись в биты временного регистра, соответствующего линиям данных LCD нулей
or tmpL, tmpH; логическое ИЛИ регистра, содержащего младший полубайт отправляемого значения с битами временного регистра состояния выходных линий PORTD
out PORTD, tmpL; вывод результата в PORTD
rcall LCD_short_delay; вызов короткой задержки
pop tmpL; извлечение первоначального значения отправляемого байта в tmpL для передачи подпрограмме тактирования LCD с последующей задержкой
rcall LCD_strobe_delay; вызов подпрограммы тактирования индикатора с последующей задержкой
ret; и выход из подпрограммы отправки байта на LCD
; подпрограмма тактирования индикатора с последующей задержкой - время задержки зависит от значения отправленного байта, содержащегося в tmpL
LCD_strobe_delay:
rcall LCD_strobe; вызов подпрограммы тактирования индикатора
sbic PORTD, LCD_RS_line
rjmp PC+3
cpi tmpL, 0x03
brlo PC+3
ldi cnt1,0x01; если были отправлены данные либо команда <> команде очистке, запись в счётчик 64 мкс-задержек значения = 1
rjmp next_del
ldi cnt1,0x20; если отправлена команда очистки LCD, запись в счётчик 64 мкс-задержек значения = 32 (для формирования задержки после отправки около 2 мс)
next_del:
rcall LCD_after_send_delay; вызов подпрограммы 64 мкс
dec cnt1; декремент счётчика 64 мкс-задержек
brne next_del; пока счётчик не обнулился, переход на next_del
ret; и выход из подпрограммы
; подпрограмма тактирования LCD-индикатора
LCD_strobe:
sbi PORTD, LCD_E_line
rcall LCD_short_delay; вывод состояния логической «1» в линию, соответствующую линии тактирования индикатора с последующей короткой задержкой
cbi PORTD, LCD_E_line
rcall LCD_short_delay; вывод состояния логического «0» в линию, соответствующую линии тактирования индикатора с последующей короткой задержкой
ret; и выход из подпрограммы
; подпрограмма короткой задержки для LCD (применяется внутри подпрограмм нижнего уровня для LCD)
LCD_short_delay:
ldi cnt2,0x04
rcall short_delay1
ret
; подпрограмма длительной задержки (около 64 мкс) после отправки байта на LCD
LCD_after_send_delay:
clr cnt2
rcall short_delay1
ret
; подпрограммы нижнего уровня для шины I2C
; подпрограмма формирования старт-состояния на шине I2C
I2C_start:
sbi PORTB, SCL
rcall i2c_delay
sbi DDRB, SDA
rcall i2c_delay
ret
; подпрограмма отправки байта, содержащегося в tmpL по шине I2C
I2C_send:
ldi cnt1,0x08
cbi PORTB, SCL
rcall i2c_delay
lsl tmpL
brcc PC+3
cbi DDRB, SDA
rjmp PC+2
sbi DDRB, SDA
rcall i2c_delay
sbi PORTB, SCL
rcall i2c_delay
dec cnt1
brne I2C_send+1
cbi PORTB, SCL
rcall i2c_delay
cbi DDRB, SDA
rcall i2c_delay
sbi PORTB, SCL
rcall i2c_delay
ret
; подпрограмма формирования стоп-состояния на шине I2C
I2C_stop:
cbi PORTB, SCL
rcall i2c_delay
sbi DDRB, SDA
rcall i2c_delay
sbi PORTB, SCL
rcall i2c_delay
cbi DDRB, SDA
Подобные документы
Сравнительный анализ существующих приборов. Разработка функциональной схемы устройства. Выбор и статистический расчет элементов, входящих в систему: датчика, источник тока, усилителя, микроконтроллера, блок питания. Блок-схема управляющей программы.
курсовая работа [769,9 K], добавлен 12.01.2015Описание функциональной схемы контроллера системы отопления, обеспечивающего многопозиционный контроль температуры и управление ветками отопления и котлом. Разработка принципиальной схемы. Обоснование выбора. Алгоритм работы устройства. Листинг программы.
курсовая работа [1,1 M], добавлен 26.12.2012Разработка структурной и принципиальной схемы. Блок-схема основной программы и подпрограмм обработки прерываний. Имена переменных, используемых в них. Результаты моделирования работы устройства в программе ISIS пакета Рroteus. Разработка печатной платы.
курсовая работа [1,5 M], добавлен 13.11.2016Микропроцессоры позволяют строить универсальные устройства управления электронными весами. Разработка функциональной схемы, схемы алгоритма прикладной программы. Разработка принципиальной схемы, управляющей программы. Листинг управляющей программы.
курсовая работа [118,0 K], добавлен 04.07.2008Актуальность задачи. Разработка функциональной схемы устройства. Радиолокационная установка (РЛУ). Микропроцессорная часть. Обоснование алгоритма работы устройства. Разработка управляющей программы устройства. Схема алгоритма. Пояснения к программе.
курсовая работа [193,9 K], добавлен 18.10.2007Разработка функциональной и принципиальной схемы. Выбор управляющего контроллера. Описание МК PIC16F626, МК AVR, МК 51. Выбор элементной базы. Разработка управляющей программы. Описание алгоритма работы программы. Схема устройства, листинг программы.
курсовая работа [492,9 K], добавлен 28.12.2012Выбор манипулятора-указателя, микропроцессора, интерфейса подключения к ПК. Обзор используемых команд. Проектирование функциональной и электрической принципиальной схемы контроллера трекбола. Разработка алгоритма и программы функционирования системы.
курсовая работа [453,3 K], добавлен 22.10.2012Распределение функций между аппаратной и программной частями микропроцессорной системы. Выбор микроконтроллера, разработка и описание структурной, функциональной и принципиальной схемы. Выбор среды программирования, схема алгоритма и листинг программы.
курсовая работа [304,4 K], добавлен 17.08.2013Разработка принципиальной электрической схемы микропроцессорного устройства управления двигателем постоянного тока на базе контроллера ATmega 128. Разработка пакета подпрограмм на языке Assembler в целях регулирования и корректной работы устройства.
курсовая работа [271,5 K], добавлен 14.01.2011Основные характеристики выбранных приборов: датчики и первичные преобразователи, вторичные инструменты. Схема сигнализации, ее внутренняя структура и функциональные возможности, оценка эффективности. Описание и принцип работы данного устройства.
контрольная работа [230,0 K], добавлен 16.03.2015