Открываю я даташит, скажем, на BME280, нахожу там, что адрес девайса 0x76, запихиваю на F1 это значение в I2C1->DR, перещелкиваю или нет "младший бит" и хоть усрись, никогда не получу подтверждения от датчика по завершению передачи. Я все сделал по референсу, но получил кукиш. Тогда я беру nRF52832, по референсу от него записываю в TWIM->ADDRESS то же самое значение 0х76, дергаю передачу и подтверждение получаю. И на какой "опыт работы с I2C" мне уповать в каждом из случаев?
STM32 новичку в ARM что к чему
- Сообщения: 6457
- Зарегистрирован: Пт сен 13, 2013 13:11:31
Эта тема уже звучала и я так же говорил об этом. Вопрос не в опыте, а в том, каким образом данные должны быть записаны в МК перед отправкой. Один и тот же "опыт работы с I2C" требует разных манипуляций в зависимости от того, имеем ли мы дело с STM32F0, STM32F1 или, скажем, nRF52832. Протокол один, а действия требуются разные и нифига друг на друга не похожие. Только если в случае F0 или nRF52 нужно просто прочесть референс, чтобы узнать, какие биты куда, то в случае F1, из референса мы узнаем полную лажу о том, что "младший бит адреса" управляет направлением передачи.
Открываю я даташит, скажем, на BME280, нахожу там, что адрес девайса 0x76, запихиваю на F1 это значение в I2C1->DR, перещелкиваю или нет "младший бит" и хоть усрись, никогда не получу подтверждения от датчика по завершению передачи. Я все сделал по референсу, но получил кукиш. Тогда я беру nRF52832, по референсу от него записываю в TWIM->ADDRESS то же самое значение 0х76, дергаю передачу и подтверждение получаю. И на какой "опыт работы с I2C" мне уповать в каждом из случаев?
Открываю я даташит, скажем, на BME280, нахожу там, что адрес девайса 0x76, запихиваю на F1 это значение в I2C1->DR, перещелкиваю или нет "младший бит" и хоть усрись, никогда не получу подтверждения от датчика по завершению передачи. Я все сделал по референсу, но получил кукиш. Тогда я беру nRF52832, по референсу от него записываю в TWIM->ADDRESS то же самое значение 0х76, дергаю передачу и подтверждение получаю. И на какой "опыт работы с I2C" мне уповать в каждом из случаев?
- Реклама
Вообще, это больше похоже на проблему спецификации самого I²C, что понятие адреса устройства там настолько размыто. А если учесть ещё и второй, 10-битный, режим адресации, всё становится ещё сложнее.
Например, в даташите часов DS1307 адрес указан как 7-битный, а идущий после него бит R/W - сам по себе.
А вот в даташитах разных аудиопроцессоров (TDA7439, TDA7313 и многих других) однозначно адрес устройства - это 8 бит, включающих R/W бит.
А вообще соглашусь, серия F1 действительно выглядит не слишком "красиво" на фоне других. Те же отличия в конфигурации GPIO/AFIO - в более новых семействах (F0, F4) там всё выглядит несколько более разумным. Ну, на то он и "первый блин".
Например, в даташите часов DS1307 адрес указан как 7-битный, а идущий после него бит R/W - сам по себе.
А вот в даташитах разных аудиопроцессоров (TDA7439, TDA7313 и многих других) однозначно адрес устройства - это 8 бит, включающих R/W бит.
А вообще соглашусь, серия F1 действительно выглядит не слишком "красиво" на фоне других. Те же отличия в конфигурации GPIO/AFIO - в более новых семействах (F0, F4) там всё выглядит несколько более разумным. Ну, на то он и "первый блин".
Я в документации встречал такие перлы как "адрес для чтения" и "адрес для записи"
Никакая контра не уйдёт от нас
- Сообщения: 3604
- Зарегистрирован: Пн июл 28, 2008 22:12:01
Для упорото сомневающихся, список ляпов в документации на F4
http://www.efton.sk/STM32/STM32F4xx_doc_errors.txt
http://www.efton.sk/STM32/STM32F4xx_doc_errors.txt
- Сообщения: 6457
- Зарегистрирован: Пт сен 13, 2013 13:11:31
[uquote="WiseLord",url="/forum/viewtopic.php?p=3505846#p3505846"]Вообще, это больше похоже на проблему спецификации самого I²C, что понятие адреса устройства там настолько размыто.[/uquote]
В данном случае это не вопрос какой-то там "размытости". RM0008 везде на своих страницах вполне однозначно оперирует понятием 7-bit addressing (10-бит адресацию пока оставим). Если бы они хоть где-то упомянули 8-bit address, то можно было говорить о том, что у них свои координаты, оригинальный, но совместимый протокол и всякое такое. Так ведь нет -- только семибитная адресация, где младший бит адреса отвечает за выбор направления. Все. Приплыли. Это уже полная лажа.
В данном случае это не вопрос какой-то там "размытости". RM0008 везде на своих страницах вполне однозначно оперирует понятием 7-bit addressing (10-бит адресацию пока оставим). Если бы они хоть где-то упомянули 8-bit address, то можно было говорить о том, что у них свои координаты, оригинальный, но совместимый протокол и всякое такое. Так ведь нет -- только семибитная адресация, где младший бит адреса отвечает за выбор направления. Все. Приплыли. Это уже полная лажа.
Есть такое. В даташите на BMP180 указываются адреса 0xEE и 0xEF, как раз в таком "формате". Однако, все эти "восьмибитные" адреса хороши, пока не копнешь. Например, захочется сделать эмулятор такого устройства на МК, тут-то и выяснится, что возможности назначить восьмибитный адрес слейву на STM32F103 нет. Хрен в нос, а не 0xEE! Для этого тупо не хватает отведенных под адрес разрядов регистра. Оно понятно, что даже не знакомый с вопросом в состоянии разобраться при наличии желания, только тогда же и выяснится, что никакой 8-битной адресации I2C не существует в природе.prinv писал(а):Я в документации встречал такие перлы как "адрес для чтения" и "адрес для записи"
Круто. Честно сказать, я и не думал, что все так плохо. Дело даже не в том, сколько ошибок. Проблема, что ответственной стороне почти наплевать на них.dosikus писал(а):Для упорото сомневающихся, список ляпов в документации на F4
http://www.efton.sk/STM32/STM32F4xx_doc_errors.txt
- Реклама
Народ, я юзал F051 Disco, сейчас взял Blue Pills - F103C8T6 + ST-Link. Написал прогу помигать светодиодом на PC13 - ничего не получается - не могу понять - или какой глюк Keil 5 или где ошибка в проге:
#include "stm32f10x.h
int main (void)
{
uint32_t i;
RCC->AHBENR |= RCC_APB2ENR_IOPCEN; // Enable Clock GPIOC
GPIOC->CRH &= ~GPIO_CRH_CNF13;
GPIOC->CRH |= GPIO_CRH_MODE13;
while(1)
{
GPIOC->BSRR = GPIO_BSRR_BS13;
for (i=0;i<500000;i++) { }
GPIOC->BSRR = GPIO_BSRR_BR13;
for (i=0;i<500000;i++) { }
}
}
#include "stm32f10x.h
int main (void)
{
uint32_t i;
RCC->AHBENR |= RCC_APB2ENR_IOPCEN; // Enable Clock GPIOC
GPIOC->CRH &= ~GPIO_CRH_CNF13;
GPIOC->CRH |= GPIO_CRH_MODE13;
while(1)
{
GPIOC->BSRR = GPIO_BSRR_BS13;
for (i=0;i<500000;i++) { }
GPIOC->BSRR = GPIO_BSRR_BR13;
for (i=0;i<500000;i++) { }
}
}
Хорошему коту и в декабре - март 
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
[uquote="Frogfot",url="/forum/viewtopic.php?p=3506838#p3506838"]RCC->AHBENR |= RCC_APB2ENR_IOPCEN; // Enable Clock GPIOC[/uquote]
[uquote="VladislavS",url="/forum/viewtopic.php?p=3506847#p3506847"][uquote="Frogfot",url="/forum/viewtopic.php?p=3506838#p3506838"]RCC->AHBENR |= RCC_APB2ENR_IOPCEN; // Enable Clock GPIOC[/uquote][/uquote]
Заработало, благодарю, переносил код с F051, в упор не видел.
Заработало, благодарю, переносил код с F051, в упор не видел.
Хорошему коту и в декабре - март 
А вот такой вопрос. Есть такая штука, ARM semihosting. Когда, например, стандартные printf заводится особым образом на, например, UART.
Или, как вариант, выводить printf-ом не на UART, а через SWD Я, например, OpenOCD пользуюсь, и, как вариант, было бы неплохо там подобный вывод иметь.
Кто-нибудь заводил подобное? Помимо отладки дебаггером, благо с STM32 тут всё хорошо, хотелось бы иметь и подобную возможность, но как-то толкового руководства по настройке не видел.
P.S. Хотя.. вроде как получилось:

