Коллеги, кто силен в 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);
Это адрес чего? Устройства или регистра? При приёме камера должна выставить ACK? Даташит что говорит?
адрес устройства, а следом уже должен идти адрес регистра, но как мы видим ACK мы не получаем , потому продолжения никакого и нету , в этом там и беда, не пойму почему. Изображение pic1 как раз из даташита
А стартовый бит какой длительности должен быть? Так она может ещё что-то ждёт? Адрес регистра, например.
Вот смотрю на осциллограмму, и вижу, что защелкивает данные положительный (0->1) перепад такта. А по перепадам вижу, что идут 1, 0000, 11, 0, 1, 0. Что по первым восьми битам является 86H. Хотя должно идти вроде бы 0,1,0000,11. Те 43H. Хотя ХЗ - я не настаиваю. Мож надо задать что-то, например уровень по молчанию (ноль или единица), Старт-стопы и тд.
Если это аналог 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 в единицу формируя сигнал стоп и освобождает шину. С передачей всё как и должно быть. А вот почему слейв не принимает быйт от мастера надо разбираться. Может частота передачи не та или уровни сигнала. С вашей камерой не сталкивался, помочь не могу.
Немного поразмыслив пришла одна мысль - слейв не отвечает на отправку чужого адреса. Вы уверены, что ваш адрес 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 сек. до следующего сканирования }
Спасибо!! прогнал все адреса, но результат тот же. Менял частоты итд, вообще все можно уже по 10 поменял и без результата. Последний бит всегда в 1
записать вообщем смог. Но теперь прочитать не могу, но это уже точно пробелма кода, так как 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);
Осциллограмма не похожа на предыдущую. Например четыре нуля подряд я не вижу. Только три. Это какое значение адреса ?
должно прописываться 01000011 а у меня в итоге 01000010 Последний бит должен сам HAL прописывать, но он этого не делает, и никак не пойму почему
В HAL не силён. В своё время писал обмен с часами DS3231 на ASM, и тоже долго не мог въехать в разные ньюансы. Может вам поможет. Суть в следующем. Когда вы послали сигнал старт и адрес слейва с последним битом 0 - вы активировали сеанс передачи данных от мастера к слейву. Данные могут идти только в этом направлении. В моём случае, после активации, я передавал адрес регистра часов из которого я хотел получить данные. Для изменения направления передачи данных надо ещё раз передать "старт" и адрес слейва с последним битом теперь равным 1. Только после этого слейв начинает передачу информации. После каждого байта надо отвечать "ACK" если хотите получить следующий байт. Если вы получили всю информацию отвечаете "NACK" и формируете сигнал "стоп".