1wire.c

DS18B20 - nie zawsze odpowiada samymi jedynkami logicznymi.

Mikrokontroler to ATMEGA8, a jezyk C (WINAVR). Napisalem procedury z pomaca popularnej ksiazki.... Na razie proboje odczytac pierwsze 4 bity odpowiedzi ds-a, ale ciagle jedynki...


#include & lt; avr/io.h & gt;
#include & lt; avr/pgmspace.h & gt;
#include & lt; stdlib.h & gt;
#include & lt; ctype.h & gt;
#define F_CPU 1000000 /* 1MHz zegar procesora */
#define CYCLES_PER_US ((F_CPU+500000)/1000000) /* cpu cycles per microsecond */
#define lcd_rs 2 //definicja bitu portu dla linii RS
#define lcd_e 3 //definicja bitu portu dla linii E
#define CR 0x0a //definicja znaku CR (przejcie do nowej linii)

#define PIN1w PINC //definicje dot. 1wire
#define DDR1w DDRC
#define PORT1w PORTC
#define PIN PC5

unsigned char wiersz=0;
unsigned char kolumna=0;

void delay(unsigned int us){
unsigned int delay_loops;
register unsigned int i;
delay_loops = (us+3)/5*CYCLES_PER_US;
for (i=0; i & lt; delay_loops; i++) {};
}

void delayms(unsigned int ms){
unsigned int i;
for (i=0;i & lt; ms;i++){
delay(999);
asm volatile ( " WDR " ::);
}
}



void piszilcd(unsigned char instr) //zapisz instrukcj? steruj?c? do LCD
{
cbi(PORTB,lcd_rs);
sbi(PORTB,lcd_e);
PORTB=(PORTB & 0x0f)|(instr & 0xf0); //przygotuj starszy p?-bajt do LCD
asm( " nop " ); //wymagane wyd-u?enie impulsu
asm( " nop " );
asm( " nop " );
cbi(PORTB,lcd_e); //impuls strobuj?cy
delay(100);
sbi(PORTB,lcd_e);
PORTB=(PORTB & 0x0f)|((instr & 0x0f) & lt; & lt; 4); //przygotuj m-odszy p?-bajt do LCD
asm( " nop " );
asm( " nop " );
asm( " nop " );
cbi(PORTB,lcd_e); //impuls strobuj?cy
delay(100);
}

void piszdlcd(char dana) //zapisz dan? do LCD
{
sbi(PORTB,lcd_rs);
sbi(PORTB,lcd_e);
PORTB=(PORTB & 0x0f)|(dana & 0xf0); //przygotuj starszy p?-bajt do LCD
asm( " nop " ); //wymagane wyd-u?enie impulsu
asm( " nop " );
asm( " nop " );
cbi(PORTB,lcd_e); //impuls strobuj?cy
delay(100);
sbi(PORTB,lcd_e);
PORTB=(PORTB & 0x0f)|((dana & 0x0f) & lt; & lt; 4); //przygotuj m-odszy p?-bajt do LCD
asm( " nop " );
asm( " nop " );
asm( " nop " );
cbi(PORTB,lcd_e); //impuls strobuj?cy
delay(100);
}

void czysclcd(void) //czyŠ ekran
{
piszilcd(0x01); //polecenie czyszczenia ekranu dla kontrolera LCD
delayms(2);
wiersz=0;
kolumna=0;
}

void piszznak(char znak) //procedura umieszcza znak na wywietlaczu
{
piszdlcd(znak); //wywietl znak na LCD
if(++kolumna==16) //czy bie??ca kolumna mieci si? na wywietlaczu?
{
kolumna=0; //jeli nie, to ustaw pocz?tkow?...
if(++wiersz==2) //i przejd? do nowego wiersza
{
wiersz=0; //jeli nowy wiersz jest poza wywietlaczem, ustaw pocz?tkowy
}
}
}

