Eddy_Em 1 29 января, 2020 Опубликовано 29 января, 2020 · Жалоба 8 hours ago, Xenia said: CDC не заработал На easyelectronix и mcu.goodboard.ru хватает ссылок на CDC для STM32. Причем, сделанные без калокубов, т.е. почти так, как надо! Я себе делал эмулятор PL2303 (ну не нравится мне, что девайс в случае CDC имеет имя /dev/ttyACMx, хочу /dev/ttyUSBx ☺ + в теории можно пинать RTS/DTR). Но и на всякий случай начал пилить "настоящий" CDC, правда, пока что за ненадобностью до конца не допилил (он уже определяется системой как /dev/ttyACM0, но нужно функции пересылки pl2303 упростить). Да и сам код хорошо бы причесать, чтобы более компактным и читабельным сделать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Behram 0 29 января, 2020 Опубликовано 29 января, 2020 · Жалоба В 28.01.2020 в 02:32, Xenia сказал: Вы мне просто назовите 4 числа числа для pll: M, N, P, Q. А дальше я сама соображу, т.к. у меня загвоздка только в том, что 48 МГц для USB сделать не могу. Достаточно в кубе в подсвеченные синим цветом окошки ввести нужные числа и куб сам пересчитает все делители ПЛЛ ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bookmender 0 3 февраля, 2020 Опубликовано 3 февраля, 2020 (изменено) · Жалоба В 27.01.2020 в 15:15, Xenia сказал: Если осталось 0xFF, то не сработало. У меня получилось переслать байт. Получил 7 ресивом. (Статусный байт получается?) Как теперь к регистру обратиться? Вместо адреса AD написать адрес регистра? (Значения смотрел STM Studio) Вот код. Все инициализации опустил. Порт настроен на 100кГц кубом (параллелепипедом?). uint8_t aTxBuffer[8] = "00000000"; uint8_t aRxBuffer[8] = "11111111"; uint8_t aTxBufferData[8] = "00000011"; uint8_t aRxBufferData[8] = "11111111"; if (HAL_I2C_Master_Transmit (&hi2c1, 0x90, aTxBuffer, 1, 5) == HAL_OK) { if (HAL_I2C_Master_Receive (&hi2c1, 0x90, aRxBuffer, 1, 5) == HAL_OK) { if (HAL_I2C_Master_Transmit (&hi2c1, 0x90, aTxBufferData, 1, 5) == HAL_OK) { HAL_I2C_Master_Receive (&hi2c1, 0x90, aRxBufferData, 1, 5); } } } --------------------- Я правильно понимаю, что вторым заходом я шлю адрес регистра -> жду/получаю ACK от AD -> пишу в этот регистр -> потом считываю при необходимости? Изменено 3 февраля, 2020 пользователем bookmender Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 35 3 февраля, 2020 Опубликовано 3 февраля, 2020 · Жалоба 15 часов назад, bookmender сказал: У меня получилось переслать байт. Получил 7 ресивом. (Статусный байт получается?) Как теперь к регистру обратиться? Вместо адреса AD написать адрес регистра? (Значения смотрел STM Studio) Я правильно понимаю, что вторым заходом я шлю адрес регистра -> жду/получаю ACK от AD -> пишу в этот регистр -> потом считываю при необходимости? Похоже, что у вас ничего не получилось :), но если какой-то ответ получили вместо молчания, то это уже не так плохо. 1. Первая ваша ошибка - вы посылаете вместо адреса регистра не 0, а 48. Тогда как у AD7746 так много регистров нет, потому и неясно, к какому регистру относится его ответ. И мне вдвойне непонятно, отчего вы мой код забраковали, написав вместо него свой, где ошибки почти в каждой строке? Вам следовало сначала испытать мой код, и уж только после этого фантазировать на его тему. А теперь мы не знаем ничего, т.к. рекомендованный вам код вы не запускали, а ваш код работать не должен, поскольку написан с грубыми ошибками. Итак, 1-ая ваша ошибка - неправильная инициализация буфера, из-за чего в нем появились вредные числа. Вам не нужен буфер из 8-ми байт - достаточно 1-го. В будущем, принимающий буфер можно будет расширить до 3-х байт, чтобы принимать все 3 байта измерения (т.е. все 24 бита) за один раз, но я вас умоляю сейчас этим не заниматься, т.к. в 3-х соснах заблудиться легче, чем в одной. Выражения типа "00000000" или "11111111" - это не числа, а текстовые строки: первая состоит из 8-ми символов "0" (код каждого символа 48), а вторая из 8-ми символов "1" (код каждого символа 49). Тогда как разговор с AD7746 ведется не в текстовом, а в двоичном режиме. Да вы и сами должны были это заметить, т.к. VarViewer1 числа 48 и 49 вам показал, и это должно было вас насторожить. Поэтому предлагаю вам бросить инициализацию массива при его объявлении, а класть в его число явно. Вот так: uint8_t aTxBuffer[1]; // инициализацию не производим aTxBuffer[0] = 0; // записываем в начальный элемент массива число явным образом, т.к. позже будем это число менять Т.е. когда станем заниматься другими регистрами, то запишем туда какое-то другое число вместо того, чтобы всякий раз создавать новый буфер. Соответственно этому, дополнительные буфера aTxBufferData и aRxBufferData вам не нужны: вполне хватает двух - один на передачу (aTxBuffer) и один на прием (aRxBuffer). Причем, в первый из них всегда будем пиcать передаваемые данные (адрес/номер регистра или его установочное значение), а второй всегда будет рассматриваться, как вместилище для полученных от AD7746 данных, что бы они ни значили (содержимое регистра или измерение, т.к. измерение тоже содержится в регистрах). 2. Вторая ошибка: 4 транзакции не нужно, всегда достаточно только двух транзакций: Во время чтения регистра: 1-я транзакция - передаем в AD7746 адрес интересующего нас регистра, 2-я транзакция - принимаем ответ от AD7746 (это и будет число, хранимое в этом регистре). Во время записи в регистр: 1-я транзакция - передаем в AD7746 адрес интересующего нас регистра, 2-я транзакция - снова передаем в AD7746, но уже число, которое в этот регистр должно быть записано. И здесь не надо бояться того, что перед 2-ой передачей значение aTxBufferх[0] придется заменить, вколотив туда вместо адреса регистра его новое значение. Тем самым, при операциях чтения и записи 1-я транзакция всегда одинаковая (!) - это передача адреса/номера регистра. А вот тип 2-ой транзакции уже зависит от того, что нам надо - прочесть или записать. Если прочесть - то принимаем, а есть записать - то передаем, поместив передаваемый байт в aTxBuffer[0]. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bookmender 0 10 февраля, 2020 Опубликовано 10 февраля, 2020 (изменено) · Жалоба В 04.02.2020 в 00:35, Xenia сказал: вместо молчания Ага, даже контроллер не хочет со мной разговаривать. )) В 04.02.2020 в 00:35, Xenia сказал: И мне вдвойне непонятно, отчего вы мой код забраковали, ... Ну, как Вам сказать... Когда я прочитал Ваш пост на второй странице, решил, что пора писать функции записи и чтения регистров. Вы сказали, что рано. Тогда взялся за простое получение ответа от AD (опять же, спасибо за дельный совет). В итоге, как я понял, от меня требуется написать что-то простое и только потом писать функции передачи данных. Вот. Написал маленький код получения из 10го регистра (Configuration) его состояния. uint8_t aTxBuffer[1]; uint8_t aRxBuffer[1]; int main(void) { aTxBuffer[0] = 0x0A; // адрес конфигурации aRxBuffer[0] = 6; // это число перезапишется с небольшой задежкой и я увижу разницу в STM Studio. if (HAL_I2C_Master_Transmit (&hi2c1, 0x90, aTxBuffer, 1, 5) == HAL_OK) { HAL_Delay(5000); // задержка, чтобы заметить изменение буфера HAL_I2C_Master_Receive (&hi2c1, 0x90, aRxBuffer, 1, 5); } while(1){} } Изменено 10 февраля, 2020 пользователем bookmender Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 35 11 февраля, 2020 Опубликовано 11 февраля, 2020 · Жалоба В 10.02.2020 в 16:22, bookmender сказал: Вот. Написал маленький код получения из 10го регистра (Configuration) его состояния. HAL_Delay(5000); // задержка, чтобы заметить изменение буфера 1. Верните задержку 1 мс. Если вам хочется посмотреть на число 6, которое вы положили в буфер aRxBuffer, то и сделайте себе сколь угодно большую задержку следом после закладки числа в буфер: aRxBuffer [0]=6; (т.е. до трансмита), но не надо делать слишком длительных остановок между посылкой запроса и приёмом ответа - тут стоянка запрещена. Пауза в 1 мс (а желательно еще короче) необходима, чтобы AD7746 успел осмыслить вопрос и подготовиться к ответу, но долго с приемом ответа ждать не рекомендуется - незабранная вовремя на почте посылка уйдет обратно в Китай :). Особенно вредно тормозить в этом месте, когда AD7746 заработает в режиме периодического измерения, которое происходит не реже каждых 122 мс. А если вы, подав команду запроса (в виде номера регистра) будете в этом месте 5 сек на экран глазеть, то заведомо наступит другой цикл. Т.е. вы получите все 3 части (старшую, среднюю и младшую) от разных измерений. 2. Проверьте то же самое на других регистрах, а лучше опросите все 16 по порядку. А то число 7, которое вы получаете в ответе, уж больно подозрительно, т.к. в в прошлом вы его уже получали при опросе другого регистра. Есть опасение, что число 7 у вас будет получаться всякий раз, какой бы номер регистра вы ни опрашивали. 3. Я не вижу в вашем коде инициализации интерфейса I2C (это там, где ему частота задается) и пинов порта SCL и SDA. Попытайтесь найти способ послать мне текст вашей программы/проректа целиком, минуя цитирование на форуме. Оно и в дальнейшем будет полезно для дела. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bookmender 0 11 февраля, 2020 Опубликовано 11 февраля, 2020 (изменено) · Жалоба 2 часа назад, Xenia сказал: 1. Верните задержку 1 мс. Вернул )) 2 часа назад, Xenia сказал: 2. Проверьте то же самое на других регистрах,... Ах! Забыл написать. Я пробовал действительно на нескольких регистрах и получаю семерку. Опрашивал 0й, 10й и еще пару. 2 часа назад, Xenia сказал: 3. ...Попытайтесь найти способ послать мне текст вашей программы/проректа целиком,... i2c_test_polling_v1_1.rar Изменено 11 февраля, 2020 пользователем bookmender Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 35 11 февраля, 2020 Опубликовано 11 февраля, 2020 · Жалоба 11 часов назад, bookmender сказал: i2c_test_polling_v1_1.rar 1. Задержку 5000 вы так и не убрали, хотя обещали. 2. Так писать нельзя: aTxBuffer[0]=100, т.к. у AD7746 нет 100-го регистра, поскольку у него их всего 16 штук. 3. Записать в регистр число и тут же сразу его читать тоже нельзя, для чтения надо повторить процедуру сызнова - снова сперва адрес регистра загонять и только потом читать его состояние. 4. На Receive ставьте адрес на единичку больше, чем на Transmit: HAL_I2C_Master_Transmit(&hi2c1, 0x90, aTxBuffer, 1, 5) HAL_I2C_Master_Receive (&hi2c1, 0x91, aRxBuffer, 1, 5); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться