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

Камень STM32F303VC

Настроил SPI

 /*!< SPI Config */
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; 
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;  //APB1=36Mhz => ~1Mhz //APB2=72Mhz                                                                  
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init(SPIx, &SPI_InitStructure);

Размер задан - байт - SPI_DataSize_8b

На скопе на клоке вижу 16 бит - после передачи 8 бит посылает еще 8.

Я что то недонастроил?

 

Передача байта такая

uint32_t SPI_TransferByte(SPI_TypeDef *SPIx, uint8_t data)
{
    uint32_t timeout;

    // All data transmitted/received but SPI may be busy so wait until done.
    timeout = SPI_DELAY;
    while (SPIx->SR & SPI_I2S_FLAG_BSY) { if(!timeout--) return SPI_ERR; }

    // Setting the Data Register (DR) transmits the byte of data on MOSI.
    SPIx->DR = data;

    //  Wait for any data on MISO pin to be received.
    timeout = SPI_DELAY;
    while (!(SPIx->SR & SPI_I2S_FLAG_RXNE)) { if(!timeout--) return SPI_ERR; }

    //  Return the data received on MISO pin.
    return (uint8_t)(SPIx->DR);
}

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

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


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

Размер задан - байт - SPI_DataSize_8b

На скопе на клоке вижу 16 бит - после передачи 8 бит посылает еще 8.

Я что то недонастроил?

Есть такая тема в F3.

Перепишите структуру так

typedef struct
{
  __IO uint16_t CR1;      /*!< SPI Control register 1 (not used in I2S mode),       Address offset: 0x00 */
  uint16_t  RESERVED0;    /*!< Reserved, 0x02                                                            */
  __IO uint16_t CR2;      /*!< SPI Control register 2,                              Address offset: 0x04 */
  uint16_t  RESERVED1;    /*!< Reserved, 0x06                                                            */
  __IO uint16_t SR;       /*!< SPI Status register,                                 Address offset: 0x08 */
  uint16_t  RESERVED2;    /*!< Reserved, 0x0A                                                            */
  union
  {
    __IO uint16_t DR16;   /*!< SPI data register,                                   Address offset: 0x0C */
    __IO uint8_t DR8;     /*!< SPI data register,                                   Address offset: 0x0C */
  };
  uint16_t  RESERVED3;    /*!< Reserved, 0x0E                                                            */
  __IO uint16_t CRCPR;    /*!< SPI CRC polynomial register (not used in I2S mode),  Address offset: 0x10 */
  uint16_t  RESERVED4;    /*!< Reserved, 0x12                                                            */
  __IO uint16_t RXCRCR;   /*!< SPI Rx CRC register (not used in I2S mode),          Address offset: 0x14 */
  uint16_t  RESERVED5;    /*!< Reserved, 0x16                                                            */
  __IO uint16_t TXCRCR;   /*!< SPI Tx CRC register (not used in I2S mode),          Address offset: 0x18 */
  uint16_t  RESERVED6;    /*!< Reserved, 0x1A                                                            */ 
  __IO uint16_t I2SCFGR;  /*!< SPI_I2S configuration register,                      Address offset: 0x1C */
  uint16_t  RESERVED7;    /*!< Reserved, 0x1E                                                            */
  __IO uint16_t I2SPR;    /*!< SPI_I2S prescaler register,                          Address offset: 0x20 */
  uint16_t  RESERVED8;    /*!< Reserved, 0x22                                                            */    
} SPI_TypeDef;

и для 8 и менее -битных посылках используйте SPIx->DR8, а для более 8-битных SPIx->DR16.

 

Добавлю, что это как раз тот случай, когда ответ можно найти в StdLib.

void SPI_SendData8(SPI_TypeDef* SPIx, uint8_t Data)
{
  uint32_t spixbase = 0x00;

  /* Check the parameters */
  assert_param(IS_SPI_ALL_PERIPH(SPIx));

  spixbase = (uint32_t)SPIx; 
  spixbase += 0x0C;
  
  *(__IO uint8_t *) spixbase = Data;
}

 

В RM это явление описано не очевидно.

When the SPIx_DR register is accessed, data frames are always right-aligned
into either a byte (if the data fits into a byte) or a half-word (see Figure 388). During
communication, only bits within the data frame are clocked and transferred.

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


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

Есть такая тема в F3.

большое спасибо. я подозревал что ST намутили, но уверенности не было.

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


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

