Выдержка из текста работы
Целью данного курсового проекта является практическое применение знаний, полученных в различных областях науки в пределах таких курсов, как «Специализированные архитектуры ЭВМ», «Микропроцессорная техника», «Проектирование специализированных микропроцессорных систем», а также «Программирование» для реализации полученного технического задания.
Результат выполнения задания — устройство измерения температуры окружающей среды, напряжения на выходах потенциометра, управление звуковым излучателем и часы. Полученные данные необходимо периодически отображать на LCD-дисплее микроконтроллера PIC18F4520.
В пояснительной записке представлены этапы перехода от словесного описания поставленной задачи до конкретной реализации в виде функционирующего устройства. Выполнены все этапы проектирования от технического задания до реализации проекта в выбранной элементной базе (микроконтроллер PIC18F4520) с использованием среды MPLAB IDE.
МИКРОКОНТРОЛЛЕР, ТЕРМОДАТЧИК, MPLAB IDE, LCD-ДИСПЛЕЙ.
Введение
Первое, что привлекает внимание в PIC-контроллерах — это простота и эффективность. В основу концепции PIC, единую для всех выпускаемых семейств, была положена RISC-архитектура с системой простых однословных команд, применение встроенной памяти программ и данных и малое энергопотребление [2]. Микроконтроллеры PIC имеют симметричную систему команд, позволяющую выполнять операции с любым регистром, используя любой метод адресации. В настоящее время MICROCHIP выпускает четыре основных семейства 8-разрядных RISC-микроконтроллеров [6]:
- базовое семейство PIC15Cx с 12-разрядными командами, простые недорогие микроконтроллеры с минимальной периферией;
- PIC12Cxxx с 12-разрядными командами со встроенным тактовым генератором, выпускаемые в миниатюрном 8-выводном исполнении.
- Mid-range PIC16x/7x/8x/9x с 14-разрядными командами. Наиболее многочисленное семейство, объединяющее микроконтроллеры с разнообразными периферийными устройствами, в число которых входят аналоговые компараторы, аналогово-цифровые преобразователи, контроллеры последовательных интерфейсов SPI, USART и I2C, таймеры-счётчики и так далее;
- High-end PIC17C4x/5xx высокопроизводительные микроконтроллеры с расширенной системой команд 16-разрядного формата, работающие на частоте до 33 МГц, с объёмом памяти программ до 16 Кслов. Кроме обширной периферии почти все микроконтроллеры этого семейства имеют встроенный аппаратный умножитель 8х8, выполняющий операцию умножения за один машинный цикл.
Особый акцент Microсhip делает на максимально возможное снижение энергопотребления для выпускаемых микроконтроллеров. При работе на частоте 4 МГц PIC-контроллеры, в зависимости от модели, имеют ток потребления меньше 1,5 мА, а при работе на частоте 32,768 КГц — ниже 15 мкА. Поддерживается “спящий” режим работы. Диапазон питающих напряжений PIC-контроллеров составляет 2,0…6,0 В.
В настоящее время готовится к запуску в производство новое пятое семейство PIC-контроллеров PIC18Cxxx. Новые микроконтроллеры будут иметь расширенное RISC-ядро, оптимизированное под использование нового Си-компилятора, адресное пространство программ до 2 Мбайт, до 4 Кбайт встроенной памяти данных и производительность 10 MIPS.
Из программных средств отладки наиболее известны и доступны различные версии ассемблеров, а также интегрированная программная среда MPLAB. Для проектирования устройства был выбран микроконтроллер серии PIC18 так, как на его основе реализована демонстрационная плата PICDEM 2 PLUS.
В данной лабораторной работе было запрограммировано устройство измерения температуры на основе термодатчика TC74, настройка и снятие значений с него осуществлялась при помощи модуля SSP.
Также была запрограммирована работа с потенциометром посредством снятия значений с выходов аналого-цифрового преобразователя настроенного на работу с потенциометром.
Была реализована работа с Piezo Buzzerом при помощи CCP в режиме широтно-импульсной модуляции, что позволило Piezo Buzzer излучать звуки различной частоты и длительности.
Также на основе тактового генератора были запрограммированы часы реального времени с использованием внешних синхросигналов от кварцевого генератора. В каждой реализованной подпрограмме осуществляется вывод на LCD текущих значений как, то напряжение, температура, текущая длительность и период сигнала, а также времени в формате чч:мм: сс.
Отдельными подпрограммами были реализованы процедуры инициализации LCD и портов, а также меню, которое позволяет переключаться между режимами работы программы.
1. Техническое задание
Техническое задание (ТЗ) на проектирование должно содержать исчерпывающую и однозначную информацию о требованиях, предъявляемых к проекту. Техническое задание обычно объемный документ, в котором на естественном языке описана, по сути, словесная модель проектируемой системы. Несмотря на строгость и точность формулировок ТЗ не дает однозначного описания объекта проектирования и не позволяет непосредственно переходить от описания функционирования системы к ее техническому воплощению [1].
1.1 Назначение устройства
Необходимо реализовать на микроконтроллере PIC18F4520 устройство, выполняющее периодически измерение напряжение с помощью 5 кОм потенциометра, управление динамиком, измерение температуры окружающей среды и организация часов реального времени на основе счётчика. Эти данные необходимо отображать на экране. Переключение между режимами должно осуществляться с помощью меню. Все данные передавать на внешние устройства для дальнейшей обработки через порт RS-232, например для отображения на ПК при помощи Hyper Terminal.
Спроектированное устройство может применяться для измерения температуры в домашних условия, на предприятиях, в научных лабораториях и т.д. Данное устройство не подходит для высокоточного измерения температуры в связи с определенными технологическими особенностями самого микроконтроллера и встроенного в него термодатчика.
Измерение напряжения на выходах потенциометра имеет исключительно образовательное назначение, т.к. сам потенциометр является весьма неточным, но позволяет научится применять аналого-цифровые преобразования. Цели организации работы с динамиком и построения часов аналогично.
Устройство работает независимо от компьютера. Преимущество — мобильность устройства и простота использования. Для функционирования данного устройства в нормальном режиме необходимо обеспечить постоянную подачу электроэнергии. Диапазон рабочих напряжений — с 2 до 5 В. Устройство должно быть защищено от попадания на его поверхность жидкости и других вредных воздействия в связи с отсутствием корпуса.
Минимальный срок общей эксплуатации составляет 10 лет. Минимальная гарантированная продолжительность непрерывной работы — 48 часов.
В соответствии со спецификацией устройства PICDEM 2 PLUS в нём реализованы последующие соответствия портов и входов/выходов устройств (табл. 1.1)[11]. Данная таблица наилучшим образом показывает назначение входов/выходов микроконтроллера.
Таблица 1.1 — Соответствие портов и входов/выходов устройств
Устройство ввода/вывода |
Порты |
|
LEDs (D2-D5) |
RB3:RB0 |
|
USART |
RC6:RC7 |
|
Master Reset (S1) |
MCLR |
|
User-defined (S2) |
RA4 |
|
User-defined (S3) |
RB0 |
|
Potentiometer (R16) |
RA0 |
|
LCD1 |
RA3:RA1 and RD3:RD0 |
|
EEPROM (Ux) |
RC3/RC4 |
|
Buzzer (P1) |
RC2 |
|
ICD Connector (J5) |
RB6:RB7 |
|
Temperature sensor (Ux) |
RC3:RC4 |
|
Crystal oscillator (Y1) |
OSC1 and OSC2 |
|
External oscillator (Y2) |
OSC1 |
1.2 Требования к реализации
Сроки проектирования определяются сроками выполнения курсового проекта, включая разработку документации. Проект считается законченным, если проведено программирование микроконтроллера и результат соответствует техническому заданию. Основные требования к проектированию: использование свободно распространяемых микроконтроллеров PIC18F4520, описание моделей с помощью языка программирования ассемблер, использование тестового подхода к проверке исправности модели устройства. Способ проверки — физическое тестирование основных этапов программы [5].
2. Техническое предложение
Техническое предложение является частью предварительного проектирования. При этом:
1) принимается решение об использовании микроконтроллера фирмы Microchip, серии PIC18, как, во-первых, отвечающего современным требованиям к элементной базе; во-вторых, имеющегося в наличии на момент разработки проекта;
2) оптимизация алгоритма программы для устройства будет проводиться на этапе программирования микроконтроллера.
2.1 Элементная база
Демонстрационная плата PICDEM 2 Plus содержит следующие физические компоненты [6] (рис. 2.1).
1. 18, 28, 40-pin DIP разъем.
2. Встроенный +5V регулятор.
3. Разъем RS-232 и дополнительное оборудование, предназначенное для прямого подключения к разъему RS-232.
4. Разъем для подключения ICD-отладчика.
5. Вход для аналоговых устройств.
6. Три кнопки для внешних воздействий и сброс.
7. Зеленый индикатор включения LED.
8. Четыре зелёных LED, подключенных к PORTB.
9. Переключатель J6 для отключения LED от PORTB.
10. Кварцевый генератор с частотой 4 МГц.
11. Разъемы, предназначенные для подключения генератора.
12. Генератор с частотой 32,768 КГц для использованием Timer1.
13. Переключатель J7 для отключения встроенного RC генератора.
14. 32К х 8 серийный EEPROM.
15. LCD дисплей.
16. Piezo buzzer.
17. Пространство для подключения дополнительного оборудования.
18. Термодатчик TC74.
Для реализации данного проекта был выбран микроконтроллер PIC18F4520.
PIC18F4520 — это высокоскоростной RISC микроконтроллер соответствую требования, предъявляемым к элементной базе [8].
1. Оптимизированная архитектура и система команд для написания программ на языке С.
2. Тактовая частота 4 МГц.
3. Линейное адресное пространство памяти программ 32 кбайт, 16384 команд.
4. Линейное адресное пространство памяти данных 1536 байт.
5. Память EEPROM (память данных) 256 байт.
6. Быстродействие до 10MIPS.
7. 16-разрядные команды, 8-разрядные данные.
8. Система приоритетов прерывания, 17 возможных источников прерывания.
9. 75 команд микроконтроллера.
10. Пять портов ввода/вывода (PORT A, B, C, D, E).
11. Аппаратное умножение 8х8 за один машинный цикл.
12. Возможность самопрограммирования.
13. Сброс по включению питания (POR), таймер включения питания (PWRT), таймер запуска генератора (OST).
14. Поддержка последовательного интерфейса адресуемого синхронно-асинхронного приемопередатчика (USART).
15. Наличие встроенного термодатчика.
16. 4 модуля счетчика/таймера TMR0, TMR1, TMR2, TMR3 разрядности 8 и 16 бит.
17. Вторичный генератор синхросигнала на основе TMR1/ TMR3.
18. Программируемая защита кода программы.
19. Внутрисхемная отладка по двухпроводной линии (ICD).
20. 100 000 циклов стирания/запись памяти программ.
21. Широкий диапазон напряжений питания (от 2,0 В до 5,5 В).
22. Наличие 5кОм потенциометра
23. Наличие Piezo buzzer
Рисунок 2.1 — PICDEM 2 PLUS Demo Board
2.2 Алгоритм и варианты реализации
Для программирования микроконтроллера PIC18F4520 можно использовать языки программирования С и ассемблер.
Для реализации устройство измерения температуры окружающей среды выбран язык программирования ассемблер [7,8,9].
Алгоритм работы данного устройства представлен на рисунке 2.2.
Рисунок 2.2 — Алгоритм устройства
3 Эскизный проект
Эскизный проект — этап составления спецификаций отдельных блоков, разработка подробной функционально-блочной схемы устройства [5,6].
Первым исполняемым блоком, в связи с разработкой на языке С, будет main, который должен вызвать процедуру инициализации устройства и блок основного меню.
Блок инициализации выполняет функции инициализации LCD, USART универсальный синхронно-асинхронный приёмо-передатчик, CCP — модуля широтно-импульсной модуляции, таймера и кнопок управления, после чего возвращает управление в main.
Блок основного меню выполняется сразу после блока инициализации и выполняется в бесконечном цикле, что позволяет неоднократно переходить от одного реализованного устройства к другому. Блок основного меню позволяет перейти к блокам реализации вольтметра (рис 3.1), звуко-излучателя (рис 3.2), термометра (рис 3.3) и часов (рис 3.4). Каждый из блоков реализации по команде оператора возвращает управление блоку основного меню.
Рисунок 3.1 — Вывод на LCD блока основного меню, точка входа в блок реализации вольтметра
Рисунок 3.2 — Вывод на LCD блока основного меню, точка входа в блок реализации звуко-излучателя
Рисунок 3.3 — Вывод на LCD блока основного меню, точка входа в блок реализации термометра
Рисунок 3.4 — Вывод на LCD блока основного меню, точка входа в блок реализации часов
Блок реализации вольтметра осуществляет взаимодействие USART , универсального синхронно-асинхронный приёмо-передатчика, и термодатчика TC74. Выводит считанную с термодатчика информацию на LCD(рис 3.5).
Рисунок 3.5 — Вывод на LCD блока реализации вольтметра
Блок реализации звуко-излучателя позволяет излучать звуки с различной частотой и длительностью импульсов при помощи широтно-импульсного модулятора. Текущие значения, длительности импульсов и частоты их возникновения, которые пользователь может менять непосредственно во время выполнения данного блока, выводятся на LCD (рис. 3.6).
Рисунок 3.6 — Вывод на LCD блока реализации звуко-излучателя
Блок реализации термометра осуществляет взаимодействия модуля SSP, синхронного последовательного порта, и термодатчика TC 74. Текущее значение температуры полученное в результате работы блока выводится на LCD (рис. 3.7).
Рисунок 3.7 — Вывод на LCD блока реализации термометра
Блок реализации часов отображает текущее время на LCD (рис. 3.7) и позволяет вызвать блок установки текущего времени. В момент вызова блока часов из основного меню текущее время устанавливается в ноль. При возвращении из блока установки часов блок реализации часов продолжает увеличивать время, которое выставили.
Рисунок 3.8 — Вывод на LCD блока реализации часов
Блок установки часов позволяет установить текущее значение минут (рис. 3.9), часов (рис. 3.10) и вернуться в блок реализации часов (рис. 3.11).
Рисунок 3.9 — Вывод на LCD блока установки часов, установка текущего значения минут
Рисунок 3.10 — Вывод на LCD блока установки часов, установка текущего значения часов
Рисунок 3.11 — Вывод на LCD блока установки часов, предложение оператору вернуться в блок реализации часов
Рассмотрим схему взаимодействия отдельных блоков устройства (рис. 3.12).
Рисунок 3.12 — Структурная схема микроконтроллера PIC18F4520
Описание основных модулей микроконтроллера
3.1.1 Интерфейс I2C
I2C — это двухпроводной последовательный интерфейс, разработанный компанией Philips. К данной шине могут быть подключены устройства с различными скоростями доступа, если скорость передачи данных будет удовлетворять требованиям самого низкоскоростного устройства.
Протокол передачи данных по шине I2C разработан таким образом, чтобы гарантировать надежный качественный прием/передачу данных. При передаче данных одно устройство является «Ведущим», которое инициирует передачу данных и формирует сигналы синхронизации. Другое устройство «Ведомое», которое может начать передачу данных только по команде ведущего шины.
Модуль MSSP аппаратно поддерживает режим ведущего/ведомого I2C, адрес общего вызова и скорость обмена данными до 1 Мбит/с. Каждое устройство на шине I2C имеет уникальный адрес. Когда ведущий инициирует передачу данных, то сначала передается адрес устройства, к которому выполняется обращение. Остальные устройства проверяют адрес, переданный ведущим.
В состав байта адреса входит бит направления передачи данных (выполняется чтение из ведомого или запись) [10].
3.1.2 Аналого-цифровой преобразователь
Модуль аналого-цифрового преобразования (АЦП) имеет до восьми входных сигналов. Входной аналоговый сигнал через коммутатор каналов заряжает внутренний конденсатор АЦП Сhold.
Модуль АЦП преобразует напряжение, удерживаемое на конденсаторе Сhold, в соответствующий 8-разрядный цифровой код методом последовательного приближения. Источник опорного напряжения может быть программно выбран с вывода VDD или VREF. Допускается работа АЦП в SLEEP режиме микроконтроллера, при этом в качестве источника должен быть выбран RC генератор.
Для управления АЦП используется 3 регистра:
- регистр результата ADRES;
- регистр управления ADCON0;
- регистр управления ADCON1;
- регистр управления ADCON2.
регистр ADCON0 используются для настройки работы модуля АЦП, а с помощью регистра ADCON1 устанавливается, какие входы микроконтроллера будут использоваться модулем АЦП и в каком режиме (аналоговый вход или цифровой порт ввода/вывода) [10].
3.1.3 LCD — экран
Модуль LCD формирует все необходимые сигналы синхронизации для управления статическими ЖКИ с поддержкой до 32 сегмента, 4 общих выводов и управление пикселями ЖКИ.
Для управления модулем LCD используется три регистра (LCDCON, LCDSE и LCDPS), с помощью которых можно настроить параметры рабочего модуля, и до 16 регистров данных, в которых сохраняется массив данных пикселей.
Источником тактового сигнала для модуля LCD в режиме SLEEP или при низкой тактовой частоте микроконтроллера является внутренний RC генератор с номинальной частотой 14кГц [10].
3.1.4 Порты ввода/вывода
Все пины микроконтроллера сгруппированы. Эти группы пинов и называются портами ввода/вывода. В микроконтроллерах PIC принято, что порты перечисляются с помощью букв латинского алфавита. Например: PORTA, PORTB…, PORTE. В порт может быть сгруппировано различное количество пинов. Их количество в портах зависит от типа микроконтроллера. Также, большая часть пинов микроконтроллеров имеет альтернативные функции (стандартным считается, что пин используется либо, как дискретный вход, либо, как дискретный выход). Порты микроконтроллеров серии PIC18 управляются с использованием 3-х регистров: PORTx, TRISx, LATx. Где x — буква порта ввода/вывода. Регистр PORTx используется обычно для чтения входных дискретных сигналов. Чтобы записать бит в порт, сначала микроконтроллер читает весь порт, потом в прочитанном значении модифицирует бит, а потом обратно, весь порт записывает. Данный механизм может сыграть «плохую шутку». Если у Вас на каком — либо из битов порта висит большая токопотребляющая нагрузка, то есть вероятность прочитать ноль по этому биту, хотя Вы записали ранее на выход бита единицу. Тем самым после модификации, обратно может записаться в тот бит ноль. А в программе Вы будете считать, что на выходе у Вас единица. Чтобы избежать этого, добавлен регистр LATx. Запись в него не вызывает чтение физических уровней порта. Т.е. чтобы изменить значения на выводах порта, необходимо использовать регистр LATx. Регистр TRISx задает направление пинов порта. Если бит этого регистра установлен в единицу, то данный пин будет сконфигурирован, как вход. Если ноль — как выход.
3.1.5 Адресуемый универсальный синхронно-асинхронный приёмопередатчик (USART)
USART — это один из модулей последовательного порта ввода/вывода, который может работать в полнодуплексном режиме для связи с микросхемами ЦАП, АЦП, последовательными EEPROM и т.д.
USART может работать в одном из трёх режимов:
— Асинхронный, полный дуплекс;
— Ведомый синхронный, полудуплекс;
— Ведущий синхронный, полудуплекс.
Для работы модуля USART предусмотрено два регистра:
— TXSTA — регистр управления и статуса передатчика USART;
— RCSTA — регистр управления и статуса приёмник USART.
Регистр SPBRG влияет на скорость обмена в бодах.
4 Технический проект
На данном этапе происходит описание и моделирование функций языка программирования, выбор организации проекта и принципов построения моделей и т.д.
Выполняются следующие работы:
- составление и описание блоков на языке программирования;
- определяются межблоковые связи;
- описание констант и переменных;
- отладка проекта (пошаговое тестирование основных блоков программы в процессе написания и исправление некорректной работы);
Далее подробно описаны все вышеперечисленные этапы [3].
4.1 Построение проекта
Осуществив, все выше изложенные этапы проектирования и проанализировав эскизный проект, мы переходим к следующей стадии проектирования — технический проект, а именно к описанию проекта для ввода в микроконтроллер PIC18F4520.
При описании моделей на языках программирования большое внимание следует уделять конструкциям языка [4]. Так нужно использовать конструкции, которые воспринимаются программой программирования микроконтроллера, а также оптимизировать конструкции для достижения наименьших аппаратных затрат. Данный процесс очень трудоемкий и требует совершенного знания языка и программы проводящей программирования микроконтроллера.
Рисунок 4.1 — Связи файлов в проекте
4.2 Описание интерфейса
Принципы построения модели включает методологию написания языкового кода. Спецификация составляется на всю программу, состоящую из основных блоков в соответствие со следующими этапами.
Необходимо выполнить анализ требуемых входных параметров и констант, а также определить их тип и начальные значения.
Начальные значения выбираются в соответствие с описанием устройства. Тип параметров — char целочисленный тип. При этом по умолчанию используется модификатор типа unsigned, который указывает, что переменная принимает неотрицательные значения.
При этом самый левый бит области памяти, выделяемой для хранения значения, используется так же, как и все остальные биты области памяти — для представления значения [7].
Таблица 4.1 Описание интерфейса всей программы
Входы |
Начальные значения |
Тип |
Описание |
|
ptr_pos |
— |
unsigned char |
Переменная для указания строки из массива стандартных строк |
|
cmd_byte |
0x01 |
unsigned int |
Переменная для организации взаимодействия SSP и TC74 |
|
temperature |
— |
unsigned int |
Переменная для хранения значения текущей температуры |
|
seconds, minutes, hours |
— |
unsigned int |
Переменные для хранения значения текущего времени, соответственно секунд, минут и часов |
4.3 Основные конструкции и процедуры, используемые для написания программы
При разработке проекта необходимо подключить заголовочные файлы:
1. #include <p18f4520.h> — стандартный заголовочный файл с объявлением специальных регистров и битов микроконтроллера PIC18F4520;
2. #include <delay.h> — позволяет организовать задержки;
3. #include <stdlib.h> — позволяет использовать функции преобразующие целочисленные значения в символы, которые можно вывести на LCD;
4. p18lcd.asm — набор стандартных функций для работы с LCD.
Примеры наиболее значащих для проекта функций приведены в таблице 4.2.
Таблица 4.2 Описание основных функций программы.
Имя функции |
Описание |
|
main |
Точка входа в программу |
|
start |
Вызывается первой, при входе в функцию main(). Выполняет настройку системы для дальнейшей работы. В частности, выполняет инициализацию экрана и интерфейса передачи данных |
|
d_write |
Производит автоматический вывод на экран содержимого глобальной переменной temp_wr |
|
LCDInit |
Выполняет настройку и разрешает доступ к LCD |
|
LCDLine_1, LCDLine_2 |
Выполняет переход виртуального курсора на первую (вторую) строку экрана |
|
stan_char_1, stan_char_2 |
Отображают на экране последовательность символов в зависимости от значения ptr_pos на соответственно 1ю и 2ю строках LCD |
|
itoa |
Преобразовывает целочисленные значения в символы, которые можно вывести на LCD |
Разберем подробней наиболее важные функции.
void stan_char_1(void);
void stan_char_2(void);
start (). Функция выполняет настройку необходимых для нормальной работы устройства модулей микроконтроллера. К таковым можно отнести модуль LCD-экрана,MSSP,USART и CCP.
Функция LCDInit() описана в файле p18LCD.ASM.
void start (void)
LCDInit();
TXSTA=0b10100100; //initialize USART
SPBRG=25;
RCSTA=0b10010000;
TRISCbits.TRISC2=0; // initialize CCP
PR2=0x80;
CCPR1L=0x80;
CCP1CONbits.CCP1X=0;
CCP1CONbits.CCP1Y=0;
T2CON=0x05;
//initialize timer2
TRISAbits.TRISA4=1; //knopki S1 I S2 aktivni
TRISBbits.TRISB0=1;
itoa(). Функция преобразует, полученную в качестве параметра переменную типа int в переменную типа *char и помещает её в массив char который обрабатывается в зависимости от входного значения int. Это стандартная функция, для обращения к ней подключаем библиотеку stdlib.h.
menu(). Функция организует в бесконечном цикле вывод на LCD меню, которое позволяет выбрать подпрограммы реализующие вольтметр, звуко-излучатель, термометр и часы.
void menu(void)
ptr_count=16;
ptr_pos=5;
stan_char_1();
ptr_pos=6;
stan_char_2();
Delay10KTCYx(900);
while (scroll==0){};
while (select==0){};
//—————— VOLT MEASUREMENT —————————-
while(1){
ptr_pos=0;
stan_char_1();
ptr_pos=4;
stan_char_2();
while (scroll==1) {if (select==0) {voltmeter();break;}} ;
while (select==0){};while (scroll==0){};
……….
voltmeter(). Функция реализует работу вольтметра измеряющего напряжение на контактах потенциометра. Задавая необходимые значения регистрам управления модуля USART, получает значения с выхода АЦП в цифровом представлении. Преобразует числовое значение температуры в строку выводим на LCD. Повторяется в цикле пока не нажата S3.
void voltmeter(void)
ADCON0bits.ADON=1;
ADCON1=0b00001110;
ADCON2=0x01;
ptr_pos=10;
stan_char_1();
ADCON0bits.GO=1;
while (ADCON0bits.GO==0){};
temph=ADRESH;
temph*=2;
itoa(temph,tempv_char);
if (temph<10) {temph_char[0]=zero[0]; temph_char[2]=zero[0]; temph_char[3]=tempv_char[0];}
LCDLine_2();
for (i=0;i<ptr_count;i++)
temp_char=temph_char[i];
temp_wr=temp_char;
d_write();
} //for i
}while(select==1);
buzzer().Функция реализует работу звуко-излучателя с помощью модуля широтно-импульсной модуляции. Нажатие S2 приводит к увеличению длительности импульса, соответственно значение хранится в CCPR1L. Нажатие S3 приводит к увеличению периода возникновения импульсов, соответственно значение хранится в PR2. Повторяется в цикле пока одновременно не нажаты S2 и S3.
void buzzer(void)
PR2=0x80;
CCPR1L=0x80;
CCP1CON=0x0f; //включение
while(1){
n=0;
if (select==0)
PR2+=1;
n=5;
temph=PR2;
if (scroll==0) goto end;
} //if select
if (scroll==0)
{//inc dc
CCPR1L+=1;
temph=CCPR1L;
n=12;
if (select==0) goto end;
if (n!=0) {
itoa(temph,tempv_char);
if (temph<10) {tempb_char[n]=zero[0]; tempb_char[n+1]=zero[0]; tempb_char[n+2]=tempv_char[0];}
LCDLine_1();
for (i=0;i<ptr_count;i++)
d_write();
} //for i
} //if n!=0
};//while
end: CCP1CON=0; //выключение}
temp(). Функция реализует работу термометра с помощью модуля SSP и термодатчика TC74. Сперва инициализируем MSSP после чего вносим последовательность изменений в управляющие регистры модуля SSP, ч то в свою очередь поток команд от MSSP к TC74 и обратно. В результате мы получаем текущее значение температуры, которое и выводим на LCD. Функция выполняется пока не нажата S3.
void temp (void)
TRISCbits.TRISC3=1; //initialize MSSP module
TRISCbits.TRISC4=1;
SSPCON1=0b00101000;
SSPSTATbits.SMP=1;
SSPADD=0x05;
do {
get_temp: cmd_byte=0x01; //config register command byte
temp_now: SSPSTATbits.CKE=1; //SMBUS spec for TC74
SSPCON2bits.SEN=1; //write to TC74
while (SSPCON2bits.SEN==1){};
SSPBUF=0b10011010; //send TC74 ADDRESS (write)
ssprw();
while (SSPCON2bits.ACKSTAT==1) {}; //ack?
WREG=cmd_byte;
SSPBUF=WREG; //send COMMAND byte (config)
ssprw();
while (SSPCON2bits.ACKSTAT==1) {}; //ack?
SSPCON2bits.RSEN=1; //send repeated start
while (SSPCON2bits.RSEN==1) {};
SSPBUF=0b10011011; //send TC74 ADDRESS (read)
ssprw();
//module idle?
while (SSPCON2bits.ACKSTAT==1) {}; //ack?
SSPCON2bits.RCEN=1; //enable receive mode
while (SSPCON2bits.RCEN==1) {};
WREG=SSPBUF; //retrieve config reg or temp reg
SSPCON2bits.ACKDT=1;
//send NOT-ACK
SSPCON2bits.ACKEN=1;
while (SSPCON2bits.ACKEN==1){};
SSPCON2bits.PEN=1; //stop
while(SSPCON2bits.PEN==1){};
tempw=WREG;
if (cmd_byte==1) { //config command OR temp command
WREG=tempw;
_asm
andlw 0x40 //is temp ready ??
sublw 0x40
_endasm
if (STATUSbits.Z==0) {goto get_temp;}
cmd_byte=0x00;
goto temp_now;
temperature=tempw;
itoa(temperature,tempv_char);
tempt_char[6]=tempv_char[0]; tempt_char[7]=tempv_char[1];
LCDLine_1();
for (i=0;i<ptr_count;i++)
{…..
d_write();
} //for i
LCDLine_2();
ptr_pos=9;
stan_char_2();
}while(select==1);
clock(). Функция реализующая работу часов с помощью таймера TMR1. Инициализируем TMR1 в режим синхронизации с внешнем генератором тактового сигнала. После генерации периферийного прерывания инкрементируется численное значение секунд. После чего текущее время выводится на LCD. Из функции происходит вызов двух подфункций:
— clock_draw() — это функция, которая выводит на экран текущее значение времени;
— clock_set() — это функция, которая позволяет установить текущее время.
void clock (void)
T1CON=0x0F;
seconds=0;minutes=0;hours=0;
do {
PIR1bits.TMR1IF=0;
TMR1H=0x68;
TMR1L=0x00;
seconds++;
if (seconds-60==0) {minutes++;seconds=0; }
if (minutes-60==0){hours++;minutes=0;}
if (hours-13==0){ hours=0;}
if (scroll==0) clock_set();
clock_draw();
LCDLine_2();
ptr_pos=7;
stan_char_2();
while (PIR1bits.TMR1IF==0){if (scroll==0) clock_set();};
} while (select==1);
5 Рабочий проект
Рабочий проект включает в себя программирование устройства и физическое тестирование.
5.1 Реализация и программирование
Разработка программного кода, его компиляция и процесс отладки проекта был выполнен в программном продукте компании Microchip, MPLAB IDE. Эта среда разработки предоставляет единую среду для разработки кода, отладки и прошивки для всех типов микроконтроллеров фирмы Microchip. Она позволяет использовать в одном проекте как код, написанный на языке низко уровня (ассемблер), так и код, написанный на языке высокого уровня (С). Это позволяет разработчику добиться желаемого соотношения между скорость работы программы и легкость ее разработки [9,12].
При запуске Mplab появиться 2 внутренних окна: Untitled Workspace и Output. В окне Workspace отображаются все файлы, прикрепленные в проект. А в окне Output выводится вся выходная информация Mplab: ошибки, результаты компиляции, результаты программирования микроконтроллера, результаты поиска в проекте и т.п. Для удобства, располагаем их в таком виде:
Рисунок 5.1 — Интерфейс главного окна среды Mplab
Для создания проекта воспользуемся мастером Project > Project Wizard. Переходим по кнопке «Далее». Появляется окно, в котором мы выбираем из выпадающего списка нужный нам микроконтроллер, в нашем случае: PIC18F4520. Снова нажимаем кнопку «Далее». Следующим, появится окно, в котором мы выбираем язык программирования, на котором будем писать программу к нашему микроконтроллеру. Окно выглядит следующим образом:
Рисунок 5.2 — Интерфейс окна помощника создания проекта
В поле «Active Toolsuite» выбирается язык программирования, на рисунке выбран язык си для микроконтроллеров PIC — Microchip C18 Toolsuit. В поле «Toolsuite Contents» показаны исполняемые модули, которые принимают участие в компиляции программы с выбранного языка. В поле «Location» указывается полный путь к выделенному исполняемому модулю. Если путь будет неверен (перед исполняемым модулем будет стоять крестик), то его нужно прописать вручную, с использованием кнопки «Browse».
Обычно, для ассемблера микроконтроллеров серии PIC18, это путь: С:\Program Files\Microchip\MPASM Suite\. Для сборщика проекта: C:\mcc18\bin\mplink.exe, для подключения библиотек: C:\mcc18\bin\mplib.exe. Так как для создания проекта выбран язык СИ, то используем, специальный компилятор MCC18, который устанавливается отдельно от среды: C:\mcc18\bin\mcc18.exe. После того, как все исполняемые модули задействованы, нажимаем кнопку «Далее».
Мы перейдем на окно, где задается имя проекта и путь к нему. Вводим любое имя (нельзя использовать русские буквы) и выбираем путь к этому проекту.
В итоге, появится окно, в котором Wizard выдаст конечную информацию о настройках и параметрах создаваемого проекта: тип микроконтроллера; путь, по которому будет лежать проект и основной язык компилятора, на котором будет писаться программа в этом проекте. Нажимаем кнопку «Готово».
В окне Workspace стал отображаться наш проект (появилось дерево файлов проекта). Если у Вас пропало окно Output, то его нужно включить через пункт меню: View > Output. А в папке появились файлы проекта *.mcw и *.mcp
Для создания файла с кодом программы запускаем пункт меню: File > New (Ctrl+N).
У нас появится новое окно в проекте — MPLAB IDE Editor.
Теперь сохраняем полученный файл.
Переходим по пункту меню: File > Save.
Появляется стандартное окно сохранения файла. Выбираем папку, пишем имя и расширение. Теперь, добавляем созданный файл в проект. Для этого, в окне проекта Workspace (теперь это окно будет называться *.mcw), находим в дереве файлов папку Source Files (файлы с исходной программой). Кликаем правой кнопкой мыши на этой папке и выбираем пункт Add Files… .Появится окно, в котором мы выбираем нашу папку и наш файл. Выбираем этот файл и нажимаем кнопку «Открыть». Мы увидим, что наш файл появился в дереве файлов проекта. Теперь сохраняем проект.
Компилируем полученную программу [12]. Переходим на пункт меню Project > Build All(Ctrl+F10). Что проект скомпилировался без ошибок, говорит окно Output. В нем будет вот такая запись: BUILD SUCCEEDED. И в нашей папке появится загрузочный файл *.hex, который зашивается в микроконтроллер программатором. Если в процессе компиляции возникли ошибки, то в этом окне они все отобразятся.
И будет вот такая запись: BUILD FAILED. Двойной клик мышкой на записи об ошибке в окне Output, автоматически указывает на строку в программе, где находится данная ошибка. После того как код был успешно скомпилирован, необходимо выполнить прошивку устройства. Для этого необходимо выбрать тип программатора. Мы использовали программатор Microchip MPLAB ICD 2.
Рисунок 5.3 — Дебаггер MPLAB-ICD2 и демо-плата PICDEM 2 Plus
Для этого, чтобы указать этот тип программатора необходимо выбрать пункт меню Programmer -> Select Programmer -> MPLAB ICD 2. После это в окне программы MPLAB ICD 2 будет отображен ход подключения программатора. Если программатор подключен к компьютеру (для коммуникации используется интерфейс USB), включено питание на плате и выбраны правильные настройки, то появиться сообщение об успешном подключении программатора.
После этого станут активными кнопки управления программатором (Запрограммировать устройство, Проверить состояние устройства и другие). Теперь необходимо нажать кнопку «Запрограммировать устройство». Если код не содержит ошибок, то появиться сообщение об успешной прошивке устройства. Нажав кнопку «Снять со сброса», мы начинаем непосредственное выполнение программы на реальном устройстве.
5.2 Физическое тестирование
После выполнения всех вышеописанных действий, необходимо проверить соответствие полученного результата поставленной задаче[1,2].
В первую очередь проверим работоспособность алгоритмы работы с АЦП и LCD дисплеем. На экране периодически отображаются данные, считанные с АЦП:
Рисунок 5.4 — Результаты работы устройства
Полученные данные соответствует поставленной задаче, периодически отображать результаты измерений напряжения на контактах потенциометра.
Для проверки работоспособности вольтметра проведем эксперимент: сравним его показатели с другим устройством, предназначенным для измерения напряжения. Тест показал соответствие напряжения, показанной тестером и данными с АЦП микроконтроллера. Также проверим работоспособность АЦП и потенциометра изменив положение потенциометра, последствия наших действий сразу отображаются на LCD.
Граничные значения от 0В до 5В.
Для проверки звуко-излучателя достаточно запустить его из меню, сразу излучается звук. Если нажимать кнопки управления то звук меняет тональность. Аппарат работает адекватно т.к. в момент когда длительность импульсов становится равной или больше длительности задержки между импульсами звук исчезает.
Для проверки работоспособности термометра проведем два эксперимента: сравним его показатели с другим устройством, предназначенным для измерения температуры, и изменим температуру окружающей среды. Первый тест показал соответствие температуры, показанной ртутным термометром и датчиками микроконтроллера. После этого было произведено термическое воздействие (нагревание) на датчик. Через небольшой промежуток времени показатели этого датчика возросли, а после прекращения воздействий вернулись на прежние показатели, что подтверждает работоспособность термодатчика.
Для проверки работоспособности часов необходимо оставить их включёнными на довольно длительный период, после чего сравнить результаты обычных часов и часов реализованных на PICDEM 2. Проведённый эксперимент показал что за 10 часов часы сбились на 1 секунду. Что есть приемлемым результатом.
Выводы
В результате выполнения комплексного курсового проекта был описан процесс создания и программно реализованы устройства измерения напряжения, температуры, генерирования звуков и реализация часов на микроконтроллере PIC.
Полученные результаты показывают, что программа работоспособна и готова к использованию на микроконтроллере PIC18F4520.
Также к недостатком устройства можно отнести то, что само устройство работает при наличии постоянного питания. Это значительно ограничивает область применения усройства.
Данный курсовой проект можно разрабатывать дальше, реализовав передачу информации в компьютер по последовательному интерфейсу RS-232. При этом необходимо будет использовать дополнительное программное обеспечение и это значительно усложнит весь проект.
ПЕРЕЧЕНЬ ССЫЛОК
1. Методические указания к лабораторным работам по курсу Микроконтроллеры во встроенных системах управления для студентов всех специальностей / Составители Аврунин О.Г., Крук О.Я., Семенец В.В. — ХНУРЭ, 2005. — 105 с.
2. В. А. Гулиус, В. Г. Лобода, В. П. Степанов, В. Ю. Цуканов. “Средства автоматизированного проектирования специализированных микропроцессорных устройств”: Учебное пособие — Харьков: ХНУРЭ, 2001. 228 с.
3. Белова Н. В., Коряк С. Ф., Лобода В. Г.. “Основы построения ориентированных ЭВМ и систем”. Под общ. ред. В. Г. Лободы. — Харьков: ООО «Компания СМИТ», 2007. — 148 с.
4. Проектирование встроенных устройств на микропроцессорах: Учеб. пособие /В. Г. Лобода, В. В. Логвин, В. Б. Таранов. — К.: УМК ВО, 1988. — 128 с.
5. Методические указания к комплексному курсовому проекту Составители: В.Г. Лобода, А.С. Шкиль, Л.К. Штец.- Харков, ХНУРЭ,2001. — 8с.
6. Документация на демонстрационную плату PICDEM 2 Plus Users Guide 51275c.pdf
7. Руководство пользователя MPASM & MPLINK 33014g
8. MPASM Quick Reference Guide 30400f
9. Руководство пользователя MPASM
10. Документация на семейство микроконтроллеров PIC18FXX2 manual
11. Руководство пользователя PICDEM 2 Plus Demonstration Board
12. Руководство пользователя MPLAB C18
13. Библиотеки MPLAB C18
Приложение А
Программа реализации устройств
p18main.c
#include <p18f4520.h>
#include <delays.h>
#include <stdlib.h>
#pragma config OSC = HS //oscillator
#pragma config FCMEN = OFF //Fail Safe Clock Monitor
#pragma config IESO = OFF //Internal External Osc. Switch Over
#pragma config PWRT = ON //Power Up Timer
#pragma config BOREN = OFF //Brown Out Reset
#pragma config WDT = OFF //Watchdog Postscaler
#pragma config MCLRE = ON //Vhod sbrosa mikrokontrollera
#pragma config PBADEN = OFF //Port B A/D digital on Reset
#pragma config LVP = OFF /Lov Voltage ICSP
#pragma config XINST = OFF //xinst
#define scroll_dir TRISAbits.TRISA4
#define scroll PORTAbits.RA4
#define select_dir TRISBbits.TRISB0
#define select PORTBbits.RB0
extern near void LCDInit(void);
extern unsigned temp_wr;
extern near void d_write(void);
extern near void i_write(void);
extern near void LCDLine_1(void);
extern near void LCDLine_2(void);
extern unsigned char WREG;
unsigned char ptr_pos;
unsigned char ptr_count;
unsigned char cmd_byte;
unsigned char temperature;
unsigned char seconds ;
unsigned char minutes ;
unsigned char hours ;
int temph;
char tempv_char[3],temph_char[16]={«0.00V RB0=Exit «},
tempb_char[16]={«Prd.=128 DC=128 «},tempt_char[16]={«Temp= C «},
tempc_char[16]={» 00:00:00 «};
char zero[1]={«0»};
rom const char stan_table[15][16]={
» Voltmeter «, //;0
» Buzzer «, //;1
» Temperature «, //;2
» Clock «, //;3
«RA4=Next RB0=Now», //;4
» Dimasya «, //;5
» tut koviryal «, //;6
«RA4=Set RB0=Menu», //;7
«RBO=Prd+ RA4=DC+»,//;8
» RB0 = Exit «, //;9
» Volts = «, //;10
«Prd.=128 DC=128 «,//;11
«Minutes RB0=++»,//12
«Hours RB0=++»,//13
«again? RB0=Exit»};//14
//functions define
void ssprw (void);
void start (void);
void main (void);
void menu(void);
void voltmeter(void);
void buzzer(void);
void temp(void);
void clock(void);
void clock_set(void);
void clock_draw(void);
void stan_char_1(void);
void stan_char_2(void);
//functions work
void ssprw (void)
do {
_asm movlw 0x00 _endasm
WREG=WREG&&SSPCON2;
_asm sublw 0x00 _endasm
} while (STATUSbits.Z==0);
while (SSPSTATbits.R_W==1) {};
void start (void)
LCDInit();
TXSTA=0b10100100; //initialize USART
SPBRG=25;
RCSTA=0b10010000;
TRISCbits.TRISC2=0; //CCP
PR2=0x80;
CCPR1L=0x80;
CCP1CONbits.CCP1X=0;
CCP1CONbits.CCP1Y=0;
T2CON=0x05;
TRISAbits.TRISA4=1;
TRISBbits.TRISB0=1;
void main(void)
temp_wr=0;
ptr_count=16;
start();
menu();
void menu(void)
ptr_count=16;
ptr_pos=5;
stan_char_1();
ptr_pos=6;
stan_char_2();
Delay10KTCYx(900);
while (scroll==0){};
while (select==0){};
//—————— VOLT MEASUREMENT —————————-
while(1){
ptr_pos=0;
stan_char_1();
ptr_pos=4;
stan_char_2();
while (scroll==1) {if (select==0) {voltmeter();break;}} ;
while (select==0){};while (scroll==0){};
//—————— BUZZER —————————————
while (select==0){};
ptr_pos=1;
stan_char_1();
ptr_pos=4;
stan_char_2();
while (scroll==1) {if (select==0) {buzzer();break;} } ;
while (select==0){};while (scroll==0){};
//—————— TEMPERATURE MEASUREMENT ———————-
while (select==0){};
ptr_pos=2;
stan_char_1();
ptr_pos=4;
stan_char_2();
while (scroll==1) {if (select==0) {temp();break;} };
while (select==0){};while (scroll==0){};
//—————— CLOCK TIME ———————————-
while (select==0){};
ptr_pos=3;
stan_char_1();
ptr_pos=4;
stan_char_2();
while (scroll==1) {if (select==0) {clock();break;}};
while (select==0){};while (scroll==0){};
//************* STANDARD USER CODE **********************************
//————- Voltmeter———————————————
void voltmeter(void)
int i;
char temp_char;
while(select==0){};
ADCON0bits.ADON=1;
ADCON1=0b00001110;
ADCON2=0x01;
ptr_pos=10;
stan_char_1();
ADCON0bits.GO=1;
while (ADCON0bits.GO==0){};
temph=ADRESH;
temph*=2;
itoa(temph,tempv_char);
if (temph<10)
{temph_char[0]=zero[0];temph_char[2]=zero[0];temph_char[3]=tempv_char[0];}
else if (temph<100)
{temph_char[0]=zero[0];temph_char[2]=tempv_char[0];temph_char[3]=tempv_char[1];} //10<=x<100
else {temph_char[0]=tempv_char[0];temph_char[2]=tempv_char[1];temph_char[3]=tempv_char[2];} //10<=x<100
LCDLine_2();
for (i=0;i<ptr_count;i++)
temp_char=temph_char[i];
temp_wr=temp_char;
d_write();
} //for i
}while(select==1);
//——————— BUZZER —————————————
void buzzer(void)
char temp_char;
int n,i;
while(select==0){};
PR2=0x80;
CCPR1L=0x80;
LCDLine_1();
ptr_pos=11;
stan_char_1();
LCDLine_2();
ptr_pos=8;
stan_char_2();
CCP1CON=0x0f;
while(1){
n=0;
if (select==0)
PR2+=1;
n=5;
temph=PR2;
if (scroll==0)
goto end;
} //if select
if (scroll==0)
{//inc dc
CCPR1L+=1;
temph=CCPR1L;
n=12;
if (select==0)
goto end;
if (n!=0) {
itoa(temph,tempv_char);
if (temph<10)
{tempb_char[n]=zero[0];tempb_char[n+1]=zero[0];tempb_char[n+2]=tempv
_char[0];}
else if (temph<100)
{tempb_char[n]=zero[0];tempb_char[n+1]=tempv_char[0];tempb_char[n+2]=tempv_char[1];} //10<=x<100
Else
{tempb_char[n]=tempv_char[0];tempb_char[n+1]=tempv_char[1];tempb_char[n+2]=tempv_char[2];} //10<=x<100
LCDLine_1();
for (i=0;i<ptr_count;i++)
temp_char=tempb_char[i];
temp_wr=temp_char;
d_write();
} //for i
} //if n!=0
};//while
end: CCP1CON=0;
//———————- Temperature ———————————
void temp (void)
char tempw,temp_char;
int i;
while (select==0){};
TRISCbits.TRISC3=1; //initialize MSSP module
TRISCbits.TRISC4=1;
SSPCON1=0b00101000;
SSPSTATbits.SMP=1;
SSPADD=0x05;
PIR1bits.TMR1IF=0; //load Timer1 for 2 sec overflow
TMR1H=0;
TMR1L=0;
do {
//GET_TEMP
get_temp: cmd_byte=0x01; //config register command byte
//TEMP_NOW
temp_now: SSPSTATbits.CKE=1; //SMBUS spec for TC74
SSPCON2bits.SEN=1; //write to TC74
while (SSPCON2bits.SEN==1){};
SSPBUF=0b10011010; //send TC74 ADDRESS (write)
ssprw();
while (SSPCON2bits.ACKSTAT==1) {}; //ack?
WREG=cmd_byte;
SSPBUF=WREG; //send COMMAND byte (config)
ssprw();
while (SSPCON2bits.ACKSTAT==1) {}; //ack?
SSPCON2bits.RSEN=1; //send repeated start
while (SSPCON2bits.RSEN==1) {};
SSPBUF=0b10011011; //send TC74 ADDRESS (read)
ssprw(); //module idle?
while (SSPCON2bits.ACKSTAT==1) {}; //ack?
SSPCON2bits.RCEN=1; //enable receive mode
while (SSPCON2bits.RCEN==1) {};
WREG=SSPBUF; //retrieve config reg or temp reg
SSPCON2bits.ACKDT=1; //send NOT-ACK
SSPCON2bits.ACKEN=1;
while (SSPCON2bits.ACKEN==1){};
SSPCON2bits.PEN=1; //stop
while(SSPCON2bits.PEN==1){};
tempw=WREG;
if (cmd_byte==1) { //config command OR temp command
WREG=tempw;
_asm
andlw 0x40 //is temp ready ??
sublw 0x40
_endasm
if (STATUSbits.Z==0) {goto get_temp;}
cmd_byte=0x00;
goto temp_now;
temperature=tempw;
itoa(temperature,tempv_char);
tempt_char[6]=tempv_char[0]; tempt_char[7]=tempv_char[1];
LCDLine_1();
for (i=0;i<ptr_count;i++)
temp_char=tempt_char[i];
temp_wr=temp_char;
d_write();
} //for i
LCDLine_2();
ptr_pos=9;
stan_char_2();
}while(select==1);
//—————— CLOCK ——————————————
void clock (void)
char temp_char;
int i,n;
while (select==0){};
T1CON=0x0F;
seconds=0;minutes=0;hours=0;
do {
PIR1bits.TMR1IF=0;
TMR1H=0x68;
TMR1L=0x00;
seconds++;
if (seconds-60==0) {
minutes++;
seconds=0;
if (minutes-60==0){
hours++;
minutes=0;
if (hours-13==0){
hours=0;
if (scroll==0) clock_set();
clock_draw();
LCDLine_2();
ptr_pos=7;
stan_char_2();
while (PIR1bits.TMR1IF==0){if (scroll==0) clock_set();};
} while (select==1);
void clock_set(void)
while (scroll==0){};
while (select==1) {
while (scroll==1) {
clock_draw();
LCDLine_2();
ptr_pos=12;
stan_char_2();
if (select==0) {minutes++;}
if (minutes-60==0){
hours++;
minutes=0;
} //if
if (hours-13==0){hours=0;}
} //while
while (scroll==0){};
while (scroll==1) {
clock_draw();
LCDLine_2();
ptr_pos=13;
stan_char_2();
if (select==0) {hours++;}
if (hours-13==0){hours=0;}
while (scroll==0){};
while (scroll==1) {
clock_draw();
LCDLine_2();
ptr_pos=14;
stan_char_2();
if (select==0)
{goto clock_set_end;}
clock_set_end: while (select==0){};
void clock_draw(void)
char temp_char;
int i,n;
temph=seconds;
n=10;
itoa(temph,tempv_char);
if (temph<10) {tempc_char[n]=zero[0];
tempc_char[n+1]=tempv_char[0];}
else {tempc_char[n]=tempv_char[0]; tempc_char[n+1]=tempv_char[1];}
temph=minutes;
n=7;
itoa(temph,tempv_char);
if (temph<10) {tempc_char[n]=zero[0];
tempc_char[n+1]=tempv_char[0];}
else {tempc_char[n]=tempv_char[0]; tempc_char[n+1]=tempv_char[1];}
temph=hours;
n=4;
itoa(temph,tempv_char);
if (temph<10) {tempc_char[n]=zero[0];
tempc_char[n+1]=tempv_char[0];}
else {tempc_char[n]=tempv_char[0]; tempc_char[n+1]=tempv_char[1];}
LCDLine_1();
for (i=0;i<ptr_count;i++)
temp_char=tempc_char[i];
temp_wr=temp_char;
d_write();
} //for i
void stan_char_1(void)
int i;
char temp_char;
LCDLine_1();
for (i=0;i<ptr_count;i++)
temp_char=stan_table[ptr_pos][i];
temp_wr=temp_char;
d_write();
void stan_char_2(void)
int i;
char temp_char;
LCDLine_2();
for (i=0;i<ptr_count;i++)
temp_char=stan_table[ptr_pos][i];
temp_wr=temp_char;
d_write();
p18lcd.asm
********************************************************************
;* Microchip Technology Inc. 2002 *
;* Revised on 5/6/03 — Removed Linker file declaration *
;* Assembler version: 2.0000 *
;* Filename: *
;* p18lcd.asm *
;********************************************************************
list p=18f442
#include p18f442.inc
#define LCD_D4 PORTD, 0; LCD data bits
#define LCD_D5 PORTD, 1
#define LCD_D6 PORTD, 2
#define LCD_D7 PORTD, 3
#define LCD_D4_DIR TRISD, 0 ; LCD data bits
#define LCD_D5_DIR TRISD, 1
#define LCD_D6_DIR TRISD, 2
#define LCD_D7_DIR TRISD, 3
#define LCD_E PORTA, 1; LCD E clock
#define LCD_RW PORTA, 2; LCD read/write line
#define LCD_RS PORTA, 3; LCD register select line
#define LCD_E_DIR TRISA, 1
#define LCD_RW_DIR TRISA, 2
#define LCD_RS_DIR TRISA, 3
#define LCD_INS 0
#define LCD_DATA 1
D_LCD_DATA UDATA
COUNTER res 1
delay res 1
temp_wr res 1
temp_rd res 1
GLOBAL temp_wr
PROG1 CODE
LCDLine_1
movlw 0x80
movwf temp_wr
rcall i_write
return
GLOBAL LCDLine_1
LCDLine_2
movlw 0xC0
movwf temp_wr
rcall i_write
return
GLOBAL LCDLine_2
;write data
d_write;
movff temp_wr,TXREG;
btfss TXSTA,TRMT;
goto $-2
rcall LCDBusy
bsf STATUS, C
rcall LCDWrite
return
GLOBAL d_write;
write instruction
i_write
rcall LCDBusy
bcf STATUS, C
rcall LCDWrite
return
GLOBAL i_write
rlcd macro MYREGISTER
IF MYREGISTER == 1
bsf STATUS, C
rcall LCDRead
ELSE
bcf STATUS, C
rcall LCDRead
ENDIF
endm
LCDInit
clrf PORTA
bcf LCD_E_DIR;configure control lines
bcf LCD_RW_DIR
bcf LCD_RS_DIR
movlw b’00001110′
movwf ADCON1
movlw 0xff; Wait ~15ms @ 20 MHz
movwf COUNTER
lil1
movlw 0xFF
movwf delay
rcall DelayXCycles
decfsz COUNTER,F
bra lil1
movlw b’00110000′; #1 Send control sequence
movwf temp_wr
bcf STATUS,C
rcall LCDWriteNibble
movlw 0xff; Wait ~4ms @ 20 MHz
movwf COUNTER
lil2
movlw 0xFF
movwf delay
rcall DelayXCycles
decfsz COUNTER,F
bra lil2
movlw b’00110000′; #2 Send control sequence
movwf temp_wr
bcf STATUS,C
rcall LCDWriteNibble
movlw 0xFF; Wait ~100us @ 20 MHz
movwf delay
rcall DelayXCycles
movlw b’0011000′; #3 Send control sequence
movwf temp_wr
bcf STATUS,C
rcall LCDWriteNibble
;test delay
movlw 0xFF; Wait ~100us @ 20 MHz
movwf delay
rcall DelayXCycles
movlw b’00100000′; #4 set 4-bit
movwf temp_wr
bcf STATUS,C
rcall LCDWriteNibble
rcall LCDBusy; Busy?
movlw b’00101000′; #5 Function set
movwf temp_wr
rcall i_write
movlw b’00001101′; #6 Display = ON
movwf temp_wr
rcall i_write
movlw b’00000001′; #7 Display Clear
movwf temp_wr
rcall i_write
movlw b’00000110′; #8 Entry Mode
movwf temp_wr
rcall i_write
movlw b’10000000′; DDRAM addresss 0000
movwf temp_wr
rcall i_write;
movlw b’00000010′;
return home;
movwf temp_wr;
call i_write
return
GLOBAL LCDInit;
_ ______________________________;
RS _>—<______________________________;
_____;
RW \_____________________________;
__________________;
E ____________/ \___;
_____________ ______;
DB _____________>—————<______;
LCDWriteNibble
btfss STATUS, C; Set the register select
bcf LCD_RS
btfsc STATUS, C
bsf LCD_RS
bcf LCD_RW; Set write mode
bcf LCD_D4_DIR; Set data bits to outputs
bcf LCD_D5_DIR
bcf LCD_D6_DIR
bcf LCD_D7_DIR
NOP; Small delay
bsf LCD_E; Setup to clock data
btfss temp_wr, 7; Set high nibble
bcf LCD_D7
btfsc temp_wr, 7
bsf LCD_D7
btfss temp_wr, 6
bcf LCD_D6
btfsc temp_wr, 6
bsf LCD_D6
btfss temp_wr, 5
bcf LCD_D5
btfsc temp_wr, 5
bsf LCD_D5
btfss temp_wr, 4
bcf LCD_D4
btfsc temp_wr, 4
bsf LCD_D4
bcf LCD_E; Send the data
return
LCDWrite;
rcall LCDBusy
rcall LCDWriteNibble
swapf temp_wr,F
rcall LCDWriteNibble
ПРИЛОЖЕНИЕ В. Подключаемый файл с описанием функций (продолжение)
swapf temp_wr,F
return
GLOBAL LCDWrite;
_____ _____________________________________________________;
RS _____>—<_________________________________________________;
____________________________________________________;
RW _________/;
____________________ ____________________;
E ____________/ \____/ \__;
_________________ __________ ___;
DB _________________>—————<__________>—————<___;
LCDRead
bsf LCD_D4_DIR; Set data bits to inputs
bsf LCD_D5_DIR
bsf LCD_D6_DIR
bsf LCD_D7_DIR
btfss STATUS, C; Set the register select
bcf LCD_RS
btfsc STATUS, C
bsf LCD_RS
bsf LCD_RW; Read = 1
bsf LCD_E; Setup to clock data
btfss LCD_D7 ; Get high nibble
bcf temp_rd, 7
btfsc LCD_D7
bsf temp_rd, 7
btfss LCD_D6
bcf temp_rd, 6
btfsc LCD_D6
bsf temp_rd, 6
btfss LCD_D5
bcf temp_rd, 5
btfsc LCD_D5
bsf temp_rd, 5
btfss LCD_D4
bcf temp_rd, 4
btfsc LCD_D4
bsf temp_rd, 4
bcf LCD_E; Finished reading the data
bsf LCD_E; Setup to clock data
btfss LCD_D7; Get low nibble
bcf temp_rd, 3
btfsc LCD_D7
bsf temp_rd, 3
btfss LCD_D6
bcf temp_rd, 2
btfsc LCD_D6
bsf temp_rd, 2
btfss LCD_D5
bcf temp_rd, 1
btfsc LCD_D5
bsf temp_rd, 1
btfss LCD_D4
bcf temp_rd, 0
btfsc LCD_D4
bsf temp_rd, 0
bcf LCD_E; Finished reading the data
FinRd
return
LCDBusy;
Check BF
rlcd LCD_INS
btfsc temp_rd, 7
bra LCDBusy
return
GLOBAL LCDBusy
DelayXCycles
decfsz delay,F
bra DelayXCycles
return
Размещено на