stm32 ds18b20

Кто любит RISC в жизни, заходим, не стесняемся.
ivan dimir
Мучитель микросхем
Сообщения: 440
Зарегистрирован: Вс дек 29, 2019 08:05:21

Re: stm32 ds18b20

Сообщение ivan dimir »

Добавлено after 5 hours 26 minutes 13 seconds:
Спойлер

Код: Выделить всё

#include "DS18B20.h"
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#define NOID 0xCC //Пропустить идентификацию
#define T_CONVERT  0x44 //Код измерения температуры
#define READ_DATA 0xBE //Передача байтов ведущему



#define PORTTEMP PORTD
#define DDRTEMP DDRD
#define PINTEMP PIND
#define BITTEMP 1

//функция определения датчика на шине
char dt_testdevice(void) //dt - digital termomether | определим, есть ли устройство на шине
{
	//char stektemp=SREG;// сохраним значение стека
	cli(); //запрещаем прерывание
	char dt;
	DDRTEMP |= 1<<BITTEMP; //притягиваем шину
	_delay_us(485); //задержка как минимум на 480 микросекунд
	DDRTEMP &= ~(1<<BITTEMP); //отпускаем шину
	_delay_us(65); //задержка как максимум на 60 микросекунд
	if ((PINTEMP & (1<<BITTEMP))==0)//проверяем, ответит ли устройство
	{
		dt=1;//устройство есть
	} 
	else dt=0;//устройства нет
	//SREG = stektemp;// вернем значение стека
	_delay_us(420); //задержка как минимум на 480 микросекунд, но хватит и 420, тк это с учетом времени прошедших команд
	return dt; //вернем результат
}


//функция записи бита на устройство
void dt_sendbit(char bt)
{
	//char stektemp=SREG;// сохраним значение стека
	cli(); //запрещаем прерывание
	DDRTEMP |= 1<<BITTEMP; //притягиваем шину
	_delay_us(2); //задержка как минимум на 2 микросекунды
	if(bt)
		DDRTEMP &= ~(1<<BITTEMP); //отпускаем шину
	_delay_us(65); //задержка как минимум на 60 микросекунд
	DDRTEMP &= ~(1<<BITTEMP); //отпускаем шину
	//SREG = stektemp;// вернем значение стека
}
//функция записи байта на устройство
void dt_sendbyte(unsigned char bt)
{
	char i;		
	for(i=0;i<8;i++)//посылаем отдельно каждый бит на устройство
	{
		if((bt & (1<<i)) == 1<<i)//посылаем 1
			dt_sendbit(1);
		else //посылаем 0
			dt_sendbit(0);
	}	
}

//функция чтения бита с устройства
char dt_readbit(void)
{
	//char stektemp=SREG;// сохраним значение стека
	cli(); //запрещаем прерывание
	char bt; //переменная хранения бита
	DDRTEMP |= 1<<BITTEMP; //притягиваем шину
	_delay_us(2); //задержка как минимум на 2 микросекунды
	DDRTEMP &= ~(1<<BITTEMP); //отпускаем шину
	_delay_us(13);
	bt = (PINTEMP & (1<<BITTEMP))>>BITTEMP; //читаем бит
	_delay_us(45);
//	SREG = stektemp;// вернем значение стека
	return bt; //вернем результат
}

//функция чтения байта с устройства
unsigned char dt_readbyte(void)
{
	char c=0;
	char i;
	for(i=0;i<8;i++)
		c|=dt_readbit()<<i; //читаем бит
	return c;
}

