Thermometer(ElkinAlexanderCoorse.09-V1.2012)


\s

Оглавление
TOC \o "1-3" \h \z \u
Введение. PAGEREF _Toc327479578 \h 31 Выбор и обоснование основных технических решений. PAGEREF _Toc327479579 \h 31.1 Техническое задание PAGEREF _Toc327479580 \h 31.1 Источники информации PAGEREF _Toc327479581 \h 31.2 Приемники информации PAGEREF _Toc327479582 \h 31.2 Возможные варианты решения поставленной задачи, обоснования выбора PAGEREF _Toc327479583 \h 31.2.1 Выбор способа измерения температуры PAGEREF _Toc327479584 \h 31.2.2 Выбор устройства отображения информации PAGEREF _Toc327479585 \h 51.2.3 Выбор микроконтроллера PAGEREF _Toc327479586 \h 52 Структурная схема PAGEREF _Toc327479587 \h 62.1 Описание принципа действия и общий алгоритм работы PAGEREF _Toc327479588 \h 72.2 Блок-схема работы микроконтроллера PAGEREF _Toc327479589 \h 83 Разработка функциональной и принципиальной схем устройства PAGEREF _Toc327479590 \h 93.1 Принципиальная схема устройства PAGEREF _Toc327479591 \h 93.2 Функциональная схема устройства PAGEREF _Toc327479592 \h 94Разработка алгоритмов PAGEREF _Toc327479593 \h 104.1Алгоритм инициализации датчика PAGEREF _Toc327479594 \h 104.2Алгоритм отправки байта данных датчику PAGEREF _Toc327479595 \h 114.3Алгоритм получения одного байта от датчика PAGEREF _Toc327479596 \h 124.4Структура программы PAGEREF _Toc327479597 \h 124.5Код программы PAGEREF _Toc327479598 \h 125Технология отладки программы PAGEREF _Toc327479599 \h 176Моделирование PAGEREF _Toc327479600 \h 197 Список литературы PAGEREF _Toc327479601 \h 22

Введение.Измерение, контроль и регулирование температуры является одной из неотъемлемых и важных задач в современном мире. Такая задача стоит и перед промышленностью, и перед сельским хозяйством, и в быту и даже в области высоких технологий. В разных случаях задача регулирования температуры имеет свою индивидуальную цель и метод решения.
Главное преимущество использования электронного термометра является возможность контролировать температуру на расстоянии. Если нужно контролировать температуру, например, в подвале дома, на чердаке или в любом подсобном помещении, обычный ртутный (спиртовой) или механический термометр вряд ли подойдет, т.к. будет проблематично постоянно выходить из комнаты, только чтобы взглянуть на шкалу термометра. Более пригоден в подобных случаях электронный термометр, позволяющий измерять температуру дистанционно - на расстояниях в сотни метров. Причем в контролируемом помещении будет располагаться лишь миниатюрный термочувствительный датчик, а в комнате на видном месте – ЖКИ, отображающий текущую температуру.
1 Выбор и обоснование основных технических решений.1.1 Техническое заданиеРазработать аппаратные и программные средства для реализации цифрового термометра.
Термометр должен соответствовать следующим требованиям:
сфера применения: измерение температуры воздуха (или воды при доработке защиты датчика от влажности);
диапазон измеряемой температуры: -50… +99º С;
погрешность измерений: ±0.5 º С (в диапазоне от -10 до +85 º С);
напряжение питания: 3 – 5 В;
использование доступных, энергоэкономичных, дешевых элементов для возможности последующей реализации разработанного устройства.
1.1 Источники информацииОсновным источником информации в данной конструкции является термодатчик. Он должен в зависимости от величины аналогового сигнала (температуры) формировать определенный цифровой код, который должен быть доступен для считывания микроконтроллером.
Еще один источник информации – кнопка старта/останова измерений.
1.2 Приемники информацииДля случая получения информации от термодатчика приемником информации является контроллер, который обрабатывает входные данные и периодически отправляет их на цифровой индикатор.
А для случая считывания данных с цифрового индикатора приемником информации можно считать пользователя, который получает данные температуры и обрабатывает их , принимая какие-либо решения.
1.2 Возможные варианты решения поставленной задачи, обоснования выбора1.2.1 Выбор способа измерения температурыВ ходе проектирования данного устройства было рассмотрено несколько способов измерения температуры. Первый основан на использовании терморезистора или термопары, протекающий ток которых пропорционален величине температуры. Для оцифровки данного сигнала нужен дополнительный аналогово-цифровой преобразователь. Полученный результат нужно еще масштабировать в соответствии со шкалой Цельсия. Наибольшая сложность в том, что зависимость измеренной величины от температуры могла бы получиться не прямой. Вряд ли данный способ дал хорошую точность. Еще и нужно реализовать устройство передачи данных от АЦП микроконтроллеру. Так как большая часть выходов портов занята под цифровой индикатор, то параллельный способ передачи данных возможен только при введении дополнительных адресных селекторов или при последовательной передаче данных, что значительно усложняет устройство. Еще и невозможно было бы подключать несколько датчиков к одной линии, что ограничивает возможности усовершенствования прибора.
В термометре было решено использовать датчик температуры DS18B20.
Данное устройство хорошо согласуются с микроконтроллером. Термодатчик DS1820 имеет следующие технические характеристики:
индивидуальный 64-битный идентификационный номер;
напряжение питания от +3 до +5,5 В;
измеряемая температура от -55 до +125°С;
погрешность измерения температуры в диапазоне -10...+85°С не более 0,5°С;
в остальном диапазоне температур погрешность измерения не превышает 2°С;
информация о температуре выдается 9-битным кодом;
максимальное время преобразования температуры в код 750 мс;
возможность питания от высокого уровня шины данных;
термодатчики не требуют индивидуальной настройки при замене. Термодатчик типа DS18B20 отличается от DS1820 способностью измерять температуру с четырьмя уровнями погрешности — 0,5; 0,25; 0,0625°С. При этом максимальное время измерения для каждого уровня составляет соответственно 93,75; 187,5; 375; 750 мс. Необходимая погрешность измерения может быть задана при инициализации термодатчика.
Термодатчики выпускают в двух типах корпусов: ТО-92 и SOIC.

