Соединение I2C с модулем камеры MT9D111, странные результаты после записи регистров через i2C
В настоящее время я работаю над платформой камеры на основе модуля MT9D111 от Micron. Первое, что нужно сделать, это записать конфигурацию в многочисленные регистры чипа, что делается через соединение i2C.
Я адаптировал код из здесь для тестирования с помощью Arduino Uno. . Питание 3,3 В и тактовая частота 8 МГц также обеспечиваются Arduino.
Кажется, все работает нормально, но есть некоторые проблемы, причину которых я не знаю.
Итак, вот код (я только что добавил последовательность мягкого сброса в соответствии с Руководством для разработчиков):
const int freqOutputPin = 9; // Выходной контакт OC1A для плат ATmega328
#define TMR1 0
#include <Wire.h>
#include <avr/io.h>
#include <util/delay.h>
//#include <TimerOne.h>
#include <avr/interrupt.h>
void setup() {
pinMode(freqOutputPin, OUTPUT);
Serial.begin(9600);
TCCR1B |= (1 << CS10); // выбор прескалера 0b001 (Tclk/1)
TCCR1B &= ~((1 << CS12) | (1 << CS11)); // отключаем биты CS12 и CS11
TCCR1A |= ((1 << WGM11) | (1 << WGM10)); //Настроить таймер 1 для режима TOP (с TOP = OCR1A)
TCCR1B |= ((1 << WGM13) | (1 << WGM12));
TCCR1A |= (1 << COM1A0); // Включить таймер 1 Сравнить выходной канал A в режиме переключения
TCCR1A &= ~(1 << COM1A1);
TCNT1 = 0;
OCR1A = TMR1;
delay(500); //Начальная задержка
Wire.begin(); // присоединяемся к шине i2c в качестве мастера
Serial.begin(9600);
Serial.println("MT9D111 Camera Module + Arduino");
Serial.println("Read and Write 16-bit register value example");
Serial.println("* Read expected value = 0x1519 from Register 0x00");
Serial.println("* Write value = 0xA5F0 to Register 0x20:1");
Serial.println();
init1(); //выполнить код только 1 раз
}
void loop() {
}
void init1() {
int16_t a;
delay(500); // ждем начала
Serial.print("Soft reset first");
Serial.println();
soft_reset();//делаем программный сброс при запуске
//***************Конфигурация здесь!******************//
Serial.print("Read result from register 0x00");
a = read_reg(0);
Serial.println();
Serial.print("0x");
Serial.println(a, HEX); //распечатать результат
Serial.println();
Serial.print("Read original data from register 0x0a, should be 11");
Serial.println();
a = read_reg(10);
Serial.print("0x");
Serial.println(a, HEX); //распечатать результат
Serial.println();
// Включаем эту часть для записи регистра
//Некоторые примеры чтения и записи следуют
Serial.print("Writing 0xA5F0 in register 0x20:1");
Serial.println();
write_reg(32, 1, 165, 240);
Serial.print("Read new value from register 0x20:1");
Serial.println();
a = read_reg(32);
Serial.print("0x");
Serial.println(a, HEX); //распечатать результат
Serial.println();
Serial.print("Writing 0xA1F3 in register 0x20:1");
Serial.println();
write_reg(32, 1, 161, 243);
Serial.print("Read new value from register 0x20:1");
Serial.println();
a = read_reg(32);
Serial.print("0x");
Serial.println(a, HEX); //распечатать результат
Serial.println();
}
//Запись 2-байтового регистра
void write_reg(int reg_address, int page, int data_msb, int data_lsb) {
delay(5); //5 мс
Wire.beginTransmission(93); // передать на устройство 93, модуль камеры
Wire.write(240); //адрес регистрации страницы
Wire.write(0);
Wire.write(page); //выбираем страницу 0/1/2
Wire.endTransmission(1); // прекращаем передачу
Wire.beginTransmission(93); // передать на устройство 93, модуль камеры
Wire.write(reg_address); // адрес регистра 8-битный, десятичный
Wire.write(data_msb); //мсбайт
Wire.write(data_lsb); //lsbyte
Wire.endTransmission(1); // прекращаем передачу
}
//чтение 2-байтового регистра
//будьте осторожны с выбранной страницей регистрации
int16_t read_reg(int reg_address) {
int16_t err;
delay(5); //5 мс
Wire.beginTransmission(93); // передать на устройство 93, модуль камеры
Wire.write(reg_address); // адрес регистра 8-битный, десятичный
err = Wire.endTransmission(1); // прекращаем передачу
Serial.println(err);
Wire.requestFrom(93, 2, 1); // значение запроса формы устройства 93, 2 байта со стоповым битом
int16_t result = ((Wire.read() << 8) | Wire.read()); //читаем 16 бит
return result;
}
//Выполнить программный сброс, необходимый при запуске
void soft_reset(){
write_reg(101, 0, 160, 0);//регистры записи в соответствии с руководством разработчика
write_reg(195, 1, 5, 1);
write_reg(13, 0, 0, 33);
delay(5);
write_reg(13, 0, 0, 0);
delay(5);//ждем, пока i2c снова будет готов
}
Выполнение этого кода дает мне следующий результат на последовательном мониторе:
Итак, вот вопросы:
- Есть ли у вас идеи, почему я получаю дополнительный FFFF при чтении регистра после его записи? (подчеркнуто синим)
- Почему в выводе есть лишние нули? (отмечено желтым цветом)
@deinoppa, 👍1
Обсуждение1 ответ
Лучший ответ:
0
исходит из вашего кода:
Serial.println(err);
Он печатает код ошибки. 0, следовательно, ошибки нет.
Что касается дополнительного FFFF
, я бы сказал, что это потому, что вы используете целые числа со знаком. Измените объявление a
на uint16_t
и посмотрите, исправит ли это проблему.
Спасибо, это была быстрая помощь. Решил проблемы :-), @deinoppa
Рад был помочь :-), @dda
- Команда strtok() с Serial связью
- Как изменить переменную при нажатии кнопки, подключенной к контакту 2
- Последовательная связь между несколькими устройствами (или ардуино)
- Как программно обнаружить последовательный порт Arduino на разных платформах?
- Java NetBeans отправляет значение и получает значение от Arduino
- Почему нужно использовать latin-1 вместо utf-8 при использовании python с arduino?
- Акцептант векселей ИКТ
- Использование последовательной связи в .c-файлах
Как вы заставили это работать. Я попробовал тот же код с OV2640, но всегда получаю ошибку 2 и значение читается как 0xFFFF. Пожалуйста, помогите мне., @Sriranjan Rasakatla
У вас все еще есть руководство разработчика MT9D111? Кажется, я не могу найти его в Интернете., @Emmet H
Нашел здесь: https://files.niemo.de/aptina_pdfs/MT9D111_Dev_Guide.book.pdf, @deinoppa