Добавлю, что это как раз тот случай, когда ответ можно найти в StdLib.
Глядя на этот код хочется долго и настойчиво бить его автора головой об стену.

 

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


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

Глядя на этот код хочется долго и настойчиво бить его автора головой об стену.

а что в нем не так? на будущее. чтобы знать.

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


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

Глядя на этот код хочется долго и настойчиво бить его автора головой об стену.

Я для себя ничего лучшего, чем подправить структуру не придумал.

Да, вмешался в исходник StdLib, что не допустимо.

Да, не все компиляторы поддерживают анонимные структуры/объединения.

Да, ST мальца накосячили.

Есть еще варианты кроме прямого приведения типов?

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


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

а что в нем не так? на будущее. чтобы знать.
Поехали по буквам:

uint32_t spixbase = 0x00;

1)Придуманный специально для этого uintptr_t? Не, не слышали.

  spixbase = (uint32_t)SPIx; 
  spixbase += 0x0C;

2)Магические числа. Ну хоть стандартный макрос offsetof() можно было использовать вместо магичесого числа? Не, не слышали.

3)Почему не смогли взять сразу адрес SPIx->DR? Адресная арифметика, которую компилятор делает лучше криворукого программиста, тут делается вручную.

4)Переменная называется spixbase, хотя хранит совсем не base.

  *(__IO uint8_t *) spixbase = Data;

Ну наконец-то! Полэкрана кода ради одного-единственного явного приведения типа.

 

А что мешало вместо всего этого "шедевра" написать один макрос

#define SPI_SendData8(SPIx, data)   *(__IO uint8_t *)&SPIx->DR = data

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


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

А что мешало вместо всего этого "шедевра" написать один макрос

#define SPI_SendData8(SPIx, data)   *(__IO uint8_t *)&SPIx->DR = data

Полностью поддерживаю! Та функция - ну просто вырви-глаз какой-то! :laughing:

Ещё лучше регистр DR описать как union 16-битного и 8-битного. Тогда будет выглядеть ещё лучше. Я обычно так делаю.

 

Честно говоря - мне всегда противно смотреть на портянки типа:

  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
...

всегда пролистываю такие сообщения не глядя.

И это вместо, того чтобы задать блоки периферийных регистров в виде структур, а формировать битовые поля в них макросами (ну или просто номерами битов), что было бы красиво и эффективно.

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


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

и куда ж такому "программисту" как я податься? :-)

Вот и вынужден пользоваться только чужими достижениями.

 

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


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

и куда ж такому "программисту" как я податься? :-)

Вот и вынужден пользоваться только чужими достижениями.

Научитесь читать на техническом английском, и перед вами откроются многообещающие перспективы.

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


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

Научитесь читать на техническом английском, и перед вами откроются многообещающие перспективы.

 

Еще освоить сам язык Си.

 

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


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

...блоки периферийных регистров в виде структур, а формировать битовые поля в них макросами (ну или просто номерами битов), что было бы красиво и эффективно.

Символические имена, соответствующие даташиту или рефману, вместо "просто номеров битов" будут более красивы и существенно эффективны.

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


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

Чтобы не плодить тем, добавлю здесь.

Вчера у меня был фестиваль HardFault (

Зато вынес ценный опыт.

 

Ничто не предвещало..

post-33646-1522390996_thumb.png

 

Тадамм!!

post-33646-1522391010_thumb.png

 

В другом месте присвоение поля uint16_t в структуре падало так же, а копирование через memcpy проходило успешно.

Чтобы не мучать ребусами, обращаю внимание на адрес буфера данных.

 

HAL хорошая штука, но есть нюансы.

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


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

Чтобы не мучать ребусами, обращаю внимание на адрес буфера данных.

Типа данные не выровненные? А ядро какое?

На Cortex-M3 не выровненные данные не приводят к HF, а просто добавляют лишний такт (хотя можно заставить генерить исключение).

Вчера с аналогичной бедой боролся на Cortex-M0

typedef struct s_param
{
    int    v_int;
} __attribute__((packed)) s_param;
...
((s_param *)&out[p_out])->v_int += (in[p_in] - '0');

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


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

Вчера с аналогичной бедой боролся на Cortex-M0

Вот оно же и есть. Там вкладочка с халом отсвечивает

 

Кстати, если бы не криворукий пейсатель драйвера AD7799 c сайта analog.com, я бы никогда туда не залетел.

Они там в первый байт буфера кидают какой-то служебный байт, пришлось сдвинуть на один и здрасте.

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


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

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

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

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

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

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

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

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

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

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