Witam, jak w temacie mam z tym problem..otóż napisałem, bazując na dostępnych w internecie przykładach obsługę i2c w komunikacji z eepromem 24LC1025, wysyłam mu pewną liczbę a następnie ją odczytuję i wyświetlam na LCD. Niestety, komunikacja I2C nie działa - wiem to gdyż zamienienie miejscami linii SDA i SCL nie zmieniło niczego w zachowaniu programu..
edit: zamieszczam przebiegi SDA i SCL jakie zarejestrowałem analizatorem stanów logicznych : klik!
oto kod :
Z góry dziękuję za pomoc
edit: zamieszczam przebiegi SDA i SCL jakie zarejestrowałem analizatorem stanów logicznych : klik!
oto kod :
#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <util/delay.h>
#include <hd44780.c>
//---------/ DEFINICJA NUMERÓW PORTÓW SDA I SCL /--------------
#define SDA 0
#define SCL 1
#define SDA_PORT PORTB
#define SCL_PORT PORTB
//-------------/ USTAWIANIE PORTÓW NA WEJŚCIE/WYJŚCIE /--------------------
#define SDA_DDR DDRB
#define SCL_DDR DDRB
#define SCL_PIN PINB
#define SDA_PIN PINB
//-------------/ NADAWANIE SYGNAŁU NA SDA /--------------------
#define SET_SDA SDA_PORT |= (1<<SDA) //ustawia stan wysoki na lini SDA
#define CLR_SDA SDA_PORT &= ~(1<<SDA) //ustawia stan niski na lini SDA
//-------------/ NADAWANIE SYGNAŁU NA SCL /--------------------
#define SET_SCL SCL_PORT |= (1<<SCL) //ustawia stan wysoki na lini SCL
#define CLR_SCL SCL_PORT &= ~(1<<SCL) //ustawia stan niski na lini SCL
//-------------/ USTAWIANIE SDA JAKO WE/WYJ /------------------
#define SDA_OUT SDA_DDR |= (1 << SDA) // Ustawienie SDA jako wyjście
#define SDA_IN SDA_DDR &= ~(1 << SDA) // Ustawienie SDA jako wejście
//-------------/ USTAWIENIE SCL JAKO WE/WYJ /------------------
#define SCL_OUT SCL_DDR |= (1 << SCL) // Ustawienie SCL jako wyjście
#define SCL_IN SCL_DDR &= ~(1 << SCL) // Ustawienie SCL jako wejście
#define GET_SDA (SDA_PIN & (1 << SDA))
void delay(void)
{
asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
}
//------------/ BIT STARTU NA MAGISTRALI I2C /-----------------
void i2c_start(void)
{
SDA_OUT;
SCL_OUT;
SET_SDA; // i2c start bit sequence
SET_SCL;
delay();
CLR_SDA;
delay();
CLR_SCL;
}
//------------/ BIT STOPU NA MAGISTRALI I2C /-----------------
void i2c_stop(void)
{
CLR_SDA; // i2c stop bit sequence
delay();
SET_SCL;
delay();
SET_SDA;
delay();
}
//------------/ FUNKCJA WYSYŁAJĄCA BAJT NA SZYNE I2C/---------
char i2c_write(unsigned char x)
{
unsigned char ack;
SDA_OUT;
for(char i=0;i<8;i++)
{
CLR_SCL;
if(x&0x80) //sprawdza czy aktualny bit do wysylki jest rowny 1 czy 0
{
SET_SDA; //jesli jeden to wysyla jeden
delay();
SET_SCL;
delay();
CLR_SCL;
delay();
CLR_SDA;
}
else
{
SET_SCL; //jesli 0 to tylko tykniecie zegara
delay();
CLR_SCL;
delay();
}
x = x<<1;
}
SDA_IN; //uwolnienie linii SDA
delay();
SET_SCL;
delay();
ack = GET_SDA; //sprawdzenie stanu SDA
CLR_SCL;
CLR_SDA;
SDA_OUT;
if(ack) // Sprawdzenie bitu ACK
{
return 1;
}
return 0;
}
//------------/ FUNKCJA ODCZYTUJĄCA BAJT Z SZYNY I2C/---------
unsigned char i2c_read()
{
unsigned char count = 8, bufor = 0; // Ustawia licznik i bufor danych
SDA_IN; // Ustawia PORT B na wejście
SET_SDA; // Ustawia "1' na PORT B
do
{
bufor = bufor << 1; // Przesuwa dane buforu o 1
SET_SCL; // Ustawia "1" na PORT D
delay(); // Opóźnienie
if(GET_SDA) bufor++; // Jeżeli na szynie jest odbierana "1" to inkrementuje bufor
CLR_SCL; // Ustawia "0" na PORT D
} while (--count);
delay(); // Opóźnienie
SDA_OUT;
CLR_SDA;
SET_SCL;
delay();
CLR_SCL;
return (bufor); // Zwraca wartość z pamięci
}
int main(void)
{
unsigned char txt;
LCD_Initalize();
LCD_Clear();
LCD_WriteText("I2C test");
_delay_ms(500);
LCD_Clear();
LCD_WriteText("ZAPIS");
_delay_ms(500);
LCD_Clear();
LCD_WriteText("ODCZYT");
_delay_ms(500);
i2c_start();
i2c_write(0xA0); //wysyłanie adresu + bit Write
i2c_write(0);
i2c_write(0);
i2c_write(100);
delay();
i2c_stop();
delay();
delay();
i2c_start();
i2c_write(0xA0);
i2c_write(0);
i2c_write(0);
i2c_start();
i2c_write(0xA1);
txt = i2c_read();
i2c_stop();
LCD_Clear();
LCD_WriteText(txt);
}Z góry dziękuję za pomoc