ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Воскресенье
8 февраля
1569317 Топик полностью
IBAH (Вчера, 21:30, просмотров: 39) ответил POV на i2c редко когда имеет дело с большими объёмами данных. К чему неблокирующее поведение?
Как к чему?! 100кбит/с это где-то 100мкс на байт. А передача килобайта это вообще 100мС!!! Даже на 100мкс процессор останавливать не наш метод, процессор должен работать, ему за это электричество дают. А неблокирующий программный I2C вот, хвастаюсь тем что заработало с первого раза, 
//
#define __I2CSOFT_C
#include "I2Csoft.h"

static unsigned char  Sost;  //переменная состояния
static unsigned char* UkMem; //Указатель на массив передаваемой памяти
static unsigned short Ndata; //Количество передаваемых данных
static unsigned short Pdata; //Указатель передаваемых данных
static unsigned char  Pbit;  //счетчик бит

static Timer_us_t t1; //Рабочий таймер

//Инициализация модуля I2Csoft
void I2CsoftInit(void)
  {
  Set1SCL();
  Set1SDA();
  Sost=0;
  return;
  }

//Главный метод модуля I2Csoft
void I2CsoftMain(void)
  {
  if(Sost==0) {return;}
  if(Sost==10)
    {//Старт
    Set0SDA(); 
    StartTimer_us(&t1, I2CDelay);
    Sost=20;
    return;
    }
  if(Sost==20 && Timer_us(&t1))
    {
    Set0SCL();
    StartTimer_us(&t1, I2CDelay);
    Sost=30;
    return;
    }
  if(Sost==30 && Timer_us(&t1))
    {//Передача
    if(UkMem[Pdata]&Pbit) {Set1SDA();} else {Set0SDA();}
    StartTimer_us(&t1, I2CDelay);
    Sost=40;
    return;
    }
  if(Sost==40 && Timer_us(&t1))
    {
    Set1SCL();
    StartTimer_us(&t1, I2CDelay);
    Sost=50;
    return;
    }
  if(Sost==50 && Timer_us(&t1))
    {
    Set0SCL();
    StartTimer_us(&t1, I2CDelay);
    Pbit=Pbit>>1;
    if(Pbit==0)
      {//передача байта закончена
      Pbit=0x80;
      Sost=60;
      }
    else
      {
      Sost=30;
      }
    return;
    }
  
  if(Sost==60 && Timer_us(&t1))
    {//ACK
    Set1SDA();
    StartTimer_us(&t1, I2CDelay);
    Sost=70;
    return;
    }
  if(Sost==70 && Timer_us(&t1))
    {
    Set1SCL();
    StartTimer_us(&t1, I2CDelay);
    Sost=80;
    return;
    }
  if(Sost==80 && Timer_us(&t1))
    {
    Set0SCLSDA();
    StartTimer_us(&t1, I2CDelay);
    Pdata++;
    if(Pdata == Ndata)
      {//Передача закончена
      Sost=90;
      }
    else
      {//Переходим к передаче следующкго байта
      Sost=30;
      }
    return;
    }
  
  if(Sost==90 && Timer_us(&t1))
    {//Стоп
    Set1SCL();
    StartTimer_us(&t1, I2CDelay);
    Sost=100;
    return;
    }
  if(Sost==100 && Timer_us(&t1))
    {
    Set1SDA();
    StartTimer_us(&t1, I2CDelay);
    Sost=0;
    return;
    }
  
  return;
  }

//Отправка блока данных
void I2CsoftSend(unsigned char* Blok, const unsigned short N)
  {
  if(Sost==0)
    {//Если не идет передача
    UkMem = Blok; //Указатель на массив передаваемой памяти
    Ndata = N; //Количество передаваемых данных
    Pdata = 0; //Указатель передаваемых данных
    Pbit = 0x80;  //счетчик бит
    Sost = 10; //переменная состояния
    }
  return;
  }


//


Но даже при I2CDelay=0 (задержка только цикл) время передачи килобайта где-то 150-180мс