|
Один SPI на два дивайса |
|
|
|
Dec 11 2015, 08:55
|
Знающий
   
Группа: Свой
Сообщений: 922
Регистрация: 3-06-05
Из: Москва
Пользователь №: 5 709

|
Так не получается. Проект генерю из STM32CubeMx. Пока работаю только с датчиком температуры, подключены SO, SCK и CS. Если конфигурить SPI как Full-Duplex Master то программа виснет на чтении данных, если как Receive Only Msster то данные идут, но не полностью. SPI сконфигурю с DMA, когда наступает момент чтения температуры вызываю функции Код uint16_t Temp; // Значение измеренной температуры ………………………………………………… HAL_GPIO_WritePin(GPIOA,CS_Termo_Pin,GPIO_PIN_RESET); HAL_SPI_Receive_DMA(&hspi1,(uint8_t*)&Temp,2); По окончанию работы DMA вызывается прерывание со статусом HAL_DMA_STATE_READY_MEM0, поднимаю пин CS Код HAL_GPIO_WritePin(GPIOA,CS_Termo_Pin,GPIO_PIN_SET); Но по осциллографу вижу, что CS отключает датчик температуры ровно посередине второго байта. Соответственно первый байт приходит, видно он меняется, второго байта нет. Почему так может быть? В какой момент отключать CS? Как правильно работать с несколькими девайсами ни одном SPI? Нужно и одно чтение и одна запись и Full-Duplex Master для третьего девайса.
|
|
|
|
|
Dec 11 2015, 10:50
|

Знающий
   
Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663

|
Цитата(Oleg_IT @ Dec 11 2015, 12:55)  SPI сконфигурю с DMA, когда наступает момент чтения температуры вызываю функции Код uint16_t Temp; // Значение измеренной температуры ………………………………………………… HAL_GPIO_WritePin(GPIOA,CS_Termo_Pin,GPIO_PIN_RESET); HAL_SPI_Receive_DMA(&hspi1,(uint8_t*)&Temp,2); По окончанию работы DMA вызывается прерывание со статусом HAL_DMA_STATE_READY_MEM0, поднимаю пин CS Код HAL_GPIO_WritePin(GPIOA,CS_Termo_Pin,GPIO_PIN_SET); Но по осциллографу вижу, что CS отключает датчик температуры ровно посередине второго байта. Соответственно первый байт приходит, видно он меняется, второго байта нет. Почему так может быть? В какой момент отключать CS? Как правильно работать с несколькими девайсами ни одном SPI? Нужно и одно чтение и одна запись и Full-Duplex Master для третьего девайса. CS снимается, когда DMA записал последний байт в DR, а должен сниматься когда вычитан последний байт из DR. Вообще странно: цикл SPI это одновременное запись-чтение и надёжным признаком является заполнение DR принятым. Может есть другой более подходящий статус HAL_DMA_STATE_****
--------------------
Пролетарий умственного труда.
|
|
|
|
|
Dec 11 2015, 14:40
|
Знающий
   
Группа: Свой
Сообщений: 922
Регистрация: 3-06-05
Из: Москва
Пользователь №: 5 709

|
Цитата(Obam @ Dec 11 2015, 18:19)  Вот тут-то и парадокс: когда знаешь что и где "кубы" без надобности.
Так почему DMA, не приняв последний байт, отваливался? Да ни какого парадокса, просто экономия времени и можно посмотреть как люди программы пишут, если опыта мало. А с DMA пока не пойму. в прерывания он входит только с HAL_DMA_STATE_READY_MEM0, сконфигурил я его так. Я вот думаю, может в SPI флаг окончания приёма контролировать, в основном цикле и когда прерывание от DMA пришло. Кривовато это как-то.
|
|
|
|
|
Dec 12 2015, 01:07
|
Профессионал
    
Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439

|
Цитата(Oleg_IT @ Dec 11 2015, 17:40)  Да ни какого парадокса, просто экономия времени и можно посмотреть как люди программы пишут, если опыта мало.
А с DMA пока не пойму. в прерывания он входит только с HAL_DMA_STATE_READY_MEM0, сконфигурил я его так. Я вот думаю, может в SPI флаг окончания приёма контролировать, в основном цикле и когда прерывание от DMA пришло. Кривовато это как-то. Контролировать в цикле неправильно. Во первых есть аппаратный CS, который праввильно поведет себя. Если совсем нет выбора, а надо подключить несколько SPI устройств, то можно включить их последовательно. Поищите по ключевым словам daisy chain. SPI устройство это регистр сдвига, который защелкивает информацию по положительному фронту CS. Для записи в устройство в конце цепочки вам придется формировать посылку из нескольких слов, чтобы нужное дошло. Ну вот например так как здесь описано: https://en.wikipedia.org/wiki/Serial_Periph...l_Interface_BusЕсть и другие способы, но это уже если устройство их поддерживает. А куб мне пока нравится.
|
|
|
|
|
Dec 14 2015, 14:26
|
Профессионал
    
Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439

|
Цитата(Oleg_IT @ Dec 14 2015, 10:41)  Не правильно, но работает. Почему прерывание раньше происходит так и не понял, может так задумано. Пренебрежение опытом -- источник "необъяснимых" чудес в поведении разрабатываемого устройства. Бывает, что несколько событий могут вызвать прерывание по одному и тому же вектору. Если это так, то прочитайте в прерывании флаги и определите то ли прерывание произошло, которого вы ожидали. Если не то, то покинте (если вам его не надо обрабатывать) обработчик.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|