void piszliczbaxy(unsigned char l, unsigned char w, unsigned char k){
piszilcd((w*0x40+k)|0x80); //ustawienie kursora
piszznak(' '); //wymazanie zbednych liczb na koncu
piszznak(' ');
piszznak(' ');
piszilcd((w*0x40+k)|0x80); //ustawienie kursora
unsigned char *wsk;
unsigned char buflcd[4];
utoa((unsigned char)l,buflcd,16);
wsk= & buflcd[0];
while(*wsk) {
piszznak(*wsk++);
}
}

void lcdxy(unsigned char w, unsigned char k) //ustaw wsp?-rz?dne kursora
{
piszilcd((w*0x40+k)|0x80); //standardowy rozkaz sterownika LCD
//ustawiaj?cy kursor w okrelonych wsp?-rz?dnych
}

void pisztekst(char *tekst) //pisz tekst na LCD wskazywany pointerem *tekst
{
char zn;
char nr=0;

while(1)
{
zn=PRG_RDB( & tekst[nr++]); //pobranie znaku z pami?ci programu
if(zn!=0) //czy nie ma ko 1/2 ca tekstu?
{
if(zn==CR) //czy znak nowej linii
{
wiersz==1?wiersz=0:++wiersz; //przejd? do nowej linii
kolumna=0;
lcdxy(wiersz,kolumna); //ustaw obowi?zuj?ce po zmianie wsp?-rz?dne na LCD
}
else
{
piszdlcd(zn); //umieŠ pojedynczy znak tekstu na LCD
}
}
else
{
break; //zako 1/2 cz p?tl?, jeli koniec tekstu
}
}
}

void waitus(unsigned char czas){
TCCR0=0x01; //zliczamy impulsy 1us dla fosc=1MHz
TCNT0=255-czas;
while((inp(TIFR) & 0x01)!=0x01);
sbi(TIFR,TOV0);//kasowanie flagi przepe-nienia
}

void waitms(unsigned int czas){
unsigned char temp=TCNT0;
for(;czas & gt; 0;czas--){
unsigned char x=10;
for(;x & gt; 0;x--){//petla 1000us=1ms
TCCR0=1; //zliczamy impulsy 1us dla fosc=1MHz
TCNT0=155;
while(bit_is_clear(TIFR,TOV0));
TIFR=1 & lt; & lt; TOV0; //kasowanie flagi przepe-nienia
}
}
TCNT0=temp;
}

unsigned char initial(void){ //inicjacja urz?dzenia 1wire
cbi(PORT1w,PIN);
sbi(DDR1w,PIN); //stan 0
waitms(1);
cbi(DDR1w,PIN); //stan 1
waitus(65);
if(bit_is_clear(PIN1w,PIN)){waitms(1); return 1;}
else{waitms(1); return 0;}
}

void slot_wyslij1w(unsigned char znak){ //wysy?a bit 0 lub 1 do urzadzenia 1wire
if(znak==1){ //organizujac transmisje bitu w slot czasowy
cbi(PORT1w,PIN);
sbi(DDR1w,PIN); //stan 0
waitus(11);
cbi(DDR1w,PIN); //stan 1 i probkowanie przez urzadzenie 1wire
waitus(60); //czekaj az minie czas slotu
}
else{
cbi(PORT1w,PIN);
sbi(DDR1w,PIN); //stan 0
waitus(70);
cbi(DDR1w,PIN); //stan 1
}
}


void wyslij1w(unsigned char dana){//wysy?a instrukcje do urzadzenia 1wire
unsigned char i;
for(i=0;i & lt; 8;i++){
slot_wyslij1w(dana & 0x01);
dana & gt; & gt; =1;
}
}



