русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Інтерфейс 1-Wire і температурний датчик DS18B20


Дата добавления: 2015-08-14; просмотров: 1182; Нарушение авторских прав


Шина 1-Wire приваблива, в першу чергу, тим, що використовує тільки одну лінію зв'язку. Розберемо 1-Wire детальніше. Для роботи цього інтерфейсу повинен бути один ведучій пристрій і один або кілька ведених. У кожного 1-Wire пристрою є 64-бітний унікальний код. Використовуючи який, ведучий визначає з яким з пристроїв на лінії він буде працювати. Але дізнатися цей код це окрема процедура, тому поки будемо вважати, що у нас всього один пристрій, підключений до шини - температурний датчик DS18B20.

Отже, щоб працювати з будь-яким пристроєм нам потрібно ініціалізувати його, послати йому команду і прийняти якісь дані. Розберемо як це можна зробити на шині 1-Wire.

Перший крок, щоб провести пошук пристроїв на лінії, відучий пристрій (у нашому випадку мікроконтролер) повинен утримувати на сигнальній лінії логічний "0" принаймні 480 мкс (так званий Reset Pulse), потім відпустити шину мінімум на 60мкс і після цього подивитися рівень на лінії. Якщо на лінії високий рівень - пристроїв 1-Wire не виявлено, якщо низький - є хоча б один пристрій (Presence Pulse).

Рисунок 10. – Процедура пошуку підключених пристроїв до інтерфейсу 1-Wire.

 

Другий крок, тепер ми повинні послати команду пристрою. Передача інформації розбита на тайм-слоти. Один тайм-слот служить для передачі одного біта команди та тривалість його знаходиться в діапазоні 60-120 мкс. Дані передаються, починаючи з молодшого біта. Для передачі логічного нуля МК утримує на лінії "0" мінімум 60мкс, а потім відпускає шину мінімум на 1мкс. Для передачі логічної одиниці МК утримує на лінії "0" мінімум 1 мкс, але не більше 15 мкс, а потім відпускає шину на час, що залишився для тайм-слота.

 

Рисунок 11. – Пересилка команди пристрою, що підключений до інтерфейсу 1-Wire.

Третій крок, прийом даних з пристрою 1-Wire. Щоб прийняти дані МК утримує на лінії "0" не менш 1 мкс, а потім відпускає шину, трохи чекає і дивиться стан лінії (зазвичай до 15-ї мікросекунди від початку тайм-слоти). Якщо на лінії "1" - означає передається "1", якщо "0" - значить "0".



 

Рисунок 12. – Процедура прийому даних з пристрою 1-Wire.

 

До чого слід поставитися серйозно так це до затримок. Потрібно керуватися наступним правилом: сигнали, які формує МК, необхідно формувати за необхідного мінімуму тривалості (трохи більше мінімально вказаної), а від сигналів пристрою потрібно чекати найгіршого варіанту. Також, якщо 1-Wire пристрій знаходиться далеко від МК, тоді може виникнути потреба зменшити величину опору підтягуючого резистора. Це пов'язано з тим, що подовжуючи лінію ми збільшуємо погонну ємність лінії, а отже і збільшуємо час повернення лінії в одиницю за рахунок підтягуючого резистора (наприклад, після Reset імпульсу ми відпускаємо шину і за рахунок цього резистора вона повертається в одиницю). У деякий момент цей час може виявитися більше ніж максимально необхідний для роботи з 1-Wire шиною і вся подальша передача інформації буде не вірна.

Для вимірювання температури будемо використовувати датчик DS18B20. Почнемо з того, що відкриємо Datasheet і подивимося основні моменти, які нам знадобляться:

1. Датчик може забезпечувати 9-, 10-, 11-, 12-ти бітове розділення вимірювання температури в градусах Цельсія. Це розділення ми можемо вибирати, записуючи дані в конфігураційний регістр датчика (за замовчуванням 12-бітове розділення).

2. Вимірює в діапазоні -55...+125 оС. З точністю 0.5 градуса.

3. На одиницю коду перетворюваного значення температури доводиться 0.0625оС.

4. При читанні даних з датчика ми приймаємо 9 байт даних, з яких ми будемо брати 0-й і 1-й, молодший і старший байт температури відповідно. У старшому байті в бітах 11-15 міститься інформація про знак температури (якщо в цих бітах одиниця, тоді температура нижче нуля).

5. Час перетворення температури з 12-бітною точністю займає max 750 мс. Тобто це час потрібно буде почекати після виклику команди перетворення температури (0х44) і тільки потім посилати таку команду.

6. Після перетворення температури, перш ніж посилати таку команду потрібно ще раз послати імпульс скидання (Reset pulse) і отримати відповідь імпульс (Presence Pulse).

 

Приклад схеми пристрою наведений на рис. 13. Данний пристрій вимірює температуру за допомогою двох датчиків DS18B20 та виводить результат на LCD дисплей. Програму, що реалізує даний пристрій зроблену у середовищі CodeVisionAVR.

 

1. #include <mega8.h>

