Witam
Jak już widzicie po tytule nie mogę uzyskać poprawnego wyniku z przetwornika zewnętrznego PCF8591 połączonego z mikrokontrolerem (Atmega16-8Mhz pod piny SCL i SDA) poprzez programowe I2C. Już nie mam pomysłów co może być źle, w czym tkwi haczyk. Wszystko wydaje się być dobrze podłączone, program kompiluje się bez błędów. Kod sprawdziłem już na milion sposobów. Jedyne co uzyskuje na wyświetlaczu to dziwne wyniki napięcia zmienianego potencjometrem 5kOhm z 0 do 5V, a mianowicie:
0 - 1,28V ->> na wyświetlaczu liczba 028
1,28 - 1,92 ->> na wyświetlaczu liczba 128
1,92 - 2,24 ->> 192
2,24 - 2,40 ->> 224
2,4 - 2,48 ->> 240
2,48 - 2,52 ->> 248
....
2,55 - 5 ->> 255
Napięcie Vref na przetworniku mam ustawione na 2,56V co powinno mi dać regulacje 5V od 0 do 255 cyfrowo co 0,01V analogowo. Niestety nie uzyskuje tego wyniku, ale wręcz obniżony do połowy i o bardzo dziwnych kwantach (które jak można zauważyć zwiększają się o pomniejszoną liczbę potęgi 2 bo np. 224 -192=32 a juz 240 - 224 = 16 itd. ). Może ktoś wie w czym problem ?
Poniżej kod obsługi programowego I2C:
i fragment pętli głównej:
Dodam może jeszcze, że PCF8591 jest raczej podłączony jak należy.
1,2,3,4 przez R1M do masy a i na 1 napięcie z potencjometru.
5,6,7,8,12,13 do masy
9 do sda 10 do scl
11 w powietrzu
14 Vref uzyskane z dzielnika i układu TL431
15 5V
link do przetwornika
Prosiłbym o wszelaką pomoc
Jak już widzicie po tytule nie mogę uzyskać poprawnego wyniku z przetwornika zewnętrznego PCF8591 połączonego z mikrokontrolerem (Atmega16-8Mhz pod piny SCL i SDA) poprzez programowe I2C. Już nie mam pomysłów co może być źle, w czym tkwi haczyk. Wszystko wydaje się być dobrze podłączone, program kompiluje się bez błędów. Kod sprawdziłem już na milion sposobów. Jedyne co uzyskuje na wyświetlaczu to dziwne wyniki napięcia zmienianego potencjometrem 5kOhm z 0 do 5V, a mianowicie:
0 - 1,28V ->> na wyświetlaczu liczba 028
1,28 - 1,92 ->> na wyświetlaczu liczba 128
1,92 - 2,24 ->> 192
2,24 - 2,40 ->> 224
2,4 - 2,48 ->> 240
2,48 - 2,52 ->> 248
....
2,55 - 5 ->> 255
Napięcie Vref na przetworniku mam ustawione na 2,56V co powinno mi dać regulacje 5V od 0 do 255 cyfrowo co 0,01V analogowo. Niestety nie uzyskuje tego wyniku, ale wręcz obniżony do połowy i o bardzo dziwnych kwantach (które jak można zauważyć zwiększają się o pomniejszoną liczbę potęgi 2 bo np. 224 -192=32 a juz 240 - 224 = 16 itd. ). Może ktoś wie w czym problem ?

