I2c у кого есть опыт?

Тема в разделе "Флудилка", создана пользователем Алексей132, 17 дек 2020.

  1. Коллеги, кто силен в I2C, у меня у самого опыт большой много датчиков полючал. Но никак не могу получить сигнал с камеры - OV7725, там протокол SBBC - но он полностью совмещен с i2c (вроде как). Вообщем вот прикладываю фото, с мануала и с осцилограффа. Может кто нить заметит где я оплашал. Я оптравлюя адрес - 0x43 - но как мы видем ничего не происходит, увы
    Адрес для чтения - 0x43 (1000011).


    использую hal stm32

    uint8_t adress_read = 0x43;
    int status = 0x0A;
    int status_readed;
    HAL_I2C_Mem_Read(&hi2c4, adress_read<<1, status,10, (uint8_t*)&status_readed, 10, 10000);
     

    Вложения:

    • 2.jpg
      2.jpg
      Размер файла:
      41,6 КБ
      Просмотров:
      141
    • pic.1.jpg
      pic.1.jpg
      Размер файла:
      45,8 КБ
      Просмотров:
      135
  2. parovoZZ

    parovoZZ Гуру

    Это адрес чего? Устройства или регистра? При приёме камера должна выставить ACK? Даташит что говорит?
     
  3. адрес устройства,

    а следом уже должен идти адрес регистра, но как мы видим ACK мы не получаем , потому продолжения никакого и нету , в этом там и беда, не пойму почему. Изображение pic1 как раз из даташита
     
  4. parovoZZ

    parovoZZ Гуру

    А стартовый бит какой длительности должен быть?
    Так она может ещё что-то ждёт? Адрес регистра, например.
     
  5. Ariadna-on-Line

    Ariadna-on-Line Гуру

    Вот смотрю на осциллограмму, и вижу, что защелкивает данные положительный (0->1) перепад такта. А по перепадам вижу, что идут 1, 0000, 11, 0, 1, 0. Что по первым восьми битам является 86H. Хотя должно идти вроде бы 0,1,0000,11. Те 43H. Хотя ХЗ - я не настаиваю.
    Мож надо задать что-то, например уровень по молчанию (ноль или единица), Старт-стопы и тд.
     
    Последнее редактирование: 18 дек 2020
  6. a1000

    a1000 Гуру

    Если это аналог I2C то по осциллограмме как раз всё понятно. Для начала немного общей теории. Линия SDA (данные, у вас жёлная) изменяет своё состояние только при нуле на линии SCL (тактирование, у вас синяя). Нарушает это правило только мастер в двух случаях.
    1. При SCL равном 1 опускает SDA в ноль - формируется сигнал старт (начало обмена).
    2 При SCL равном 1 поднимает SDA в единицу - формируется сигнал стоп (конец обмена).
    Теперь смотрим осциллограмму. Первый раз SDA падает в ноль при SCL равном 1. Это сигнал старт. Далее сигнал меняется при SCL равном нулю. Сначала идёт 7 бит вашего адреса 1000011 плюс бит направления передачи (0 запись, 1 чтение). У вас 0 - вы пишете в слейв, всё правильно. Далее слейв должен сообщить принял он байт или нет. Вам слейв выдаёт 1 - байт не принят. После чего мастер роняет SDA в ноль и при SCL равной 1 поднимает SDA в единицу формируя сигнал стоп и освобождает шину. С передачей всё как и должно быть. А вот почему слейв не принимает быйт от мастера надо разбираться. Может частота передачи не та или уровни сигнала. С вашей камерой не сталкивался, помочь не могу.
     
  7. a1000

    a1000 Гуру

    Немного поразмыслив пришла одна мысль - слейв не отвечает на отправку чужого адреса. Вы уверены, что ваш адрес 0x43? Для ардуино есть скетч - сканер шины I2C. Проверьте адрес
    Код (C++):
    #include <Wire.h>

    byte error, address;
    int nDevices;  //Кол-во найденных устройств

    void setup() {
      Wire.begin();
      Serial.begin(9600);
      Serial.println("\nI2C Scanner");
    }

    void loop() {
      Serial.println("Scanning...");
      nDevices = 0;
      for (address = 1; address < 127; address++ )  {
        Wire.beginTransmission(address);
        error = Wire.endTransmission();
        if (error == 0)    {
          Serial.print("I2C device found at address 0x");
          if (address < 16)
            Serial.print("0");
          Serial.print(address, HEX);
          Serial.println("  !");
          nDevices++;
        }
        else if (error == 4)    {
          Serial.print("Unknow error at address 0x");
          if (address < 16)
            Serial.print("0");
          Serial.println(address, HEX);
        }
      }
      if (nDevices == 0)
        Serial.println("No I2C devices found\n");
      else
        Serial.println("done\n");
      delay(5000);  // Ждем 5 сек. до следующего сканирования
    }
     
  8. ivan_alexoff

    ivan_alexoff Гик

    А с каких пор 1000011 = 43 ?
     
  9. parovoZZ

    parovoZZ Гуру

    с самых давних
    upload_2020-12-18_14-13-44.png
     
  10. ivan_alexoff

    ivan_alexoff Гик

    А, ну да, тупанул. Я в десятичный перевел
     
  11. Спасибо!! прогнал все адреса, но результат тот же. Менял частоты итд, вообще все можно уже по 10 поменял и без результата. Последний бит всегда в 1
     
  12. вообщем, по всем признакам проблемы в slave - буду думать.
     
  13. записать вообщем смог.
    Но теперь прочитать не могу, но это уже точно пробелма кода, так как 8 бит все время - low.
    Может кто-нибудь силен в HAL
    я использую этот код, как видите 8-бит всегда в low
    uint8_t adress_read1 = 0x43;

    uint8_t status = 0x1F;
    uint8_t status_readed;
    HAL_I2C_Mem_Read(&hi2c4, adress_read, status, 1, (int8_t*)&status_readed, 1, 10); IMG_20201222_170316.jpg
     
  14. Ariadna-on-Line

    Ariadna-on-Line Гуру

    Осциллограмма не похожа на предыдущую. Например четыре нуля подряд я не вижу. Только три. Это какое значение адреса ?
     
  15. должно прописываться 01000011
    а у меня в итоге 01000010

    Последний бит должен сам HAL прописывать, но он этого не делает, и никак не пойму почему
     
  16. parovoZZ

    parovoZZ Гуру

    почему?
     
  17. если чтение то - 1 если записываем то - 0
    раньше так и было у меня
     
  18. Ariadna-on-Line

    Ariadna-on-Line Гуру

    Ну нет у вас четыре нуля подряд на осциллограмме. В первой картинке были. Щас - нет.
     
  19. parovoZZ

    parovoZZ Гуру

    Так первый или последний? Даташит что говорит?
     
  20. a1000

    a1000 Гуру

    В HAL не силён. В своё время писал обмен с часами DS3231 на ASM, и тоже долго не мог въехать в разные ньюансы. Может вам поможет.
    Суть в следующем. Когда вы послали сигнал старт и адрес слейва с последним битом 0 - вы активировали сеанс передачи данных от мастера к слейву. Данные могут идти только в этом направлении. В моём случае, после активации, я передавал адрес регистра часов из которого я хотел получить данные. Для изменения направления передачи данных надо ещё раз передать "старт" и адрес слейва с последним битом теперь равным 1. Только после этого слейв начинает передачу информации. После каждого байта надо отвечать "ACK" если хотите получить следующий байт. Если вы получили всю информацию отвечаете "NACK" и формируете сигнал "стоп".