//функция преобразования показаний датчика в температуру
int dt_check(void)
{
	unsigned char bt;//переменная для считывания байта
	unsigned int tt=0;
	if(dt_testdevice()==1) //если устройство нашлось
	{
		dt_sendbyte(NOID); //пропустить идентификацию, тк у нас только одно устройство на шине
		dt_sendbyte(T_CONVERT); //измеряем температуру
		_delay_ms(750); //в 12битном режиме преобразования - 750 милисекунд
		dt_testdevice(); //снова используем  те же манипуляции с шиной что и при проверке ее присутствия
		dt_sendbyte(NOID); //пропустить идентификацию, тк у нас только одно устройство на шине
		dt_sendbyte(READ_DATA); //даем команду на чтение данных с устройства
		bt = dt_readbyte(); //читаем младший бит
		tt = dt_readbyte(); //читаем старший бит MS
		tt = (tt<<8)|bt;//сдвигаем старший влево, младший пишем на его место, тем самым получаем общий результат
	}
	return tt;
}
uint8_t ds18b20_GetSign(uint16_t dt)
{
  //Проверим 11-й бит
  if (dt&(1<<11)) return 1;
  else return 0;
}
//преобразование температуры в единицы
char converttemp (unsigned int tt)
{
	char t = tt>>4;//сдвиг и отсечение части старшего байта
	return t;
}
Спойлер

Код: Выделить всё

/*
 * 1-wire(mega32a).c
 *
 * Created: 13.03.2018 5:40:10
 * Author : User
 */ 
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include <stdio.h>

#include "DS18B20.h"


//#include "adc.h"
#include "lcd.h"

	unsigned int tt=0;
	unsigned char S=0;
	
 
void inits_ports(void)
{
	
	
	DDRB=0xFF;
	PORTB=0x00;
	DDRC|=(1<<2);
	PORTC|=(0<<2);
	DDRA=0x00;
	PORTA=0x00;
   DDRD=0xFF;
	PORTD=0x00;
	
}


int main(void)
{
	
	//unsigned int tt=0;
	
	inits_ports();
	//init_ADC();
	lcd_init(LCD_DISP_ON);
	lcd_clrscr();
   
    while (1) 
    {
		tt = converttemp(dt_check());
		if (tt<0)
		{
			tt=(0-tt)/16;
			//tt=-tt;
		  lcd_gotoxy(0,1);
	       lcd_data('-');
	      lcd_data(tt/10+0x30);
	      lcd_data(tt%10+0x30);
	       lcd_data('*');
	      lcd_data('C');
			
		} 
		else
		{
		  lcd_gotoxy(0,1);
	       lcd_data(' ');
		  
	      lcd_data(tt/10+0x30);
	      lcd_data(tt%10+0x30);
	       lcd_data('*');
	      lcd_data('C');
			
		}
		
	  
    }
}

что не так ?На минусах не работает.
Играюсь на AVR
Аватара пользователя
Eddy_Em
Собутыльник Кота
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01
Контактная информация:

Re: stm32 ds18b20

Сообщение Eddy_Em »

Все очень просто:

Код: Выделить всё

    uint16_t l = r[0], m = r[1], v;
    int32_t t;
    if(r[4] == 0xff){ // DS18S20
        t = ((uint32_t)l) * 10;
        t >>= 1;
	}else{ // DS18B20
        v = ((m & 7) << 8)| l;
        t = ((uint32_t)v)*10;
        t >>= 4;
	}
    if(m & 0x80) t = -t;
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
veso74
Поставщик валерьянки для Кота
Сообщения: 1904
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

Re: stm32 ds18b20

Сообщение veso74 »

С другими компиляторами/микроконтроллерами здесь это даст предупреждение: сравнение не имеет смысла.

Код: Выделить всё

unsigned int tt=0;
...
if (tt<0) ...
Узнайте, что хотите, и первое: исправьте типы данных.

---
CCS:

Код: Выделить всё