unsigned char slot_odbierz1w(void){ //odbiera bit nadany przez urz. 1wire
unsigned char bit1w; //w w jednym slocie czasowym
cbi(PORT1w,PIN);
sbi(DDR1w,PIN); //stan 0
waitus(1);
cbi(DDR1w,PIN); //stan 1
waitus(14);//14
if(bit_is_clear(PIN1w,PIN)) bit1w=0;
if(bit_is_set(PIN1w,PIN)) bit1w=1;
waitus(60);//60
return bit1w;
}

unsigned char odbierz1w(void){
unsigned char dana=0;
unsigned char j;
for(j=0x01;j!=0;j=j & lt; & lt; 1)
dana|=slot_odbierz1w()?j:dana;
return dana;
}

int main(void) //program g-?wny
{
unsigned char i;
// & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gt; definicje tekst?w wywietlanych na LCD & lt; & lt; & lt; & lt; & lt; & lt; & lt; & lt; & lt; & lt; & lt; & lt; & lt; & lt;
//char *tekst1=PSTR( " Pudzialy stoja! " );

// & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gt; konfigurowanie port?w & lt; & lt; & lt; & lt; & lt; & lt; & lt; & lt; & lt; & lt; & lt; & lt; & lt; & lt; & lt; & lt; & lt; & lt; & lt; & lt; & lt; & lt; & lt; & lt; & lt; & lt;
PORTB=0x03; //port z podci?ganiem
DDRB=0xff; //PORTB - wy
delayms(45);
for(i=0;i & lt; 3;i++) //3-krotne wys-anie 3-
{
sbi(PORTB,lcd_e);
PORTB=(PORTB & 0x0f)|0x30; //wylij 3- do LCD
asm( " nop " );
asm( " nop " );
asm( " nop " );
cbi(PORTB,lcd_e);
delayms(5);
}
sbi(PORTB,lcd_e);
PORTB=(PORTB & 0x0f)|0x20; //wylij 2- do LCD
asm( " nop " ); //wymagane wyd-u?enie impulsu
asm( " nop " );
asm( " nop " );
cbi(PORTB,lcd_e);
delay(100);
piszilcd(0x28); //interfejs 4-bitowy, 2 linie, znak 5x7
piszilcd(0x08); //wy-?cz LCD, wy-?cz kursor, wy-?cz mruganie
piszilcd(0x01); //czyŠ LCD
delayms(2);
piszilcd(0x06); //bez przesuwania w prawo
piszilcd(0x0c); //w-?cz LCD, w-?cz kursor, w-?cz mruganie


/*

unsigned int wynik=0;
unsigned int wynik1=0;
unsigned int wynik2=0;
unsigned int wynik3=0;
unsigned int wynik4=0;
unsigned int wynik5=0;
unsigned int wynik6=0;
unsigned int wynik7=0;

unsigned int x=0;
delayms(200);
x=initial();
if(x==1){
wyslij1w(0x33);
wynik=odbierz1w();
wynik1=odbierz1w();
wynik2=odbierz1w();
wynik3=odbierz1w();
wynik4=odbierz1w();
wynik5=odbierz1w();
wynik6=odbierz1w();
wynik7=odbierz1w();


piszliczbaxy(wynik,0,0);
piszliczbaxy(wynik1,0,3);
piszliczbaxy(wynik2,0,6);
piszliczbaxy(wynik3,0,9);
piszliczbaxy(wynik4,0,12);
piszliczbaxy(wynik5,1,0);
piszliczbaxy(wynik6,1,3);
piszliczbaxy(wynik7,1,6);


*/

if(initial()){
wyslij1w(0x33);
unsigned int wynik=0;
unsigned int wynik1=0;
unsigned int wynik2=0;
unsigned int wynik3=0;
wynik=slot_odbierz1w();
wynik1=slot_odbierz1w();
wynik2=slot_odbierz1w();
wynik3=slot_odbierz1w();
piszliczbaxy(wynik,0,0);
piszliczbaxy(wynik1,0,3);
piszliczbaxy(wynik2,0,6);
piszliczbaxy(wynik3,0,9);
}



return(0);
}


Pobierz plik - link do postu