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

 
 
> SPI не принимает больше одного байта
Nosaer
сообщение Jun 29 2017, 11:37
Сообщение #1


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

Группа: Свой
Сообщений: 85
Регистрация: 6-02-15
Пользователь №: 84 967



Доброго времени суток.
Столкнулся со следующей проблемой.
В данном случае SPI работает корректно:

Код
uint8_t    BufReadMR45[3] = {0x03,0x00,0x00};
uint8_t     DataReadMR45[5] = {0};    

    void ReadMR45(void)
    {

        HAL_GPIO_WritePin(PortCSMR45, PinCSMR45, GPIO_PIN_RESET);                                                        // CS on
        HAL_Delay(1);
        HAL_SPI_Transmit(&hspi1, &BufReadMR45[0], 3, 1000);                                                                // Отправка данных по SPI
        HAL_SPI_Receive(&hspi1, &DataReadMR45[0], 1, 1000);                                                                // Получение данных по SPI

        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);
        HAL_GPIO_WritePin(PortCSMR45, PinCSMR45, GPIO_PIN_SET);                                                            // CS off
        HAL_UART_Transmit(&huart1, &DataReadMR45[0], 1, 0x1000);                                                    // Отправляю данные по UART
        ByteMR45_R = ByteMR45_R + 1;
    }


Если я изменю функцию:
Код
HAL_SPI_Receive(&hspi1, &DataReadMR45[0], 5, 1000);

Чтобы считывать сразу больше 1 байта, программа зависает.
Отладчик приводит в HardFault_Handler(void)

Процессор STM32F030, до этого работал с серией F4, таких проблем вроде как не было.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Nosaer
сообщение Jun 30 2017, 04:23
Сообщение #2


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

Группа: Свой
Сообщений: 85
Регистрация: 6-02-15
Пользователь №: 84 967



Код
/* SPI1 init function */
static void MX_SPI1_Init(void)
{

  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 7;
  hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
  hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}


Проинициалированно на 8 бит, и считываю по 8.
Не совсем понял про 16 бит.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 30 2017, 05:52
Сообщение #3


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Nosaer @ Jun 30 2017, 07:23) *
Проинициалированно на 8 бит, и считываю по 8.
У STM32F0 немного перемудрили с регистром данных - он 16-битный и если хотите передавать байты -
надо их запихивать по два за раз (они назвали это "упаковка"). А когда количество байт нечетное и остается один последний - надо еще и битик управляющий выставить, типа "пихаю последние 8 бит и все".

QUOTE (Nosaer @ Jun 30 2017, 07:23) *
Не совсем понял про 16 бит.
Ваш указатель pTxData лежит в R5 и имеет значение 0x20000047. Своим приведением *(uint16_t *) вы принуждаете компилятор использовать команду чтения 16 бит. А поскольку адрес в указател у вас не выровнен на границу двух байт, то вы и получаете исключение из-за невыровненного доступа. Пламенный привет писателям "библиотеки". Чтобы этот код работал на CM0(+), адрес начала вашего буфера должен быть кратен двум. Или же переписать этот код правильно: если ваш компилятор умеет указатели на упакованные данные, надо объявить pTxData указателем на упакованные данные (как-то наподобие uint16_t __packed * pTxData). Или же объявить его указателем на uint8_t, вычитывать с его помощью два байта, вручную собирать их в 16-битное слово и уже это слово запихивать в DR. Я бы использовал второй вариант - объектный код получится такой же, а исходник останется портируемым на другие компиляторы.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 30th July 2025 - 19:08
Рейтинг@Mail.ru


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