#include <main.h>
unsigned int tt = 0;
void main() {
  while(TRUE) {
     if (tt < 0) {
...

Код: Выделить всё

>>> Warning 205 "... main.c" Line 6(1,1): Unsigned variable is never less than zero
>>> Warning 204 "... main.c" Line 6(1,1): Condition always FALSE
---
Arduino IDE:

Код: Выделить всё

unsigned int tt = 0;
  if (tt < 0) {
  }

Код: Выделить всё

7:10: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits]
   if (tt < 0) {
ivan dimir
Мучитель микросхем
Сообщения: 440
Зарегистрирован: Вс дек 29, 2019 08:05:21

Re: stm32 ds18b20

Сообщение ivan dimir »

[uquote="Eddy_Em",url="/forum/viewtopic.php?p=4244883#p4244883"]Все очень просто:

Код: Выделить всё

    uint16_t l = r[0], m = r[1], v;
    int32_t t;
    if(r[4] == 0xff){ // DS18S20
        t = ((uint32_t)l) * 10;
        t >>= 1;
	}else{ // DS18B20
        v = ((m & 7) << 8)| l;
        t = ((uint32_t)v)*10;
        t >>= 4;
	}
    if(m & 0x80) t = -t;
[/uquote]
У вас много переменных вы хоть бы закоментировали обозначили а и б сидели на трубе.
А у меня нет варнингов Микрочип студию использываю для AVR.
Я всё понимаю что программу мою нужно переработать.Так откуда начать перерабатывать.?Я понимаю что нужно две переменные для положительной температуры и для отрицательной.А дальше поплыл мозгами.
Аватара пользователя
AlanDrakes
Прорезались зубы
Сообщения: 236
Зарегистрирован: Пн июл 04, 2016 16:51:22
Откуда: Россия, Омск

Re: stm32 ds18b20

Сообщение AlanDrakes »

Код: Выделить всё

extern uint8_t ow_Answ[9]; // Внешняя глобальная (мне хвостом, что это не кошерно!) переменная, которая хранит полный ответ датчика (значение из его Scratch Pad), включая температуру и настройки предупреждений.
// Код в другом файле исходника просто циклически отправляет команду оцифровки температуры и производит чтение данных.

int16_t curr_temp; // Переменная хранит текущую температуру. ЗНАКОВАЯ.

<...>
curr_temp = ((ow_Answ[1] << 8) | ow_Answ[0]); // Получаем СЫРЫЕ байты ответа от DS18B20.
curr_temp = curr_temp / 16; // Убираем дробную часть
curr_temp = curr_temp * 10; // Домножаем на 10
// И прибавляем дробную.
curr_temp += (((ow_Answ[0] & 0x0F) >> 1) + ((ow_Answ[0] & 0x0F) >> 2));
УСЁ. В переменной находится целочисленное(!) значение температуры в градусах цельсия, домноженное на 10.
0° = 0
12,3° = 123
-55° = -550

Почему-то все начали биться с дополнительными битами температуры, а DS уже возвращает число в формате INT16, знаковом.
Откройте даташит на датчик, долистайте до таблицы 1 `Table 1. Temperature/Data Relationship`, возьмите отрицательную температуру из примера, вбейте в калькулятор, который умеет переводить системы счисления и... И вдруг сходится!
scr_1.png
(112.35 КБ) 64 скачивания
ivan dimir
Мучитель микросхем
Сообщения: 440
Зарегистрирован: Вс дек 29, 2019 08:05:21

Re: stm32 ds18b20

Сообщение ivan dimir »

Спойлер
int16_t curr_temp;extern uint8_t ow_Answ[9];
Хорошо у меня есть переменная int tt=int16_t curr_temp;А вторая переменная это массив?и почему экстерн.?И как всё это вывести на lcd7
veso74
Поставщик валерьянки для Кота
Сообщения: 1904
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

Re: stm32 ds18b20

Сообщение veso74 »

[uquote="ivan dimir",url="/forum/viewtopic.php?p=4244920#p4244920"]... Я понимаю что нужно две переменные для положительной температуры и для отрицательной.[/uquote]
The temperature data is stored as a 16-bit sign-extended two’s complement number in the temperature register (see Figure 4).
The sign bits (S) indicate if the temperature is positive or negative: for positive numbers S = 0 and for negative numbers S = 1.

Нет. Она одна, со знаком. (см. как обозначается знак в 16-битных целочисленных выражениях - бинарная математика).

пример (стр. 6 из pdf-а DS18B20):
-10.125 oC = 0b1111 1111 0101 1110 = 0xFF5E

-------

попробуйте:

Код: Выделить всё

//функция преобразования показаний датчика в температуру
int dt_check(void) {
  int bt;                     //переменная для считывания байта
  int tt = 0;

  if (dt_testdevice() == 1) { //если устройство нашлось
    dt_sendbyte(NOID);        //пропустить идентификацию, тк у нас только одно устройство на шине
    dt_sendbyte(T_CONVERT);   //измеряем температуру
    _delay_ms(750);           //в 12битном режиме преобразования - 750 милисекунд
    dt_testdevice();          //снова используем  те же манипуляции с шиной что и при проверке ее присутствия
    dt_sendbyte(NOID);        //пропустить идентификацию, тк у нас только одно устройство на шине
    dt_sendbyte(READ_DATA);   //даем команду на чтение данных с устройства
    bt = dt_readbyte();       //читаем младший бит
    tt = dt_readbyte();       //читаем старший бит MS
  }
  return ((tt << 8) | bt);    //сдвигаем старший влево, младший пишем на его место, тем самым получаем общий результат
}
затем используйте функцию:
int temp = dt_check() * 5 / 8;
Будет температура * 10 со знаком (+ или -).

Примеры:
256 = 25,6 оC
-54 = -5,4 оC
Последний раз редактировалось veso74 Пн июн 13, 2022 18:19:18, всего редактировалось 2 раза.
Аватара пользователя
Eddy_Em
Собутыльник Кота
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01
Контактная информация:

Re: stm32 ds18b20

Сообщение Eddy_Em »

[uquote="ivan dimir",url="/forum/viewtopic.php?p=4244920#p4244920"]У вас много переменных вы хоть бы закоментировали обозначили а и б сидели на трубе.[/uquote]
Не нужны там комментарии: и так все ясно же!
Кстати, я там сильно перемудрил: достаточно было сделать температуру int16_t, и не пришлось бы эти пляски с масками устраивать!
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
veso74
Поставщик валерьянки для Кота
Сообщения: 1904
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

Re: stm32 ds18b20

Сообщение veso74 »

Eddy_Em, tnx за идею обработки ниже нуля.
При t * 5 / 8 с отрицательным числом иногда теряю 0,1 через шаг например. (По первой идее - от переполнения?)
Последний раз редактировалось veso74 Пн июн 13, 2022 20:52:40, всего редактировалось 4 раза.
ivan dimir
Мучитель микросхем
Сообщения: 440
Зарегистрирован: Вс дек 29, 2019 08:05:21

Re: stm32 ds18b20

Сообщение ivan dimir »

Всё так туманно не прозрачно.
Аватара пользователя
Eddy_Em
Собутыльник Кота
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01
Контактная информация:

Re: stm32 ds18b20

Сообщение Eddy_Em »

[uquote="veso74",url="/forum/viewtopic.php?p=4244997#p4244997"]иногда теряю 0,1 через шаг например[/uquote]
Учитывая то, что у DS18 точность - хуже ±0.5℃, вообще не нужно на десятые заморачиваться. Можно сразу в целых градусах Цельсия выводить результат, все равно брехня!
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
ivan dimir
Мучитель микросхем
Сообщения: 440
Зарегистрирован: Вс дек 29, 2019 08:05:21

Re: stm32 ds18b20

Сообщение ivan dimir »

[uquote="Eddy_Em",url="/forum/viewtopic.php?p=4245000#p4245000"][uquote="veso74",url="/forum/viewtopic.php?p=4244997#p4244997"]иногда теряю 0,1 через шаг например[/uquote]
Учитывая то, что у DS18 точность - хуже ±0.5℃, вообще не нужно на десятые заморачиваться. Можно сразу в целых градусах Цельсия выводить результат, все равно брехня![/uquote]
Так покажите полную картину вывода на экран LCD?.А то кусочек секса не интересно.
И вообще СССР мертвое государство как Атлантида.
veso74
Поставщик валерьянки для Кота
Сообщения: 1904
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

Re: stm32 ds18b20

Сообщение veso74 »

[uquote="Eddy_Em",url="/forum/viewtopic.php?p=4245000#p4245000"]Учитывая то, что у DS18 точность - хуже ±0.5℃ ..![/uquote]
А, нееет, мне нужны показания. DS18B20 можно исползовать даже как датчик присутствия! :)
Зима например, вношу чашку горячее кофе в комнате, на 1 метр и уже через 3 минуты могу сказать, что есть кофе в комнате :).
Есть рост t + 0,2 оC.
---
То ли Протеус грешит при -t, то ли другого, еще не исправил неточность ...
Последний раз редактировалось veso74 Пн июн 13, 2022 20:54:56, всего редактировалось 1 раз.
Аватара пользователя
Eddy_Em
Собутыльник Кота
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01
Контактная информация:

Re: stm32 ds18b20

Сообщение Eddy_Em »

veso74, согласен: относительную температуру вроде бы более-менее измеряет. Но вот воспроизводимость никакущая. Хоть калибруй — все равно ±0.1℃ не получить.
Поэтому я и советовал обычный дешевый терморезистор. Тот, правда, по какому-нибудь хорошему термометру нужно будет откалибровать, зато тоже ±0.5℃ получим. Я себе делал контроллер домашней файлопомойки: 4 точки измерения температуры, для упрощения вычислений - кусочно-линейная аппроксимация калибровочной кривой.
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
veso74
Поставщик валерьянки для Кота
Сообщения: 1904
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

Re: stm32 ds18b20

Сообщение veso74 »

А, нет: ставлю DS18, пишу две цифры и все, реле готово. :) Не хочу откалибровать датчик. На этот путь не раз за годы прошел. Так уже легче.
Последний раз редактировалось veso74 Вт июн 14, 2022 01:17:02, всего редактировалось 1 раз.
Аватара пользователя
Eddy_Em
Собутыльник Кота
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01
Контактная информация:

Re: stm32 ds18b20

Сообщение Eddy_Em »

Ну, это до поры — до времени, пока не нужно будет измерять температуры за пределами возможностей DS18. Скажем, температуру вблизи кипения азота я измерял платиновыми терморезисторами (на 2010г стоили почти по 1000р за штучку), для температур выше кипения воды при н.у. нужны будут тоже или терморезисторы или термопары.
В общем, помимо простейших вариантов всегда полезно в загашнике иметь разнообразие.
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
veso74
Поставщик валерьянки для Кота
Сообщения: 1904
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

Re: stm32 ds18b20

Сообщение veso74 »

пфу, непонятно что грешит:
(знак - поставлю позже)

Код: Выделить всё

tt = ds1820_read();
printf("T = %LX\r\n", tt);
printf("T = %Lu\r\n", tt);
if (tt < 0)
  tt = -tt;
printf("T = %Lu\r\n", tt);
printf("T = %Lu\r\n", tt * 5 / 8);
show_display(tt * 5 / 8 );          // temp * 10
А на -0,5 oC - ОК.
Вложения
2.jpg
(119.11 КБ) 57 скачиваний
1.jpg
(153.33 КБ) 52 скачивания
Аватара пользователя
Карбофос
Опытный кот
Сообщения: 760
Зарегистрирован: Сб окт 22, 2016 17:33:32
Откуда: кг