DS18B20 обменивается данными по 1-Wire шине и при этом может быть как единственным устройством на линии так и работать в группе. Это также послужило ключевой особенностью в пользу выбора датчика, т. к. позволяет впоследствии модернизировать устройство путем добавления новых датчиков.
Другая особенность DS18B20 - способность работать без внешнего питания. Эта возможность предоставляется через подтягивающий резистор. Высокий сигнал шины заряжает внутренний конденсатор (CPP), который питает прибор, когда на шине низкий уровень. Этот метод носит название «Паразитное питание». При этом максимальная измеряемая температура составляет + 100 °C. Для расширения диапазона температур до + 125 °C необходимо использовать внешнее питание.

Основные функциональные возможности DS18B20 - его температурный преобразователь.
Чтобы начать температурное измерение и преобразование, ведущий должен подать команду начала конвертирования температуры [0х44]. После конвертирования, полученные данные запоминаются в 2-байтовом регистре температуры в оперативной памяти, и DS18B20 возвращается к неактивному состоянию. Если DS18B20 включен с внешним питанием, ведущий может контролировать конвертирование температуры (после команды [0х44]) по состоянию шины. DS18B20 будет формировать (ответ на слот времени чтения от устройства управления) логический «0» когда происходит температурное преобразование. И логическую «1», когда конвертирование выполнено. Если DS18B20 включен с паразитным питанием, эта технология уведомления не может быть использована, так как шину нужно подать высокий уровень (напряжение питания) в течение всего времени температурного преобразования. В этом случае устройство управления должно самостоятельно контролировать время конвертирования.
Выходные температурные данные DS18B20 калиброваны в градусах Цельсия. Температурные данные запоминаются как 16-битовое число со знаком (см. рис. 2). Биты признака (S) указывают, является ли температура положительная или отрицательная: для положительных S = 0, а для отрицательных чисел S = 1. Если DS18B20 будет настроен для конвертирования 12-битной разрешения, то все биты в температурном регистре будут содержать действительные данные. Для 11-битной разрешающей способности, бит 0 неопределен. Для 10-битной разрешающей способности, биты 1 и 0 неопределенны, и для 9 битной разрешающей способности 2, 1 и 0 неопределенны.
1.2.2 Выбор устройства отображения информацииБыли рассмотрены возможности использования LCD дисплея без подсветки и семисегментного индикатора. Основной плюс LCD - простой вывод информации без дополнительных преобразований кодов и небольшое энергопотребление, что позволило бы использовать в качестве источника питания устройства гальванические элементы.
Все же было решено использовать блок семисегментных индикаторов, т.к. он более доступен и имеет подсветку, что позволяет использовать устройство в темное время суток. Есть широкий выбор таких индикаторов, можно использовать практически любые. Кроме того, можно самостоятельно изготовить индикаторы из цепочек светодиодов. В стационарном режиме работы термометра это позволит сконструировать индикаторы больших размеров. При определенном навыке изготовления таких устройств можно продавать их за немалые деньги.
1.2.3 Выбор микроконтроллераВ качестве устройства управления должен быть выбран микроконтроллер, обладающий хорошими техническими характеристиками, иметь, а также иметь относительно невысокую стоимость.
Также необходимо определить количество необходимых для работы портов, которые должен иметь микроконтроллер.
Причины выбора микроконтроллера PIC16f628A
Характеристика RISC ядра
Тактовая частота от DC до 20МГц
Поддержка прерываний
8-уровневый аппаратный стек
Прямая, косвенная и относительная адресация
35 однословных команд
Все команды выполняются за один машинный цикл, кроме команд ветвления и условия с истинным результатом
Особенности микроконтроллеров
Внешний и внутренний режимы тактового генератора
Режим энергосбережения SLEEP
Программируемые подтягивающие резисторы на входах PORTB
Защита кода программы
Сброс по снижению напряжения питания BOR
Сброс по включению питания POR
Широкий диапазон напряжения питания от 2.0В до 5.5В
Промышленный и расширенный температурный диапазон
Периферия
16 каналов ввода/вывода с индивидуальными битами направления
Сильноточные схемы портов сток/исток, допускающих непосредственное подключение светодиодов.
Вывод
16 каналов ввода/вывода вполне достаточно для подключения датчика и индикаторов. Еще и остаются свободные каналы, например, для добавления новых линий датчиков и кнопок при модернизации устройства.
Кроме того, данный микроконтроллер поддерживает интерфейс работы с устройствами 1-Wire, что дает полную совместимость его с выбранным мной датчиком DS18B20. Подтягивающие выходные транзисторы микроконтроллера позволяют использовать функцию «паразитного» питания датчика.
Данный микроконтроллер имеет довольно небольшую цену, в сравнении с другими подобными.
2 Структурная схемаКлавиша Старт/Останов
Микроконтроллер
PIC16f628
Блок семисегментных индикаторов
Теродатчик DS18B20
Клавиша Старт/Останов
Микроконтроллер
PIC16f628
Блок семисегментных индикаторов
Теродатчик DS18B20

