цифровая электроника
вычислительная техника
встраиваемые системы

 
» » Программная эмуляция интерфейса I2C


Программная эмуляция интерфейса I2C

Автор: Mike(admin) от 2-03-2014, 11:08

Интерфейс I2C является довольно популярным средством взаимосвязи микроконтроллеров и других электронных устройств. Но некоторые микроконтроллеры могут не поддерживать данный интерфейс. Кроме того, может случиться так, что выводы аппаратного I2C используются в других целях. В связи с этим встает вопрос о необходимости программной эмуляции шины I2C.


Шина I2C

Код на языке C с комментариями приведен ниже.





typedef struct 
{
   unsigned int PIN0:1;
   unsigned int PIN1:1;
   unsigned int PIN2:1;
   unsigned int PIN3:1;
   unsigned int PIN4:1;
   unsigned int PIN5:1;
   unsigned int PIN6:1;
   unsigned int PIN7:1;
} PORT;

/* Здесь задан адрес для примера. Его необходимо заменить на требуемый */
#define PORT0 *(volatile PORT *)0x1234

/* Определяем выводы порта для передачи данных и тактирования */
#define I2C_DATA PORT0.PIN0
#define I2C_CLK  PORT0.PIN1

#define HIGH 1
#define LOW  0

/* Старт I2C */
void I2C_START(void)
{
     /* Эмуляция стартового условия I2C */
     I2C_DATA = HIGH;
     I2C_CLK = HIGH;
     I2C_DATA = LOW;
     I2C_CLK = LOW;
}

/* Стоп I2C*/
void I2C_STOP (void)
{
     /* Эмуляция стопового условия I2C */
     I2C_CLK = LOW;
     I2C_DATA = LOW;
     I2C_CLK = HIGH;
     I2C_DATA = HIGH;
}

/* Режим записи I2C */
void I2C_WRITE(unsigned char data)
{
         unsigned char outBits;
         unsigned char inBit;
         
         /* 8 бит */
         for(outBits = 0; outBits < 8; outBits++) 
         {
             if(data & 0x80)
                     I2C_DATA = 1;
                 else
                     I2C_DATA = 0;
         data  <<= 1;
                 /* Синхронизация для 8-битовой передачи данных */
                 SCLK = HIGH;
                 SCLK = LOW;                                     
         }
         
         /* Синхронизация для ACK */
         I2C_CLK = HIGH;
         /* Ждем, пока линия синхронизации не перейдет в лог. 1 */
         while(I2C_CLK);
         /* Синхронизация в лог. 1, подтверждение ACK */
         inBit = I2C_DATA;
         I2C_CLK = LOW;                                  
}

unsigned char I2C_READ (void)
{
         unsigned char inData, inBits;

         inData = 0x00;
         /* 8 бит */
         for(inBits = 0; inBits < 8; inBits++)
         {
                 inData <<= 1;
                 I2C_CLK = HIGH;
         inData |= I2C_DATA;
                 I2C_CLK = LOW;                                  
         }

    return inData;
}

/* Пример записи в ведомого (slave) I2C */
void writeI2CSlave (unsigned char data) 
{
     /* Старт */
         I2C_START();
         /* Адрес  ведомого */
         I2C_WRITE(0xAA)
         /* Управляющий байт ведомого */
         I2C_WRITE(0xBB);
         /* Запись данных */
         I2C_WRITE(data);
         /* Стоп */
         I2C_STOP();
}

/* Пример для чтения из ведомого I2C */
unsigned char readI2CSlave(unsigned char data)
{
         unsigned char inData;

         /* Старт */
         I2C_START(); 
         /* Адрес ведомого */
         I2C_WRITE(0xAA);
         /* Управляющий байт ведомого */
         I2C_WRITE(data);
         /* Стоп */
         I2C_STOP();
         
         /* Старт */
         I2C_START();
         /* Адрес ведомого + чтение */
         I2C_WRITE(0xAA | 1);
         /* Чтение */
         inData = I2C_READ();

         return inData;                 
}



Перевод © digitrode.ru


<Источник>




Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

Комментарии:

Оставить комментарий