реклама на сайте
подробности

 
 
> Atmega328P и DS18B20 в фоновом режиме
iiv
сообщение Nov 28 2011, 03:53
Сообщение #1


вопрошающий
*****

Группа: Свой
Сообщений: 1 726
Регистрация: 24-01-11
Пользователь №: 62 436



Всем привет,

имеется атмега328п, хочется к ней прикрутить несколько, от одного до четырех, датчиков температуры DS18B20 по 1-wire. Незадачка в том, что эта атмега должна в реальном времени выполнять кучу другой работы, которую нельзя прерывать 100мкс-750мс ожиданиями протокола 1-wire.

В то же время, как я понимаю из прочтения исходников протокола общения с этими датчиками, большую часть времени микроконтроллер должен ждать.

Возникает идея, что этот протокол может быть реализован на прерываниях таймера и int0 (я могу повесить 1-wire на эту ножку) и практически не занимать время процессора, но программировать это может быть довольно не тривиально.

Скажите, пожалуйста, может кто-то уже такое запрограммировал, и такие исходники существуют в сети? Если да, тыкните, пожалуйста, пальцем где скачать. Если нет, может я в чем-то ошибаюсь и это не так просто, как мне кажется?

Знаю, что есть еще решение - поставить на плату тиньку или еще одну ардуину, которая будет 100% занята опросами этой температуры, но очень не хотелось бы это делать.

Спасибо

ИИВ
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
ARV
сообщение Nov 28 2011, 04:19
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



100 мкс - 750 мкс ждать никогда не нужно с запрещенными прерываниями. запрет прерываний требуется на 15-60 мкс максимум, так что сколько-нибудь заметного влияния на фоновые процессы обмен 1-wire не должен оказать


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
iiv
сообщение Nov 28 2011, 04:36
Сообщение #3


вопрошающий
*****

Группа: Свой
Сообщений: 1 726
Регистрация: 24-01-11
Пользователь №: 62 436



Цитата(ARV @ Nov 28 2011, 09:19) *
100 мкс - 750 мкс ждать никогда не нужно с запрещенными прерываниями. запрет прерываний требуется на 15-60 мкс максимум, так что сколько-нибудь заметного влияния на фоновые процессы обмен 1-wire не должен оказать

на сколько понимаю, 5-10мкс (или все-таки 60 мкс?) мне надо ждать для передачи одного бита, а передавать надо где-то 16 байт, то есть на момент коммуникации мне надо выделить 1-2 милисекунду. Вот их-то я и не готов выделить, так как в реальном времени у меня с 6 портов идут конвертации с АЦП и на результаты мне надо реагировать незамедлительно.

Термодатчики хочу вкрячить на силовые модули, чтобы мониторить нагрев мосфетов во время работы...
Go to the top of the page
 
+Quote Post
Леонид Иванович
сообщение Nov 28 2011, 07:48
Сообщение #4


Местный
***

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



Цитата(iiv @ Nov 28 2011, 07:36) *
или все-таки 60 мкс?


Если делать всё корректно, то 60 мкс. Тайм-слот надо полностью закончить, а только потом разрешать прерывания, иначе передача нуля может затянуться и это будет воспринято как сброс. Ну и после сброса чтение ответа устройства делается примерно через 65 мкс, тут без запрещенных прерываний никак.

Можно поделить работу с датчиками на элементарные операции, каждая из которых будет не длиннее 60 мкс. Ведь между тайм-слотами задержка не ограничивается. Я делал что-то подобное, но делил на байты, Вам же нужно поделить на биты:

CODE
//----------------------------------------------------------------------------

//DSS-90
//Модуль обслуживания термометра DS18B20

//Цифровой датчик температуры DS18B20 подключен по 1-проводному
//интерфейсу, который реализован программно.
//Для подключения датчика используется порт OWP.
//Порт должен быть настроен на ввод,
//внутренний подтягивающий резистор должен быть отключен,
//используется внешний подтягивающий резистор 4.7 кОм.
//Во время измерения обеспечивается сильноточная
//подтяжка линии данных (порт переключается на вывод ВЫСОКОГО уровня),
//поэтому возможно использование термометра с паразитным питанием.
//Должны быть определены следующие макросы:
//#define OWP (1 << Pxn)
//#define Port_OWP_OUT (DDRx |= OWP)
//#define Port_OWP_IN (DDRx &= ~OWP)
//#define Pin_OWP (PINx & OWP)
//Датчик DS18B20 должен быть запрограммирован в 12-разрядный режим
//(биты R0, R1 в регистре конфигурации равны единице,
//это заводская установка).