Назначение микроконтроллера PIC16f628A
Осуществляет управление всей системой, а именно: периодически опрашивает датчик, обрабатывает полученные данные, раскладывает данные в вид, удобный для вывода на семисегментные индикаторы.
Назначение термодатчика DS18B20
Термодатчик измеряет аналоговую величину температуры, преобразует ее в цифровой вид по запросу микроконтроллера, сохраняет полученное значение в своей памяти, выдает микроконтроллеру сигнал завершения температурного преобразования.
Назначение блока семисегментных индикаторов.
Отображает информацию о температуре в цифровом виде.
Назначение блока клавиши Старт/Останов
Запускает, останавливает процесс опроса датчика и вывода информации на индикаторы.
2.1 Описание принципа действия и общий алгоритм работыПосле подачи питания на устройство, микроконтроллер производит настройку портов, общее конфигурирование, например, отключение компаратора. После этого запускается основной цикл работы микроконтроллера. На этом этапе микроконтроллер дожидается нажатия клавиши «Старт/Останов» для начала измерений.
Вначале инициализируется термодатчик. Так как на линии только один датчик, отправляется команда интерфейса 1-Wire выбора всех датчиков. Затем отправляется команда начала температурного преобразования. Так как для температурного преобразования нужно определенное время, микроконтроллер ожидает от датчика сигнала завершения температурного преобразования. Для этого он в цикле опрашивает состояние порта датчика, настроенного на ввод данных.
Настройка точности преобразования не производится, т.к. для данной работы достаточно точности 0.5 градуса Цельсия.
После получения сигнала завершения температурного преобразования, датчик вновь инициализируется и считывается содержимое его памяти.
Считанные данные преобразуются в вид, удобный для вывода на индикатор, определяется знак числа. Если оно отрицательное, то происходит преобразования из дополнительного кода в прямой код.
Затем происходит вывод данных на семисегментный индикатор.
Опрашивается порт, к которому подключена клавиша управления. Если клавиша нажата, микроконтроллер переходит в цикл ожидания.
2.2 Блок-схема работы микроконтроллераНачало
Конфигурация микроконтроллера
Опрос клавиши управления
Инициализация термодатчика,
Отправка команды выбора датчика
Команда температурного преобразования
Темп. преобразование завершено?
Получения содержимого датчика, преобразование в удобный вид для вывода на индикатор
Вывод на индикатор
Начало
Конфигурация микроконтроллера
Опрос клавиши управления
Инициализация термодатчика,
Отправка команды выбора датчика
Команда температурного преобразования
Темп. преобразование завершено?
Получения содержимого датчика, преобразование в удобный вид для вывода на индикатор
Вывод на индикатор

