[Решено] I2C2 на STM32F103C8T6 и HWIRE

luca_stm32
Пн 12 июня 2017 г., 19:50
Это мой первый пост на форуме :-)
Я пытаюсь использовать Hwire на i2C2 моего BluePill для чтения/подключения внешнего EEPROM (24LC128).
Я подключил EEPROM на PB10 (SCL) и PB11 (SDA): если я использую программную версию I2C, это работает. Если я использую Hwire, это не работает.
До свидания: я скачал последнюю версию репозитория и нашел ошибку в строке 79 arduino_stm32/stm32f1/libraries/wire/hardwire.Файл CPP: отсутствует ":" в void hardwire: end ().

Я использовал этот код, комментируя правильные строки (аппаратное или программное обеспечение i2c)... Извините за моего плохого инженера: //#include #include #define EEPROM_ADDRESS 0x50 //Address of 24LC256 eeprom chip //Declare the instance that the users of the library can use //TwoWire Wire(SCL, SDA, SOFT_STANDARD); //TwoWire Wire2(PB10, PB11, SOFT_STANDARD); HardWire HWire(2, I2C_FAST_MODE); // I2C2 void setup(void) { Serial.begin(115200); delay(10000); Serial.println("EEPROM Test"); //Wire2.begin(); HWire.begin(); unsigned int address = 0; writeEEPROM(EEPROM_ADDRESS, address, 0x55); while(1){ Serial.print(readEEPROM(EEPROM_ADDRESS, address), HEX); Serial.print(" "); address++; delay(1000); } } void loop(){} void writeEEPROM(int deviceaddress, unsigned int eeaddress, byte data ) { // Wire2.beginTransmission(deviceaddress); // Wire2.write((int)(eeaddress >> 8)); // MSB // Wire2.write((int)(eeaddress & 0xFF)); // LSB // Wire2.write(data); // Wire2.endTransmission(); HWire.beginTransmission(deviceaddress); HWire.write((int)(eeaddress >> 8)); // MSB HWire.write((int)(eeaddress & 0xFF)); // LSB HWire.write(data); HWire.endTransmission(); delay(5); } byte readEEPROM(int deviceaddress, unsigned int eeaddress ) { byte rdata = 0xFF; // Wire2.beginTransmission(deviceaddress); // Wire2.write((int)(eeaddress >> 8)); // MSB // Wire2.write((int)(eeaddress & 0xFF)); // LSB // Wire2.endTransmission(); // // Wire2.requestFrom(deviceaddress,1); HWire.beginTransmission(deviceaddress); HWire.write((int)(eeaddress >> 8)); // MSB HWire.write((int)(eeaddress & 0xFF)); // LSB HWire.endTransmission(); HWire.requestFrom(deviceaddress,1); // if (Wire2.available()) rdata = Wire2.read(); if (HWire.available()) rdata = HWire.read(); return rdata; }

Стивестронг
Пн 12 июня 2017 г. 20:11
И что именно не работает?
Пожалуйста, дайте подробное описание ошибки.

Пито
Пн 12 июня 2017 г., 8:42 вечера
Hwire на i2c2 работает здесь, по крайней мере, с Maplem, так что он должен с BP.
Посмотрите на существующую библиотеку EEPROM, как работает материал.

luca_stm32
Вт 13 июня 2017 г. 8:35 утра
Привет, Стивестронг.
Кодекс записывает приветственное сообщение на Termianl (тест eeprom), затем записывает 0x55 на месте 0 eeProm, затем напишите в окне терминала все значения EERPOM, начиная с местоположения 0 с задержкой на одну секунду.
С версией «Программное обеспечение» на терминале я могу увидеть приветственное сообщение, а затем 0x55 0xff 0xff....
С версией "оборудования" я могу видеть только приветственное сообщение.
Я использовал область применения, чтобы увидеть деятельность в линии SCL, но с кодовой версией «аппаратное» ничего не происходит (она исправлена ​​в 3.3 В и часа не появляется).

@Pito.
В вашем предыдущем посте я увидел, что вы использовали i2c2 с аппаратной реализацией. Я обеспокоен ошибкой, которую я нашел в Hardwire.Файл CPP. Mybe ваша версия библиотеки Hwire немного отличается... Я мог бы сделать тест, используя предыдущую версию репозитория.
Просто чтобы быть уверенным: I2C2 находится на PB10 (SCL2) и PB11 (SDA2), верно?

