Страница 1 из 1

ATmega16 не находит DS18S20

Добавлено: Чт дек 24, 2009 17:03:10
st_silver
Здравствуйте столкнулся с проблемой. Необходимо подключить DS18S20 к ATmega16 и вывести температуру на LCD дисплей. Нашел в интернете исходник на си, скомпилировал, собрал в Proteus схему и зашил микроконтроллер... не работает... Не могу разобраться чем проблема, помогите пожалуйста!

/* Multipoint thermometer with LCD display
using the Dallas Semiconductor DS1820/18S20
1 Wire bus temperature sensors

CodeVisionAVR C Compiler
(C) 2000-2007 HP InfoTech S.R.L.
www.hpinfotech.ro

Chip: ATmega8515
Memory Model: SMALL
Data Stack Size: 128 bytes

PLEASE MAKE SURE THAT THE CKSEL0..3 FUSE
BITS ARE PROGRAMMED TO USE THE EXTERNAL
3.6864MHz CLOCK SOURCE OF THE STK500 AND NOT
THE INTERNAL 1MHz OSCILLATOR.
The ATmega8515 chip comes from the factory
with CKSEL0..3 fuse bits set to use the
internal 1 MHz oscillator.

The DS1820/18S20 sensors are connected to
bit 6 of PORTA of the ATmega8515 as follows:

[DS1820/18S20] [STK500 PORTA HEADER]
1 GND - 9 GND
2 DQ - 7 PA6
3 VDD - 10 +5V

All the temperature sensors must be connected
in parallel

AN 4.7k PULLUP RESISTOR MUST BE CONNECTED
BETWEEN DQ (PA6) AND +5V !
*/
#asm
.equ __w1_port=0x12
.equ __w1_bit=0
#endasm

/* Use an 2x16 alphanumeric LCD connected
to PORTC as follows:

[LCD] [STK500 PORTC HEADER]
1 GND- 9 GND
2 +5V- 10 VCC
3 VLC- LCD contrast control voltage 0..1V
4 RS - 1 PC0
5 RD - 2 PC1
6 EN - 3 PC2
11 D4 - 5 PC4
12 D5 - 6 PC5
13 D6 - 7 PC6
14 D7 - 8 PC7
*/

#asm
.equ __lcd_port=0x15
#endasm

#include <lcd> // LCD driver routines
#include <ds1820>
#include <delay>
#include <stdio>

char lcd_buffer[33];

/* maximum number of DS1820/DS18S20 connected to the 1 Wire bus */
#define MAX_DEVICES 8

/* DS1820/DS18S20 devices ROM code storage area */
unsigned char rom_code[MAX_DEVICES][9];

main()
{
unsigned char i,j,devices;
int temp;

lcd_init(16);
lcd_putsf("CodeVisionAVR\n1 Wire Bus Demo");
delay_ms(2000);
lcd_clear();

/* detect how many DS1820/DS18S20 devices
are connected to the 1 Wire bus */
devices=w1_search(0xf0,rom_code);
sprintf(lcd_buffer,"%u DS1820\nDevice detected",devices);
lcd_puts(lcd_buffer);
delay_ms(2000);

/* display the ROM codes for each device */
if (devices)
{
for (i=0;i<devices;i++)
{
sprintf(lcd_buffer,"Device #%u ROM\nCode is:",i+1);
lcd_clear();
lcd_puts(lcd_buffer);
delay_ms(2000);
lcd_clear();
for (j=0;j<8;j++)
{
sprintf(lcd_buffer,"%02X ",rom_code[j]);
lcd_puts(lcd_buffer);
if (j==3) lcd_gotoxy(0,1);
};
delay_ms(5000);
};
}
else
while (1); /* stop here if no devices were found */

/* measure and display the temperature(s) */
while (1)
{
for (i=0;i<devices;)
{
temp=ds1820_temperature_10(&rom_code[0]);
j='+';
if (temp<0)
{
j='-';
temp=-temp;
};
sprintf(lcd_buffer,"t%u=%c%i.%u\xdfC",++i,j,temp/10,temp%10);
lcd_clear();
lcd_puts(lcd_buffer);
delay_ms(800);
};
};
}

Как я понял проблема в строке "devices=w1_search(0xf0,rom_code);", но что тут может быть неправильно мне абсолютно не понятно!!
Ах да чуть не забыл, исходник написан под много датчиков, а как сделать чтобы микроконтроллер не опрашивал датчики, а сразу снимал показания с одного единственного!

Добавлено: Чт дек 24, 2009 17:10:06
sheva_s
Не знаю правильно ли написана программа но попробуйте для начала увеличить частоту тактирования микроконтроллера минимум до 4 мГц. У меня при полностью рабочей программе на 1 мГц работать не хотело.

Добавлено: Чт дек 24, 2009 17:18:41
st_silver
sheva_s писал(а):Не знаю правильно ли написана программа но попробуйте для начала увеличить частоту тактирования микроконтроллера минимум до 4 мГц. У меня при полностью рабочей программе на 1 мГц работать не хотело.
Ну надо же насколько все просто))) Действительно как только я поднял частоту датчик сразу же откликнулся! Спасибо большое...
Программа кстати работает, причем правильно, только кгда выдает температуру показывает сначала +85.0, а уже потом меняет на показания датчика не стирая знак "+"... Ну это мы сейчас исправим)))

Добавлено: Чт дек 24, 2009 23:36:04
Игорь Владимирович
Два маленьких совета по исп. ДС18Б20

При использовании одного датчика, можно пропустить выбор датчика по серийному номеру. После старта надо ждать 800 мс ессно:
//========
// Старт преобразования DS18B20
//========
void start_conv (void)
{
while(w1_init()==0)
{
lcd_clear();
lcd_putsf("1W ERROR!");
delay_ms(1000);
}

w1_init(); // 1W инициализация, старт записи
w1_write(0xCC); // пропустить ROM
w1_write(0x44); // старт преобразования
}

Конвертирование температуры:
Температура хранится в переменной Темр в таком формате, что первый знак, десятые доли, остальное - целое число тем-ры:
//========
// Вычисление температуры DS18B20
//========
void get_temp (void)
{
char integer;
int frac;

ds18b20_read_spd(0); // Читаем scratcpad

if (__ds18b20_scratch_pad.temp_msb & 0xF8) // Проверка знака температуры, если "-" то выполнить
{
integer=((((~__ds18b20_scratch_pad.temp_msb) & 0x07)<<4>>4));
frac=(10000-((__ds18b20_scratch_pad.temp_lsb & 0x0F)*625));
if (frac==10000)
{
integer++;
frac=0;
};
if (integer>=50)
{
integer=50;
frac=0;
};
temp=0-(((int)integer)*10+frac/1000);
}
else
{
integer=(((__ds18b20_scratch_pad.temp_msb & 0x07)<<4>>4));
frac=((__ds18b20_scratch_pad.temp_lsb & 0x0F)*625);
if (integer>=99)
{
integer=99;
frac=0;
};
temp=(((int)integer)*10+frac/1000);
};
}

Добавлено: Пн дек 28, 2009 05:29:39
Vov123
С одним датчиком:
#include <mega8535>

// 1 Wire Bus functions
#asm
.equ __w1_port=0x15 ;PORTC
.equ __w1_bit=7
#endasm
#include <1wire>
#include <ds1820>


}

void main(void)
{

int temp; //результат температуры
w1_init(); // 1 Wire инициализация

while (1)
{
temp=ds1820_temperature_10(0); //получаем значение температуры
//преобразовываем и выводим куда надо

};
}