3 Разработка функциональной и принципиальной схем устройства3.1 Принципиальная схема устройства
Данная принципиальная электрическая схема — графическое изображение с помощью условных графических и буквенно-цифровых обозначений (пиктограмм) связей между элементами проектируемого устройства.
На ней видно как между собой связанны составные элементы системы: микроконтроллер, блок семисегментных индикаторов, термодатчиков.
В отличие от разводки печатной платы эта схема не показывает взаимного (физического) расположения элементов, эта лишь указывает на то, какие элементы с какими соединяются.
3.2 Функциональная схема устройства129540-189865PIC16f628 микроконтроллер
Порт PORTA
PIC16f628 Бл. инд.
RA2 A1
RA3 A2
RA6 A3
Блок семисегментных индикаторов
Порт PORTB
PIC16f628 Бл. инд.
RB0 b
RB1 g
RB2 a
RB3 e
RB4 d
RB5 DP
RB6 c
RB7 Порт PORTA
PIC16f628 DS18B20
RA1 DQ
Датчик
Порт PORTA
PIC16f628 Клавиша
RA7 -
Клавиша Старт/Останов
00PIC16f628 микроконтроллер
Порт PORTA
PIC16f628 Бл. инд.
RA2 A1
RA3 A2
RA6 A3
Блок семисегментных индикаторов
Порт PORTB
PIC16f628 Бл. инд.
RB0 b
RB1 g
RB2 a
RB3 e
RB4 d
RB5 DP
RB6 c
RB7 Порт PORTA
PIC16f628 DS18B20
RA1 DQ
Датчик
Порт PORTA
PIC16f628 Клавиша
RA7 -
Клавиша Старт/Останов

Устройство управляется микроконтроллером PIC16f628. Для связи с семисегментным индикатором, используются выводы RA2, RA3, RA6 порта PORTA для передачи номера позиции отображаемого символа и выводы RB0-RB6 порта PORTB для включения конкретного сегмента.
Для связи с датчиком используется вывод RA1 порта PORTA.
Клавиша «Старт/Останов» подключена к порту RA7
Разработка алгоритмовАлгоритм инициализации датчикаДля инициализации устройства интерфейса 1-Wire необходимо подать на устройство единичный импульс, «провалить» шину примерно на 500 мкс, затем возобновить единичный сигнал и подождать еще 500 мкс.
Начало
Выход
Единичный импульс, «проваливаем» шину на 500 мкс, ожидание 500 мксНачало
Выход
Единичный импульс, «проваливаем» шину на 500 мкс, ожидание 500 мкс
Код процедуры инициализации датчика:
void InitSensor(void)
{
// подаем на датчик высокий уровень, затем "проваливаем" шину
TRISA = 0xFF;
PORTA = 0x00;
TRISA = 0xFD;
Delay10Microsecond(50);
// высокий уровень
TRISA = 0xFF;
Delay10Microsecond(50);
}
Алгоритм отправки байта данных датчикуКод процедуры отправки байта датчику
Для отправки единицы подается кратковременный низкий уровень, затем высокий уровень на 60 микросекунд.
Для отправки нуля подается сначала низкий уровень на 60 микросекунд, затем кратковременный высокий импульс.
91492068440Начало
Получение значения одного разряда байта (с 1-го)
1?
Короткий импульс высокого уровня, ожидание 60 мксНизкий уровень на 60 мкс, короткий импульс высокого уровня
Отправлен 8-й разряд
Выход
0Начало
Получение значения одного разряда байта (с 1-го)
1?
Короткий импульс высокого уровня, ожидание 60 мксНизкий уровень на 60 мкс, короткий импульс высокого уровня
Отправлен 8-й разряд
Выход

