Chciałem sobie złożyć do kupy zbiór procedur do obsługi 2 czujników DS'a, które później wykorzystam w programie. Znalazłem kod który wyrzucał dane na RS'a.
Złożyłem, trochę przerobiłem. Pierwszy raz piszę coś poważnego w C dla AVR'a.
Na razie nie mam jak sprawdzić czy to ruszy i prosiłbym szanownych forumowiczów o sprawdzenie poprawności tego kodu, czy ruszy tak jak jest i będzie to działało prawidłowo czy czegoś mi brakuje / jest źle.
Jak mówię kod jakby nie był do końca taki jak potrzebuję i stąd, niektóre rzeczy wrzucone w komentarz, które powodowały jakieś błędy czy nie wiedziałem po co one właściwie tu są.
Używam AVRSTUDIO4 i WINAVR2010.
Złożyłem, trochę przerobiłem. Pierwszy raz piszę coś poważnego w C dla AVR'a.
Na razie nie mam jak sprawdzić czy to ruszy i prosiłbym szanownych forumowiczów o sprawdzenie poprawności tego kodu, czy ruszy tak jak jest i będzie to działało prawidłowo czy czegoś mi brakuje / jest źle.
#include <avr/io.h>
#include <avr/interrupt.h>
//#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#define MATCH_ROM 0x55
#define SKIP_ROM 0xCC
#define SEARCH_ROM 0xF0
#define CONVERT_T 0x44 // DS1820 commands
#define READ 0xBE
#define WRITE 0x4E
#define EE_WRITE 0x48
#define EE_RECALL 0xB8
#define SEARCH_FIRST 0xFF // start new search
#define PRESENCE_ERR 0xFF
#define DATA_ERR 0xFE
#define LAST_DEVICE 0x00 // last device found
// 0x01 ... 0x40: continue searching
#define W1_PIN PD6
#define W1_IN PIND
#define W1_OUT PORTD
#define W1_DDR DDRD
//#define XTAL 11059200L
#define XTAL 16000000L
#define uchar unsigned char
#define uint unsigned int
#define bit uchar
#define idata
#define code
#define W1_PIN PD6
#define W1_IN PIND
#define W1_OUT PORTD
#define W1_DDR DDRD
#define DELAY_US(x) ((uint)( (x) * 1e-6 * XTAL ))
#define DELAY(x) delay(x)
// Attention !!!
// take care, that during delay no interrupt access a timer register
// or restore TCNT1H
void delay( int d ) // d = 0 ... 32000
{
d += TCNT1; // not atomic !
while( (TCNT1 - d) & 0x8000 ); // not atomic !
}
typedef struct
{
uint t1;
uint t2;
}wyniki;
bit w1_reset(void)
{
bit err;
W1_OUT &= ~(1<<W1_PIN);
W1_DDR |= 1<<W1_PIN;
DELAY( DELAY_US( 480 )); // 480 us
cli();
W1_DDR &= ~(1<<W1_PIN);
DELAY( DELAY_US( 66 ));
err = W1_IN & (1<<W1_PIN); // no presence detect
sei();
DELAY( DELAY_US( 480 - 66 ));
if( (W1_IN & (1<<W1_PIN)) == 0 ) // short circuit
err = 1;
return err;
}
uchar w1_bit_io( bit b )
{
cli();
W1_DDR |= 1<<W1_PIN;
DELAY( DELAY_US( 1 ));
if( b )
W1_DDR &= ~(1<<W1_PIN);
DELAY( DELAY_US( 15 - 1 ));
if( (W1_IN & (1<<W1_PIN)) == 0 )
b = 0;
DELAY( DELAY_US( 60 - 15 ));
W1_DDR &= ~(1<<W1_PIN);
sei();
return b;
}
uint w1_byte_wr( uchar b )
{
uchar i = 8, j;
do{
j = w1_bit_io( b & 1 );
b >>= 1;
if( j )
b |= 0x80;
}while( --i );
return b;
}
uint w1_byte_rd( void )
{
return w1_byte_wr( 0xFF );
}
uchar w1_rom_search( uchar diff, uchar idata *id )
{
uchar i, j, next_diff;
bit b;
if( w1_reset() )
return PRESENCE_ERR; // error, no device found
w1_byte_wr( SEARCH_ROM ); // ROM search command
next_diff = LAST_DEVICE; // unchanged on last device
i = 8 * 8; // 8 bytes
do{
j = 8; // 8 bits
do{
b = w1_bit_io( 1 ); // read bit
if( w1_bit_io( 1 ) ){ // read complement bit
if( b ) // 11
return DATA_ERR; // data error
}else{
if( !b ){ // 00 = 2 devices
if( diff > i || ((*id & 1) && diff != i) )
{
b = 1; // now 1
next_diff = i; // next pass 0
}
}
}
w1_bit_io( b ); // write bit
*id >>= 1;
if( b ) // store bit
*id |= 0x80;
i--;
}while( --j );
id++; // next byte
}while( i );
return next_diff; // to continue search
}
void w1_command( uchar command, uchar idata *id )
{
uchar i;
w1_reset();
if( id ){
w1_byte_wr( MATCH_ROM ); // to a single device
i = 8;
do{
w1_byte_wr( *id );
id++;
}while( --i );
}else{
w1_byte_wr( SKIP_ROM ); // to all devices
}
w1_byte_wr( command );
}
void start_meas( void ){
if( W1_IN & 1<< W1_PIN ){
w1_command( CONVERT_T, NULL );
W1_OUT |= 1<< W1_PIN;
// W1_DDR |= 1<< W1_PIN; // parasite power on
}
}
wyniki read_meas( void )
{
uchar id[8], diff;
wyniki i;
uint temp;
uchar j=0;
for( diff = SEARCH_FIRST; diff != LAST_DEVICE; ){
diff = w1_rom_search( diff, id );
if( diff == PRESENCE_ERR ){
//uputsnl( "No Sensor found" );
break;
}
if( diff == DATA_ERR ){
//uputsnl( "Bus Error" );
break;
}
w1_byte_wr( READ ); // read command
temp = w1_byte_rd(); // low byte
temp |= (uint)w1_byte_rd() << 8; // high byte
if( id[0] == 0x10 ) // 9 -> 12 bit
temp <<= 3;
if(j == 1)
i.t1 = temp;
else
i.t2 = temp;
j++;
}
return i;
}
int main( void )
{
//init_timer();
//uinit();
sei();
wyniki w;
start_meas();
w = read_meas();
}
Jak mówię kod jakby nie był do końca taki jak potrzebuję i stąd, niektóre rzeczy wrzucone w komentarz, które powodowały jakieś błędy czy nie wiedziałem po co one właściwie tu są.
Używam AVRSTUDIO4 i WINAVR2010.
