Измерительные устройства

Термометр на микроконтроллере PIC12F629

Термометр на PIC12F629Важной частью любого измерительного устройства является индикатор. От его характеристик часто зависит сложность всего изделия. В современных приборах измерения температуры применяются светодиодные индикаторы. Но они требуют большого количества линий для работы, что подразумевает применение микроконтроллеров с большим количеством выводов. Между тем, существует вариант индикатора, построенный на регистрах сдвига, требующий только две линии для управления.

Принципиальная схема

Использование индикатора на регистрах сдвига позволяет создать компактный двухточечный термометр, с использованием самого простого микроконтроллера PIC12F629. Два вывода этого микроконтроллера используются для управления индикатором. Один из них выполняет функцию передачи тактового сигнала, второй информационный. Регистры сдвига 74164 при обнаружении тактового импульса, переключают уровень сигнала с информационного входа, на выход Q0. Информация предыдущего состояния выходов сдвигается на один разряд. К выходам регистров подключены светодиодные семисегментные индикаторы. При этом десятичная точка используется только у  второго индикатора, а к свободным выходам подключены светодиоды отрицательной температуры и номера отображаемого датчика. Для работы индикатора применены простые сдвиговые регистры 74HC164 (1553ИР8). Три таких микросхемы соединены последовательно. В итоге, в работе индикатор не требует постоянного к нему обращения, как это необходимо при реализации динамической индикации.

Термометр на PIC12F629 - принципиальная схема

В схеме термометра использованы датчики DS18B20. Каждый из них подключен к отдельному выводу МК. Возможность работы датчиков одновременно по одному проводу не использована, с целью упрощения программы. Для нейтрализации эффекта саморазогрева, питание датчиков взято с выход микроконтроллера, включаемого только на время измерения.

Термометр на PIC12F629

Особенности PIC12F629 не дают возможность использования одного вывода (GPIO3), так как он работает только на вход. Сам микроконтроллер работает от внутреннего тактового генератора, что позволило освободить две линии ввода/вывода.

Конструкция термометра

Конструктивно термометр выполнен на односторонней печатной плате. В конструкции использовано большое количество элементов поверхностного монтажа. микросхемы регистров используются в корпусе SOIC, а сопротивления типоразмера 1206. На плате установлены две перемычки, а также два разъема для подключения датчиков. Печатная плата размерами 64х30 мм выполнена в программе SprintLayout5 под технологию лазерно-утюжную технологию.

Термометр на PIC12F629 - печатная плата Термометр на PIC12F629 - печатная плата

Файлы проекта и другие ресурсы

Архив проекта

Даташит на PIC12F629. Язык русский.

Некоторые советы по реализации схемы

Термометр на PIC12F629. Альтернативная управляющая программа от Дмитрия

Управляющая программа

Программа работы термометра  написана на языке MikroPASCAL. Использованы стандартные функции работы с устройствами шины 1-Wire.

Программа термометра
program Termo1;
const TEMP_RESOLUTION : byte = 12; home : byte = 5; // номер пина домашнего термометра street : byte = 2; // номер пина уличного термометра
var port_array: array[3] of Byte; temp_home : word; temp_street : word; temp1 : byte; temp2 : byte; i : byte;function mask(num: word): byte; //преобразование в коды индикатора
begin case num of //fgabpcde 0 : result:= %10110111; 1 : result:= %00010100; 2 : result:= %01110011; 3 : result:= %01110110; 4 : result:= %11010100; 5 : result:= %11100110; 6 : result:= %11100111; 7 : result:= %00110100; 8 : result:= %11110111; 9 : result:= %11110110; end; //case end
end;//~

procedure get_temp; // чтение температуры из термометра

begin Ow_Reset(GPIO,home); // сброс шины Ow_Write(GPIO,home,$CC); // команда SKIP_ROM Ow_Write(GPIO,home,$44); // команда CONVERT_T   Ow_Reset(GPIO,street); // сброс шины Ow_Write(GPIO,street,$CC); // команда SKIP_ROM Ow_Write(GPIO,street,$44); // команда CONVERT_T   Delay_ms(600); // задержка на время преобразования   Ow_Reset(GPIO,home); // сброс шины Ow_Write(GPIO,home,$CC); // команда SKIP_ROM Ow_Write(GPIO,home,$BE); // команда READ_SCRATCHPAD temp1 := Ow_Read(GPIO,home); // чтение первого байта temp2 := Ow_Read(GPIO,home); // чтение второго байта temp_home := temp1; // преобразование в слово temp_home := (temp2 shl 8) + temp_home;   Ow_Reset(GPIO,street); // сброс шины Ow_Write(GPIO,street,$CC); // команда SKIP_ROM Ow_Write(GPIO,street,$BE); // команда READ_SCRATCHPAD temp1 := Ow_Read(GPIO,street); // чтение первого байта temp2 := Ow_Read(GPIO,street); // чтение второго байта temp_street := temp1; // преобразование в слово temp_street:= (temp2 shl 8) + temp_street;  end;

procedure Calc_Temperature(temp2write: Word;str: Boolean);// преобразование температуры
const RES_SHIFT : byte = 4;
var temp_whole : byte; temp_fraction : Word; dig : Word; dig1 : byte;
begin port_array[0]:=0; if (temp2write and $8000) = 0x8000 then begin temp2write := not temp2write + 1; port_array[0]:=8; end; temp_whole := temp2write shr RES_SHIFT ; dig:=(temp_whole/10) mod 10; port_array[0] := port_array[0] + mask(dig); dig:=temp_whole mod 10; port_array[1] := mask(dig)+8; temp_fraction := temp2write shl (4-RES_SHIFT); temp_fraction := temp_fraction and $000F; temp_fraction := temp_fraction * 625; dig:=temp_fraction/1000; port_array[2] := mask(dig); if str then port_array[2]:=port_array[2]+8;
end; //~
procedure show_temp; // отображение температуры
var digit_show : byte; dig_buf : byte;
begin
for digit_show:=0 to 2 do begin dig_buf := port_array[digit_show]; // запись в буфер отображения for i:=1 to 8 do begin if testbit(dig_buf,0) then setbit(GPIO,0) else clearbit(GPIO,0); setbit(GPIO,1); // включить тактовую линию dig_buf:=dig_buf shr 1; // сдвиг символа в буфере отображения clearbit(GPIO,1); // отключить тактовую линию Delay_ms(75); // задержка для красоты end; end;
end;
begin GPIO:=0; CMCON:=7; TRISIO := %00001000; while TRUE do // основной цикл begin setbit(GPIO,4); Delay_ms(10); get_temp; // чтение домашней температуры clearbit(GPIO,4); Calc_Temperature(temp_home,0); // преобразование температуры show_temp; // индикация температуры Delay_ms(5000); Calc_Temperature(temp_street,1); // преобразование температуры show_temp; // индикация температуры Delay_ms(5000); end;
end.

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