Re: stm32 ds18b20

Сообщение Карбофос »

[uquote="AlanDrakes",url="/forum/viewtopic.php?p=4244931#p4244931"]УСЁ. В переменной находится целочисленное(!) значение температуры в градусах цельсия, домноженное на 10.[/uquote]
Хорошее решение.
Я делал так:

Код: Выделить всё

uint16_t t;
uint8_t s, d;
if(temperature < 0) {
    s = 1;
    t = -temperature;
} else {
    s = 0;
    t =  temperature;
}
d = t & 0b1111;
// *5, /8 с округлением
d += d << 2; d += 4; d >>= 3;
t >>= 4;
sprintf(aTextOut, " Temperature = %s%u.%u", s ? "-" : "+", t, d);
Последний раз редактировалось Карбофос Пн июн 13, 2022 21:22:30, всего редактировалось 1 раз.
veso74
Поставщик валерьянки для Кота
Сообщения: 1904
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

Re: stm32 ds18b20

Сообщение veso74 »

Вопрос снят. Ошибка: из-за шага изменения.
Последний раз редактировалось veso74 Вт июн 14, 2022 01:35:52, всего редактировалось 3 раза.
Аватара пользователя
Карбофос
Опытный кот
Сообщения: 760
Зарегистрирован: Сб окт 22, 2016 17:33:32
Откуда: кг

Re: stm32 ds18b20

Сообщение Карбофос »

А что вы к этому DS18B20 привязались?
0.5% погрешность по дш, тормозной как черепаха.
MF52 капелька, реактивный.
+-0.1грС легко с 12-битным АЦП.
Ответить

Вернуться в «ARM»