Страница 1 из 3
термометр в codevision ds18b20
Добавлено: Чт окт 02, 2008 22:14:05
skalish
Я новичок в программировании пытаюсь собрать термометр в codevisionavr з двома датчиками температуры DS18B20 , МК ATMEGA8 и LCD LM016L
При запуске,МК находит только один датчик. Что я делаю не так?
#include <mega8>
#asm
.equ __w1_port=0x15 ;PORTC
.equ __w1_bit=0
#endasm
#include <1wire>
#include <ds18b20>
#define MAX_DS1820 8
unsigned char rom_codes[MAX_DS1820][9];
#include <stdio>
char lcd_buffer[33];
#include <delay>
#asm
.equ __lcd_port=0x18 ;PORTB
#endasm
#include <lcd>
int temp[8];
void main(void)
{
unsigned char devices,i;
lcd_init(16);
delay_ms(200);
devices=w1_search(0xf0,rom_codes);
sprintf(lcd_buffer," devices=%u",devices); // devices = 1 ): ???
lcd_clear();
lcd_puts(lcd_buffer);
delay_ms(2000);
while (1)
{
temp[0]=ds18b20_temperature(&rom_codes[0]);
if (temp>1000){
temp[0]=4096-temp[0];
temp[0]=-temp[0];
}
sprintf(lcd_buffer,"t=%i.%u\xdfC",temp[0],temp[0]%1);
lcd_clear();
lcd_puts(lcd_buffer);
delay_ms(500);
};
}
Добавлено: Чт окт 02, 2008 22:50:50
alex2103
Код: Выделить всё
unsigned char devices,i;
lcd_init(16);
delay_ms(200);
devices=w1_search(0xf0,rom_codes);
попробуй больше задержку сделать[/quote]
Добавлено: Чт окт 02, 2008 23:11:58
Goodefine
Посмотрите здесь. Сделано на основе Helpa. Интерфейс 1-wire. Код имеет некоторые особенности, но насколько я помню, несколько устройств он находил...
http://forum.cxem.net/index.php?s=&show ... t&p=246243
Добавлено: Пт окт 03, 2008 09:15:28
skalish
MK знаходить только разные датчики наприклад: ds18b20+ds18s20+ds1822...а якщо поставить однакови дачикы ds18b20+ds18b20...то мк бачить только один датчик .
МК может працювати з однаковими датчиками? якщо так то як це реализувати?
Добавлено: Пт окт 03, 2008 10:05:10
Goodefine
А это в железе или в симуляторе? Если в Протеусе то серийные номера датчикам поставить разные надо. Иначе по одному и найдет.
Вот рабочий пример (для симулятора):
Код: Выделить всё
/*****************************************************
Chip type : ATmega16
Program type : Application
Clock frequency : 16,000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 256
*****************************************************/
#include <mega16>
// 1 Wire Bus functions
#asm
.equ __w1_port=0x18 ;PORTB
.equ __w1_bit=2
#endasm
#include <1wire>
#include <delay>
// Standard Input/Output functions
#define DS1990_FAMILY_CODE 1
#define DS2405_FAMILY_CODE 5
#define DS1822_FAMILY_CODE 0x22
#define DS2430_FAMILY_CODE 0x14
#define DS2431_FAMILY_CODE 0x2d
#define DS18S20_FAMILY_CODE 0x10
#define DS18B20_FAMILY_CODE 0x28
#define DS2433_FAMILY_CODE 0x23
#define SEARCH_ROM 0xF0
#include <stdio>
#define MAX_DEVICES 8
unsigned char rom_code[MAX_DEVICES,9];
void main(void)
{
// Declare your local variables here
unsigned char i,j,devices;
unsigned char n=1;
unsigned int addr = 1;
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud rate: 9600
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x67;
#asm("sei")
printf("1-Wire MicroLan Net demo\n\r");
devices=w1_search(SEARCH_ROM,&rom_code[0,0]);
printf("%u device(s) found\n\r",devices);
for (i=0;i<devices;i++)
{
// Acknowledge DS1990 family code.
if (rom_code[i,0]==DS1990_FAMILY_CODE)
printf("DS1990 #%u serial number:",n++);
// Acknowledge DS2405s family code.
else if (rom_code[i,0]==DS2405_FAMILY_CODE)
printf("DS2405 #%u serial number:",n++);
// Acknowledge DS1822s family code.
else if (rom_code[i,0]==DS1822_FAMILY_CODE)
printf("DS1822 #%u serial number:",n++);
// Acknowledge DS2430s family code.
else if (rom_code[i,0]==DS2430_FAMILY_CODE)
printf("DS2430 #%u serial number:",n++);
// Acknowledge DS18S20s family code.
else if (rom_code[i,0]==DS18S20_FAMILY_CODE)
printf("DS18S20 #%u serial number:",n++);
else if (rom_code[i,0]==DS18B20_FAMILY_CODE)
printf("DS18B20 #%u serial number:",n++);
// Acknowledge DS2431 family code.
else if (rom_code[i,0]==DS2431_FAMILY_CODE)
printf("DS2431 #%u serial number:",n++);
// Acknowledge DS2433 family code.
else if (rom_code[i,0]==DS2433_FAMILY_CODE)
printf("DS2433 #%u serial number:",n++);
for (j=1;j<=6;j++) {
printf(" %02X",rom_code[i,j]);
};
printf("\n\r");
}
while (1)
{
};
}
Добавлено: Пт окт 03, 2008 10:06:09
ARV
МК должен находить любые датчики в любых комбинациях - и одинаковые и разные. если это не так - что-то не так в программе
Добавлено: Пт окт 03, 2008 10:16:32
Goodefine
ARV писал(а):МК должен находить любые датчики в любых комбинациях...
Может быть Вы не заметили, но человек использует библиотеку 1wire от CVAVR. Поиск числа устройств - функция этой библиотеки. Поэтому все претензии можно адресовать ее разработчику...
Добавлено: Пт окт 03, 2008 10:26:16
ARV
Goodefine писал(а):Может быть Вы не заметили, но человек использует библиотеку 1wire от CVAVR. Поиск числа устройств - функция этой библиотеки. Поэтому все претензии можно адресовать ее разработчику...
мне-то все равно, к кому претензии