Еще раз спасибо за вашу поддержку.
Лука

luca_stm32
Вт 13 июня 2017 г. 20:07
Привет всем.
Еще один маленький шаг.
В файле Hardwire.CPP я изменил Hardwire :: процесс таким образом: uint8 HardWire::process() { Serial.println("1"); int8 res = i2c_master_xfer(sel_hard, &itc_msg, 1, 0); Serial.println("2"); if (res == I2C_ERROR_PROTOCOL) { if (sel_hard->error_flags & I2C_SR1_AF) { /* NACK */ res = (sel_hard->error_flags & I2C_SR1_ADDR ? ENACKADDR : ENACKTRNS); } else if (sel_hard->error_flags & I2C_SR1_OVR) { /* Over/Underrun */ res = EDATA; } else { /* Bus or Arbitration error */ res = EOTHER; } i2c_disable(sel_hard); i2c_master_enable(sel_hard, (I2C_BUS_RESET | dev_flags)); } return res; }

ZMEMW16
Вт 13 июня 2017 г. 8:55 вечера
тайм -ауты могут быть странными, устанавливать на ноль обычно означает ждать бесконечности, а не немедленно вернуться назад : D

Winnie_the_pooh
Чт 15 июня 2017 г., 6:40
Привет!

Год назад я протестировал второй канал I2C с использованием Hardwire LIB и после масштабного тестирования с помощью логического анализатора и тестовых точек после того, как каждый оператор обнаружил, что я должен использовать правильный размер var, используя i2c2.

я.эн. вместо int вы должны использовать int16_t или uint8_t.

I2c1 работает без него, но i2c2 работает только со строгим и правильным размером var int16_t или uint8_t

Включая рабочий пример № 1:
//#include #include #define START PB0 HardWire HWire(2, I2C_FAST_MODE); // I2c1 , I2C_FAST_MODE SOFT_STANDARD void setup() { HWire.begin(); Serial.begin(115200); pinMode(START, OUTPUT); //синхроимпульс для лог анализатора digitalWrite(START,HIGH); delay(1); digitalWrite(START,LOW); } void loop() { Serial.print("Light (lux): "); Serial.println(get_lux()); delay(1000); } uint8_t read_register(uint8_t addr) { uint8_t ret; digitalWrite(START,HIGH); delay(1); digitalWrite(START,LOW); HWire.beginTransmission(0x4A); HWire.write(addr); HWire.endTransmission(); HWire.requestFrom(0x4A,1); ret = HWire.read(); digitalWrite(START,HIGH); return ret; } float get_lux(void) { int luxHigh = read_register(0x03); int luxLow = read_register(0x04); int exponent = (luxHigh & 0xf0) >> 4; int mant = (luxHigh & 0x0f) << 4 | luxLow; return (float)(((0x00000001 << exponent) * (float)mant) * 0.045); //return (float)((pow(2,exponent) * mant) * 0.045); }

luca_stm32
Чт 15 июня 2017 г., 11:47
Привет, winni_the_pooh
Спасибо за повтор.
Сегодня я протестировал тот же код (аппаратная версия i2c) на i2c1, и я могу подтвердить, что он работает.

Поэтому я попытался исправить размер var, как вы предложили, и протестировал на i2c1: работает ОК.
Изменился на i2c2 и не работает. Я перепровешу объявления VAR.

Мой код сейчас: //#include #include #define EEPROM_ADDRESS 0x50 //Address of 24LC256 eeprom chip HardWire HWire(2, I2C_FAST_MODE); // I2C2 void setup(void) { Serial.begin(115200); delay(10000); Serial.println("EEPROM Test"); HWire.begin(); uint16_t address = 0; writeEEPROM(EEPROM_ADDRESS, address, 0x55); while(1){ Serial.print(readEEPROM(EEPROM_ADDRESS, address), HEX); Serial.print(" "); address++; delay(1000); } } void loop(){} void writeEEPROM(int16_t deviceaddress, int16_t eeaddress, uint8_t data ) { uint16_t temp = 0; HWire.beginTransmission(deviceaddress); temp = eeaddress >> 8; HWire.write((uint8_t)temp); // MSB temp = eeaddress & 0xFF; HWire.write((uint8_t)temp); // LSB HWire.write(data); HWire.endTransmission(); delay(5); } uint8_t readEEPROM(uint16_t deviceaddress, uint16_t eeaddress ) { uint8_t rdata = 0xFF; uint16_t temp; HWire.beginTransmission(deviceaddress); temp = eeaddress >> 8; HWire.write((uint8_t)temp); // MSB temp = eeaddress & 0xFF; HWire.write((uint8_t)temp); // LSB HWire.endTransmission(); HWire.requestFrom(deviceaddress,1); if (HWire.available()) rdata = HWire.read(); return rdata; }