Или, как вариант, выводить printf-ом не на UART, а через SWD Я, например, OpenOCD пользуюсь, и, как вариант, было бы неплохо там подобный вывод иметь.
Кто-нибудь заводил подобное? Помимо отладки дебаггером, благо с STM32 тут всё хорошо, хотелось бы иметь и подобную возможность, но как-то толкового руководства по настройке не видел.
P.S. Хотя.. вроде как получилось:
- Сообщения: 6457
- Зарегистрирован: Пт сен 13, 2013 13:11:31
Через встроенные средства IDE я вывод в семихостинг делал, но это под каждую среду нужно настраивать, что ломает. Поэтому делаю "печать" в последовательный порт. На примере F0:
Дальше можно макрос uprintf() использовать полностью аналогично printf(). Переписав нужным образом uputc(), можно хоть азбукой морзе в блинк форматированную печать выдавать.
Код: Выделить всё
/* Send a char via UART */
void __STATIC_INLINE uputc(uint8_t c) {
/* Polling idle frame Transmission */
while((USART1->ISR & USART_ISR_TXE) != USART_ISR_TXE) {
/* Timeout handler follows here */
}
USART1->ICR = USART_ICR_TCCF; /* Сlear TC flag */
USART1->TDR = c; /* Send char */
}
/* Send a string via UART */
void __STATIC_INLINE uputs(char *s) {
while (*s != 0) uputc(*s++); /* Send string char by char */
}
/* MACRO to emulate printf() via UART */
#define uprintf(...) for(char _b[100]; snprintf(_b, sizeof(_b), __VA_ARGS__), uputs(_b), 0;){}
Да, этот вариант более очевиден. Хотя я имел в виду чуть другое - а именно сам printf "завернуть" на UART или куда там нужно. То есть, сам stdout перенастроить
Я вот вчера этот семихостинг "пощупал" - прикольно, но всё-таки не очень удобно. Во-первых, в момент вызова print всё словно подвисает на какую-то долю секунды. То есть, такой вариант, похоже, сам по себе медленный, и ещё работу МК приостанавливает. Даже таймеры "плывут". Во вторых, прошивка с семихостингом без подключенного отладчика виснет. То есть, годится только для отладки, потом же приходится снова компилировать обычную, без всех этих printf-ов.
В общем, немножко разочаровался с семихостингом. Вариант с UART получше будет. Разве что доработать его так, чтобы это был не поллинг, а работало оно через прерывания, дабы не блокировать основной поток программы на время вывода в UART.
Я вот вчера этот семихостинг "пощупал" - прикольно, но всё-таки не очень удобно. Во-первых, в момент вызова print всё словно подвисает на какую-то долю секунды. То есть, такой вариант, похоже, сам по себе медленный, и ещё работу МК приостанавливает. Даже таймеры "плывут". Во вторых, прошивка с семихостингом без подключенного отладчика виснет. То есть, годится только для отладки, потом же приходится снова компилировать обычную, без всех этих printf-ов.
В общем, немножко разочаровался с семихостингом. Вариант с UART получше будет. Разве что доработать его так, чтобы это был не поллинг, а работало оно через прерывания, дабы не блокировать основной поток программы на время вывода в UART.
- Сообщения: 3604
- Зарегистрирован: Пн июл 28, 2008 22:12:01
- Сообщения: 574
- Зарегистрирован: Вт ноя 02, 2010 17:46:37
dosikus, А можно чуть по подробнее что это такое ? На хабре читал не давно "функции отладочного вывода асинхронные и практически не занимают процессорного времени и не оказывают никакого влияния на ход выполнения программы при отсутствии подключения отладочного адаптера." Это как там сделано ?
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
[uquote="pokk",url="/forum/viewtopic.php?p=3507122#p3507122"]Это как там сделано ?[/uquote]Если на пальцах, то в ОЗУ выделяется область памяти в которую приложение кладёт информацию, которую хочет вывести во внешний мир. То есть, для приложения скорость вывода отладочной информации равна скоростью копирования память-память. Далее вступает в действие "магия отладчика". В канале управления SWD выделено 25% пропускной способности, чтобы J-Link забирал из этого буфера информацию в фоне. После того как J-Link заберёт данные из буфера, он отдаёт их клиенту, подключившемуся к нему по Telnet. Если же отладчик не подключен, то данные из буфера просто никто не забирает и они вытесняются новыми данными. Приложению до этого никакого дела нет.
Из плюсов:
- не задействованы никакие аппаратные ресурсы. Не надо резервировать UART для отладки, например.
- скорость вывода сообщений приложением очень высока. Это просто копирование память-память. Можно мониторить очень быстрые события практически не влияя на скорость их обработки.
- не надо никаких лишний подключений типа SWO или UART. Всё по тем же SWDIO и SWC идёт.
- можно не пересобирать приложение, если отладка больше не нужна. Просто не подключать отладчик и всё. Приложение ничего об этом не узнает.
Из минусов:
- работает только на J-Link.
- общая скорость считывания сообщений из буфера не очень высока. Для J-Link-OB это около 500 кбит. В то время как в UART можно мегабиты пропихнуть.
- ну и собственно нужно некоторое количество памяти для буфера. 1-2 кбайт.
Из плюсов:
- не задействованы никакие аппаратные ресурсы. Не надо резервировать UART для отладки, например.
- скорость вывода сообщений приложением очень высока. Это просто копирование память-память. Можно мониторить очень быстрые события практически не влияя на скорость их обработки.
- не надо никаких лишний подключений типа SWO или UART. Всё по тем же SWDIO и SWC идёт.
- можно не пересобирать приложение, если отладка больше не нужна. Просто не подключать отладчик и всё. Приложение ничего об этом не узнает.
Из минусов:
- работает только на J-Link.
- общая скорость считывания сообщений из буфера не очень высока. Для J-Link-OB это около 500 кбит. В то время как в UART можно мегабиты пропихнуть.
- ну и собственно нужно некоторое количество памяти для буфера. 1-2 кбайт.
- Сообщения: 2089
- Зарегистрирован: Вс июн 19, 2016 09:32:03
[uquote="VladislavS",url="/forum/viewtopic.php?p=3507147#p3507147"]Если же отладчик не подключен, то данные из буфера просто никто не забирает и они вытесняются новыми данными.[/uquote]
Зависит от флагов, если при полном буфере выбрано ожидание его освобождения, то данные не будут теряться, но без отладчика при переполнении все зависнет.
Зависит от флагов, если при полном буфере выбрано ожидание его освобождения, то данные не будут теряться, но без отладчика при переполнении все зависнет.
Работает и с ST-Link, нужен OpenOCD с патчем.- работает только на J-Link.
- Сообщения: 3604
- Зарегистрирован: Пн июл 28, 2008 22:12:01
VladislavS, телнет клинет это только часть , в SES так же встроена поддержка.
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
[uquote="Reflector",url="/forum/viewtopic.php?p=3507156#p3507156"]Работает и с ST-Link, нужен OpenOCD с патчем.[/uquote]Читал как-то про эти потуги. Назвать это словом "работает" язык не поворачивается.
[uquote="dosikus",url="/forum/viewtopic.php?p=3507158#p3507158"]VladislavS, телнет клинет это только часть , в SES так же встроена поддержка.[/uquote]Очень большая вероятность, что внутри SES тот же телнет. Впрочем, какая разница, есть поддержка - хорошо. Нет - подключаемся любым телнет-клиентом хоть локально, хоть удалённо.
[uquote="dosikus",url="/forum/viewtopic.php?p=3507158#p3507158"]VladislavS, телнет клинет это только часть , в SES так же встроена поддержка.[/uquote]Очень большая вероятность, что внутри SES тот же телнет. Впрочем, какая разница, есть поддержка - хорошо. Нет - подключаемся любым телнет-клиентом хоть локально, хоть удалённо.
- Сообщения: 3386
- Зарегистрирован: Пн окт 11, 2010 19:00:08
Если нужно, можно и с ST-Link. EmBitz есть что-то подобное под названием EB Monitor.VladislavS писал(а):- работает только на J-Link.
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
[uquote="Мурик",url="/forum/viewtopic.php?p=3507186#p3507186"]Если нужно, можно и с ST-Link.[/uquote]Поднимите руку те кто пользуется этим на st-link. А теперь тек кто на j-link. Видишь разницу? 


