Перейти к содержанию

Алгоритм Работы С 1wire


TWIN

Рекомендуемые сообщения

Программирую на Си в IAR для ATmega128. Датчик DS18B20, полноценное питание, датчик впаян прямо в макетную плату...

Получаю неправильные (а для этого датчика нереальные) результаты температуры, типа -2731C. Показания неправильные не от перевода 2-х байт в реальную температуру, а именно из-за неправильного считывания байтов, содержащих температуру (проверял значения этих байтов).

Перечитал кучу инфы... Запутался совсем... :(

Ниже привожу код реализации работы с 1Wire:

в файле main.cpp

#define SENS   0x20  // Пин датчика
#define SetBit(x,y) (x|=y)
#define ClrBit(x,y) (x&=~y)
#define TestBit(x,y) (x&y)
bool presence;
unsigned char bit_e;	// содержит текущий бит для чтения или записи
unsigned char byte_e; // содержит текущий байт для чтения или записи

void ow_reset(void)
{
char si;
si = __save_interrupt();
__disable_interrupt();

SetBit(DDRС,SENS);   // Пин определяем как выход
ClrBit(PORTС,SENS);  // Устанавливаем 0 на шине на 500us
delay_us(500); SetBit(PORTС,SENS);  // Включаем пдтяжку pull-up ClrBit(DDRС,SENS);   // Пин определяем как вход delay_us(70);
if(TestBit(PINC,SENS)==0) presence = true; else presence = false;
delay_us(250);
__restore_interrupt(si);
delay_us(500);

}

void read_bit(void)
{
char si;
si = __save_interrupt();
__disable_interrupt();
SetBit(DDRC,SENS);	// Пин определяем как выход
ClrBit(PORTC,SENS);  // Устанавливаем 0 на шине на 2us
delay_us(2);
SetBit(PORTC,SENS);  // Включаем пдтяжку pull-up
ClrBit(DDRC,SENS);	// Пин определяем как вход
delay_us(12);
if(TestBit(PINC,SENS)==0) bit_e = 0; else bit_e = 1;
delay_us(46);
__restore_interrupt(si);
delay_us(2);
}

void write_bit(void)
{
char si;
si = __save_interrupt();
__disable_interrupt();
SetBit(DDRС,SENS);   // Пин определяем как выход
ClrBit(PORTС,SENS); // Устанавливаем 0 на шине на 2us
delay_us(2);
if(bit_engine==1) SetBit(ONE_WIRE_PORT,SENS_ENGINE); // Выводим в пин явную 1   delay_us(58);

SetBit(PORTС,SENS);  // Включаем пдтяжку pull-up
ClrBit(DDRС,SENS);	// Пин определяем как вход
__restore_interrupt(si);
delay_us(2);
}

unsigned char OneWire_ReadByte(void)
{
byte_e=0;
unsigned char i;
for (i=0;i<8;i++)
{
  read_bit();
  if(bit_e==1) byte_e|=0x01<<i;	 // reads byte in, one byte at a time an shifts it left
 }
return byte_e;
}


void OneWire_WriteByte(unsigned char val)
{
unsigned char i;
unsigned char temp;

for (i=0; i<8; i++)			 // writes byte, one bit at a time
{
  temp = val>>i;
  temp &= 0x01;
  bit_e = temp;			 write_bit();			// write bit
}
delay_us(24);
}

Подскажите пожалуйста, что я делаю не так?

Изменено пользователем TWIN
Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

...........Получаю неправильные (а для этого датчика нереальные) результаты температуры, типа -2731C. Показания неправильные не от перевода 2-х байт в реальную температуру, а именно из-за неправильного считывания байтов, содержащих температуру (проверял значения этих байтов).

Подскажите пожалуйста, что я делаю не так?

Интересно, каким образом из 12 разрядов формата 8.4 можно поиметь 12 разрядное число формата 12.0 ? Там вообще невозможно получить число более 255 с любым знаком, даже если и неправильно принимать.

Изменено пользователем my504

戦う前に相手のベルトの色に注目

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

unsigned char OneWire_ReadByte(void)
{
unsigned char i;
for (i=0;i<8;i++)
{
  read_bit();
  if(bit_e==1) byte_e|=0x01<<i;	 // reads byte in, one byte at a time an shifts it left
 }
return byte_engine;
}

А где очистка переменной byte_e ? У Вас, через несколько вызовов функции, она вся забьётся и начнёт возвращать FF-ки.

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

Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

О да! С очисткой переменной byte_e и впрямь лопухнулся!!! :huh:

А возвращается именно она, это я просто сократил некоторые наименования в выложенном здесь коде для удобства чтения, а вот в этом месте не убрал лишнее... В общем, код в своем первом посте изменил. СПАСИБО!

Однако, до сих пор не могу добиться правильной работы - все считанные байты от датчика FF. Не пойму, то ли датчик не принимает нормально запись битов, то ли не попадаю при чтении отдельного бита в импульс от датчика... Даташит зачитал до дыр, перепробовал несколько вариантов паузы перед считыванием:

1. Шина в "0" - пауза 2мкс - Шина в "Z" (подтяжка до "1" резистором 4,7к) - пауза 11мкс - считываем состояние шины - ждем конца слота 47мкс

2. Шина в "0" - пауза 2мкс - Шина в "Z" - пауза 12мкс - считываем состояние шины - ждем конца слота 46мкс

3. Шина в "0" - пауза 2мкс - Шина в "Z" - пауза 13мкс - считываем состояние шины - ждем конца слота 45мкс

Где же косяк то? :wacko:

Изменено пользователем TWIN
Ссылка на комментарий
Поделиться на другие сайты

Кстати, задержки в коде реализую так:

delay.h

#define CPU_CLK_Hz 16000000
#define CPU_CLK_kHz (unsigned long)(CPU_CLK_Hz/1000)

#define delay_ns(x) __delay_cycles(x*CPU_CLK_kHz*0.000001)
#define delay_us(x) __delay_cycles(x*(CPU_CLK_Hz/1000000))
#define delay_ms(x) __delay_cycles(x*(CPU_CLK_Hz/1000))
#define delay_s(x) __delay_cycles(x*CPU_CLK_Hz)

Ну и в коде просто использую delay_us(...)

Изменено пользователем TWIN
Ссылка на комментарий
Поделиться на другие сайты

Для того чтобы чтение шло, необходимо как минимум перед этим сделать reset, skip ROM и read scratchpad, после чего, отсчитав 16 таймслотов чтения, снова сделать reset. Осторожно предположу, что если при чтении одни единицы, то датчик просто не отвечает, а значит его и не спросили должным образом. Так что придется опубликовать остальной код...

Изменено пользователем my504

戦う前に相手のベルトの色に注目

Ссылка на комментарий
Поделиться на другие сайты

Да вроде бы все так и делаю... Кстати, по апноуту от DALLAS AN162. Да и датчик отзывается сигналом presence...

Привожу код:

  
char* Read_Temperature(void) 
{
 char get[10];
 char temp_lsb, temp_msb; 
 int k;   

		ow_reset(); 
		OneWire_WriteByte(0xCC);  // Skip ROM
		OneWire_WriteByte(0x44);  // Start conv

		delay_us(750); 
		ow_reset(); 
		OneWire_WriteByte(0xCC);  // Skip ROM
		OneWire_WriteByte(0xBE);  // Read Scratch Pad

		for (k=0;k<9;k++)
		{			  
		  get[k]=OneWire_ReadByte();			
		} 

		temp_msb = get[1]; // Sign byte + lsbit 
		temp_lsb = get[0]; // Temp data plus lsb 

		sprintf(tempBuffer, "PAD: %X %X", get[0], get[1]);			 
		return  tempBuffer;
}

Изменено пользователем TWIN
Ссылка на комментарий
Поделиться на другие сайты

Вычитал тут в инете, что при реализации 1Wire на Си возможны проблемы с временными задержками, а именно при чтении бита - проблемы с попаданием в импульс датчика, возможно, поэтому у меня все байты FF? Просто ни разу не считывает 0...

В связи с этим такая мысль - написать функцию со вставкой на асме, параметром в которую должно передаваться кол-во микросекунд бездействия. Я асм совсем не знаю! Пожалуйста, прошу прокомментировать эту идею и помочь с написанием, кто знает асм?

Ссылка на комментарий
Поделиться на другие сайты

Ну всё! Блиииин, какая досадная ошибка! Сколько раз перечитывал код!!!!! :(

Всё оказалось очень просто! При передаче бита датчику, в конце функции не переводил шину в "Z"... Сколько потрачено сил и времени :(

Изменено пользователем TWIN
Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...