Winnie_the_pooh
Чт 15 июня 2017 г. 12:17
Привет, Лука!

Да, PB10 == SCL2 и PB11 == SDA2

Нет, я не пробовал свой код с последним хранилищем. Тестирование было проведено примерно. Год назад, в октябре 2016 года.

Может предложить вам сделать следующее: Используйте тестовые точки, такие как серийные.print ("tp1"); до и после каждого оператора провода, чтобы найти плохую линию.

Затем попробуйте использовать различный размер var один за другим - я преуспею в :)

Может быть, какой -то старый код для второго I2C не был тщательно проверен, а переменная неверного размера приводит к проблемам с памятью.

luca_stm32
Чт 15 июня 2017 г. 20:03
Привет, winni_the_pooh.
Я пытается, как вы предложили, но не повезло (попробовал uint8_t, int ....).

Я использовал этот код: #include #define EEPROM_ADDRESS 0x50 //Address of 24LC256 eeprom chip HardWire HWire(2, I2C_FAST_MODE); // I2C2 void setup(void) { Serial.begin(115200); delay(10000); Serial.println("EEPROM Test"); HWire.begin(); uint16_t address = 0; writeEEPROM(EEPROM_ADDRESS, address, 0x55); while(1){ Serial.print(readEEPROM(EEPROM_ADDRESS, address), HEX); Serial.print(" "); address++; delay(1000); } } void loop(){} void writeEEPROM(int deviceaddress, uint16_t eeaddress, int data ) { HWire.beginTransmission(deviceaddress); HWire.write((int)(eeaddress >> 8)); // MSB HWire.write((int)(eeaddress & 0xFF)); // LSB HWire.write(data); Serial.print(" TP1 "); HWire.endTransmission(); Serial.print(" TP2 "); delay(5); } int readEEPROM(int deviceaddress, uint16_t eeaddress ) { int rdata = 0xFF; HWire.beginTransmission(deviceaddress); HWire.write((int)(eeaddress >> 8)); // MSB HWire.write((int)(eeaddress & 0xFF)); // LSB Serial.print(" TP3 "); HWire.endTransmission(); Serial.print(" TP4 "); HWire.requestFrom(deviceaddress,1); if (HWire.available()) rdata = HWire.read(); return rdata; }

Winnie_the_pooh
Пт 16 июня 2017 г. 7:14
Утро, Лука!

вот https: // yadi.SK/D/NYZLMCES3KBF3W

Но SMTH говорит мне, что это будет работать абсолютно одинаково :)

luca_stm32
Солнце 18 июня 2017 г. 18:30
Привет, winni_the_pooh
Вчера я проверяю код, используя изображение вашего репозитория, но, как вы уже сказали, это было то же самое.
Но я заметил что -то: во вторых рабочих примерах вы называете Hwire.begin () функционируйте дважды, один раз в функции настройки и снова в функции write_dac.
Если я позвоню Hwire.begin () дважды, во второй раз, когда я называю это код, остановится (я протестировал его, используя сериал.print ("tpx") до и после Hwire.begin () функция).
Я чувствую, что i2c2 в моем случае не настроен исправленным образом, и когда я пытаюсь написать на нем, код застрял.
Итак, у меня есть два вопроса: какая доска вы используете? Я использую синюю таблетку.
Второй вопрос: я хотел бы использовать серийный.Печать в i2c.C библиотека, чтобы сделать более глубокую отладочную отладку. Как я могу его использовать? Я попробовал, но у меня есть ошибка компилятора. Или еще один способ отладка в I2C.C Библиотека без Stlink?

еще раз спасибо.
Лука.

Пито
Солнце 18 июня 2017 г. 18:47
@Luca: у вас есть подтягивания резисторов 4K7 на SDA и SCL??
Раньше я использовал (теперь не удобно, однако) два i2c сразу с Maplemini (или BP), т.е HardWire HWire(1, I2C_FAST_MODE); // I2C1 HardWire HWire2(2, I2C_FAST_MODE); // I2C2

