Witam.
Jestem nowy na forum i nie mam zbyt duzego doświadczenia w programowaniu mikrokontrorów wiec z gory przepraszam za błedy.
Otóż mam do napisania projekt w którym mam DS18B20i za nic w swiecie nie moge dokonać odczytu z czujnika. Analizowałem datasheeta dosc dlugo i nie widze błedu.Przegladałem również tematy na forum, próbowałem różnych rzeczy i nic. Urządzenie teoretycznie zgłasza sie po resecie, ale na tym koniec. Programuje w C gdyz assembler nie jest moją mocną stroną(C zresztą tez
). Na forum wyczytałem ze ważne są czasy i poświeciłem im duzo uwagi,ale wegług mnie obliczam je dobrze. Ponizej zamieszczam kawałek kodu wraz z tlumaczeniem kompilatora na asm. Dodam ze uzywam kwarcu 11.059Mhz i porcka AT89c2051. No więc licząc opożninie pisze takie cos:
wait=(unsigned char)((XTAL/12e6)*30/2);//30us
W1_IO=1;
while(--wait);
co odpowiada nastepującym poleceniom asm:
MOV R7,#0Dh
SETB W1_IO
DJNZ R7,025Ah
Tak więc ponieważ mam taktowanie 11,059MHz, a wewnetrze procek dzieli to przez 12 to wynika z tego ze jeden cykl maszynowy trwa mniej wiecej 1,08us tak wiec liczymy: na poczatku załadowanie do R7 0x0Dh czyli 13 dec. Z tego co sie doczytałem to DJNZ zajmuje 2 cykle maszynowe.Wiec mamy 13x2=26 cykli + 1(MOV) + 1(SETB) czyli łącznie 28cykli*1,08us=30,24us czyli tyle ile zakładałem. Debbuger w RIDE mówi mi to samo więc to raczej nie kwestia czasów.
Układ sprawdzany na 3 czujnikach na kazdym to samo..same jedynki w odbiorze,czyli nie zyje, a nie mozliwe zeby 3 uklady byly walniete. Czujnik podpiety pod P1^0, z podciagniem przez 4,7kOM do +5V.Wszystko wydaje sie byc dobrze,ale nie działa. Naprawde nie wiem co zrobic.Prosze o pomoc
#pragma SMALL
#include <reg51.h>
Aha po lekturze forum wiem ze duzo prosciej mozna napisac funcje konwerujace otrzymane dane na liczby do wyslania na LCD(wlasnie projekt zawiera LCD,który dziala i fukcji jego obslugi nie zamieszczalem) no ale ogolnie nie o to chodzi.Jak DS przemówi do mnie to zmienie to.
Z góry wielkie dzieki za pomoc.
Jestem nowy na forum i nie mam zbyt duzego doświadczenia w programowaniu mikrokontrorów wiec z gory przepraszam za błedy.
Otóż mam do napisania projekt w którym mam DS18B20i za nic w swiecie nie moge dokonać odczytu z czujnika. Analizowałem datasheeta dosc dlugo i nie widze błedu.Przegladałem również tematy na forum, próbowałem różnych rzeczy i nic. Urządzenie teoretycznie zgłasza sie po resecie, ale na tym koniec. Programuje w C gdyz assembler nie jest moją mocną stroną(C zresztą tez
wait=(unsigned char)((XTAL/12e6)*30/2);//30us
W1_IO=1;
while(--wait);
co odpowiada nastepującym poleceniom asm:
MOV R7,#0Dh
SETB W1_IO
DJNZ R7,025Ah
Tak więc ponieważ mam taktowanie 11,059MHz, a wewnetrze procek dzieli to przez 12 to wynika z tego ze jeden cykl maszynowy trwa mniej wiecej 1,08us tak wiec liczymy: na poczatku załadowanie do R7 0x0Dh czyli 13 dec. Z tego co sie doczytałem to DJNZ zajmuje 2 cykle maszynowe.Wiec mamy 13x2=26 cykli + 1(MOV) + 1(SETB) czyli łącznie 28cykli*1,08us=30,24us czyli tyle ile zakładałem. Debbuger w RIDE mówi mi to samo więc to raczej nie kwestia czasów.
Układ sprawdzany na 3 czujnikach na kazdym to samo..same jedynki w odbiorze,czyli nie zyje, a nie mozliwe zeby 3 uklady byly walniete. Czujnik podpiety pod P1^0, z podciagniem przez 4,7kOM do +5V.Wszystko wydaje sie byc dobrze,ale nie działa. Naprawde nie wiem co zrobic.Prosze o pomoc
#pragma SMALL
#include <reg51.h>
#define CONVERT_T 0x44 // Komendy DS1820
#define READ1W 0xBE
#define SKIP_ROM 0xCC
#define PORT P1
#define XTAL 11059200
//ZMIENNE GLOBALNE
unsigned char Tmax=0;
unsigned char Tmin=0;
unsigned char TmaxHalf=0;
unsigned char TminHalf=0;
unsigned char TmaxMinus=0;
unsigned char TminMinus=0;
unsigned char Hour=0,Minute=0,Second=0,InterruptCounter=0;
unsigned char AlarmHour=0,AlarmMinute=0;
unsigned char Mode=0;
//FUNCKJE OBSUGI WYSWIETLACZA
sbit LcdEnable = P1^3;
sbit LcdRead = P1^1;
sbit LcdRS = P1^2;
sbit W1_IO = P1^0;
sbit Key = P3^0;
sbit Buzer = P3^1;
//FUNKCJE OBSLUGI 1-WIRE
//definicja podlaczenia linii portu 1W
//wyslanie polecenia "1W Reset"
bit W1_reset(void)
{
unsigned char wait;
bit present;
wait=(unsigned char)((XTAL/12e6)*490/3);//obliczenie opoznienia 491us
do
{
W1_IO=0;
}
while(--wait);//1 wait to 2us
wait=(unsigned char)((XTAL/12e6)*30/2);//30us
W1_IO=1;
while(--wait);
present=W1_IO;
wait=(unsigned char)((XTAL/12e6)*70/2);//70us
while(--wait);
present=W1_IO;
return !present;
}
//przeslanie lub odczyt bitu przez linie W1
void W1_bit_write(bit b)//zapis bitru z master2slave
{
unsigned char wait;
wait=(unsigned char)((XTAL/12e6)*15/2);//15 us
W1_IO=0;
while(--wait);
W1_IO=b;
wait=(unsigned char)((XTAL/12e6)*47/2);//47 us
while(--wait);
W1_IO=1;
wait=(unsigned char)((XTAL/12e6)*2/2);//2 us
while(--wait);
}
bit W1_bit_read()
{
unsigned char wait;
bit b;
W1_IO=0;
wait=(unsigned char)((XTAL/12e6)*4/2);//4us
while(--wait);
W1_IO=1;
wait=(unsigned char)((XTAL/12e6)*8/4);//10us
do
{
b=W1_IO;
}
while(--wait);
wait=(unsigned char)((XTAL/12e6)*55/2);//47us
while(--wait);
return b;
}
void W1_byte_write(unsigned char b)
{
unsigned char mask=0x01;
unsigned char counter=8;
do
{
if ((b & mask))
{W1_bit_write(1);} //if ((byte & mask)!=0) W1_bite_write(1)
else
{W1_bit_write(0);} //if ((byte & mask)=0) W1_bite_write(0)
mask=mask<<1;
}
while(counter--);
}
unsigned char W1_byte_read()
{
unsigned char byte=0x00;
unsigned char mask=0x01;
unsigned char counter;
for (counter=0;counter<8;counter++)
{
if (W1_bit_read()) byte=byte|mask;
mask=mask<<1;
}
return byte;
}
//FUNCKJE OBSLUGI POMIARU
unsigned char ConverT(unsigned char LSByte,unsigned char MSByte)
{
unsigned char Temp=0x07;
Temp=Temp & MSByte;//wyłuskanie 3 najmniej znaczących bitów z MSByte
Temp=Temp<<4;//Przesuniesie o 4 w lewo,aby zrobic miejsce dla gornej polowki LSByte
Temp=Temp & 0xF0;//ustawienie dolnej polownki Temp na '0'
LSByte=LSByte & 0xF0;//wylusaknie gornej polowki LSByte
LSByte=LSByte>>4;//Przsuniecie o 4 w lewo
Temp=Temp | LSByte;//ustawienie dolnej połowki Temp na wlasciwa wartosc
//Temperature=LSByte+(MSByte*256);
//Temperature=Temperature/16;
return Temp;
}
void WriteTempOnLcd(unsigned char Temp,bit Minus,bit HalfDegree,char select)
{
unsigned char NumOfTens=0x00;
while (Temp>9)
{
Temp=Temp-10;
NumOfTens++;
}
//LcdClrScr();
switch(select)
{
case 0:
if (Minus) WriteTextXY(0,1,"-",0);
else (WriteTextXY(0,1,"+",0));
break;
case 1:
if (Minus) WriteTextXY(0,2,"Max:-",0);
else (WriteTextXY(0,2,"Max:+",0));
break;
case 2:
if (Minus) WriteTextXY(8,2,"Min:-",0);
else (WriteTextXY(8,2,"Min:+",0));
break;
}
LcdRS=1;
WriteByte2Lcd(NumOfTens+48);//wypisanie cyfry dziesiatek
LcdRS=1;
WriteByte2Lcd(Temp+48);//wypisanie cyfry jednostek
LcdRS=1;
WriteByte2Lcd(44);//wypisanie przecinka
if (HalfDegree)
{
LcdRS=1;
WriteByte2Lcd(53);//wypisanie '5'
}
else
{
LcdRS=1;
WriteByte2Lcd(48);//wypisanie '0'
};
LcdRS=1;
WriteByte2Lcd(223);//wypisanie znaku stopnia
LcdRS=1;
WriteByte2Lcd(67);//wypisanie 'C'
}
void Temp2LCD_MAXMIN(unsigned char LSByte,unsigned char MSByte)
{
bit Minus,HalfDegree;
unsigned char Temp=0;
if ((LSByte & 0x08)!=0) HalfDegree=1;
else HalfDegree=0;
if ((MSByte & 0xF8)==0) Minus=0;
else {Minus=1;MSByte=~MSByte;LSByte=~LSByte;}
Temp=ConverT(LSByte,MSByte);
if (TmaxMinus)
{
if (Minus)
{
if (Temp<=Tmax)
{
Tmax=Temp;
TmaxMinus=1;
if (TmaxHalf) TmaxHalf=HalfDegree;
}
}
else
{
Tmax=Temp;
TmaxMinus=0;
TmaxHalf=HalfDegree;
}
}
else
{
if (Temp>=Tmax)
{
Tmax=Temp;
TmaxMinus=0;
if (HalfDegree) TmaxHalf=1;
}
}
if(TminMinus)
{
if (Minus)
{
if (Temp>=Tmin)
{
Tmin=Temp;
TminMinus=1;
if (HalfDegree) TminHalf=1;
}
}
}
else
{
if (Minus)
{
Tmin=Temp;
TminMinus=1;
TminHalf=HalfDegree;
}
else
{
if (!TminMinus)
{
if (Temp<=Tmin)
{
Tmin=Temp;
TminMinus=0;//nawet nie trza tego modyfikowac
if (HalfDegree==0) TminHalf=0;
}
}
}
}
WriteTempOnLcd(Temp,Minus,HalfDegree,0);
WriteTempOnLcd(Tmax,TmaxMinus,TmaxHalf,1);
WriteTempOnLcd(Tmin,TminMinus,TminHalf,2);
}
void main (void)
{
unsigned char Counter=0;
unsigned char ScratchPad[9];
bit noerror=0;
TMOD=0x01;//ustawienie TIMER 0 w tryb 16-bit
TR0=1;//uruchomienie TIMER 0
EA=1;//zezwolenie na przerwania
ET0=1;//zezwolenie na przerwania z Timera
EX0=1;//zezwolenie ma przerwania z INT0
IT0=1;//wywolanie przerwania INT0 zboczem opadającym
LcdInitialize(); // inicjalizacja wyswietlacza
LcdClrScr();
while(1)
{
LcdClrScr();
WriteTextXY(0,1,"Witamy",100);
Delay(2000);
LcdClrScr();
WriteTextXY(0,1,"Initiation",100);
WriteTextXY(0,2,"1-WIRE",100);
Delay(2000);
noerror=W1_reset();
if (noerror)
{
LcdClrScr();
WriteTextXY(0,1,"Initiation OK",100);
}
else
{
LcdClrScr();
WriteTextXY(0,1,"InitiationERROR",100);
};
LcdClrScr();
while(noerror)
{
W1_reset();
W1_byte_write(SKIP_ROM);
W1_byte_write(CONVERT_T);
Delay(1000);
W1_reset();
W1_byte_write(SKIP_ROM);
W1_byte_write(READ1W);
for (Counter=0;Counter<9;Counter++) ScratchPad[Counter]=W1_byte_read();
Temp2LCD_MAXMIN(ScratchPad[0],ScratchPad[1]);
}
}
}Aha po lekturze forum wiem ze duzo prosciej mozna napisac funcje konwerujace otrzymane dane na liczby do wyslania na LCD(wlasnie projekt zawiera LCD,który dziala i fukcji jego obslugi nie zamieszczalem) no ale ogolnie nie o to chodzi.Jak DS przemówi do mnie to zmienie to.
Z góry wielkie dzieki za pomoc.