В предыдущей части урока мы познакомились с датчиком температуры LMT01 и подключили схему нашего занятия.
Приступим к проекту.
Проект за основу мы возьмём из урока 25 по АЦП с именем ADC, а новый проект назовём по имени датчика LMT01.
Откроем проект в среде MPLAB X, сделаем его главным, убедимся в свойствах, что питание от программатора не используется.
Первым делом в файлах main.h, i2c.h и i2clcd.h изменим значение частоты тактирования
#define _XTAL_FREQ 16000000
Удалим функцию delay() вместе с телом.
В функции main() оставим инициализацию шины I2C, инициализацию и очистку дисплея, а также бесконечный цикл без кода в теле. Функция примет вот такой вид
1 2 3 4 5 6 7 8 9 |
void main() { InitI2C();// Initialize i2c LCD_Init(); LCD_Clear(); while(1) { } } |
Добавим несколько глобальных переменных
1 2 3 4 |
#include "string.h" //------------------------------------------------ unsigned char tmp; unsigned int isr_cnt=0, current_time = 0, cnt1=0, old_cnt=0; |
А в функции main() добавим локальную переменную для хранения показаний температуры
1 2 3 |
void main() { float temper = .0f; |
Произведём инициализацию ножек портов
1 2 3 4 5 |
float temper = .0f; TRISA=0X03; PORTA=0X00; TRISC=0X00; PORTC=0X00; |
После очистки дисплея произведём настройку модуля источника опорного напряжения и модуля компараторов приблизительно также, как и в прошлом уроке по модулю компараторов.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
LCD_Clear(); CVRR = 1; CVR3 = 0; CVR2 = 1; CVR1 = 1; CVR0 = 0; CVREN = 1; C1INV = 1; CM2 = 1; CM1 = 1; CM0 = 0; __delay_us(10); tmp = CMCON; CMIF = 0; CMIE = 1; PEIE = 1; GIE = 1; |
У нас только коэффициент у опорного напряжения немного другой.
Добавим обработчик прерывания от модуля компараторов над функцией main(), в котором мы всего лишь будем инкрементировать значение переменной, которая и будет подсчитывать импульсы от датчика
1 2 3 4 5 6 7 8 9 10 11 12 13 |
//------------------------------------------------ void __interrupt(high_priority) tcInt(void) { if (CMIF) { CMIF=0; if (C1OUT) { isr_cnt++; } } } //------------------------------------------------ |
В бесконечном цикле функции main() мы запретим прерывания, обнулим счётчик импульсов, а затем прерывания снова разрешим
1 2 3 4 5 |
while(1) { GIE = 0; isr_cnt = 0; GIE = 1; |
Переведём ножку порта, отвечающую за питание датчика, в высокое состояние и подождём 55 милисекунд, чтобы датчик сконвертировал показания в цифровой код
1 2 3 |
GIE = 1; PORTC|=0X01; __delay_ms(55); |
Глобальную переменную, которая будет считать количество временных отрезков по 5 милисекунд, обнулим, а переменную, которая будет хранить количество импульсов, переведём в -1, чтобы счёт начинался с нуля
1 2 3 |
__delay_ms(55); current_time = 0; cnt1 = -1; |
Добавим цикл, который будет заканчиваться по истечению 11 отрезков по 5 милисекунд, в котором и будет подсчитываться общее количество пришедших от датчика импульсов. Цикл также будет прерываться, если значение подсчитанных импульсов в итерации не изменилось, чтобы не ждать 11 циклов.
В данном цикле мы сначала сохраним текущее значение счётчика
1 2 3 4 5 |
cnt1 = -1; do { old_cnt = cnt1; } while( cnt1 != old_cnt && current_time < 11); |
Сохраним в счётчик количество импульсов, которые сосчитал счётчик в обработчике прерывания, запретив на это время прерывания
1 2 3 4 |
old_cnt = cnt1; GIE = 0; cnt1 = isr_cnt; GIE = 1; |
Прерывание мы запрещаем для того, чтобы в момент сохранения не потерять значение.
Подождём 5 милисекунд и проинкрементируем значение количества временных отрезков
1 2 3 |
GIE = 1; __delay_ms(5); current_time++; |
Выйдем из цикла и переведём ножку порта, обеспечивающую питание датчика, в низкое состояние
1 2 |
} while( cnt1 != old_cnt && current_time < 11); PORTC&=~0X01; |
Теперь, когда датчик отключен от питания, мы можем спокойно заниматься переводом количества импульсов в значение температуры, отображать его на дисплее и вообще заниматься любыми действиями.
Посчитаем значение температуры, немного упростив формулу
1 2 |
PORTC&=~0X01; float temper = ((float)isr_cnt-808)/16; |
Отобразим значение температуры на дисплее, а также отобразим количество импульсов, а затем сделаем паузу в 1 секунду
1 2 3 4 5 6 7 8 9 |
float temper = ((float)isr_cnt-808)/16; sprintf(str01,"%.2f C",temper); LCD_SetPos(0,0); LCD_String(str01); sprintf(str01,"%06d",isr_cnt); LCD_SetPos(0,1); LCD_String(str01); __delay_ms(1000); } |
Соберём код, прошьём контроллер и посмотрим результат нашей работы на дисплее
Прикоснёмся на некоторое время к датчику пальцем, и показания температуры начнут подниматься
Таким образом, мы видим, что датчик прекрасно работает и температура отлично измеряется.
Итак, на данном занятии мы изучили работу интересного датчика с нестандартным способом передачи показаний — датчика температуры LMT01. Также мы лишний раз повторили работу с модулем компаратор. Ну, и также мы повторили на практике закон Ома.
Всем спасибо за внимание!
Предыдущая часть Программирование МК PIC Следующий урок
Купить программатор (неоригинальный) можно здесь: PICKit3
Купить программатор (оригинальный) можно здесь: PICKit3 original
Датчик температуры LMT01 можно приобрести здесь: LMT01
Дисплей LCD 20×4 можно приобрести тут: Дисплей LCD 20×4
Переходник I2C to LCD можно приобрести здесь: I2C to LCD1602 2004
Смотреть ВИДЕОУРОК в RuTube (нажмите на картинку)
Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)
Добавить комментарий