void WriteByte(unsigned char outputByte)
{
unsigned char i;
for (i = 0; i < 8; i++)
{
if (outputByte & 0x01)
{
// Низкий уровень на датчик
PORTA = 0x00;
TRISA = 0xFD;
// Высокий уровень на 60 микросекунд
TRISA = 0xFF;
Delay10Microsecond(6);
}
else
{
// Низкий уровень на 60 микросекунд
PORTA = 0x00;
TRISA = 0xFD;
Delay10Microsecond(6);
// Отключить выводы порта
TRISA = 0xFF;
}
outputByte = outputByte>>1; // Обработка следущего разряда
}
}
Алгоритм получения одного байта от датчикаДля получения очередного разряда от датчика подается низкий уровень на датчик, производится небольшая задержка, затем опрашивается порт. Датчик поддерживает нулевой потенциал на шине, если разряд равен нулю, на протяжении 60 мкс.
Код функции для получения байта от датчика:
char ReadByte()
{
unsigned char i;
unsigned char inputByte;
unsigned char value;
for (i = 0; i < 8; i++)
{
// Низкий уровень на датчик
PORTA=0x00;
TRISA=0xFD;
TRISA=0xFF;
// Задержка
#asm
CLRWDT
NOP
NOP
#endasm
value=PORTA;
if (value & 0x03)
{
// сдвинуть число и добавить единицу в старший разряд
inputByte = (inputByte >> 1) | 0x80;
}
else
{
inputByte = inputByte >> 1;
}
Delay10Microsecond(6);
}
return(inputByte);
}
Структура программыБлок подключения библиотек для работы с микроконтроллером
Блок макроподстановок
Блок объявлений процедур и функций работы с датчиком, других процедур
Основной цикл программы.
Блок определений процедур и функций.
Код программы#include <pic.h>
__CONFIG(0x03F78);
#define key1RA7
#define code00x03
#define code10x9F
#define code20x25
#define code30x0D
#define code40x99//4
#define code50x49
#define code60x41
#define code70x1F
#define code80x01
#define code90x09
#define codeDP0xFE
#define codeS0xFD
#define seg7_1RA2
#define seg7_2RA3
#define seg7_3RA6
// Процедура задержки
void Delay(unsigned char p);
// Процедура задержки, кратная 10 микросекундам
void Delay10Microsecond(unsigned char t);
// Процедура задержки в миллисекундах
void DelayMillisecond(unsigned char t);
// Процедура инициализации датчика DS18B20
void InitSensor(void);
// Функция получения одного байта от датчика
unsigned char ReadByte();
// Отправка одного байта датчику
void WriteByte(unsigned char outputByte);
// Процедура отображения симовола на индикаторе
void Display(char number, unsigned char position, unsigned char toh);
void main(void)
{
unsigned int counter;
unsigned char t;
unsigned char t2;
char buff[9];
char temp;
char temp_dec;
char keyStart = 0;
CMCON=0x07;//отключение компаратора
while(1)
{
// Опрос клавиши Старт-СтопTRISA = 0xFF;
if(keyStart == 0)
{
DelayMillisecond(500);
while (key1!=1);
keyStart = 1;
DelayMillisecond(400);

}
InitSensor();
WriteByte(0xCC);// Команда обращения к всем 1-Wire устройствам
WriteByte(0x44);// Команда запуска процесса температурного преобразования датчика DS18B20
while (ReadByte()==0xFF);// Ожидание завершения преобразования
InitSensor();
WriteByte(0xCC);// Команда обращения к всем 1-Wire устройствам
WriteByte(0xBE);// Команда считывания содержимого ОЗУ датчика DS18B20
for (counter = 0; counter < 9; counter++)
{
buff[counter] = ReadByte();
}
temp = buff[0]>>1;
if (buff[0] & 0x1)
{
temp_dec=5;
}
else{
temp_dec=0;
}
if(temp>80)
{
temp = 127 - temp;
if(temp_dec == 0)
{
temp += 1;
}
t = temp/10;
t2 = temp%10;
for(counter = 0; counter < 200; counter++)
{
Display(0, 1, 2);
if(temp < 10)
{
Display(t2, 2, 0);
Display(0, 2, 1);
Display(temp_dec, 3, 0);
}
else{
Display(t, 2, 0);
Display(t2, 3, 0);
}
}
}
else{
t = temp/10;
t2 = temp%10;
for(int counter = 0; counter < 200; counter++)
{
if(temp > 9)
{
Display(t,1,0);
}
Display(t2, 2, 0);
Display(0, 0, 1);
Display(temp_dec,3,0);
}
}
// Опрос клавиши Старт-СтопTRISA = 0xFF;
if(key1==1)
{
keyStart = 0;
DelayMillisecond(500);
}
}
}
// Процедура инициализации датчика DS18B20
// Датчик подключен к RA1
void InitSensor(void)
{
// подаем на датчик высокий уровень, затем "проваливаем" шину
TRISA = 0xFF;
PORTA = 0x00;
TRISA = 0xFD;
Delay10Microsecond(50);
// высокий уровень
TRISA = 0xFF;
Delay10Microsecond(50);
}
// Отправка одного байта датчику
void WriteByte(unsigned char outputByte)
{
unsigned char i;
for (i = 0; i < 8; i++)
{
if (outputByte & 0x01)
{
// Низкий уровень на датчик
PORTA = 0x00;
TRISA = 0xFD;
// Высокий уровень на 60 микросекунд
TRISA = 0xFF;
Delay10Microsecond(6);
}
else{
// Низкий уровень на 60 микросекунд
PORTA = 0x00;
TRISA = 0xFD;
Delay10Microsecond(6);
// Отключить выводы порта
TRISA = 0xFF;
}
outputByte = outputByte>>1; // Обработка следущего разряда
}
}
// Функция получения одного байта от датчика
char ReadByte()
{
unsigned char i;
unsigned char inputByte;
unsigned char value;
for (i = 0; i < 8; i++)
{
// Низкий уровень на датчик
PORTA=0x00;
TRISA=0xFD;
TRISA=0xFF;
// Задержка
#asmCLRWDT
NOP
NOP
#endasmvalue=PORTA;
if (value & 0x03)
{
// сдвинуть число и добавить единицу в старший разряд
inputByte = (inputByte >> 1) | 0x80;
}
else{
inputByte = inputByte >> 1;
}
Delay10Microsecond(6);
}
return(inputByte);
}
// Процедура задержки
void Delay(unsigned char steps)
{
unsigned char i;
for(i = 0; i < steps; i++){asm("NOP");}
}
// Процедура задержки в миллисекундах
void DelayMillisecond(unsigned char ms)
{
do{
Delay10Microsecond(100);
}
while(--ms);
}
// Процедура задержки, кратная 10 микросекундам
void Delay10Microsecond(unsigned char microsecondX10)
{
while (microsecondX10--)
{
#asmCLRWDT
NOP
NOP
#endasm}
}
void Display(char number, char position, char attribute)
{
TRISB = 0xFF;
// Порт RA2, RA3, RA6 на вывод
TRISA=0xB3;
switch(position)
{
case 1 :
seg7_1 = 1;
seg7_2 = 0;
seg7_3 = 0;
break;
case 2 :
seg7_1 = 0;
seg7_2 = 1;
seg7_3 = 0;
break;
case 3 :seg7_1 = 0;
seg7_2 = 0;
seg7_3 = 1;
break;
}
if(attribute == 2)
{
PORTB = codeS;
}
else if(attribute == 1)
{
PORTB = codeDP;
}
else{
switch(number % 10)
{
case 0 :
PORTB = code0;
break;
case 1 :
PORTB = code1;
break;
case 2 :
PORTB = code2;
break;
case 3 :
PORTB = code3;
break;
case 4 :
PORTB = code4;
break;
case 5 :
PORTB = code5;
break;
case 6 :
PORTB = code6;
break;
case 7 :
PORTB = code7;
break;
case 8 :
PORTB = code8;
break;
case 9 :
PORTB = code9;
break;
}
}
TRISB=0x00;
DelayMillisecond(1);
TRISA = 0xFF;
}
Технология отладки программыВ качестве основной среды для написания кода программы и его отладки я использовал приложение MPLAB IDE, являющимся стандартным средством разработки кода для микроконтроллеров PIC. Так как приложение имеет только встроенный компилятор ассемблерного кода, мне пришлось использовать внешний компилятор кода на языке Си.

Я использовал компилятор кода на языке Си HI-TECH C Compiler.
Для синхронизации приложения написания кода и компилятора при создании проекта в мастере проектов указал в качестве приложения компиляции HI-TECH C Compiler.

Так же в мастере была возможность выбора используемого микроконтроллера и настройки его начальной конфигурации. Например, указание частоты тактового генератора.
Ниже приведен фрагмент листинга программы, полученного на этапе компиляции
--------------------------------------------------------------------------------------------------------------
1128 ;; *************** function _ReadByte *****************
1129 ;; Defined at:
1130 ;;line 166 in file "E:\Thermometer Coorse\MPLAB IDE Project\thermometer.c"
1131 ;; Parameters: Size Location Type
1132 ;;None
1133 ;; Auto vars: Size Location Type
1134 ;; inputByte 1 3[COMMON] unsigned char
1135 ;; i 1 2[COMMON] unsigned char
1136 ;; value 1 1[COMMON] unsigned char
1137 ;; Return value: Size Location Type
1138 ;; 1 wreg unsigned char
1139 ;; Registers used:
1140 ;;wreg, status,2, status,0, pclath, cstack
1141 ;; Tracked objects:
1142 ;;On entry : 40/20
1143 ;;On exit : 60/0
1144 ;;Unchanged: FFF9F/0
1145 ;; Data sizes: COMMON BANK0 BANK1 BANK2
1146 ;; Params: 0 0 0 0
1147 ;; Locals: 3 0 0 0
1148 ;; Temps: 0 0 0 0
1149 ;; Totals: 3 0 0 0
1150 ;;Total ram usage: 3 bytes
1151 ;; Hardware stack levels used: 1
1152 ;; Hardware stack levels required when called: 1
1153 ;; This function calls:
1154 ;;_Delay10Microsecond
1155 ;; This function is called by:
1156 ;;_main
1157 ;; This function uses a non-reentrant model
1158 ;;
1159 06A4 _ReadByte:
1160
1161 ;thermometer.c: 167: unsigned char i;
1162 ;thermometer.c: 168: unsigned char inputByte;
1163 ;thermometer.c: 169: unsigned char value;
1164 ;thermometer.c: 170: for (i = 0; i < 8; i++)
1165
1166 ; Regs used in _ReadByte: [wreg+status,2+status,0+pclath+cstack]
1167 06A4 01F2 [email protected]
1168 06A5 l1250:
1169
1170 ;thermometer.c: 171: {
1171 ;thermometer.c: 173: PORTA=0x00;
1172 06A5 1283 bcf3,5;RP0=0, select bank0
1173 06A6 0185 clrf5;volatile
1174
1175 ;thermometer.c: 174: TRISA=0xFD;
1176 06A7 30FD movlw253
1177 06A8 1683 bsf3,5;RP0=1, select bank1
1178 06A9 0085 movwf5;volatile
1179
1180 ;thermometer.c: 175: TRISA=0xFF;
1181 06AA 30FF movlw255
1182 06AB 0085 movwf5;volatile
1183 06AC 0064 clrwdt;#
1184 06AD 0000 nop;#
1185 06AE 0000 nop;#
1186
1187 ;thermometer.c: 184: value=PORTA;
1188 06AF 1283 bcf3,5;RP0=0, select bank0
1189 06B0 0805 movf5,w;volatile
1190 06B1 00F1 [email protected]
1191
1192 ;thermometer.c: 185: if (value & 0x03)
1193 06B2 3903 andlw3
1194 06B3 1903 btfsc3,2
1195 06B4 2EB7 gotol372
1196
1197 ;thermometer.c: 186: {
1198 ;thermometer.c: 188: inputByte = (inputByte >> 1) | 0x80;
1199 06B5 1403 setc
1200 06B6 2EB8 gotoL17
1201 06B7 l372:
1202 ;thermometer.c: 189: }
1203
1204
1205 ;thermometer.c: 190: else
1206 ;thermometer.c: 191: {
1207 ;thermometer.c: 192: inputByte = inputByte >> 1;
1208 06B7 1003 clrc
1209 06B8 L17:
1210 06B8 0CF3 [email protected],f
1211
1212 ;thermometer.c: 193: }
1213 ;thermometer.c: 194: Delay10Microsecond(6);
1214 06B9 3006 movlw6
1215 06BA 2654 fcall_Delay10Microsecond
1216 06BB 0AF2 [email protected],f
1217 06BC 3008 movlw8
1218 06BD 0272 [email protected],w
1219 06BE 1C03 skipc
1220 06BF 2EA5 gotol1250
1221
1222 ;thermometer.c: 195: }
1223 ;thermometer.c: 196: return(inputByte);
1224 06C0 0873 [email protected],w
1225 06C1 0008 return
1226 06C2 __end_of_ReadByte:
1227
1228 psecttext172
1229 06C2 __ptext172:
1230 ;; =============== function _ReadByte ends ============
МоделированиеДля моделирования работы цифрового термометра использовалась программа Proteus 7.7 Professional.
Использовались следующие компоненты:
Вид Описание
Микроконтроллер PIC16f628A.
RA0-RA7 – выводы порта PORTA
RB0-RB7 – выводы порта PORTB
Термодатчик DS18S20
1 – заземляющий вывод
2 – вывод на шину данных
3 – вывод основного питания
Блок из четырех семисегментных индикаторов
A-G – входы соответствующих сегментов
DP – вход сегмента-точки
1-4 – вход позиции отображаемого символа
Управляющая клавиша.
При щелчке мышью по значку клавиши, контакт замыкается.
При повторном щелчке – размыкается.
Клавиша должна находиться в нормально-разомкнутом состоянии.
Для подачи управляющего сигнала нужно замкнуть контакт и сразу же разомкнуть.
Резистор 4.7 кОм. Используется для зануления порта RA7 при разомкнутой клавише управления.
Подтягивающий резистор шины данных термодатчика.
Нужен для установки на шине высокого уровня при отключении соответствующего порта (вернее, при переключении его на ввод).
Еще этот резистор позволяет датчику работать в режиме паразитного питания.
Осциллограф.
Использовался для отслеживания сигналов на шине данных термодатчика.
Для получения кодов отображаемых на индикаторе символов, я собрал следующую схему:

Последовательность разработки и отладки программного обеспечения
Создал проект в вышеописанной программе MPLAB IDE для конкретного микроконтроллера с указанием начальных параметров конфигурации, добавил в него файл с расширением «.c» - файл кода на языке Си.
Редактировать файл Си в MPLAB IDE оказалось неудобно. Открыл файл в Visual Studio, после внесения изменений и сохранении файла при переключении в MPLAB IDE он автоматически обновлял проект, предварительно запросив подтверждение:

Запускал трансляцию и компиляцию проекта. За этот этап отвечает HI-TECH C Compiler, синхронизированный с MPLAB IDE (см. пункт 6 «Технология отладки программы»).
Результаты компиляции можно посмотреть в окне «Output».

В результате компиляции получается выходной файл с расширением «.hex», находящийся в корневом каталоге проекта.
В Proteus в настройках микроконтроллера необходимо прописать путь к нему. Это требуется сделать лишь один раз. В последствии можно запускать модель на выполнение сразу же после компиляции, что существенно экономит время.

Тестировал модель и программное обеспечение путем отслеживания уровней на входах и выходах с помощью подсветки сигналов и осциллографа

Так же иногда полезно просмотреть состояние регистров и памяти выбором соответствующего пункта в контекстном меню модели микроконтроллера.

Результаты моделирования
Положительные показания прибора

Отрицательные показания

Вид осциллограммы передачи байта данных датчику

Передается байт 0xCC.
0xCC = 11001100b
«Провал» шины на 60 мс соответствует логической единице.
Кратковременный провал и поддержка высокого уровня на 60 мс – нулю.
7 Список литературы«PIC16F62X Однокристальные 8-разрядные FLASH CMOS микроконтроллеры компании Microchip Technology Incorporated» - перевод компании ООО «Микро-Чип», основанный на оригинальной документации микроконтроллера.
«Программирование на языке С для AVR и PIC микроконтроллеров» - Ю. А. Шпак.

Приложенные файлы

  • docx 661140
    Размер файла: 717 kB Загрузок: 0

Добавить комментарий