реклама на сайте
подробности

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> STM32 HAL SPI ошибка или глюки IAR,, ошибка чтения SPI с помощью HAL от CubeMX
Pasa
сообщение Jul 27 2016, 10:20
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 100
Регистрация: 4-03-09
Из: Беларусь, Минск
Пользователь №: 45 665



STM32F051, IAR, CubeMX

Читаю в пакетном режиме два регистра - ответ правильный. Добавляю чтение 3-его регистра - в приемном буфере ерунда.
На осцилографе картинка нормальная - все диаграмы и ответы красивые и правильные...

В парметрах функции пробовал и 3 сразу читать и в цикле по одному байту - не получается....

И вот так уже попробовал:
Код
uint8_t localRxBuf[4];
uint8_t data1,data2,data3;

HAL_SPI_Receive(&hspi1, (uint8_t*)&localRxBuf[0], 1, 10000);
data1 = localRxBuf[0];
HAL_SPI_Receive(&hspi1, (uint8_t*)&localRxBuf[0], 1, 10000);
data2 = localRxBuf[0];
//HAL_SPI_Receive(&hspi1, (uint8_t*)&localRxBuf[0], 1, 10000);
//data3 = localRxBuf[0];
придобавлении третьего чтения портятся data1,data2,data3......мистика какая-то. Повторюсь - на осцилографе все красиво и правильно

Такое ощущение, что HAL-библиотека глючит...
внутрь HAL что-ли полезть

Сообщение отредактировал IgorKossak - Jul 27 2016, 14:30
Причина редактирования: [codebox] для длинного кода. [code]-для короткого!!!
Go to the top of the page
 
+Quote Post
serglg
сообщение Jul 27 2016, 15:57
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 49
Регистрация: 19-07-16
Пользователь №: 92 603



хочу заметить, что с HAL_SPI_Receive и у меня какое-то подозрение (STM32L476).
Пока я не вставил CHTREG = SPI1->DR:

HAL_SPI_Receive(&hspi1, OTVRC522, 1, 20);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_12, GPIO_PIN_SET);
CHTREG = SPI1->DR;
BUFRC522[j]=OTVRC522[0];

у меня был полный дурдом.
Там же регистр 16-битный, а прием 8-битный. Такое подозрение, что путаются ст. и мл. байты.


Сообщение отредактировал serglg - Jul 27 2016, 15:58
Go to the top of the page
 
+Quote Post
Pasa
сообщение Jul 27 2016, 17:27
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 100
Регистрация: 4-03-09
Из: Беларусь, Минск
Пользователь №: 45 665



Цитата(serglg @ Jul 27 2016, 19:27) *
Пока я не вставил CHTREG = SPI1->DR:

HAL_SPI_Receive(&hspi1, OTVRC522, 1, 20);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_12, GPIO_PIN_SET);
CHTREG = SPI1->DR;
BUFRC522[j]=OTVRC522[0];

...... ээээ ....я не совсем с наскоку понял CHTREG = SPI1->DR;
- вызываете HAL_Recive
- CS вверх
- CHTREG = SPI1->DR; кудато руками читаете приемные данные? название CHTREG непонятно...
- зачем BUFRC522[j]=OTVRC522[0]; ......вроде выше все считано в CHTREG(что это такое?)

...или я не правильно понял...поясните пж-ста...

p.s.
у самого бродит идея весь прием переписать через CMSIS...только вот времени нету
Go to the top of the page
 
+Quote Post
Pasa
сообщение Jul 27 2016, 20:17
Сообщение #4


Частый гость
**

Группа: Свой
Сообщений: 100
Регистрация: 4-03-09
Из: Беларусь, Минск
Пользователь №: 45 665



В инициализации SPI в HAL:

Код
  if(hspi->Init.DataSize > SPI_DATASIZE_8BIT)
  {
    frxth = SPI_RXFIFO_THRESHOLD_HF;
  }
  else
  {
    frxth = SPI_RXFIFO_THRESHOLD_QF;
  }


похоже тут надо наоборот.....может быть