исходники библиотечной функции там есть - так что все в силах пользователя
кстати, думаю, что функция как раз работает правильно...
Добавлено: Пт окт 03, 2008 10:37:39
tych
Goodefine писал(а): все претензии можно адресовать ее разработчику...
или в ДЕЗ или в СЭС ...
Добавлено: Пт окт 03, 2008 10:39:19
Goodefine
ARV писал(а):...исходники библиотечной функции там есть - так что все в силах пользователя

...
Правда? Вас не затруднит привести реализацию (без дизасма, разумеется)?
ARV писал(а):...кстати, думаю, что функция как раз работает правильно...
Судя по:
МК должен находить любые датчики в любых комбинациях - и одинаковые и разные. если это не так - что-то не так в программе
думаете Вы иначе...
Добавлено: Пт окт 03, 2008 11:04:49
ARV
Goodefine писал(а):Правда? Вас не затруднит привести реализацию (без дизасма, разумеется)?
пожалуй, я погорячился - исходников там много, но как раз не этой функции

так что увы...
а если кто недоволен - может сам написать функцию, да и писать-то особо нечего - исходник и так доступен - в одном из апноутов от Максима-с-Далласом

Добавлено: Пт окт 03, 2008 11:07:19
ARV
tych писал(а):Goodefine писал(а): все претензии можно адресовать ее разработчику...
или в ДЕЗ или в СЭС ...
ООН лучше. а еще лучше в ОБЭП - пусть нажмут на пиратов: ваще обнаглели, ломают, ломают - а оно потом не работает, как хочется! да еще, как выяснилось, и без исходников!
безобразие!!!
Добавлено: Пт окт 03, 2008 11:27:37
Goodefine
ARV писал(а):...а если кто недоволен...
ИМХО, серийники уникальны по определению, так что повода для недовольства в этом плане быть не должно

