Witam
Mam prośbę, napisałem sobie bibliotekę do obsługi 1wire i mam problem w procedurze wyszukiwania do 3 urządzeń wykrywa mi poprawnie, a powyżej wykrywa mi więcej niż powinien
w zastosowaniu ta procedura ma się tak
Byłbym wdzięczny za jakąś sugestię co może być nietak w algorytmie wyszukiwania
Mam prośbę, napisałem sobie bibliotekę do obsługi 1wire i mam problem w procedurze wyszukiwania do 3 urządzeń wykrywa mi poprawnie, a powyżej wykrywa mi więcej niż powinien
#ifndef _AVR_ONEWIRE_
#define _AVR_ONEWIRE_
#include <avr/interrupt.h>
#define ONEWIRE_SEARCH_ROM 0xF0
#define ONEWIRE_NO_DEVICES 0xFF
#define ONEWIRE_DATA_ERROR 0xFE
#define ONEWIRE_OK 0x00
#define ONEWIRE_LAST_DEVICE -2
int8_t _onewire_level;
uint32_t _onewire_mask;
static uint8_t onewire_reset()
{
ONEWIRE_DDR |= (1<<ONEWIRE_PIN);
_delay_us(480);
ONEWIRE_DDR &= ~(1<<ONEWIRE_PIN);
_delay_us(70);
uint8_t ret = ~(ONEWIRE_PORT & (1<<ONEWIRE_PIN));
_delay_us(410);
return ret;
}
static void _onewire_write_bit(uint8_t value)
{
uint8_t sreg = SREG;
cli();
ONEWIRE_DDR |= (1<<ONEWIRE_PIN);
_delay_us(1);
if(value)
{
ONEWIRE_DDR &= ~(1<<ONEWIRE_PIN);
_delay_us(59);
}
else
{
_delay_us(59);
ONEWIRE_DDR &= ~(1<<ONEWIRE_PIN);
}
SREG = sreg;
_delay_us(30);
}
static uint8_t _onewire_read_bit()
{
uint8_t sreg = SREG;
cli();
ONEWIRE_DDR |= (1<<ONEWIRE_PIN);
_delay_us(1);
ONEWIRE_DDR &= ~(1<<ONEWIRE_PIN);
_delay_us(15);
uint8_t ret = ONEWIRE_PORT & (1<<ONEWIRE_PIN);
SREG = sreg;
_delay_us(75);
return ret;
}
static void onewire_write_byte(uint8_t value)
{
for(uint8_t i = 0; i < 8; i++)
{
_onewire_write_bit(value & 0x01);
value = value >> 1;
}
}
static uint8_t onewire_read_byte()
{
uint8_t ret = 0;
for(uint8_t i = 0; i < 8; i++)
{
ret = ret >> 1;
if(_onewire_read_bit()) ret |= 0x80;
}
return ret;
}
static void onewire_write_command(uint8_t *id)
{
onewire_reset();
if(id)
{
onewire_write_byte(0x55);
for(uint8_t i = 0; i < 8; i++)
onewire_write_byte(*id++);
}
else
{
onewire_write_byte(0xCC);
}
}
static uint8_t _onewire_search_rom(uint8_t *buffer)
{
if(_onewire_level == ONEWIRE_LAST_DEVICE) return ONEWIRE_NO_DEVICES;
int8_t pos = -1;
uint8_t bufpos = 0;
if(!onewire_reset()) return ONEWIRE_NO_DEVICES;
onewire_write_byte(ONEWIRE_SEARCH_ROM);
for(uint8_t i = 0; i < 64; i++)
{
bufpos = i / 8;
buffer[bufpos] >>= 1;
if(_onewire_read_bit())
{
if(_onewire_read_bit())
{
return ONEWIRE_DATA_ERROR;
}
else
{
buffer[bufpos] |= 0x80;
_onewire_write_bit(1);
}
}
else
{
if(_onewire_read_bit())
{
_onewire_write_bit(0);
}
else
{
pos++;
if(pos > _onewire_level)
{
_onewire_write_bit(0);
_onewire_mask <<= 1;
_onewire_level++;
}
else
{
if(_onewire_mask & (1<<(_onewire_level - pos)))
{
_onewire_write_bit(1);
buffer[bufpos] |= 0x80;
}
else
{
_onewire_write_bit(0);
}
}
}
}
}
uint8_t bits = 0;
for(int8_t i = 0; i <= _onewire_level; i++)
if((_onewire_mask >> i) & 1) bits++;
if(bits == _onewire_level + 1)
{
_onewire_level = ONEWIRE_LAST_DEVICE;
return ONEWIRE_OK;
}
if(_onewire_level >= 0) _onewire_mask++;
if((_onewire_mask & 0x0003) == 0x0002){
_onewire_mask >>= 1;
_onewire_level--;
}
return ONEWIRE_OK;
}
static void onewire_findinit()
{
_onewire_level = -1;
_onewire_mask = 0;
}
static inline uint8_t onewire_find(uint8_t *buffer)
{
return _onewire_search_rom(buffer);
}
#endif
w zastosowaniu ta procedura ma się tak
#include <avr/io.h>
#define ONEWIRE_PORT PINB
#define ONEWIRE_DDR DDRB
#define ONEWIRE_PIN PB0
#include "1wire.c"
int main()
{
unit8_t ids[8][8];
ids_count=0;
onewire_findinit();
while(ids_count < 8 && onewire_find(ids[id_count]) == ONEWIRE_OK)
{
ids_count++;
}
while(1);
}
Byłbym wdzięczny za jakąś sugestię co może być nietak w algorytmie wyszukiwania