jenya7 0 27 марта, 2018 Опубликовано 27 марта, 2018 (изменено) · Жалоба Камень 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); } Изменено 27 марта, 2018 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 27 марта, 2018 Опубликовано 27 марта, 2018 · Жалоба Размер задан - байт - 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. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 27 марта, 2018 Опубликовано 27 марта, 2018 · Жалоба Есть такая тема в F3. большое спасибо. я подозревал что ST намутили, но уверенности не было. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 136 27 марта, 2018 Опубликовано 27 марта, 2018 · Жалоба Добавлю, что это как раз тот случай, когда ответ можно найти в StdLib.Глядя на этот код хочется долго и настойчиво бить его автора головой об стену. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 27 марта, 2018 Опубликовано 27 марта, 2018 · Жалоба Глядя на этот код хочется долго и настойчиво бить его автора головой об стену. а что в нем не так? на будущее. чтобы знать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 27 марта, 2018 Опубликовано 27 марта, 2018 · Жалоба Глядя на этот код хочется долго и настойчиво бить его автора головой об стену. Я для себя ничего лучшего, чем подправить структуру не придумал. Да, вмешался в исходник StdLib, что не допустимо. Да, не все компиляторы поддерживают анонимные структуры/объединения. Да, ST мальца накосячили. Есть еще варианты кроме прямого приведения типов? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 136 27 марта, 2018 Опубликовано 27 марта, 2018 · Жалоба а что в нем не так? на будущее. чтобы знать.Поехали по буквам: 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 27 марта, 2018 Опубликовано 27 марта, 2018 · Жалоба А что мешало вместо всего этого "шедевра" написать один макрос #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; ... всегда пролистываю такие сообщения не глядя. И это вместо, того чтобы задать блоки периферийных регистров в виде структур, а формировать битовые поля в них макросами (ну или просто номерами битов), что было бы красиво и эффективно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
serglg 0 28 марта, 2018 Опубликовано 28 марта, 2018 · Жалоба и куда ж такому "программисту" как я податься? :-) Вот и вынужден пользоваться только чужими достижениями. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 28 марта, 2018 Опубликовано 28 марта, 2018 · Жалоба и куда ж такому "программисту" как я податься? :-) Вот и вынужден пользоваться только чужими достижениями. Научитесь читать на техническом английском, и перед вами откроются многообещающие перспективы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
serglg 0 28 марта, 2018 Опубликовано 28 марта, 2018 · Жалоба Научитесь читать на техническом английском, и перед вами откроются многообещающие перспективы. Еще освоить сам язык Си. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 38 28 марта, 2018 Опубликовано 28 марта, 2018 · Жалоба ...блоки периферийных регистров в виде структур, а формировать битовые поля в них макросами (ну или просто номерами битов), что было бы красиво и эффективно. Символические имена, соответствующие даташиту или рефману, вместо "просто номеров битов" будут более красивы и существенно эффективны. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 23 30 марта, 2018 Опубликовано 30 марта, 2018 · Жалоба Чтобы не плодить тем, добавлю здесь. Вчера у меня был фестиваль HardFault ( Зато вынес ценный опыт. Ничто не предвещало.. Тадамм!! В другом месте присвоение поля uint16_t в структуре падало так же, а копирование через memcpy проходило успешно. Чтобы не мучать ребусами, обращаю внимание на адрес буфера данных. HAL хорошая штука, но есть нюансы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 30 марта, 2018 Опубликовано 30 марта, 2018 · Жалоба Чтобы не мучать ребусами, обращаю внимание на адрес буфера данных. Типа данные не выровненные? А ядро какое? На 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'); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 23 30 марта, 2018 Опубликовано 30 марта, 2018 · Жалоба Вчера с аналогичной бедой боролся на Cortex-M0 Вот оно же и есть. Там вкладочка с халом отсвечивает Кстати, если бы не криворукий пейсатель драйвера AD7799 c сайта analog.com, я бы никогда туда не залетел. Они там в первый байт буфера кидают какой-то служебный байт, пришлось сдвинуть на один и здрасте. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться