Pokładałem sobie urzadzonko które ma czytac z czterech ds-ów temperature, wszystkie cztery sa na jednej magistrali z zasilaniem osobnym, (trzy kable) wyswietlacze na których ma byc pokazana temperatura to zwykłe 7-mio segmentowe led-y, multipleksowane w przerwaniu od timera (przerwanie działa tylko w momentach kiedy ds czeka naprzykład na impuls strobujacy z procesora i odwrotnie, stad nie przeszkadzxa w transmisji po 1wire) i wszystko niby jest ok ale... jak podłacze wiecej jak 2 ds-y to całosc sie psuje, co któras transmisja to odczyt samych jedynek z magistrali, przy podłaczeniu 4 ds-ów to juz sie nieda zobaczyc temperatury tak czesto sa te złe odczyty.... zmieniałem opornik podciagajacy, próbowałem delikatnie filtrowac magistrale i nic...bład jest w programie , załaczam listing z nadzieja ze ktos cos znajdzie, to mój pierwszy program w C prosze o wyrozumiałosc, zapomniał bym, numery ds-ów sa zapisane w eepromie atmegi8 która całoscia steruje
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
unsigned char tablica[18];
unsigned char tablica2[32];
unsigned char licznik;
void selectchar (unsigned char numchar);
void zapisz1w (unsigned char rozkaz);
void czytaj1w(void);
unsigned char odbierz(void);
void wait1w (unsigned char time)
{
do
{asm("NOP");}
while(--time);
}
void wait480us(void)
{TIMSK |= _BV(0);
unsigned char zt1;
unsigned char zt;
for (zt=15;zt>0;zt--)
{for(zt1=20;zt1!=0;zt1--)
asm("NOP");}
TIMSK &= ~_BV(0);}
void wait415us (void)
{TIMSK |= _BV(0);
unsigned char zt1;
unsigned char zt;
for (zt=14;zt>0;zt--)
{for(zt1=20;zt1!=0;zt1--)
asm("NOP");}
TIMSK &= ~_BV(0);}
unsigned char reset1w()
{unsigned char stan;
TIMSK |= _BV(0);
stan = 0;
DDRC |= _BV(2);
wait480us();
DDRC &= ~_BV(2);
wait1w(49);
if bit_is_clear(PINC,PC2)
stan = 1;
wait415us();
if bit_is_clear(PINC,PC2)
stan = 0;
TIMSK &= ~_BV(0);
return stan;}
void wyslij (unsigned char znak)
{
if (znak)
{
DDRC |= _BV(2); //sciagnij wyjscie 1wire do masy
wait1w(5);
DDRC &= ~_BV(2); //zwolnij linie 1wire
TIMSK |= _BV(0); //zezwolenie na przerwania od timera
wait1w(44);
TIMSK &= ~_BV(0); //wylaczenie obslugi przerwania od timera
DDRC &= ~_BV(2); //zwolnij linie 1wire
}
else
{
DDRC |= _BV(2); //sciagnij wyjscie 1wire do masy
TIMSK |= _BV(0); //zezwolenie na przerwania od timera
wait1w(54);
TIMSK &= ~_BV(0); //wylaczenie obslugi przerwania od timera
DDRC &= ~_BV(2); //zwolnij linie 1wire
}}
void zapiseeproma (void)
{
unsigned char flag;
unsigned char i;
extern unsigned char tablica2[32];
flag = 0;
EEARH = 0;
unsigned char slot;
if bit_is_clear(PIND,PD2)
{slot = 0;
flag = 1;}
if bit_is_clear(PIND,PD1)
{slot = 8;
flag = 1;}
if bit_is_clear(PIND,PD0)
{slot = 16;
flag = 1;}
if bit_is_clear(PINC,PC5)
{slot = 24;
flag = 1;}
if (flag == 1)
{
if (reset1w()) //reset magistrali
{
zapisz1w(0x33); //rzadanie o przedstawienie pastylki
for(i=(0+slot);i<(8+slot);i++) //8 razy odczytaj i zapisz bajt z układu do eeproma
{
do //petla nieskonczona
{} //czeka az dostane zezwolenie na zapis
while(bit_is_set(EECR,EEWE)); //eeproma
EEARL = i;
EEDR=odbierz(); //odbierz bajt z 1wire
EECR = 0b00000100;
EECR = 0b00000110;
}}
EECR = 0b00000000;
}
for (i=0;i<32;i++)
{
do //petla nieskonczona
{} //czeka az dostane zezwolenie na odczyt
while(bit_is_set(EECR,EEWE)); //eeproma
EEAR = i;
EECR |= 0b00000001;
tablica2[i]=EEDR;}
}
///////////////////////////////////////////
///////////////////////////////////////////
///////////////////////////////////////////
int main(void)
{
extern unsigned char tablica2[32];
unsigned char adres;
unsigned char temporary;
extern unsigned char tablica[18];
unsigned char temperatura;
unsigned char liczniczek;
DDRD = 0b11111111; //konfiguracja portów PD3,4,5,6,7 jako wyjsciowy
DDRB = 0b00011111; //konfiguracja portów PB0,1,2,3,4 jako wyjsciowy (podciagniecie do jeden)
DDRC = 0b00100011; //konfiguracja portu C jako wyjsciowy
PORTC |=0b00100011; //ustawienie pinów C0, i C2 na jedynke
PORTD |=0b00000111;
zapiseeproma ();
TCCR0 = 0b00000100; //konfiguracja preskalera dla timera 0 na 1024
TCNT0 = 0b11111000; //załaduj do rejestru timera liczbe 245 (przerwaniepo 10 impulsach)
TIMSK |= _BV(0); //LOKALNE ZEZWOLENIE NA PRZERWANIE "0"
SREG |= _BV(7); //GLOBALNE ZEZWOLENIE NA OBSLUGE PRZERWAN
do
{
liczniczek++;
if(liczniczek==4)
liczniczek=0;
if (reset1w()) //sprawdź czy na magistrali sa jakies urzadzenia
{
zapisz1w(0xCC); //zapisz do ds-a polecenie skip rom
zapisz1w(0x44); //poczatek konwersji dla wszystkich czujników
if bit_is_set(PINC,PC2) //poczekaj na zakonczenie konwersji A/D
{
reset1w(); //reset ds-a - jasna sprawa
zapisz1w(0x55); //zapisz do ds-a polecenie match rom
//tablica[18]=17;
//tablica[17]=17;
if(liczniczek == 0)
{temporary = 0;
for (adres=0;adres<8;adres++)
zapisz1w(tablica2[adres]);}
if(liczniczek == 1)
{temporary = 4;
for (adres=8;adres<16;adres++)
zapisz1w(tablica2[adres]);}
if(liczniczek == 2)
{temporary = 9;
for (adres=16;adres<24;adres++)
zapisz1w(tablica2[adres]);}
if(liczniczek == 3)
{temporary = 13;
for (adres=24;adres<32;adres++)
zapisz1w(tablica2[adres]);}
zapisz1w(0xBE); //zapisz do ds-a zadanie odczytu temperatury
}
temperatura = odbierz();
if(temperatura < 255)
{tablica[temporary+1]=(temperatura/20);
tablica[temporary+2]=(temperatura-(20*(temperatura/20)))/2;
tablica[temporary+3]=16;
tablica[temporary+4]=12;}
else
{tablica[temporary+1]=14;
tablica[temporary+2]=18;
tablica[temporary+3]=18;
tablica[temporary+4]=17;}
}
else
{for (temporary=0;temporary<17;temporary++)
tablica[temporary]=19;}
}
while(1);
return 0;
}
///////////////////////////////////////////
///////////////////////////////////////////
///////////////////////////////////////////
void selectchar (unsigned char numchar)
{switch(numchar){
case 0:
PORTD = 0b11000000;
PORTB = 0b00001111;
break;
case 1:
PORTD = 0b01000000;
PORTB = 0b00000010;
break;
case 2:
PORTD = 0b01000000;
PORTB = 0b00011101;
break;
case 3:
PORTD = 0b01000000;
PORTB = 0b00010111;
break;
case 4:
PORTD = 0b11000000;
PORTB = 0b00010010;
break;
case 5:
PORTD = 0b10000000;
PORTB = 0b00010111;
break;
case 6:
PORTD = 0b10000000;
PORTB = 0b00011111;
break;
case 7:
PORTD = 0b01000000;
PORTB = 0b00000011;
break;
case 8:
PORTD = 0b11000000;
PORTB = 0b00011111;
break;
case 9:
PORTD = 0b11000000;
PORTB = 0b00010111;
break;
//case 10:
//PORTD = 0b11000000;
//PORTB = 0b00011011;
//break;
//case 11:
//PORTD = 0b10000000;
//PORTB = 0b00011110;
//break;
case 12:
PORTD = 0b10000000;
PORTB = 0b00001101;
break;
//case 13:
//PORTD = 0b01000000;
//PORTB = 0b00011110;
//break;
case 14:
PORTD = 0b10000000;
PORTB = 0b00011101;
break;
//case 15:
//PORTD = 0b10000000;
//PORTB = 0b00011001;
//break;
case 16:
PORTD = 0b11000000;
PORTB = 0b00010001;
break;
case 17:
PORTD = 0b00000000;
PORTB = 0b00000000;
break;
case 18:
PORTD = 0b00000000;
PORTB = 0b00011000;
break;
case 19:
PORTD = 0b00000000;
PORTB = 0b00010000;
break;
}}
void zapisz1w (unsigned char rozkaz)
{
unsigned char i;
for(i=0;i<8;i++)
{
wyslij(rozkaz&0x01);
rozkaz>>=1;
}}
unsigned char odbierz(void)
{
unsigned char bitna1w;
unsigned char i;
unsigned char bajt;
bajt=0;
for (i=0;i<8;i++)
{
bitna1w =1; //ustaw wstepnie bit
DDRC |= _BV(2); //sciagnij wyjscie 1wire do masy
wait1w(1);
DDRC &= ~_BV(2); //zwolnij linie 1wire
wait1w(6);
if bit_is_clear(PINC,PC2) //jesli pastylka sciagneła linie to
bitna1w = 0; //odczytany bit jest zerem, jesli nie to jeden
TIMSK |= _BV(0);
wait1w(44);
TIMSK &= ~_BV(0);
if(bitna1w) bajt |= 0x01<<i;
}
return bajt; //no i zwróc to co odczytałes
}
SIGNAL(SIG_OVERFLOW0)
{
extern unsigned char tablica[18];
extern unsigned char licznik;
TCNT0 = 0b11110000;
PORTD = 0b00000000;
PORTB = 0b00000000;
licznik++;
PORTD |= _BV(4);
PORTD &= ~_BV(4);
if (licznik==17)
licznik = 0;
if (licznik<9)
{
PORTD &= ~_BV(5);
PORTD |= _BV(3);
}
else
{
PORTD &= ~_BV(3);
PORTD |= _BV(5);
}
selectchar (tablica[licznik+1]);
}
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
unsigned char tablica[18];
unsigned char tablica2[32];
unsigned char licznik;
void selectchar (unsigned char numchar);
void zapisz1w (unsigned char rozkaz);
void czytaj1w(void);
unsigned char odbierz(void);
void wait1w (unsigned char time)
{
do
{asm("NOP");}
while(--time);
}
void wait480us(void)
{TIMSK |= _BV(0);
unsigned char zt1;
unsigned char zt;
for (zt=15;zt>0;zt--)
{for(zt1=20;zt1!=0;zt1--)
asm("NOP");}
TIMSK &= ~_BV(0);}
void wait415us (void)
{TIMSK |= _BV(0);
unsigned char zt1;
unsigned char zt;
for (zt=14;zt>0;zt--)
{for(zt1=20;zt1!=0;zt1--)
asm("NOP");}
TIMSK &= ~_BV(0);}
unsigned char reset1w()
{unsigned char stan;
TIMSK |= _BV(0);
stan = 0;
DDRC |= _BV(2);
wait480us();
DDRC &= ~_BV(2);
wait1w(49);
if bit_is_clear(PINC,PC2)
stan = 1;
wait415us();
if bit_is_clear(PINC,PC2)
stan = 0;
TIMSK &= ~_BV(0);
return stan;}
void wyslij (unsigned char znak)
{
if (znak)
{
DDRC |= _BV(2); //sciagnij wyjscie 1wire do masy
wait1w(5);
DDRC &= ~_BV(2); //zwolnij linie 1wire
TIMSK |= _BV(0); //zezwolenie na przerwania od timera
wait1w(44);
TIMSK &= ~_BV(0); //wylaczenie obslugi przerwania od timera
DDRC &= ~_BV(2); //zwolnij linie 1wire
}
else
{
DDRC |= _BV(2); //sciagnij wyjscie 1wire do masy
TIMSK |= _BV(0); //zezwolenie na przerwania od timera
wait1w(54);
TIMSK &= ~_BV(0); //wylaczenie obslugi przerwania od timera
DDRC &= ~_BV(2); //zwolnij linie 1wire
}}
void zapiseeproma (void)
{
unsigned char flag;
unsigned char i;
extern unsigned char tablica2[32];
flag = 0;
EEARH = 0;
unsigned char slot;
if bit_is_clear(PIND,PD2)
{slot = 0;
flag = 1;}
if bit_is_clear(PIND,PD1)
{slot = 8;
flag = 1;}
if bit_is_clear(PIND,PD0)
{slot = 16;
flag = 1;}
if bit_is_clear(PINC,PC5)
{slot = 24;
flag = 1;}
if (flag == 1)
{
if (reset1w()) //reset magistrali
{
zapisz1w(0x33); //rzadanie o przedstawienie pastylki
for(i=(0+slot);i<(8+slot);i++) //8 razy odczytaj i zapisz bajt z układu do eeproma
{
do //petla nieskonczona
{} //czeka az dostane zezwolenie na zapis
while(bit_is_set(EECR,EEWE)); //eeproma
EEARL = i;
EEDR=odbierz(); //odbierz bajt z 1wire
EECR = 0b00000100;
EECR = 0b00000110;
}}
EECR = 0b00000000;
}
for (i=0;i<32;i++)
{
do //petla nieskonczona
{} //czeka az dostane zezwolenie na odczyt
while(bit_is_set(EECR,EEWE)); //eeproma
EEAR = i;
EECR |= 0b00000001;
tablica2[i]=EEDR;}
}
///////////////////////////////////////////
///////////////////////////////////////////
///////////////////////////////////////////
int main(void)
{
extern unsigned char tablica2[32];
unsigned char adres;
unsigned char temporary;
extern unsigned char tablica[18];
unsigned char temperatura;
unsigned char liczniczek;
DDRD = 0b11111111; //konfiguracja portów PD3,4,5,6,7 jako wyjsciowy
DDRB = 0b00011111; //konfiguracja portów PB0,1,2,3,4 jako wyjsciowy (podciagniecie do jeden)
DDRC = 0b00100011; //konfiguracja portu C jako wyjsciowy
PORTC |=0b00100011; //ustawienie pinów C0, i C2 na jedynke
PORTD |=0b00000111;
zapiseeproma ();
TCCR0 = 0b00000100; //konfiguracja preskalera dla timera 0 na 1024
TCNT0 = 0b11111000; //załaduj do rejestru timera liczbe 245 (przerwaniepo 10 impulsach)
TIMSK |= _BV(0); //LOKALNE ZEZWOLENIE NA PRZERWANIE "0"
SREG |= _BV(7); //GLOBALNE ZEZWOLENIE NA OBSLUGE PRZERWAN
do
{
liczniczek++;
if(liczniczek==4)
liczniczek=0;
if (reset1w()) //sprawdź czy na magistrali sa jakies urzadzenia
{
zapisz1w(0xCC); //zapisz do ds-a polecenie skip rom
zapisz1w(0x44); //poczatek konwersji dla wszystkich czujników
if bit_is_set(PINC,PC2) //poczekaj na zakonczenie konwersji A/D
{
reset1w(); //reset ds-a - jasna sprawa
zapisz1w(0x55); //zapisz do ds-a polecenie match rom
//tablica[18]=17;
//tablica[17]=17;
if(liczniczek == 0)
{temporary = 0;
for (adres=0;adres<8;adres++)
zapisz1w(tablica2[adres]);}
if(liczniczek == 1)
{temporary = 4;
for (adres=8;adres<16;adres++)
zapisz1w(tablica2[adres]);}
if(liczniczek == 2)
{temporary = 9;
for (adres=16;adres<24;adres++)
zapisz1w(tablica2[adres]);}
if(liczniczek == 3)
{temporary = 13;
for (adres=24;adres<32;adres++)
zapisz1w(tablica2[adres]);}
zapisz1w(0xBE); //zapisz do ds-a zadanie odczytu temperatury
}
temperatura = odbierz();
if(temperatura < 255)
{tablica[temporary+1]=(temperatura/20);
tablica[temporary+2]=(temperatura-(20*(temperatura/20)))/2;
tablica[temporary+3]=16;
tablica[temporary+4]=12;}
else
{tablica[temporary+1]=14;
tablica[temporary+2]=18;
tablica[temporary+3]=18;
tablica[temporary+4]=17;}
}
else
{for (temporary=0;temporary<17;temporary++)
tablica[temporary]=19;}
}
while(1);
return 0;
}
///////////////////////////////////////////
///////////////////////////////////////////
///////////////////////////////////////////
void selectchar (unsigned char numchar)
{switch(numchar){
case 0:
PORTD = 0b11000000;
PORTB = 0b00001111;
break;
case 1:
PORTD = 0b01000000;
PORTB = 0b00000010;
break;
case 2:
PORTD = 0b01000000;
PORTB = 0b00011101;
break;
case 3:
PORTD = 0b01000000;
PORTB = 0b00010111;
break;
case 4:
PORTD = 0b11000000;
PORTB = 0b00010010;
break;
case 5:
PORTD = 0b10000000;
PORTB = 0b00010111;
break;
case 6:
PORTD = 0b10000000;
PORTB = 0b00011111;
break;
case 7:
PORTD = 0b01000000;
PORTB = 0b00000011;
break;
case 8:
PORTD = 0b11000000;
PORTB = 0b00011111;
break;
case 9:
PORTD = 0b11000000;
PORTB = 0b00010111;
break;
//case 10:
//PORTD = 0b11000000;
//PORTB = 0b00011011;
//break;
//case 11:
//PORTD = 0b10000000;
//PORTB = 0b00011110;
//break;
case 12:
PORTD = 0b10000000;
PORTB = 0b00001101;
break;
//case 13:
//PORTD = 0b01000000;
//PORTB = 0b00011110;
//break;
case 14:
PORTD = 0b10000000;
PORTB = 0b00011101;
break;
//case 15:
//PORTD = 0b10000000;
//PORTB = 0b00011001;
//break;
case 16:
PORTD = 0b11000000;
PORTB = 0b00010001;
break;
case 17:
PORTD = 0b00000000;
PORTB = 0b00000000;
break;
case 18:
PORTD = 0b00000000;
PORTB = 0b00011000;
break;
case 19:
PORTD = 0b00000000;
PORTB = 0b00010000;
break;
}}
void zapisz1w (unsigned char rozkaz)
{
unsigned char i;
for(i=0;i<8;i++)
{
wyslij(rozkaz&0x01);
rozkaz>>=1;
}}
unsigned char odbierz(void)
{
unsigned char bitna1w;
unsigned char i;
unsigned char bajt;
bajt=0;
for (i=0;i<8;i++)
{
bitna1w =1; //ustaw wstepnie bit
DDRC |= _BV(2); //sciagnij wyjscie 1wire do masy
wait1w(1);
DDRC &= ~_BV(2); //zwolnij linie 1wire
wait1w(6);
if bit_is_clear(PINC,PC2) //jesli pastylka sciagneła linie to
bitna1w = 0; //odczytany bit jest zerem, jesli nie to jeden
TIMSK |= _BV(0);
wait1w(44);
TIMSK &= ~_BV(0);
if(bitna1w) bajt |= 0x01<<i;
}
return bajt; //no i zwróc to co odczytałes
}
SIGNAL(SIG_OVERFLOW0)
{
extern unsigned char tablica[18];
extern unsigned char licznik;
TCNT0 = 0b11110000;
PORTD = 0b00000000;
PORTB = 0b00000000;
licznik++;
PORTD |= _BV(4);
PORTD &= ~_BV(4);
if (licznik==17)
licznik = 0;
if (licznik<9)
{
PORTD &= ~_BV(5);
PORTD |= _BV(3);
}
else
{
PORTD &= ~_BV(3);
PORTD |= _BV(5);
}
selectchar (tablica[licznik+1]);
}