mikrokontrolery.net

 

   

Przykład 10 - magistrala 1-wire

Przykład 10 - magistrala 1-wire (wersja wstępna)

Poniższy program odczytuje temperaturę z czujnika DS1822 (18B20) i wyświetla ją na dwóch cyfrach wyświetlacza siedmiosegmentowego płytki AVT-3500. Czujnik należy podłączyć do złącza śrubowego SCL (końcówka DQ) oraz do zasilania (+5V, GND). Zworki J1 i J2 należy przełączyć w pozycję B-C.

#include <avr/io.h>
#include <avr/delay.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

#define DQ 5

#define SET_DQ DDRD &= ~_BV(DQ)
#define CLR_DQ DDRD |= _BV(DQ)

#define IN_DQ PIND & _BV(DQ)
char znaki[17] = {192,249,164,176,153,146,130,248,128,144};
char wysw = 0;
unsigned char d1, d2;
// procedura obsługi przerwania od timera TC0
SIGNAL (SIG_OVERFLOW0)
{
TCNT0 = 250; // załadowanie do licznika wartości początkowej
PORTD |= _BV(4); // wygaszenie wszystkich cyfr wyświetlacza
PORTD |= _BV(3);
PORTB = 0xFF;
wysw++; // zwiększenie o 1 zmiennej wysw
// w zależności od wartości wysw włącz odpowiednią cyfrę na wyświetlaczu
switch(wysw){
case 1:
{
PORTD &= ~_BV(4); // włącz pierwszą cyfrę wyświetlcza
PORTB = *(znaki + d2); // na wyświetlaczu wyświetl odpowiedni znak
// pobrany z tablicy znaków
break; // opuść instrukcję switch
}
case 2:
{
PORTD &= ~_BV(3); // włącz drugą cyfrę wyświetlcza
PORTB = *(znaki + d1); // na wyświetlaczu wyświetl odpowiedni znak
// pobrany z tablicy znaków
wysw = 0;
break; // opuść instrukcję switch
}
}
}
// procedura opóźniająca o (5+5*t)* 0,25 us dla 4MHz kwarcu
void delay(unsigned char t)
{
do{asm("nop");}while(--t);
}
// procedura reset
void ow_reset(void)
{
CLR_DQ; // stan niski na linii 1wire
delay(255); //
delay(119); // opóźnienie ok 480us
//delay(1);
SET_DQ;// stan wysoki na linii 1wire
delay(255); //
delay(119); // opóźnienie ok 480 us
}
// procedura zapisu bitu na linię 1wire
void ow_write_bit(char b)
{
cli(); // zablokowanie przerwań
CLR_DQ; // stan niski na linii 1wire
delay(7); // opóźnienie 10us
if(b) SET_DQ; // jeśli parametr jest niezerowy to ustaw stan wysoki na linii
delay(80); // opóźnienie 100us
SET_DQ; // stan wysoki na linii 1wire
sei(); // odblokowanie pzrerwań
}

char ow_read_bit(void)
{
cli();
CLR_DQ;
delay(1);
SET_DQ;
delay(11);
sei();
if(IN_DQ) return 1; else return 0;
}

unsigned char ow_read_byte(void)
{
unsigned char i;
unsigned char value = 0;
for (i=0;i<8;i++)
{
if(ow_read_bit()) value|=0x01<<i;
delay(6);
}
return(value);
}

void ow_write_byte(char val)
{
unsigned char i;
unsigned char temp;
for (i=0; i<8; i++)
{
temp = val >> i;
temp &= 0x01;
ow_write_bit(temp);
}
delay(5);
}

int main(void)
{
char msb, lsb, temp;
//
TCCR0 = 0x04;
// wpisanie wartości początkowej
TCNT0 = 250;
// odblokowanie przerwania od licznika
TIMSK = 0x02;
// globalne odblokowanie przerwań
sei();
//
DDRB = 0xFF;
//
DDRD |= _BV(4);
//
DDRD |= _BV(3);
//
//PORTD |= _BV(DQ);
while(1)
{
ow_reset();
ow_write_byte(0xCC);
ow_write_byte(0x44);
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
ow_reset();
ow_write_byte(0xCC);
ow_write_byte(0xBE);
lsb = ow_read_byte();
msb = ow_read_byte();

lsb = lsb >> 4;
msb &= 0x07;
msb = msb << 4;
temp = lsb | msb;
d2 = temp / 10;
d1 = temp % 10;
}
return 0;
}

 

 

 

 

 

 

 

 

 

 

 

 
 
 
 

(c) 2004-2008 Radosław Kwiecień
Polityka prywatności