|
Датчик DS18B20, Нужен совет |
|
|
|
 |
Ответов
|
Sep 17 2010, 17:59
|

Местный
  
Группа: Участник
Сообщений: 318
Регистрация: 21-07-06
Из: Минск
Пользователь №: 18 986

|
Для нескольких термометров делал так: Код //---------------------------------------------------------------------------- //--------------------------- Цифровые датчики: ------------------------------ //----------------------------------------------------------------------------
//Используются термометры DS18B20 (S20), которые подключены к портам OWPn. //Считывание и повторный запуск преобразования производится //в момент считывание таходатчика того же канала. //Считываются только два байта температуры, CRC не проверяется. //Суммарное время опроса всех термометров должно быть больше //времени преобразования, т.е. длительность интервала счета тахометра //не должна быть меньше 750 мс / CHANNELS. //Считанное значение температуры заносится в массив Temp[], //температура представлена в десятых долях градуса. //Диапазон возможных температур составляет от TEMP_MIN до TEMP_MAX //градусов. При отсутствии термометра показания равны TEMP_MIN.
//------------------------------- Константы: ---------------------------------
#define OWP0 (1 << PC0) //порт цифрового термометра 0 #define OWP1 (1 << PC1) //порт цифрового термометра 1 #define OWP2 (1 << PC2) //порт цифрового термометра 2 #define OWP3 (1 << PC3) //порт цифрового термометра 3 #define OWP4 (1 << PC4) //порт цифрового термометра 4 #define OWP5 (1 << PC5) //порт цифрового термометра 5 //Направление: #define I_DDRC (0) //Подтягивающие резисторы / начальное состояние: #define I_PORTC (0) //Макроопределения для работы с портами: #define Port_OWP_0(m) (DDRC |= m) #define Port_OWP_Z(m) (DDRC &= ~m) #define Pin_OWP(m) (PINC & m)
//Маски термометров: const __flash char Masks[CHANNELS] = {OWP0, OWP1, OWP2, OWP3, OWP4, OWP5};
//------------------------------- Переменные: --------------------------------
static int Temp[CHANNELS]; //текущая температура static bool Present[CHANNELS]; //флаги присутствия термометров
//---------------------------- Прототипы функций: ----------------------------
void Start(char n); //старт термометра void Read(char n); //чиение термометра void TReset(char n); //генерация импульса сброса char TByte(char n, char dat); //запись/чтение байта bool TBit(char n, bool b); //запись/чтение бита void Do_Crc(char b, char *crc); //вычисление CRC
//------------------ Инициализация измерителя температуры: -------------------
void Therm_Init(void) { ACSR = (1<<ACD); //запрещение аналогового компаратора for(char i = 0; i < CHANNELS; i++) { Temp[i] = TEMP_MIN; //инициализация температуры Start(i); //старт всех термометров } }
//------------------------ Измерение температуры: ----------------------------
void Therm_Exe(char n) { Read(n); //чтение термометра - самое первое измерение Start(n); //старт термометра }
//-------------------------- Старт термометра: -------------------------------
void Start(char n) { TReset(n); //импульс сброса if(Present[n]) { TByte(n, 0xCC); //skip ROM TByte(n, 0x44); //convert T } }
//------------------------- Чтение термометра: -------------------------------
void Read(char n) { if(Present[n]) { TReset(n); //импульс сброса if(Present[n]) { TByte(n, 0xCC); //skip ROM TByte(n, 0xBE); //read scratchpad #ifdef DS18B20 char l = TByte(n, 0xFF); //чтение младшего байта char h = TByte(n, 0xFF); //чтение старшего байта int t = WORD(h, l); //температура с дискретностью 0.0625°C t = (t * 10) / 16; //температура с дискретностью 0.1°C #else char Data[9]; //данные термометра char Crc = 0; //инициализация CRC for(char i = 0; i < 9; i++) { char b = TByte(n, 0xFF); //чтение данных Do_Crc(b, &Crc); //обновление CRC Data[i] = b; //сохранение данных } int t = TEMP_MIN; if(!Crc) { t = WORD(Data[1], Data[0]) / 2; t = (t * 20 - 5 + (int)(Data[7] - Data[6]) * 20 / Data[7]) / 2; } #endif Temp[n] = t; return; } } Temp[n] = TEMP_MIN; //термометр отсутствует return; }
//--------------------- Генерация импульса сброса: ---------------------------
void TReset(char n) { char m = Masks[n]; char si; Present[n] = 0; //сброс флага присутствия термометра Port_OWP_0(m); //OWP <- 0 Delay_us(500); //delay 500 uS si = __save_interrupt(); __disable_interrupt(); //запрещение прерываний Port_OWP_Z(m); //OWP <- 1 Delay_us(14); //delay 14 uS if(Pin_OWP(m)) //если OWP = 0, то ошибка { Delay_us(52); //delay 52 uS if(!Pin_OWP(m)) //если OWP = 1, то ошибка { __restore_interrupt(si); //восстанавление прерываний Delay_us(250); //delay 250 uS if(Pin_OWP(m)) //если OWP = 0, то ошибка { Present[n] = 1; //если ошибок нет, термометр присутствует } } } __restore_interrupt(si); //восстанавление прерываний в случае ошибки }
//-------------- Запись/чтение байта по однопроводной шине: ------------------
char TByte(char n, char dat) { char res; char m = Masks[n]; for(char i = 0; i < 8; i++) { res = res >> 1; if(TBit(m, dat & 1)) res |= 0x80; else res &= ~0x80; dat = dat >> 1; } return(res); }
//--------------- Запись/чтение бита по однопроводной шине: ------------------
bool TBit(char m, bool b) { char si; si = __save_interrupt(); __disable_interrupt(); //запрещение прерываний Port_OWP_0(m); //OWP <- 0 Delay_us(2); //delay 2 uS if(b) Port_OWP_Z(m); //bit = 1, OWP <- 1 Delay_us(13); //delay 13 uS bool owp = Pin_OWP(m); //чтение порта Delay_us(45); //delay 45 uS Port_OWP_Z(m); //OWP <- 1 __restore_interrupt(si); //восстанавление прерываний Delay_us(2); //delay 2 uS return(owp); }
//--------------------- Вычисление контрольной суммы: ------------------------
void Do_Crc(char b, char *crc) { for(char i = 0; i < 8; b = b >> 1, i++) if((b ^ *crc) & 1) *crc = ((*crc ^ 0x18) >> 1) | 0x80; else *crc = (*crc >> 1) & ~0x80; }
--------------------
|
|
|
|
Сообщений в этой теме
Letis Датчик DS18B20 Sep 14 2010, 21:11 miksergei Цитата(Letis @ Sep 15 2010, 00:11) У меня... Sep 14 2010, 23:41 Letis А как нужно сделать ? Sep 15 2010, 00:51 vovanse AVR318: Dallas 1-Wire master on tinyAVR and megaAV... Sep 15 2010, 02:35 Letis Чесно говоря я ничего не понял с єтого app_note. М... Sep 15 2010, 07:06 wer_1 http://www.gaw.ru/html.cgi/txt/app/micros/avr/avr3... Sep 15 2010, 07:32 Letis м-да, сложно єто, проще поставить ключ 4066.
А мо... Sep 15 2010, 08:14 Сергей Борщ Цитата(Letis @ Sep 15 2010, 00:11) Посове... Sep 15 2010, 08:16 Letis Например ? Sep 15 2010, 09:42 Сергей Борщ Цитата(Letis @ Sep 15 2010, 12:42) Наприм... Sep 15 2010, 10:35 Letis что надежнее ключи или программный метод? Sep 15 2010, 12:37 MrYuran Цитата(Letis @ Sep 15 2010, 16:37) что на... Sep 15 2010, 12:55 zalg У меня такая проблема. Писал код "с нуля... Sep 15 2010, 17:04 ILYAUL Цитата(zalg @ Sep 15 2010, 21:04) При вкл... Sep 15 2010, 17:22 alexeyv to zalg
Цитата(zalg @ Sep 15 2010, 23:04)... Sep 16 2010, 03:04  serge71 to zalg:
Если младший бит "0", может всё... Sep 16 2010, 08:04 zalg Опыт программирования у меня не большой, так что з... Sep 15 2010, 17:37 ARV у меня вообще сложилось впечатление, что Code Visi... Sep 15 2010, 18:01 ILYAUL zalg Вы создайте свою тему всё таки. Sep 15 2010, 21:12 Letis Цитатаи сам не один вариант написал для обмена 1-w... Sep 16 2010, 09:20 ARV Цитата(Letis @ Sep 16 2010, 13:20) Виложи... Sep 16 2010, 11:42 Letis Код несколько не понятен в силу того что пишу в Co... Sep 16 2010, 21:18 ARV Цитата(Letis @ Sep 17 2010, 01:18) Как мн... Sep 17 2010, 06:17 xemul Цитата(Letis @ Sep 17 2010, 01:18) Код не... Sep 17 2010, 09:56
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|