luca_stm32
Пн 19 июня 2017 г. 12:54
@Pito: Я проводя 4K7 резисторов на линии SDA и SCL, и я уверен, что оборудование в порядке. На самом деле, если я не изменяю оборудование и использую программную реализацию I2C на PINS PB10 и PB11, я могу читать/писать внешний eEPROM.
На том же оборудовании, если я использую аппаратную имплеметацию i2c2 (расположенное на Pins PB10 E PB11), я не могу писать и читать с внешнего eeprom.

Если я подключаю внешний EEPROM на контактах PB6 и PB7 (I2C1), я смогу читать и писать внешний EEPROM с помощью программного и аппаратного I2C библиотеки I2C (TwoWire и Hwire).

Мое объявление для i2c2:
HardWire H2Wire(2, I2C_FAST_MODE); // I2C2

ZMEMW16
Пн 19 июня 2017 г. 13:40
Программное обеспечение i2c должно быть медленнее, чем HW Fast Mode, поэтому попробуйте HW Mlow Mode ?
SRP

Пито
Пн 19 июня 2017 г. 13:41
Вот как я прочитал регистры (ы) с датчика давления BMP085, в то время как на i2C2 (Maple Mini): .. HardWire HWire(2, I2C_FAST_MODE); // I2C2 .. HWire.begin(); .. // Read 1 byte from the BMP085 at 'address' char bmp085Read(unsigned char address) { unsigned char data; HWire.beginTransmission(BMP085_ADDRESS); HWire.write(address); HWire.endTransmission(); HWire.requestFrom(BMP085_ADDRESS, 1); while(!HWire.available()) ; return HWire.read(); } // Read 2 bytes from the BMP085 // First byte will be from 'address' // Second byte will be from 'address'+1 int bmp085ReadInt(unsigned char address) { unsigned char msb, lsb; HWire.beginTransmission(BMP085_ADDRESS); HWire.write(address); HWire.endTransmission(); HWire.requestFrom(BMP085_ADDRESS, 2); while(HWire.available()<2) ; msb = HWire.read(); lsb = HWire.read(); return (short int) msb<<8 | lsb; }

luca_stm32
Пн 19 июня 2017 г., 19:34
Привет, пито.
Первая ссылка - это именно код, который я использовал. Infact It работает (на версии аппаратного и программного обеспечения I2C1 и только программная версия I2C2).
Я также видел вторую ссылку, но функция чтения/записи EEPROM одинакова.

Я попробовал также сменить доску (еще одна синяя таблетка), но с тем же результатом.

Я также следую инструкциям WINNI_THE_POOH, изменяющему тип вариабила, но не работает.

Единственное основное отличие состоит в том, что я использую синюю таблетку (STM32F103C8) и вы используете мини -клен (STM32F103CB), но единственное отличие - флэш -память...

Я также пытался написать регистры i2c2 с серийным.напечатать на эскизе, но ничто не оказалось странным.

@zmemw16: как я могу поместить оборудование i2c в медленном режиме?

Лука

luca_stm32
Вт 20 июня 2017 г. 11:39
Привет всем.
Сегодня прошел простой тест: используя тот же код, но составление выбора «минимума» вместо «Общая серия STM32F103C», аппаратное i2C2 работает : D

Теперь я должен понять, почему.

Лука.

Rogerclark
Вт 20 июня 2017 12:02
[luca_stm32 - Вт 20 июня 2017 г. 11:39] - Привет всем.
Сегодня прошел простой тест: используя тот же код, но составление выбора «минимума» вместо «Общая серия STM32F103C», аппаратное i2C2 работает : D

Теперь я должен понять, почему.

Лука.
Есть некоторые предположения о том, что некоторые STM32F103 - это клоны, а не официальные. В этом случае это может объяснить, почему одна доска работает, а другая - не.

Я буду PM @fpstm и спрошу его, знает ли он о каких -либо клонах

Winnie_the_pooh
Вт 20 июня 2017 12:05
Привет, Лука!

Да, я использовал синюю таблетку.

Winnie_the_pooh
Вт 20 июня 2017 12:09
Когда я отлаживал какой -то код либера.

luca_stm32
Вт 20 июня 2017 12:56
@Роджер
Я использовал то же аппаратное обеспечение: синие таблетки и eeprom, подключенные на I2C2 (Pins PB10 и PB11).
В Arduino IDE, если я выберу инструменты->Доска->Generic STM32F103C Series, Scketch не работает (он застрял, как только пытается отправить данные на i2c2. В частности, он не проходит H2Wire.EndTransmission (), то есть функция, которая запускает начало передачи).

