[c] Atmeaga16, LCD 2x16, DS18B20

To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
ODPOWIEDZ
n0lab
-
Posty: 18
Rejestracja: 26 cze 2007, 21:45

[c] Atmeaga16, LCD 2x16, DS18B20

Post autor: n0lab » 02 sie 2009, 13:13

Witam,
próbuje uruchomić termometr na 1 wire wykorzystując układ DS18B20 i ATmega16.
Wyświetlacz podpięty do portu A, sterowany 4bitach, działa poprawnie.
DS18B20 - GND do GND , VCC do VCC, Data do Port D Pin 0 z rezystorem 4k7 podciągniętym do VCC.

Na wyświetlaczu jak DS jest podpięty to pokazuje się 0.0 , jak nie jest podpięty to -0.1.
Jak odłączę rezystor podciągający to wyświetla błąd pomiaru.
Kwarc ustawiony na wewnętrzny 1MHz (chyba :mrgreen: )

Kod źródłowy programu

Kod: Zaznacz cały


#include <stdlib.h>
#include <avr/io.h>
#include <util/delay.h>
#include "lcd.h"

#define WE 0
#define PORT_1WIRE PIND
#define SET_1WIRE DDRD&=~_BV(WE)
#define CLEAR_1WIRE DDRD|=_BV(WE)

char buf[8];

// reset magistrali
unsigned char RESET_PULSE(void)
{
	unsigned char PRESENCE;
	CLEAR_1WIRE;
	_delay_us(500);
	SET_1WIRE;
	_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_1WIRE;
	_delay_us(5);
	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);
}

unsigned 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<<i;
		_delay_us(15);
	}
	return (wartosc);
}

int main (void)
{
	unsigned char sprawdz;
	char temp1=0, temp2=0;
	lcd_init(LCD_DISP_ON);
	lcd_clrscr();
	lcd_puts("1 Wire\n");		
	_delay_ms(200);
	for(;;) {
		sprawdz=RESET_PULSE();
		if (sprawdz == 1)
		{
			send_byte(0xCC);
			send_byte(0x44);
			_delay_ms(750);

			sprawdz=RESET_PULSE();
			send_byte(0xCC);
			send_byte(0x44);
			temp1=read_byte();
			temp2=read_byte();

			sprawdz=RESET_PULSE();
			float temp=0;
			temp=(float)(temp1+(temp2*256))/16;
			dtostrf(temp,1,1,buf);
			lcd_clrscr();
			lcd_home();
			lcd_puts(buf);
			_delay_ms(200);
		}
		else
		{
			lcd_clrscr();
			lcd_home();
			lcd_puts("Brak pomiaru");
		}

	}
}
Log z kompilacji

Kod: Zaznacz cały

> "make.exe" all

-------- begin --------
avr-gcc (GCC) 3.4.1
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