//Дискретность измерения температуры составляет 0.1°C.
//Из датчика считываются только 2 байта, CRC не проверяется.

//Для инициализации модуля один раз в начале программы должна
//вызываться функция DS18B20_Init(). Функция DS18B20_Exe() должна
//вызываться в основном цикле, она осуществляет запуск преобразования,
//формирует в фоновом режиме временную задержку и производит считывание
//температуры во внутреннюю переменную Temp.

//Поскольку обмен по однопроводной шине довольно медленный (чтение или
//запись одного байта занимает порядка 0.5 мс), целиком выполнять
//чтение температуры и запуск преобразования за один вызов DS18B20_Exe()
//нельзя. Это может нарушить выполнение других задач. Поэтому процесс
//обмена с термометром разбит на элементарные операции, каждая из
//которых включает в себя обмен не более чем одним байтом.

//Значение температуры в любой момент может быть считано с помощью функции
//DS18B20_GetT(). Значение представлено в виде 16-разрядного целого числа
//со знаком и представляет собой температуру в десятых долях градуса.
//До того, как закончится первое преобразование температуры, возвращается
//значение T_NORDY. В случае отсутствия ответа термометра возвращается
//код ошибки T_ERROR.

//----------------------------------------------------------------------------

#include "Main.h"
#include "DS18B20.h"

//------------------------------ Константы: ----------------------------------

#define TCONV 800 //время преобразования температуры, мс

//----------------------------- Переменные: ----------------------------------

static int Temp; //текущая температура
static char TState; //состояние процесса измерения

//-------------------------- Прототипы функций: ------------------------------

