Перейти к содержанию
    

Как соединить STM32 через I2C через HAL-прерывания с AD7746?

8 hours ago, Xenia said:

CDC не заработал

На easyelectronix и mcu.goodboard.ru хватает ссылок на CDC для STM32. Причем, сделанные без калокубов, т.е. почти так, как надо!

Я себе делал эмулятор PL2303 (ну не нравится мне, что девайс в случае CDC имеет имя /dev/ttyACMx, хочу /dev/ttyUSBx ☺ + в теории можно пинать RTS/DTR). Но и на всякий случай начал пилить "настоящий" CDC, правда, пока что за ненадобностью до конца не допилил (он уже определяется системой как /dev/ttyACM0, но нужно функции пересылки pl2303 упростить). Да и сам код хорошо бы причесать, чтобы более компактным и читабельным сделать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 28.01.2020 в 02:32, Xenia сказал:

Вы мне просто назовите 4 числа числа для pll: M, N, P, Q. А дальше я сама соображу, т.к. у меня загвоздка только в том, что 48 МГц для USB сделать не могу.

Достаточно в кубе в подсвеченные синим цветом окошки ввести нужные числа и куб сам пересчитает все делители ПЛЛ ;)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 27.01.2020 в 15:15, Xenia сказал:

Если осталось 0xFF, то не сработало.

У меня получилось переслать байт. Получил 7 ресивом. (Статусный байт получается?) Как теперь к регистру обратиться? Вместо адреса AD написать адрес регистра? (Значения смотрел STM Studio)

 

Вот код. Все инициализации опустил. Порт настроен на 100кГц кубом (параллелепипедом?:biggrin:).

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);
  		}
	  }
    }

 

1.PNG

 

---------------------

Я правильно понимаю, что вторым заходом я шлю адрес регистра -> жду/получаю ACK от AD -> пишу в этот регистр -> потом считываю при необходимости?

Изменено пользователем bookmender

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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].

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 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){}
}

 

1.PNG

Изменено пользователем bookmender

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 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. Попытайтесь найти способ послать мне текст вашей программы/проректа целиком, минуя цитирование на форуме. Оно и в дальнейшем будет полезно для дела.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, Xenia сказал:

1. Верните задержку 1 мс.

Вернул ))

 

2 часа назад, Xenia сказал:

2. Проверьте то же самое на других регистрах,...

Ах! Забыл написать. Я пробовал действительно на нескольких регистрах и получаю семерку. Опрашивал 0й, 10й и еще пару.

 

2 часа назад, Xenia сказал:

3. ...Попытайтесь найти способ послать мне текст вашей программы/проректа целиком,...

i2c_test_polling_v1_1.rar

Изменено пользователем bookmender

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

11 часов назад, bookmender сказал:

 

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);

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...