Compiling: test_lcd.c
avr-gcc -c -mmcu=atmega16 -I. -gdwarf-2   -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=test_lcd.lst  -std=gnu99 -Wp,-M,-MP,-MT,test_lcd.o,-MF,.dep/test_lcd.o.d test_lcd.c -o test_lcd.o 
test_lcd.c: In function `send_byte':
test_lcd.c:63: warning: control reaches end of non-void function

Compiling: lcd.c
avr-gcc -c -mmcu=atmega16 -I. -gdwarf-2   -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=lcd.lst  -std=gnu99 -Wp,-M,-MP,-MT,lcd.o,-MF,.dep/lcd.o.d lcd.c -o lcd.o 

Linking: test_lcd.elf
avr-gcc -mmcu=atmega16 -I. -gdwarf-2   -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=test_lcd.o  -std=gnu99 -Wp,-M,-MP,-MT,test_lcd.o,-MF,.dep/test_lcd.elf.d test_lcd.o lcd.o   --output test_lcd.elf -Wl,-Map=test_lcd.map,--cref    -lm

Creating load file for Flash: test_lcd.hex
avr-objcopy -O ihex -R .eeprom test_lcd.elf test_lcd.hex

Creating load file for EEPROM: test_lcd.eep
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 -O ihex test_lcd.elf test_lcd.eep

Creating Extended Listing: test_lcd.lss
avr-objdump -h -S test_lcd.elf > test_lcd.lss

Creating Symbol Table: test_lcd.sym
avr-nm -n test_lcd.elf > test_lcd.sym

Size after:
test_lcd.elf  :
section           size      addr
.text             2652         0
.data               22   8388704
.bss                 8   8388726
.noinit              0   8388734
.eeprom              0   8454144
.debug_aranges      40         0
.debug_pubnames    255         0
.debug_info       2352         0
.debug_abbrev      807         0
.debug_line       1744         0
.debug_str         536         0
.debug_ranges       12      2652
Total             8428



Errors: none
-------- end --------


> Process Exit Code: 0
> Time Taken: 00:01
Zrzut z programu ISP Prog

Obrazek

snow
Użytkownik
Posty: 794
Rejestracja: 16 sty 2007, 3:44
Lokalizacja: lubelskie
Kontakt:

Post autor: snow » 02 sie 2009, 13:40

Kod: Zaznacz cały

#define SET_1WIRE DDRD&=~_BV(WE)
#define CLEAR_1WIRE DDRD|=_BV(WE) 
Tu masz do poprawki

n0lab
-
Posty: 18
Rejestracja: 26 cze 2007, 21:45

Post autor: n0lab » 02 sie 2009, 13:46

to jak mam to poprawić ?
Co jest źle ?

snow
Użytkownik
Posty: 794
Rejestracja: 16 sty 2007, 3:44
Lokalizacja: lubelskie
Kontakt:

Post autor: snow » 02 sie 2009, 16:04

Masz odwrotnie zadeklarowane. Zamiast ustawiać bit jako "1" zerujesz go.

n0lab
-
Posty: 18
Rejestracja: 26 cze 2007, 21:45

Post autor: n0lab » 07 sie 2009, 20:34

po zmianie na

Kod: Zaznacz cały

#define CLEAR_1WIRE DDRD&=~_BV(WE)
#define SET_1WIRE   DDRD|=_BV(WE)
cały czas pojawia się brak pomiaru

[ Dodano: 2009-08-07, 21:34 ]
z tym już sobie poradziłem.

Teraz mam pytanie, jak zmienić rozdzielczość ?
próbuje już drugi dzień coś z tym zrobić i nie wychodzi mi to ;/
na razie wyświetla mi temp np tak 23.0 a chcę żeby pokazywał 23,5 lub 23,475.

8mixer8
-
Posty: 1
Rejestracja: 12 sie 2009, 23:25
Lokalizacja: Wejherowo

Post autor: 8mixer8 » 13 sie 2009, 19:00

Siemanko.

Mógłbyś powiedzieć jak ten problem rozwiązałeś? ciągle sie bawie tym termo i to samo mi wyswietla..

byłbym wdzieczny gdybys napisał :)

3l3ctr0
-
Posty: 2
Rejestracja: 16 lis 2009, 2:00
Lokalizacja: Śrem

Post autor: 3l3ctr0 » 16 lis 2009, 2:18

Witam,

Skoro kolega n0lab zamieścił tu post z pytaniem, został częściowo nakierowany przez innych użytkowników i uporał się z przedstawionym problemem, to aby post przedstawiał coś wartościowego, wypadałoby napisać w czym był problem i jak został rozwiązany. Zapewne przyda się to następnym osobom czytającym ten post.

Korzystając z okazji dodam, iż mam ten sam problem :( Część

Kod: Zaznacz cały

#define CLEAR_1WIRE DDRD&=~_BV(WE)
#define SET_1WIRE   DDRD|=_BV(WE)
mam zadeklarowaną prawidłowo, mój MCU to AtMega8, kwarc 1 MHz wewnętrzny, port PC5, wszystko podłączone prawidłowo, a widzę tylko 0.0, lub -0.1 jak w przypadku autora postu...

Proszę o pomoc.

snow
Użytkownik
Posty: 794
Rejestracja: 16 sty 2007, 3:44
Lokalizacja: lubelskie
Kontakt:

Post autor: snow » 16 lis 2009, 8:26

Czasy opóźnień w 1wire się zgadzają z tymi które są opisane w PDF'ie tego czujnika?

3l3ctr0
-
Posty: 2
Rejestracja: 16 lis 2009, 2:00
Lokalizacja: Śrem

Post autor: 3l3ctr0 » 17 lis 2009, 1:26

Witam,

Próbowałem najróżniejszych kombinacji ustawiania wartości czasów przybliżonych do tych z datasheet'a czujnika, niestety bez jakiegokolwiek pozytywnego rezultatu. Dokładnie nie wiem, czy te podane w powyższym listingu są prawidłowe, gdyż jak dotąd nie do końca jest dla mnie jasny zapis ich zależności w pdf'ie czujnika.

Zauważyłem inny moim zdaniem absurd:

Kod: Zaznacz cały

if (bit_is_clear(PORT_1WIRE, WE)) PRESENCE=1; else PRESENCE=0;
...
if (bit_is_set(PORT_1WIRE, WE)) PRESENCE=1; else PRESENCE=0;
...
gdzie jeden if zaprzecza drugiemu. Powinno chyba być, o ile oczywiście się nie mylę:

Kod: Zaznacz cały

if (bit_is_clear(PORT_1WIRE, WE)) PRESENCE=1; else PRESENCE=0;
lub ewentualnie:

Kod: Zaznacz cały

if (bit_is_clear(PORT_1WIRE, WE)) PRESENCE=1;
...
if (bit_is_set(PORT_1WIRE, WE)) PRESENCE=0;
...
Mimo poprawienia powyższego, mój program nadal nie działa prawidłowo, wygląda to tak, jakby coś było nie tak z komunikacją, konwersją zmiennych, bądź z przeliczaniem temperatury:(

Co jeszcze może być nie tak :?: :???:

Proszę o pomoc.

[ Dodano: 2009-11-18, 00:27 ]
Witam,

Mam kolejne pytanie, czy w moim przypadku (kwarc wewnętrzny 1 MHz) funkcja _delay_us(100) daje rzeczywiście opóźnienie 100 us, czy i w jaki sposób jest ona zależna od prędkości taktowania mikrokontrloera? Czy takie rozwiązanie jest w tym przypadku prawidłowe? Pytam, gdyż jak do tąd nie mogę uruchomić powyższego programu.

Drugie moje pytanie dotyczy możliwości podejrzenia, bądź zasymulowania tego, co dzieje się w mikrokontrolerze. Jak tego dokonać, czy są do tego jakieś urządzenia, programy? Być może mając do dyspozycji takowe narzędzie łatwiej byłoby zdiagnozować to, co obecnie dzieje się w mikrokontrolerze podczas jego pracy i czy poszczególne części programu są prawidłowo wykonywane. Mam nadzieję, że jedynym wyjściem w tym kierunku nie jest tylko i wyłącznie konieczność użycia oscyloskopu, gdyż jak wiadomo nie jest to łatwo dostępne rozwiązanie.

Proszę o odpowiedź.

[ Dodano: 2009-11-22, 13:50 ]
Ok, dzięki, ja też nie odpowiem jak to zrobiłem. Powodzenia.

janoda80
-
Posty: 1
Rejestracja: 28 cze 2013, 9:19
Lokalizacja: Polska

Post autor: janoda80 » 28 cze 2013, 9:33

Witam!

Obecnie mam podobny problem z komunikacją z DS przy użyciu tego samego programu i mam pytanie, czy komuś udało się rozwiązać w/w tę zagadkę?

Pozdrawiam!

ODPOWIEDZ