Разработка устройства для электросна

Разработка функциональной и принципиальной схемы прибора, ее структура и элементы. Источник тока, управляемый напряжением, схема подключения кнопок. Разработка основной программы и применяемые подпрограммы, оценка эффективности проектируемой системы.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 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

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.