bool TReset(void); //формирование импульса сброса
char TByte(char dat); //запись/чтение байта
bool TBit(bool cool.gif; //запись/чтение бита

//--------------------- Инициализация термометра: ----------------------------

void DS18B20_Init(void)
{
Temp = T_NORDY; //результат измерения не готов
TState = 0; //начало процесса
}

//----------------------- Измерение температуры: -----------------------------

void DS18B20_Exe(bool t)
{
static int TTimer = 0; //таймер термометра
static int T; //код температуры
if(t)
{
if(TTimer) //если интервал таймера не истек,
{
TTimer--; //ожидание (и декремент таймера)
}
else //иначе выполнение шага
{
switch(TState)
{
case 0: if(TReset()) //команда RESET
TState++; //если выполнена успешно, следующий шаг
else TState = 0xFF; //если ошибка, переход на задержку
break;
case 1: TByte(0xCC); //команда SKIP ROM
TState++; //следующий шаг
break;
case 2: TByte(0x44); //команда START CONVERSION
TTimer = ms2sys(TCONV); //загрузка задержки преобразования
TState++; //следующий шаг
break;
case 3: if(TReset()) //команда RESET
TState++; //если выполнена успешно, следующий шаг
else TState = 0xFF; //если ошибка, переход на задержку
break;
case 4: TByte(0xCC); //команда SKIP ROM
TState++; //следующий шаг
break;
case 5: TByte(0xBE); //команда READ SCRATCHPAD
TState++; //следующий шаг
break;
case 6: T = TByte(0xFF); //чтение TL
TState++; //следующий шаг
break;
case 7: T |= TByte(0xFF) << 8; //чтение TH
TState++; //следующий шаг
break;
case 8: Temp = 10 * T / 16; //вычисление температуры
TState = 0; //переход на первый шаг
break;
default: TTimer = ms2sys(TCONV); //загрузка задержки
Temp = T_ERROR; //код ошибки
TState = 0; //переход на первый шаг
}
}
}
}

//--------------------- Генерация импульса сброса: ---------------------------

bool TReset(void)
{
char si;
Port_OWP_0;
Port_OWP_OUT; //OWP <- 0
Delay_us(500); //delay 500 uS
si = __save_interrupt();
__disable_interrupt(); //запрещение прерываний
Port_OWP_IN; //OWP <- 1
Delay_us(14); //delay 14 uS
if(Pin_OWP) //если OWP = 0, то ошибка
{
Delay_us(52); //delay 52 uS
if(!Pin_OWP) //если OWP = 1, то ошибка
{
__restore_interrupt(si); //восстанавление прерываний
Delay_us(250); //delay 250 uS
if(Pin_OWP) //если OWP = 0, то ошибка
{
return(1); //если ошибок нет, термометр присутствует
}
}
}
__restore_interrupt(si); //восстанавление прерываний в случае ошибки
return(0);
}

//-------------- Запись/чтение байта по однопроводной шине: ------------------

char TByte(char dat)
{
char res;
for(char i = 0; i < 8; i++)
{
res = res >> 1;
if(TBit(dat & 1)) res |= 0x80;
else res &= ~0x80;
dat = dat >> 1;
}
return(res);
}

//--------------- Запись/чтение бита по однопроводной шине: ------------------

bool TBit(bool cool.gif
{
char si;
si = __save_interrupt();
__disable_interrupt(); //запрещение прерываний
Port_OWP_0;
Port_OWP_OUT; //OWP <- 0
Delay_us(2); //delay 2 uS
if(cool.gif Port_OWP_IN; //bit = 1, OWP <- 1
Delay_us(13); //delay 13 uS
bool owp = Pin_OWP; //чтение порта
Delay_us(45); //delay 45 uS
Port_OWP_1; //force pullup
Port_OWP_OUT;
__restore_interrupt(si); //восстанавление прерываний
Delay_us(2); //delay 2 uS
return(owp);
}

//------------------------- Чтение температуры: ------------------------------

int DS18B20_GetT(void)
{
return(Temp);
}

//----------------------------------------------------------------------------


Сообщение отредактировал IgorKossak - Nov 28 2011, 10:17
Причина редактирования: [codebox]


--------------------
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- iiv   Atmega328P и DS18B20 в фоновом режиме   Nov 28 2011, 03:53
- - birden   Вариантов реализации 1-Wire довольно много - выбир...   Nov 28 2011, 04:18
||- - iiv   Цитата(Леонид Иванович @ Nov 28 2011, 13...   Nov 28 2011, 10:21
|- - e-serg   Цитата(iiv @ Nov 28 2011, 13:36) на сколь...   Nov 28 2011, 08:01
- - Палыч   Цитата(iiv @ Nov 28 2011, 07:53) Возникае...   Nov 28 2011, 04:25
|- - ILYAUL   Цитата(Палыч @ Nov 28 2011, 08:25) Надавн...   Nov 28 2011, 04:37
|- - Палыч   Цитата(ILYAUL @ Nov 28 2011, 08:37) Изуми...   Nov 28 2011, 12:13
|- - ILYAUL   Цитата(Палыч @ Nov 28 2011, 16:13) Для пр...   Nov 28 2011, 16:37
- - Павлик   По одному проводу 4 датчика часто читать нельзя, п...   Nov 29 2011, 18:18
|- - ARV   Цитата(Павлик @ Nov 29 2011, 22:18) По од...   Nov 29 2011, 19:03
|- - iiv   Цитата(ARV @ Nov 30 2011, 01:03) не на ка...   Nov 29 2011, 22:25
|- - ILYAUL   Цитата(iiv @ Nov 30 2011, 02:25) ага, я у...   Nov 30 2011, 05:56
|- - ARV   Цитата(ILYAUL @ Nov 30 2011, 09:56) Почем...   Nov 30 2011, 08:57
- - Павлик   На 8 портов и еще с питанием на датчик все будет б...   Nov 30 2011, 18:26
|- - Shaeto   1-wire вообще интересные устройства у них, особенн...   Dec 1 2011, 20:30
|- - xemul   Цитата(Павлик @ Nov 30 2011, 22:26) а при...   Dec 1 2011, 21:24
- - Br.Misha   http://kibermaster.net/rabota-s-shinoy-1-w...-ds18...   Dec 4 2011, 01:01
- - usav   А у кого опыт паразитного питания? Какие основные ...   Dec 8 2011, 19:46
- - Павлик   Нормально все работает на паразитном питании -50 ....   Dec 12 2011, 06:10
- - usav   "Время заряда давать не менее 800-900мс...   Dec 13 2011, 17:06
- - Павлик   Так будет понятнее CODEds_start: // ...   Dec 13 2011, 17:36
- - usav   Понятно, спасибо, Павлик!   Dec 13 2011, 22:52


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd August 2025 - 04:44
Рейтинг@Mail.ru


Страница сгенерированна за 0.01355 секунд с 7
ELECTRONIX ©2004-2016