Witam!
Zacznę od tego, że jestem mocno początkujący w programowaniu uC w C (no i w ogóle w programowaniu). Chciałem zrobić termometr na atmega32, wyświetlaczu lcd przy wykorzystaniu DS18B20. Przewertowałem podobnych tematów na forum multum, przerobiłem datasheet'y i inne takie. Siedzę już nie wiem ile czasu nad tym i nie mogę dojść co jest nie tak więc proszę o pomoc.
DS podłączony jak należy, tj:
1 - GND, 2 - DQ (do PIND4), 3 - Vcc oraz dodatkowo linia danych podciągnięta jest przez rezystor 3,3kΩ (próbowałem i dla 4.7kΩ) do zasilania. Procesor taktowany jest wewnętrznym oscylatorem 4MHz.
Jak widać użyłem poleceń i funkcji jakie już pojawiały się na forum w podobnych tematach, z góry dzięki!
Problem polega na tym, że LCD wyświetla mi temperaturę T=0.1 C. Jeśli pominę fragment kodu dotyczący tego co za przecinkiem to oczywiście mam same 0. Czasy wydają się być OK, próbowałem przy różnych częstotliwościach taktowania jest to samo:/. Po odłączeniu linii danych wyświetla się "cisza" - czyli niby prawidłowo. Jak dla mnie to jeśli konwersja się odbywa to tak jakby nie zczytywał danych z DSa ale bardzo możliwe że się mylę. Wymieniałem DSa na drugiego i to samo...
Proszę o pomoc
Regulamin p.11 - poprawiłem tytuł.
[zumek]
Zacznę od tego, że jestem mocno początkujący w programowaniu uC w C (no i w ogóle w programowaniu). Chciałem zrobić termometr na atmega32, wyświetlaczu lcd przy wykorzystaniu DS18B20. Przewertowałem podobnych tematów na forum multum, przerobiłem datasheet'y i inne takie. Siedzę już nie wiem ile czasu nad tym i nie mogę dojść co jest nie tak więc proszę o pomoc.
DS podłączony jak należy, tj:
1 - GND, 2 - DQ (do PIND4), 3 - Vcc oraz dodatkowo linia danych podciągnięta jest przez rezystor 3,3kΩ (próbowałem i dla 4.7kΩ) do zasilania. Procesor taktowany jest wewnętrznym oscylatorem 4MHz.
#ifndef _delay_h_
#define _delay_h_
#include <inttypes.h>
#include <avr/io.h>
#include <stdlib.h>
#define F_CPU 4000000UL
static inline void delayloop16(uint16_t count)
{
asm volatile ( "cp %A0,__zero_reg__ \n\t" \
"cpc %B0,__zero_reg__ \n\t" \
"breq L_Exit_%= \n\t" \
"L_LOOP_%=: \n\t" \
"sbiw %0,1 \n\t" \
"brne L_LOOP_%= \n\t" \
"L_Exit_%=: \n\t" \
: "=w" (count)
: "0" (count)
);
}
#define DELAY_US_CONV(us) ((uint16_t)(((((us)*1000L)/(1000000000/F_CPU))-1)/4))
#define delay_us(us) delayloop16(DELAY_US_CONV(us))
static void delayms(int cnt)
{
while(cnt--) delay_us(995);
}
#define delay_ms(ms) delayms(ms)
#endif
#define WE 4
#define PORT_1wire PIND
#define SET_1wire DDRD&=~_BV(WE)
#define CLEAR_1wire DDRD|=_BV(WE)
char buf[8];
unsigned char RESET_PULSE(void)
{
unsigned char PRESENCE;
CLEAR_1wire;
delay_us(600);
SET_1wire;
delay_us(50);
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_1wire;
delay_us(10);
if(bit==1)
SET_1wire;
delay_us(80);
SET_1wire;
}
unsigned char read(void)
{
unsigned char PRESENCE=0;
CLEAR_1wire;
delay_us(2);
SET_1wire;
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(102);
}
unsigned char read_byte(void)
{
unsigned char i;
unsigned char wartosc=0;
for (i=0; i<8; i++)
{
if(read()) wartosc|=0x01<<i;
delay_us(120);
}
return(wartosc);
}
.
.
.//obsługa LCD
.
.
.
union {
int tds;
char nds[2];
}ds;
int main(void)
{
unsigned char sprawdz;
char temp1=0, temp2=0;
.
.
.//inicjalizacja LCD
.
LCDxy(0,0);
tekst("DS18B20");
delay_ms(1000);
for(;; ){
sprawdz=RESET_PULSE();
if (sprawdz==1)
{
send_byte(0xCC);
send_byte(0x44);
delay_ms(1000);
sprawdz=RESET_PULSE();
send_byte(0xCC);
send_byte(0xBE);
ds.nds[0]=read_byte();
ds.nds[1]=read_byte();
RESET_PULSE();
itoa(ds.tds/2,buf,10);
LCDxy(0,0);
tekst("T=");
tekst(buf);
tekst(".\0");
itoa(abs((ds.tds*10/8 )%10),buf,10);
tekst(buf);
tekst("C");
delay_ms(500);
}
else
{
LCDxy(0,0);
tekst("cisza");
}
}
}
Jak widać użyłem poleceń i funkcji jakie już pojawiały się na forum w podobnych tematach, z góry dzięki!
Problem polega na tym, że LCD wyświetla mi temperaturę T=0.1 C. Jeśli pominę fragment kodu dotyczący tego co za przecinkiem to oczywiście mam same 0. Czasy wydają się być OK, próbowałem przy różnych częstotliwościach taktowania jest to samo:/. Po odłączeniu linii danych wyświetla się "cisza" - czyli niby prawidłowo. Jak dla mnie to jeśli konwersja się odbywa to tak jakby nie zczytywał danych z DSa ale bardzo możliwe że się mylę. Wymieniałem DSa na drugiego i to samo...
Proszę o pomoc
Regulamin p.11 - poprawiłem tytuł.
[zumek]