В Arduino IDE, если я выберу инструменты->Доска->Maple Mini Scketch работает, как и ожидалось.

Важно: в обоих случаях я использовал одно и то же оборудование!
Теперь я пытаюсь распечатать регистры STM32, чтобы увидеть различия. Я заметил, что использование «Generic STM32F103C Series», реестр I2C2 SR2 составляет 2 (занят), как только настраиваю фериферию.
Если я использую «Maple Mini», регистр SR2 равен 0.

Вот код, который я использую: //#include #include #define EEPROM_ADDRESS 0x50 //Address of 24LC256 eeprom chip //Declare the instance that the users of the library can use //TwoWire Wire(SCL, SDA, SOFT_STANDARD); //TwoWire Wire2(PB10, PB11, SOFT_STANDARD); HardWire H2Wire(2, I2C_FAST_MODE); // I2C2 //HardWire H1Wire(1, I2C_FAST_MODE); // I2C2 void setup(void) { Serial.begin(115200); delay(10000); Serial.println("EEPROM Test"); //Wire2.begin(); H2Wire.begin(); Serial.println("I2C2:"); Serial.print("CR1: "); Serial.println(I2C2->regs->CR1, HEX); Serial.print("CR2: "); Serial.println(I2C2->regs->CR2, HEX); Serial.print("OAR1: "); Serial.println(I2C2->regs->OAR1, HEX); Serial.print("OAR2: "); Serial.println(I2C2->regs->OAR2, HEX); Serial.print("DR: "); Serial.println(I2C2->regs->DR, HEX); Serial.print("SR1: "); Serial.println(I2C2->regs->SR1, HEX); Serial.print("SR2: "); Serial.println(I2C2->regs->SR2, HEX); Serial.print("CCR: "); Serial.println(I2C2->regs->CCR, HEX); Serial.print("TRISE: "); Serial.println(I2C2->regs->TRISE, HEX); Serial.print("PORTB CRL: "); Serial.println(GPIOB->regs->CRL, HEX); Serial.print("PORTB CRH: "); Serial.println(GPIOB->regs->CRH, HEX); Serial.print("PORTB ODR: "); Serial.println(GPIOB->regs->ODR, HEX); Serial.print("PORTB BSRR: "); Serial.println(GPIOB->regs->BSRR, HEX); Serial.print("PORTB BRR: "); Serial.println(GPIOB->regs->BRR, HEX); int address = 0; writeEEPROM(EEPROM_ADDRESS, address, 0x55); while(1){ Serial.print(readEEPROM(EEPROM_ADDRESS, address), HEX); Serial.print(" "); address++; delay(1000); } } void loop(){} void writeEEPROM(int deviceaddress, int16_t eeaddress, uint8_t data ) { // Wire2.beginTransmission(deviceaddress); // Wire2.write((int)(eeaddress >> 8)); // MSB // Wire2.write((int)(eeaddress & 0xFF)); // LSB // Wire2.write(data); // Wire2.endTransmission(); H2Wire.beginTransmission(deviceaddress); H2Wire.write((int)(eeaddress >> 8)); // MSB H2Wire.write((int)(eeaddress & 0xFF)); // LSB H2Wire.write(data); H2Wire.endTransmission(); delay(5); } uint8_t readEEPROM(int deviceaddress, uint16_t eeaddress ) { uint8_t rdata = 0xFF; // Wire2.beginTransmission(deviceaddress); // Wire2.write((int)(eeaddress >> 8)); // MSB // Wire2.write((int)(eeaddress & 0xFF)); // LSB // Wire2.endTransmission(); // Wire2.requestFrom(deviceaddress,1); H2Wire.beginTransmission(deviceaddress); H2Wire.write((int)(eeaddress >> 8)); // MSB H2Wire.write((int)(eeaddress & 0xFF)); // LSB H2Wire.endTransmission(); H2Wire.requestFrom(deviceaddress,1); // if (Wire2.available()) rdata = Wire2.read(); if (H2Wire.available()) rdata = H2Wire.read(); return rdata; }

Стивестронг
Вт 20 июня 2017 г. 14:10
Как и где вы определяете булавки i2c, которые будут использоваться для экземпляра Hardwire?
Это может иметь значение между досками.
Я предлагаю всегда использовать нотацию PXY (PA2, PB10) вместо необработанных чисел (например, 2, 33 и т. Д.).