Сообщение отредактировал Pasa - Jul 27 2016, 20:20
Go to the top of the page
 
+Quote Post
serglg
сообщение Jul 28 2016, 04:14
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 49
Регистрация: 19-07-16
Пользователь №: 92 603



Цитата(Pasa @ Jul 27 2016, 23:27) *
...... ээээ ....я не совсем с наскоку понял CHTREG = SPI1->DR;
- вызываете HAL_Recive
- CS вверх
- CHTREG = SPI1->DR; кудато руками читаете приемные данные? название CHTREG непонятно...
- зачем BUFRC522[j]=OTVRC522[0]; ......вроде выше все считано в CHTREG(что это такое?)

...или я не правильно понял...поясните пж-ста...

p.s.
у самого бродит идея весь прием переписать через CMSIS...только вот времени нету


CHTREG - совсем левая переменная. Чтобы было куда считать регистр данных SPI ( SPI1->DR).

BUFRC522[j]=OTVRC522[0] - у меня все регистры платы RFID-RC522 (их там больше 30 рабочих) считывались в массив.
А OTVRC522[0] - это же просто массив куда HAL-функция складывает текущий байт.

Так вот. Без этой дурацкой строки (признаю полностью, что дурацкой):
CHTREG = SPI1->DR;
у меня читается в массив OTVRC522[0] черт те что.
Таким образом что-то там в HAL-функциях по SPI у них накосячено.


Цитата(Pasa @ Jul 28 2016, 02:17) *
В инициализации SPI в HAL:

Код
  if(hspi->Init.DataSize > SPI_DATASIZE_8BIT)
  {
    frxth = SPI_RXFIFO_THRESHOLD_HF;
  }
  else
  {
    frxth = SPI_RXFIFO_THRESHOLD_QF;
  }


похоже тут надо наоборот.....может быть


Ну вот, может и у меня тут потому глюк?
Go to the top of the page
 
+Quote Post
tehn1k
сообщение Jul 28 2016, 05:41
Сообщение #6





Группа: Новичок
Сообщений: 4
Регистрация: 12-02-16
Из: Самара
Пользователь №: 90 422



Как Вы выбираете чтение того или иного регистра, если работаете только в режиме приема? Пользуюсь HALовскими функциями HAL_SPI_TransmitReceive и HAL_SPI_TransmitReceive_IT, работают как часы, проц stmf745. В режиме дебага посмотрите, что по факту находится в дата регистре. Про порчу data1, data2 - такого не может быть, если только что то еще в коде не обращается к этим переменным.
Go to the top of the page
 
+Quote Post
k155la3
сообщение Jul 28 2016, 06:09
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 551
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(Pasa @ Jul 27 2016, 13:20) *
STM32F051, IAR, CubeMX

Читаю в пакетном режиме два регистра - ответ правильный. Добавляю чтение 3-его регистра - в приемном буфере ерунда.
На осцилографе картинка нормальная - все диаграмы и ответы красивые и правильные...

. . . .

Такое ощущение, что HAL-библиотека глючит...
внутрь HAL что-ли полезть


Про осцилограф.
Проверьте соответствие настроек полярности-фазы SPI и их соответствие девайсу с которым работаете.
(извиняюсь, конечно, IMHO)

Полезть внутрь HAL. Тоже вариант. Выкопать исполнимый код будет сложновато.
Можно посмотреть что там творится на уровне ASM-листинга или дизассемблера в отладчике.
Go to the top of the page
 
+Quote Post
serglg
сообщение Jul 28 2016, 06:09
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 49
Регистрация: 19-07-16
Пользователь №: 92 603



Цитата(tehn1k @ Jul 28 2016, 11:41) *
Как Вы выбираете чтение того или иного регистра, если работаете только в режиме приема? Пользуюсь HALовскими функциями HAL_SPI_TransmitReceive и HAL_SPI_TransmitReceive_IT, работают как часы, проц stmf745. В режиме дебага посмотрите, что по факту находится в дата регистре. Про порчу data1, data2 - такого не может быть, если только что то еще в коде не обращается к этим переменным.


Мне надо прочитать регистр в RC522 c определенным адресом. Для этого надо сначала передать этот адрес (1 байт) и потом (не снимая CS) принять один байт. Вы может предложить пример вызова функции HAL_SPI_TransmitReceive для такого случая? У меня почему-то не получалось.
Go to the top of the page
 
+Quote Post
tehn1k
сообщение Jul 28 2016, 06:55
Сообщение #9





Группа: Новичок
Сообщений: 4
Регистрация: 12-02-16
Из: Самара
Пользователь №: 90 422



Цитата(serglg @ Jul 28 2016, 10:09) *
Мне надо прочитать регистр в RC522 c определенным адресом. Для этого надо сначала передать этот адрес (1 байт) и потом (не снимая CS) принять один байт. Вы может предложить пример вызова функции HAL_SPI_TransmitReceive для такого случая? У меня почему-то не получалось.

1) Проверьте вот это
Data bytes on both MOSI and MISO lines are sent with the MSB first. Data on both MOSI and MISO lines must be stable on the rising edge of the clock and can be changed on the falling edge. Data is provided by the MFRC522
on the falling clock edge and is stable during the rising clock edge

2) Вместо NSS SPI интерфейса подключите к NSS любой свободный пин и управляйте им. Опускаете его в 0, передаете принимаете нужное количество байт вызвав HAL_SPI_TransmitReceive и поднимаете пин вверх.
Go to the top of the page
 
+Quote Post
Lagman
сообщение Jul 28 2016, 09:35
Сообщение #10


Знающий
****

Группа: Свой
Сообщений: 797
Регистрация: 28-10-05
Пользователь №: 10 245



Цитата(serglg @ Jul 28 2016, 09:09) *
Мне надо прочитать регистр в RC522 c определенным адресом. Для этого надо сначала передать этот адрес (1 байт) и потом (не снимая CS) принять один байт. Вы может предложить пример вызова функции HAL_SPI_TransmitReceive для такого случая? У меня почему-то не получалось.

А зачем тогда читать 3 байта подряд?

Если исходить из того, что используется функция HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout) то можно поступить так, надо отправить 1 байт с адресом регистра и принять 1 байт с данными (не одновременно), размер Size будет равен 2 байтам, pTxData[0] = адресу регистра откуда будут читаться данные, pTxData[1] = 0xff; При обработке pRxData[0] игнорируем и данные берем из pRxData[1].
Go to the top of the page
 
+Quote Post
k155la3
сообщение Jul 28 2016, 10:18
Сообщение #11


Знающий
****

Группа: Свой
Сообщений: 551
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(Lagman @ Jul 28 2016, 12:35) *
А зачем тогда читать 3 байта подряд?

Если исходить из того, что используется функция HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout) то можно поступить так, надо отправить 1 байт с адресом регистра и принять 1 байт с данными (не одновременно), размер Size будет равен 2 байтам, pTxData[0] = адресу регистра откуда будут читаться данные, pTxData[1] = 0xff; При обработке pRxData[0] игнорируем и данные берем из pRxData[1].


Чотбы прочитать один байт из 8-разрядного регистра.
1. Установить CS
2. Передать опкод, принять мусор (или регистр статуса)
3. Передать адрес регистра, принять мусор
4. Передать мусор, принять значение регистра.
5. Снять CS
Это если "SPI-безвыпендривания"
Для конкретного девайса надо смотреть диаграмму запроса по конкретному опкоду.
Go to the top of the page
 
+Quote Post
k155la3
сообщение Jul 28 2016, 12:45
Сообщение #12


Знающий
****

Группа: Свой
Сообщений: 551
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(Pasa @ Jul 27 2016, 13:20) *
И вот так уже попробовал:
Код
uint8_t localRxBuf[4];
uint8_t data1,data2,data3;

HAL_SPI_Receive(&hspi1, (uint8_t*)&localRxBuf[0], 1, 10000);
data1 = localRxBuf[0];
HAL_SPI_Receive(&hspi1, (uint8_t*)&localRxBuf[0], 1, 10000);
data2 = localRxBuf[0];
//HAL_SPI_Receive(&hspi1, (uint8_t*)&localRxBuf[0], 1, 10000);

//data3 = localRxBuf[0];
придобавлении третьего чтения портятся data1,data2,data3......мистика какая-то. Повторюсь - на осцилографе все красиво и правильно

. . . . .


"при добавлении третьего чтения портятся data1,data2,data3"

uint8_t localRxBuf[4];
uint8_t data1,data2,data3;

Исходя из объявления, эта память находится в одном сегменте, одного типа (uint8_t) , и вполне вероятно "слитно".
Похоже что ф-ия HAL пишет в массив данные, которые не того типа, или не того кол-ва, или и то и другое.
Запись начиная с localRxBuf[0] зашкаливает за localRxBuf[3] и возможно, затирает data123

Go to the top of the page
 
+Quote Post
rudy_b
сообщение Jul 28 2016, 13:57
Сообщение #13


Знающий
****

Группа: Свой
Сообщений: 820
Регистрация: 25-09-08
Из: Питер
Пользователь №: 40 458



Что-то я не понял, у вас SPI в режиме slave или master?
Если в slave - то дергание CS недопустимо, в этом режиме это входной сигнал.
А если master - вы сами должны дергать CS. Проверьте, что периферия правильно на него реагирует.

С работой SPI в режиме slave через DMA (не IT) действительно есть какие-то проблемы (f207). Они есть даже без HAL. Очень долго мучился заставляя его правильно работать, но, в конце концов, это удалось. Подробностей уже не помню, но долго возился с тем, чтобы не было перестановки байт и не пропадал первый байт посылки.
Go to the top of the page
 
+Quote Post
x893
сообщение Jul 28 2016, 14:17
Сообщение #14


Знающий
****

Группа: Свой
Сообщений: 969
Регистрация: 27-10-08
Из: Планета Земля
Пользователь №: 41 226



Функция SPI Receive в HAL занимает строк 20 из них 10 фуфло всякое. Пройдите по шагам и посмотрите что там делается. За пять минут (вместо дня гадания) уже всё определили бы и получали свои байты.
Go to the top of the page
 
+Quote Post
alag57
сообщение Jul 28 2016, 14:41
Сообщение #15


Частый гость
**

Группа: Участник
Сообщений: 128
Регистрация: 26-06-06
Из: Березовский
Пользователь №: 18 355



В CR2 есть такой хитрый битик - FRXTH, так вот у меня получилось только так:

CODE

void SPI1_WriteRead(uint8_t *tx_buf, uint8_t *rx_buf, uint8_t length)
{
SPI1_CS_On();
SPI1_WriteRead_NotCS(tx_buf, rx_buf, length);
SPI1_CS_Off();
}

void SPI1_WriteRead_NotCS(uint8_t *tx_buf, uint8_t *rx_buf, uint8_t length)
{
uint8_t rx_length = length;

if (length > 1)
{
SPI1->CR2 &= ~SPI_CR2_FRXTH; // Threshold = 16
}
else
{
SPI1->CR2 |= SPI_CR2_FRXTH; // Threshold = 8
}

while (length)
{
while ((SPI1->SR & SPI_I2S_FLAG_TXE) == 0);

if (length > 1)
{
SPI1->DR = *((uint16_t *)tx_buf);
tx_buf += 2;
length -=2;
}
else
{
*(__IO uint8_t *)&SPI1->DR = *tx_buf++;
length--;
}

while ((SPI1->SR & SPI_I2S_FLAG_RXNE) == 0);

if (rx_length > 1)
{
*((uint16_t *)rx_buf) = SPI1->DR;
rx_buf += 2;
rx_length -= 2;
if (rx_length <= 1)
{
SPI1->CR2 |= SPI_CR2_FRXTH; // Threshold = 8
}
}
else
{
(*rx_buf++) = *(__IO uint8_t *)&SPI1->DR;
}
}
}

Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 24th July 2017 - 22:56
Рейтинг@Mail.ru


Страница сгенерированна за 0.01467 секунд с 7
ELECTRONIX ©2004-2016