Witam, od paru dni męczę się z ds18b20, spakowałem go na płytkę testową, wszystko podłączone dobrze, nie na pasożytniczym tylko na normalnym zasilaniu. Odpowiada na reset a później już na nic.
Krótki kurs obsługi wziąłem z karty i z
http://tnij.org/ds18b20
Bardzo przyjemny pdf.
Program jest napisany na podstawie tego pdf. Jako, że podłączony jest tylko jeden ds to nie muszę nic adresować. Program wygląda tak:
Funkcje print i error są tylko do wyświetlania liczb, mam to wszystko dla testów na płytce testowej i dwóch diodach więc musiałem jakoś rozwiązać output
Żeby sprawdzić czy cokolwiek działa spróbowałem dać po resecie:
Czyli powinienem dostać adres. Ale niestety w każdej zmiennej tab jest liczba 2.
Jeżeli pytam go o temperature jak w głównym programie pokazuje 32. Czyli funkcja read_byte zwraca zawsze 2.
Jeżeli nie podepne termometru pod układ i zczytam temperaturę to też da mi 32. Read zawsze daje 2.
W sumie bez podpięcia termometru reset zwraca poprawny wynik więc coś jest z kodem. Mi się od razu wydawał podejrzany, tzn jest trochę dziwnych konstrukcji językowych ale myślałem że coś zadziała... Atmega jest na wewnętrznym rezonatorze 8MHz. Myślicie że może źle odmierzać czas prze _delay_us?
Proszę o jakiekolwiek rady.
Krótki kurs obsługi wziąłem z karty i z
http://tnij.org/ds18b20
Bardzo przyjemny pdf.
Program jest napisany na podstawie tego pdf. Jako, że podłączony jest tylko jeden ds to nie muszę nic adresować. Program wygląda tak:
Funkcje print i error są tylko do wyświetlania liczb, mam to wszystko dla testów na płytce testowej i dwóch diodach więc musiałem jakoś rozwiązać output
#include <avr/io.h>
#include <avr/delay.h>
#include <avr/signal.h>
#include<stdlib.h>
#include <lcd.h>
#define f_CPU 8000000
#define RED _BV(7)
#define GREEN _BV(5)
#define IN 4
#define DEL_TIME 500
#define WE 6
#define PORT_1Wire PINB
#define set DDRB&=~_BV(WE)
#define clear DDRB|=_BV(WE)
char buf[8];
//*************************************************************************************
void print(int x);
void wyswietl_temp(void);
void send(char bit);
unsigned char read(void);
void send_byte(char wartosc);
unsigned char read_byte(void);
void error(int i);
//*************************************************************************************
int main( void )
{
DDRD = 255;//output
DDRC = 0;//input
PORTC |= _BV(IN);//pullup
while(1)
{
if(bit_is_clear(PINC, IN)) //Wciśnięty
{
_delay_ms(500);
wyswietl_temp();
}
else
{
PORTD &= ~RED;
PORTD |= GREEN;
}
}
}
//*************************************************************************************
void print(int x)
{
int i;
if(x > 100)
{
//Na razie nie ma takiej opcji
}
else if(x > 10)
{
int tens = x / 10;
int ones = x % 10;
x = 10 % x;//jedności
for(i=0; i<ones; i++)
{
PORTD |= RED;
_delay_ms(DEL_TIME);
PORTD &= ~RED;
_delay_ms(DEL_TIME);
}
_delay_ms(1000);
//brejk
for(i=0; i<5; i++)
{
PORTD |= RED;
PORTD &= ~GREEN;
_delay_ms(50);
PORTD &= ~RED;
PORTD |= GREEN;
_delay_ms(50);
}
_delay_ms(1000);
for(i=0; i<tens; i++)
{
PORTD |= RED;
_delay_ms(DEL_TIME);
PORTD &= ~RED;
_delay_ms(DEL_TIME);
}
_delay_ms(1000);
//brejk
for(i=0; i<5; i++)
{
PORTD |= RED;
PORTD &= ~GREEN;
_delay_ms(50);
PORTD &= ~RED;
PORTD |= GREEN;
_delay_ms(50);
}
_delay_ms(1000);
}
else//(0..10)
{
for(i=0; i<x; i++)
{
PORTD |= RED;
_delay_ms(DEL_TIME);
PORTD &= ~RED;
_delay_ms(DEL_TIME);
}
_delay_ms(1000);
//Brejk:
for(i=0; i<5; i++)
{
PORTD |= RED;
PORTD &= ~GREEN;
_delay_ms(50);
PORTD &= ~RED;
PORTD |= GREEN;
_delay_ms(50);
}
_delay_ms(1000);
}
}
//*************************************************************************************
unsigned char RESET_PULSE(void)
{
unsigned char PRESENCE;
clear;
_delay_us(500);
set;
_delay_us(30);
if(bit_is_clear(PORT_1Wire, WE)) {PRESENCE = 1;} else {PRESENCE = 0;}
_delay_us(470);
if(bit_is_set(PORT_1Wire, WE)) {PRESENCE = 1;}
else {PRESENCE = 0;}
return PRESENCE;
}
//*************************************************************************************
void send(char bit)
{
clear;
_delay_us(5);
if(bit == 1)
set;
_delay_us(80);
set;
}
//*************************************************************************************
unsigned char read(void)
{
unsigned char PRESENCE = 0;
clear;
_delay_us(2);
set;
_delay_us(15);
if(bit_is_set(PORT_1Wire, WE)) PRESENCE = 1;
else PRESENCE = 0;
return (PRESENCE);
}
//*************************************************************************************
void send_byte(char wartosc)
{
unsigned char i;
unsigned char pom;
for(i=0; i<8; i++)
{
pom = wartosc >> i;
pom &= 0x01;
send(pom);
}
_delay_us(100);
}
//*************************************************************************************
unsigned char read_byte(void)
{
unsigned char i;
unsigned char wartosc = 0;
for(i=0; i<8; i++)
{
if(read()) wartosc |= 0x01 << 1;
_delay_us(15);
}
return (wartosc);
}
//*************************************************************************************
void wyswietl_temp(void)
{
int i;
unsigned char sprawdz;
char temp1 = 0, temp2 = 0;
_delay_ms(200);
sprawdz = RESET_PULSE();
if(sprawdz == 1)
{
send_byte(0xCC);
send_byte(0x44);
_delay_ms(750);
sprawdz = RESET_PULSE();
send_byte(0xCC);
send_byte(0xBE);
temp1 = read_byte();
temp2 = read_byte();
int t = (temp1 + (temp2 * 256)) / 16;
print(t);
}
else
{
//error
error(1);
}
}
//*************************************************************************************
void error(int i)
{
for(int a=0; a<i; a++)
{
_delay_ms(500);
PORTD |= RED;
PORTD &= ~GREEN;
_delay_ms(500);
PORTD &= ~RED;
PORTD |= GREEN;
}
}
//*************************************************************************************
//*************************************************************************************Żeby sprawdzić czy cokolwiek działa spróbowałem dać po resecie:
int tab[8];
send_byte(0xF0);
tab[0] = read_byte();
tab[1] = read_byte();
tab[2] = read_byte();
tab[3] = read_byte();
tab[4] = read_byte();
tab[5] = read_byte();
tab[6] = read_byte();
tab[7] = read_byte();
print(tab[0]);
_delay_ms(2000);
print(tab[1]);
_delay_ms(2000);
print(tab[2]);
_delay_ms(2000);
print(tab[3]);
_delay_ms(2000);
print(tab[4]);
_delay_ms(2000);
print(tab[5]);
_delay_ms(2000);
print(tab[6]);
_delay_ms(2000);
print(tab[7]);
_delay_ms(2000);Czyli powinienem dostać adres. Ale niestety w każdej zmiennej tab jest liczba 2.
Jeżeli pytam go o temperature jak w głównym programie pokazuje 32. Czyli funkcja read_byte zwraca zawsze 2.
Jeżeli nie podepne termometru pod układ i zczytam temperaturę to też da mi 32. Read zawsze daje 2.
W sumie bez podpięcia termometru reset zwraca poprawny wynik więc coś jest z kodem. Mi się od razu wydawał podejrzany, tzn jest trochę dziwnych konstrukcji językowych ale myślałem że coś zadziała... Atmega jest na wewnętrznym rezonatorze 8MHz. Myślicie że może źle odmierzać czas prze _delay_us?
Proszę o jakiekolwiek rady.