Poniżej kod obsługi programowego I2C:
//----------------------------------------------------------------------------------------
//Ustawienie i zerowanie wyjscia danych
static inline void i2c_sdasetddr(void)
{
DDR(I2C_SDAPORT) |= 1<<I2C_SDA;
}
static inline void i2c_sdasetport(void)
{
PORT(I2C_SDAPORT) |= 1<<I2C_SDA;
}
static inline void i2c_sdaclearddr(void)
{
DDR(I2C_SDAPORT) &= ~(1<<I2C_SDA);
}
static inline void i2c_sdaclearport(void)
{
PORT(I2C_SDAPORT) &= ~(1<<I2C_SDA);
}
//----------------------------------------------------------------------------------------
//Pobieranie danej z wyprowadzenia portu
static inline uint8_t i2c_sdaget(void)
{
return PIN(I2C_SDAPORT) & (1<<I2C_SDA);
}
//----------------------------------------------------------------------------------------
//Zerowanie i ustawianie zegara
static inline void i2c_sclsetport(void)
{
PORT(I2C_SCLPORT) |= 1<<I2C_SCL;
}
static inline void i2c_sclclearport(void)
{
PORT(I2C_SCLPORT) &= ~(1<<I2C_SCL);
}
static inline void i2c_sclsetddr(void)
{
DDR(I2C_SCLPORT) |= 1<<I2C_SCL;
}
static inline void i2c_sclclearddr(void)
{
DDR(I2C_SCLPORT) &= ~(1<<I2C_SCL);
}
//----------------------------------------------------------------------------------------
//Funkcja startujaca transmisje
void i2c_start(void)
{
//jesli start bez stop
i2c_sdasetddr();
i2c_sclsetddr();
i2c_sdasetport();
i2c_sclsetport();
i2c_hdelay();
//normalna sekwencja startu
i2c_sdaclearport();
i2c_hdelay();
i2c_sclclearport();
}
//----------------------------------------------------------------------------------------
//Funkcja zatrzymujaca transmisje
void i2c_stop(void)
{
//jesli start bez stop
i2c_sdaclearport();
i2c_hdelay();
i2c_sclsetport();
i2c_hdelay();
i2c_sdasetport();
i2c_hdelay();
}
//----------------------------------------------------------------------------------------
//Funkcja wysylajaca dane
uint8_t i2c_send(uint8_t data)
{
uint8_t n=9;
do
{
i2c_sclclearport();
if(data & 0x80)
{
i2c_sdasetport();
}
else
{
i2c_sdaclearport();
}
data <<= 1;
i2c_hdelay();
i2c_sclsetport();
i2c_hdelay();
}
while(--n);
i2c_sclclearport();
return n;
}
//----------------------------------------------------------------------------------------
//Funkcja pobierajaca dane
uint8_t i2c_get(uint8_t ack)
{
unsigned char n=8, temp=0;
i2c_sdasetport();
i2c_sdaclearddr();
do
{
i2c_hdelay();
i2c_sclsetport();
i2c_hdelay();
temp <<=1;
if(i2c_sdaget())
{
temp++;
i2c_sclclearport();
}
}
while(--n);
//ack
if(ack)
{
i2c_sdasetport();
i2c_hdelay();
i2c_sclsetport();
i2c_hdelay();
i2c_sclclearport();
}
return temp;
}
i fragment pętli głównej:
int main(void)
{
//inicjalizacja portow
DDR(LCD_DPORT) |= 1<<LCD_LIGHT | 1<<LCD_E | 1<<LCD_RS | 0x0F<<LCD_D4; //wyjscia pod LCD
DDR(I2C_SDAPORT) |= 1<<I2C_SCL;
PORT(LCD_DPORT) |= 1<<I2C_SDA | 1<<I2C_SCL;
//przygotowanie wyswietlacza
lcd_init();
lcd_cls();
PORTD |= 1<<LCD_LIGHT;
//lcd_str_P((prog_char*)PSTR("Dane z AC/CA I0:"));
lcd_command(LCDC_DDA | 64);
//konfiguracja prztwornika
i2c_start();
//bajt adresowy, dzieki niemu zapiszemy bajt kontrolny w przetworniku
i2c_send(0x90);//przy zwartych A0,A1,A2 mamy 90; podlaczajac pod te piny 1 zmieniamy adres przetwornika
//bajt kontrolny
i2c_send(0x00);//przechowywany w rejestrze przetwornika - np. kontrloluje przelaczaenie wejsc ac
i2c_stop();//koniec konfiguracji
//----------------------------------------------------------------------------------------
//pobieranie danych
for(;;)
{
lcd_command(LCDC_DDA |64);
//odczyt danych
i2c_start();
//bajt adresowy, dzieki niemu odczytamy wartosc przetwornika na kanale 0
i2c_send(0x91);
//pobieranie i wyswietlanie danej
lcd_dec(i2c_get(I2C_NACK));
//przysloniecie reszty napisu
//lcd_str_P((prog_char*)PSTR(" "));
i2c_stop();
}
//return 0;
}
Dodam może jeszcze, że PCF8591 jest raczej podłączony jak należy.
1,2,3,4 przez R1M do masy a i na 1 napięcie z potencjometru.
5,6,7,8,12,13 do masy
9 do sda 10 do scl
11 w powietrzu
14 Vref uzyskane z dzielnika i układu TL431
15 5V
link do przetwornika
Prosiłbym o wszelaką pomoc