...
Добавлено: Пт окт 03, 2008 11:44:44
skalish
А это в железе или в симуляторе? Если в Протеусе то серийные номера датчикам поставить разные надо. Иначе по одному и найдет.
Огромное спасибо после замене серийные номера датчика в протеуси все заработало
Добавлено: Пт окт 03, 2008 11:56:53
Goodefine
Результат отображается с одним значащим знаком после запятой, но если выставить градацию датчиков в 0.5С точности это не прибавляет (15.0С и 15.5С отображаются как 15.0С) - Вас это устраивает?
Добавлено: Сб окт 04, 2008 12:41:05
skalish
Результат отображается с одним значащим знаком после запятой, но если выставить градацию датчиков в 0.5С точности это не прибавляет (15.0С и 15.5С отображаются как 15.0С) - Вас это устраивает?
Нет не устраивает
Как вывести на LCD перемену типа float ?
Мне необходим сам алгоритм преобразования
float в char .
Добавлено: Вс окт 05, 2008 08:57:02
Krik99
Меряй сразу в signed int , плюс будет менше ресурсов жрать, так как не надо переводить. Я так делаю (код для измерения с десятичными в переменную int):
Код: Выделить всё
int ds18b20_temperature_10(unsigned char *addr)
{
int temper;
unsigned char resolution;
if (ds18b20_read_spd(addr)==0) return -9999;
resolution=(__ds18b20_scratch_pad.conf_register>>5) & 3;
if (ds18b20_select(addr)==0) return -9999;
#asm("cli")
w1_write(0x44);
#asm("sei")
delay_ms(conv_delay[resolution]);
if (ds18b20_read_spd(addr)==0) return -9999;
#asm("cli")
w1_init();
#asm("sei")
return ((*((int *) &__ds18b20_scratch_pad.temp_lsb) & bit_mask[resolution])*10)>>4;
}
Это надо ввести в либу и изменить ds18b20.h , так как у нас функция без плавающе запятой. Значения приймёш типа такого 127 = 12,7*С.
Добавлено: Ср окт 15, 2008 00:48:31
Denis-d20
skalish писал(а):Результат отображается с одним значащим знаком после запятой, но если выставить градацию датчиков в 0.5С точности это не прибавляет (15.0С и 15.5С отображаются как 15.0С) - Вас это устраивает?
Нет не устраивает
Как вывести на LCD перемену типа float ?
Мне необходим сам алгоритм преобразования
float в char .
Напиши на аську 327117582 все докладно розкажу та покажу може й ти чим поділишся.
Добавлено: Ср окт 15, 2008 13:01:05
KIP
skalish писал(а):Как вывести на LCD перемену типа float ?
Переводишь число в строку символов функцией ftoa, и готовый массив гонишь в функцию вывода lcd.
Добавлено: Пт янв 09, 2009 20:49:20
CCCP
Добрый день. В продолжение темы.
Пример в CodeVision для работы с DS18B20, на мой взгляд не очень удачный. Одна из проблем в строке(файл DS18B20.lib)
В результате чего создаётся впечатление, что датчик сильно медленно работает. На самом деле "тормозит" программа.
Можно сделать так:
Код: Выделить всё
while(1)
{
///////////////////////////// какой-то код /////////////////////////////
if(temper_read) //если температура считана
{
#asm("cli")
w1_init();
w1_write(0xCC); //пропуск ROM чтобы обратиться ко всем датчикам одновременно
w1_write(0x44); //команда на преобразование для всех датчиков
#asm ("sei")
delay_ms(10); //пропуск импульсов ответа датчиков
temper_read=0;
};
///////////////////////////// какой-то код /////////////////////////////
if(PINB.3)//если показания готовы (по даташиту) PORTB.3 куда подкл датчик
{
#asm("cli")
temper=ds18b20_temperature_10(&rom_code[i][0]); // смотри на 3 сообщения выше (от Krik99)
#asm ("sei")
temper_read=1; // показания считаны можно запускать новое преобразование
};
///////////////////////////// какой-то код /////////////////////////////
};
Это рабочий код для трехпроводного проключения. Необходимо исправить библиотеку, удалив строки
Код: Выделить всё
#asm("cli")
w1_write(0x44);
#asm("sei")
delay_ms(conv_delay[resolution]);
#asm("cli")
w1_init();
#asm("sei")
Теперь программа не будет сидеть в одном месте почти секунду. Это для одного датчика, а для нескольких надо доработать вывод показаний. Я проверял с одним.
И собственно говоря вопрос - как можно прочитать регистр температуры датчика? В программировании я практически ничего не понимаю, как производится считывание в примере CodeVision мне не нравится (абсолютно ничего не понятно), поэтому и не нравится. Должна же быть команда BEh, но где она? Нужно просто получить 2 байта из датчика, как это сделать?