luca_stm32
Вт 20 июня 2017 г. 14:29
Привет, Стивестронг.
Я использую функцию: HardWire H2Wire(2, I2C_FAST_MODE); // I2C2

Стивестронг
Вт 20 июня 2017 г. 15:14
Да, кажется, что у i2c есть пара перекрывающихся вызовов функций...
Альтернативное отображение функции не происходит, потому что DEV_FLAGS не содержит флаг Remap.
И I2C2 не может быть переплетена, он прикреплен к PB10/11.

И да, кажется, что сброс должен быть только до конфигурации init и gpio. Это выглядит как ошибка!

Так что правильная последовательность должна быть: /* Turn on clock and set GPIO modes */ i2c_init(dev); i2c_config_gpios(dev); /* Reset the bus. Clock out any hung slaves. */ if (flags & I2C_BUS_RESET) { i2c_bus_reset(dev); }

Пито
Вт 20 июня 2017 г. 16:56
Попробуйте собрать для Maplem и пропустить его на BluePill. Бьюсь об заклад, это сработает.
Возможно, вариант BP имеет ошибку в некоторых определениях (сравните варианты BP и MM).

ZMEMW16
Вт 20 июня 2017 г., 17:53
думал, что уже опубликовал это
Конструктор имеет невыполненный параметр для режима HardWire HWire(2, I2C_FAST_MODE); // I2C2 HardWire HWire(2); // I2C2 slow mode

Стивестронг
Вт 20 июня 2017 г., 19:07
[ZMEMW16 - Вт 20 июня 2017 г., 17:53] - думал, что уже опубликовал это
Конструктор имеет невыполненный параметр для режима HardWire HWire(2, I2C_FAST_MODE); // I2C2 HardWire HWire(2); // I2C2 slow mode

luca_stm32
Вт 20 июня 2017 г., 19:54
@Pito
Это именно то, что я сделал. Я собрал эскиз для MM и работал.

@Stevestrong
Да, сравните файлы карты, сгенерированные для MM и BP, - это то, что я хотел бы сделать.
Я также хотел бы исправить инициализацию i2c.

Лука.

Rogerclark
Вт 20 июня 2017 г. 22:40
Если вы загружены с использованием USB Serial для обеих плат, код должен быть таким же, как единственное различие между ними должно быть управление перечислением USB

luca_stm32
Ср 21 июня 2017 г. 8:07
Привет всем.
С моим другом мы нашли проблему.
Он расположен, если доски.H (под каталогом STM32F1 \ vaiants \ generic_stm32f103c \ poard).

Совет по разнице.H Maple Mini - это линия, где определяется вывод, который управляет отключением USB через внешний транзистор.
#define BOARD_USB_DISC_DEV GPIOB #define BOARD_USB_DISC_BIT 10

Пито
Ср 21 июня 2017 г. 8:12
USB D+ Transistor используется во время init in bootloader, не так ли?
INIT I2C должен установить его как «open_drain», тогда..

luca_stm32
Ср 21 июня 2017 г. 8:19
Я также нашел этот протектор о инициализации I2C:

https: // Сообщество.ул.com/thread/24199