2. #include <1wire.h>

3. #include <ds18b20.h>

4. #define MAX_DS1820 8

5. unsigned char rom_codes[MAX_DS1820][9];

6. #include <stdio.h>

7. char lcd_buffer[33]; // буфер для температуры

8. #include <delay.h>

9. #include <alcd.h>

10. unsigned char buf[33];// буфер для значений АЦП

11. int temp[8]; int a;

12. //--------------------------------------------------------------------------

13. // Далее строки 13-39 настройка работы АЦП по входу 1 (РС1 или 24 лапка чипа

14. #define FIRST_ADC_INPUT 1

15. #define LAST_ADC_INPUT 1

16. unsigned char adc_data[LAST_ADC_INPUT-FIRST_ADC_INPUT+1];

17. #define ADC_VREF_TYPE 0x20

18. // ADC interrupt service routine

19. // with auto input scanning

20. interrupt [ADC_INT] void adc_isr(void)

21. {

22. static unsigned char input_index=0;

23. // Read the 8 most significant bits

24. // of the AD conversion result

25. adc_data[input_index]=ADCH;

26. PORTD=ADCH;// можно эту строку удалить, просто она выводит в порт результат АЦП (при

27. настройке удобно)

28. // Select next ADC input

29. if (++input_index > (LAST_ADC_INPUT-FIRST_ADC_INPUT))

30. input_index=0;

31. ADMUX=(FIRST_ADC_INPUT | (ADC_VREF_TYPE & 0xff))+input_index;

32. // Delay needed for the stabilization of the ADC input voltage

33. delay_us(10);

34. // Start the AD conversion

35. ADCSRA|=0x40;

36. }

37. //----------все АЦП настроили ;) ------------------------------------------------------------

38. // Timer1 output compare A interrupt service routine

39. /*

40. Именно таймером 1 выставляем время (интервалы) обновления информации на LCD,

41. в данном примере термометры и АЦП обновляются одновременно.

42. */

43. interrupt [TIM1_COMPA] void timer1_compa_isr(void)

44. {

45. // Place your code here

46. TCNT1H=0x00;

47. TCNT1L=0x00;

48. a=ADCH;

49. temp[0]=ds18b20_temperature(&rom_codes[1][0]);

       
   
 
 

 


temp[1]=ds18b20_temperature(&rom_codes[0][0]);
lcd_clear();
// стр. 57-78 пишем "холодно", "норма", "жарко"
if (temp[0]<20)
{
//lcd_clear();
sprintf(buf,"Cold!");//
lcd_gotoxy(10,1);
lcd_puts(buf);
}
if (temp[0]>=20&temp[0]<=30)
{
//lcd_clear();
sprintf(buf,"Norma");//
lcd_gotoxy(10,1);
lcd_puts(buf);
}
if (temp[0]>30)
{
//lcd_clear();
sprintf(buf,"Hot!");//
lcd_gotoxy(10,1); lcd_puts(buf);
}
sprintf(lcd_buffer,"t=%i.%u\xdfC",temp[0],temp[0]%1);
lcd_gotoxy(0,0); lcd_puts(lcd_buffer);
// строки 80-82 вывели датчик температуры 1 на дисплей
sprintf(lcd_buffer,"t=%i.%u\xdfC",temp[1],temp[1]%1);
lcd_gotoxy(0,1);
lcd_puts(lcd_buffer);
// строки 85-87 вывели датчик температуры 2 на дисплей
sprintf(buf,"U=%d.%u",a/51,a%100);// АЦП - делитель сам выставляй
lcd_gotoxy(10,0);
lcd_puts(buf);
delay_ms(50);
// строки 90-93 результат АЦП вывели на дисплей (только 8-старших битов)
}
//------------------------- основное тело программы -----------------------
void main(void)
{
unsigned char devices;
DDRD=0xff;
PORTD=0x00;
// настраиваем таймер 1
TCCR1A=0x00;
TCCR1B=0x03;
TCNT1H=0x00;// со скольки считаем - старший регистр
TCNT1L=0x00;// со скольки считаем - младший регистр
OCR1AH=0x00;// до скольки считаем - старший регистр
OCR1AL=0x08;// до скольки считаем - младший регистр
// Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x10; // маска таймера (обязательно!)
ADMUX=FIRST_ADC_INPUT | (ADC_VREF_TYPE & 0xff);
ADCSRA=0xCC;
lcd_init(16);// ну..., это понятно
delay_ms(200);
devices=w1_search(0xf0,rom_codes); // и сколько же у нас девайсов?
sprintf(lcd_buffer," devices=%u",devices);// а вот мы и видим число подключенных дивайсов!
lcd_clear();
lcd_puts(lcd_buffer);
delay_ms(2000);
// Global enable interrupts
#asm("sei")
while (1)
{
};
}
// все...

 

 



<== предыдущая лекция | следующая лекция ==>
Робота з таймерами/лічильниками МК AVR | принципиально новая система автоблокировки, получившая название АБТЦ-М.


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 0.032 сек.