PIC и mikroPascal
Работа с DS18B20 и LED-индикатором на плате EasyPIC5.
На отладочной плате EasyPIC5, выпускаемой фирмой Mikroelektronika, предусмотрено несколько элементов отображения информации. Имеется поле отдельных светодиодов, четырехзначный семисегментный светодиодный индикатор, а также разъемы для установки символьного и графического ЖК-дисплеев. Также на плате установлено гнездо для цифрового температурного датчика DS18B20. Это позволяет конструировать различные устройства, реализующие измерение и отображение температуры.· В поставляемой вместе с платой, среде MicroPASCAL, существует· пример программы, отображающей температуру на ЖК-индикаторе. К сожалению, нет примера, выводящего температуру на LED индикаторе. Ниже приведен такой пример, являющийся компиляцией программ отображения на светодиодном индикаторе и измерения температуры.
Используемые элементы EasyPIC5
Для работы данной программы были использованы следующие элементы:
- микроконтроллер PIC16F887.
- датчик температуры DS18B20, подключенный с помощью перемычки к PORTE микроконтроллера.
- кварцевый резонатор на 20МГц. Применение кристалла повышенной частоты потребовалось для нейтрализации эффекта мерцания индикатора во время обращения к термометру. В случае программирования на ассемблере, без мерцания можно работать и на более низких частотах, но особенности результата компилирования требуют использования максимально возможной тактовой частоты.
Приведенный ниже код, написанный на языке MicroPASCAL, может быть использован в качестве программы термометра для других типов микросхем. При этом необходимо учесть, что доступно использование другого· микроконтроллера, с меньшим количеством линий ввода/вывода, но не менее 13. Например, можно применить микроконтроллер PIC16F628. Для этого потребуется изменение названий портов. Использование кварцевого резонатора меньшей частоты потребует сброса бита разрешения прерывания перед операциями с термометром. Это может привести к некоторому мерцанию индикатора. Отсутствие сброса разрешения прерывания приведет к периодическим неправильным показаниям температуры.
Текст программы на языке MicroPASCAL
program DSLED;
const TEMP_RESOLUTION : byte = 12; // Установка разрешающей способности датчика
var shifter, portd_index : byte;
number : word;
portd_array: array[4] of Word;
temp : word;
function mask(num: Word): Word; // Подпрограмма преобразования чисел в код индикатора
begin
case num of
0 : result:= $3F;
1 : result:= $06;
2 : result:= $5B;
3 : result:= $4F;
4 : result:= $66;
5 : result:= $6D;
6 : result:= $7D;
7 : result:= $07;
8 : result:= $7F;
9 : result:= $6F;
end; //case end
end;//~
procedure interrupt; // Подпрограмма обработки прерываний. В ней производится работа с индикатором
begin
PORTA := 0; // Выключение всех сегментов
PORTD := portd_array[portd_index]; // Запись кода индикатора на вывод PORTD
PORTA := shifter; // Включение нужнй цифры на индикаторе
shifter:= shifter shl 1; // Определение номера бита для следующей цифры
if (shifter > 8) then shifter := 1;
Inc(portd_index); // Определение следующей цифры
if (portd_index > 3) then portd_index := 0;
TMR0 := 0; // Сброс таймера TIMER0
INTCON := $20; // Сброс флага прерывания T0IF
end;
procedure Calc_Temperature(temp2write: Word); //Вычисление температуры
const RES_SHIFT : byte = TEMP_RESOLUTION - 8;
var temp_whole : byte;
temp_fraction : Word;
dig: Word;
begin
portd_array[3]:=0;
if (temp2write and $8000) = 0x8000 then // Проверка на отрицательное значение
begin
portd_array[3]:=64; // Установка знака минус
temp2write := not temp2write + 1;
end;
temp_whole := temp2write shr RES_SHIFT ;
dig:=(temp_whole/10) mod 10; // Получение десятков градусов
portd_array[2] := mask(dig);
dig:=temp_whole mod 10; // Полученик единиц градусов
portd_array[1] := mask(dig)+128; // +128 - установка десятичной точки
// Вычисление дробной части
temp_fraction := temp2write shl (4-RES_SHIFT);
temp_fraction := temp_fraction and $000F;
temp_fraction := temp_fraction * 625;
dig:=temp_fraction/1000; // Выделение десятых градуса
portd_array[0] := mask(dig);
end;//~
begin // Основная часть
// Настройка контроллера
ANSEL := 0;
ANSELH := 0;
OPTION_REG := $80;
portd_index := 0;
shifter := 1;
TMR0 := 0;
INTCON := $A0;
PORTA := 0;
TRISA := 0;
PORTD := 0;
TRISD := 0;
while TRUE do // Основной цикл
begin
//Работа с DS18B20
Ow_Reset(PORTE,2); // Сброс шины
Ow_Write(PORTE,2,$CC); // Команда SKIP_ROM
Ow_Write(PORTE,2,$44); // Команда CONVERT_T
Delay_us(120); // Задержка шины
Ow_Reset(PORTE,2); // Сброс шины
Ow_Write(PORTE,2,$CC); // Команда SKIP_ROM
Ow_Write(PORTE,2,$BE); // Команда READ_SCRATCHPAD
temp := Ow_Read(PORTE,2); // Чтение температуры
temp := (Ow_Read(PORTE,2) shl 8) + temp;
Calc_Temperature(temp); // Вызов преобразования температуры
Delay_ms(1000); // Задержка работы
end;
end.