На этом протекторе я нашел следующее предложение:
Я решил эту проблему, изменяя порядок инициализации с того, что показано в вашем коде. Сначала инициализируйте контакты порта I2C в качестве контактов функции i2c (открытый коллектор) и включить их модуль RCC, затем запустите модуль I2C RCC. Поэтому я думаю, что было бы лучше изменить также функцию i2c_master_enable в i2c.С таким образом:
void i2c_master_enable(i2c_dev *dev, uint32 flags) { /* PE must be disabled to configure the device */ ASSERT(!(dev->regs->CR1 & I2C_CR1_PE)); /* Ugh */ _i2c_handle_remap(dev, flags); i2c_config_gpios(dev); // first, initialize gpio. Or call it before _i2c_handle_remap(dev, flags);? /* Reset the bus. Clock out any hung slaves. */ if (flags & I2C_BUS_RESET) { i2c_bus_reset(dev); } /* Turn on clock and set GPIO modes */ i2c_init(dev);

luca_stm32
Ср 21 июня 2017 г. 9:21
Я думаю, что мой последний пост неверный.
Наставление функции i2c_master_enable вызовы i2c_bus_reset, которая вызывает i2c_master_release_bus. В этой последней функции выполняется конфигурация GPIO.

Таким образом, кажется, что конфигурация GPIO производится до включения i2c.

luca_stm32
Ср 21 июня 2017 г. 9:30 утра
@Pito. Да, я думаю, что ты прав.
Я заметил это событие. С исходными файлами репозитория, выберите Generic_stm32, печать регистров I2C2, я увидел, что после i2C2Inialization SR2 был 2 (I2C занят). Выбор MM (который использует PB9), после инициализации I2C2 SR2 был 0 (не занят).
Может быть, это когда USB -управление внешним транзистором на PB10 он генерирует условие для I2C Фериферию.

Таким образом, сброс i2c -фериферистов может быть достаточным, чтобы заставить его работать. Но в целом, на BP вы можете использовать PB10 в качестве входного. В этом случае USB -инициализация установила PB10 как вывод и приводит к нему высокий и низкий. Это может потенциально повредить внешнюю цепь BP, подключенную к PB10.

Лука.

Пито
Ср 21 июня 2017 г. 9:51
INION I2C появляется после того, как BP играет с USB -транзистором (в загрузчике или в Serialusb). Таким образом, мое нынешнее понимание - это INIT I2C (с Hwire) использует P10 «As -IS» - это означает, что при установке в загрузчик или Serialusb в качестве «выхода» он будет испортить i2c.
С SW Wire i2c init () устанавливает P10 как «открытое дрена», и он работает.

Rogerclark
Ср 21 июня 2017 г. 10:08
Только мм должен связываться с штифтом, который он использует для перечисления USB.

Если общие платы делают это, это ошибка, и код MM должен быть определен

Rogerclark
Солнце 25 июня 2017 г. 3:26 утра
Исправлено для BP и нескольких других досок в этом коммите

https: // github.com/rogerclarkmelbourne/ ... A2F6C76051

luca_stm32
Пн 26 июня 2017 г., 19:35
Привет, Роджер.
Сегодня я проверил ваш последний репозиторий: он работает! :-)

Я также провел сравнение между SOFWARE Inleplectaion и аппаратной реализацией I2C. Разница составляет 880 байтов (программная реализация занимает меньше памяти, чем аппаратная реализация).

еще раз спасибо!
Поздравляю (всех вас) снова с хорошей работой.

Лука.

GC9N
Сб 05 августа 2017 г. 10:27 утра
Я пытаюсь написать и читать в EEPROM (ATMLH712-02CM) . Но напрасно код не может читать или написать из eeprom . он не висит (стеки), он работает и выполняет команды, но без результата
Я проверил, чтобы увидеть, является ли адрес eeprom, который я даю, верен с помощью сканера I2C, и я получаю 0x50 . Так что это там и задержано, что он работает
Мой eeprom подключен в Hardwire Hwire (2, i2c_fast_mode);

ATMLH712-02см
Порт -этикетка
Pcb-gnd 1 a0 0
Pcb-gnd 2 a1 0
Pcb-gnd 3 a2 0
PCB-GND 4 GND
MCU-22 (PB11) 5 SDA RES-1K в VCC
MCU-21 (PB10) 6 SCL RES-1K в VCC
PCB-GND 7 WP Читать/запись
PCB-1 8 VCC

Мои библиотеки - последние . с последним проводом.H Улучшение Hardwire, но также и с помощью исправлений ошибок Rogerclark
Я попробовал и Softwire, и Hardwire

Я использую ST-Link для загрузки кода в STM32F103C8T6

Rogerclark
Сб 05 августа 2017 11:49
Вы должны опубликовать это в новую тему, так как это звучит так, как это связано с этим конкретным EEPROM

Пса. Вы пробовали использовать нормальную / медленную скорость I2C

GC9N
Сб 05 августа 2017 г., 23:53
[Rogerclark - Сб 05 августа 2017 11:49 вечера] - Вы должны опубликовать это в новую тему, так как это звучит так, как это связано с этим конкретным EEPROM

Пса. Вы пробовали использовать нормальную / медленную скорость I2C
Да, я попробовал с
Hardwire Hwire (2, i2c_fast_mode); и
Hardwire Hwire (2);
Но нет,,

Rogerclark
Солнце 06 августа 2017 1:04
По умолчанию в быстрый режим

Это, вероятно, должно быть по умолчанию, чтобы замедлиться, так что это то, что мне нужно исправить

"Черная таблетка" доска?