当前位置:网站首页>STM32F103 SPI (pit Diary)
STM32F103 SPI (pit Diary)
2022-07-03 07:49:00 【Seven demons 71】
SPI Study
Preface
The first 1 Partially targeted spi Basic knowledge of
The first 2、3 Part is the pit encountered in use and my own understanding . You are also welcome to point out the mistakes in the article 、 correct .
You can read selectively .
1.SPI agreement
SPI It's a serial peripheral interface (Serial Peripheral Interface) Abbreviation , It's a high speed , full duplex , Synchronous communication bus , And only four wires are used on the chip pins . They are 4 root
- MISO– Master Input Slave Output, Main equipment data input , Output data from device ;
- MOSI– Master Output Slave Input, Main device data output , From device data input ;
- SCLK – Serial Clock, Clock signal , Generated by the main equipment ;
- CS – Chip Select, Slave enable signal , Controlled by the main equipment .
1.1SPI Of 4 Patterns
spi Of 4 One mode is through CPOL and CPHA Set up 0 and 1 To decide . Arrange and combine them, a total of 4 Kind of :
CPOL: SPI Idle clock signal level (1: High level , 0: Low level )
CPHA: SPI On the edge of the clock (1: The second edge starts , 0: The first edge starts )
So in STM32 Is embodied in this structure ( With Ellipsis ):
typedef struct
{
......
uint16_t SPI_CPOL; /*!< Specifies the serial clock steady state. This parameter can be a value of @ref SPI_Clock_Polarity */
uint16_t SPI_CPHA; /*!< Specifies the clock active edge for the bit capture. ...... }SPI_InitTypeDef;
This side needs to be based on the slave station datasheet To configure the , For example, the following sequence diagram :
SCLK The default is high , from sck The second edge of the collects data bits , therefore :
CPOL=1;
CPHA=1;
2. STM32F103 Hardware SPI
STMf103 Of SPI->DR Register is a 16 Bit , From the reference manual F1 Chip support 8 Bit and 16 Bit data transmission , adopt SPI->CR1 Of DFF The flag bit determines that the transmitted data is 8 A still 16 position . This also needs to refer to the slave station datasheet To decide . Main mode baud rate prescaler coefficient ( The maximum is fPCLK/2) , therefore SPI You can get a maximum score 36MHz The frequency of . About SPI Send function for , Standard library function version and HAL Library provides two solutions :
2.1 Standard library sending function
/** * @brief Transmits a Data through the SPIx/I2Sx peripheral. * @param SPIx: where x can be * - 1, 2 or 3 in SPI mode * - 2 or 3 in I2S mode * @param Data : Data to be transmitted. * @retval None */
void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data)
{
/* Check the parameters */
assert_param(IS_SPI_ALL_PERIPH(SPIx));
/* Write in the DR register the data to be sent */
SPIx->DR = Data;
}
assert_param
This assertion can be ignored , In fact, it is to write the data DR register , There is no judgment . So generally, when we use it, we timeout to jump out and check whether the sending is successful , as follows :
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) // Check the specified SPI Flag bit setting or not : Send cache empty flag bit
{
retry++;
if(retry>200)return 0;// retry 200 Time
}
But to perform retry++ and SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET Take up CPU Time , This can lead to SPI Discontinuous transmission occurs during transmission. See 3. section .
2.2 HAL Library send function
HAL The sending function of the library is relatively long , I made a deletion here, just look 8 The process of sending bits .
HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
.......
/* Set the transaction information */
hspi->State = HAL_SPI_STATE_BUSY_TX;
hspi->ErrorCode = HAL_SPI_ERROR_NONE;
hspi->pTxBuffPtr = (uint8_t *)pData;
hspi->TxXferSize = Size;
hspi->TxXferCount = Size;
.......
while (hspi->TxXferCount > 0U)
{
/* Wait until TXE flag is set to send data */
if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE))
{
*((__IO uint8_t *)&hspi->Instance->DR) = (*hspi->pTxBuffPtr);
hspi->pTxBuffPtr += sizeof(uint8_t);
hspi->TxXferCount--;
}
else
{
/* Timeout management */
if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
{
errorcode = HAL_TIMEOUT;
goto error;
}
}
}
}
The core part of the :
if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE))
*((__IO uint8_t *)&hspi->Instance->DR) = (*hspi->pTxBuffPtr);
It is also to check the transmission completion flag bit and write data to DR In the register . however HAL The better thing about the library is that it supports writing data length . Generally, we don't just write 8 position , Generally, an instruction has 32 Bit or longer ,HAL I only need to provide a first address for the encapsulation of the Library , hold Size Set it to the corresponding length . Click the jump
2.2.1 There's a little pit here
The data stored in the single chip microcomputer is stored in the small end format , But often the data is sent in big format .
For example, I want to send 01 02 03 04
But we can easily save :
uint32_t data =0x01020304
And then put *pData Point to data The address of , Then through the SPI The data sent out will become 04 03 02 01
So the big end and small end conversion requires software to do the conversion .
3. SPI Continuous transmission and discontinuous transmission
Prerequisite , The setting here is 8 Bit spi transmission , First look at the transmission 32 The difference between time sequence diagram of bit data :
When sending data in main mode , If the software is fast enough , Can detect every TXE The rising edge of ( or TXE interrupt ), And write immediately before the end of the ongoing transfer SPI_DR register , Can realize continuous communication ; here , Between the transmission of each data item SPI The clock remains continuous , meanwhile BSY Bits will not be cleared . If the software is not fast enough , Will result in discontinuous communication ; At this time , It will be cleared between each data transmission
From this description , As long as you write the data fast enough , He can transmit continuously . This is obviously not reliable ,SPI The faster the speed, the faster the software writes . So how to give full play ST Hardware SPI The performance of ? Turn on DMA Pattern .
4.SPI+DMA Transmitted pit
According to oneself SPI Channel selection DMA To configure , Use STM32Cube To configure
This is a sending function I wrote , But when grasping the waveform, I found that the data sent was wrong , But don't use DMA Sending is normal . It took a long time to find the problem .
int sgm5349_RegWrite(sgm5349Device_t *device, uint8_t channel, uint16_t data, uint8_t update){
HAL_StatusTypeDef status = HAL_OK;
uint32_t regVal = 0;
/* Input Validation Check */
if(device == NULL) return -1;
if(isChannelValid(channel) != 0) return -1;
/* 32bit register value generation with command = 0 or 2 or 3*/
regVal = (channel << 20) | (data << 4);
if(update == 1) regVal |= (3 << 24);
else if(update == 2) regVal |= (2 << 24);
regVal = LittleEndian2BigEndian(regVal);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,0);
HAL_SPI_Transmit_DMA(device->hspi, (uint8_t *)®Val, 4);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,1);
if(status != HAL_OK) return (int)status;
return 0;
}
DMA The sending code is as follows ( Part omitted ):
HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
{
......
/* Set the transaction information */
hspi->State = HAL_SPI_STATE_BUSY_TX;
hspi->ErrorCode = HAL_SPI_ERROR_NONE;
hspi->pTxBuffPtr = (uint8_t *)pData;
hspi->TxXferSize = Size;
hspi->TxXferCount = Size;
/* Enable the Tx DMA Stream/Channel */
if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->DR,
hspi->TxXferCount))
{
/* Update SPI error code */
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
errorcode = HAL_ERROR;
hspi->State = HAL_SPI_STATE_READY;
goto error;
}
......
}
The problem is DMA In the send function ,(uint32_t)hspi->pTxBuffPtr
Forced into the address of the data . But we are HAL_SPI_Transmit_DMA
Is a local variable regVal
. When you jump out sgm5349_RegWrite
Function, the local variable will be released regVal
, Then the address of this local variable is meaningless . So I did a simple test and added a delay , Can send data normally . Of course, we can't actually do this , You can add local variables +static
modification , You can also let the program solve this problem by querying and sending the completion flag bit dead .
Finally, a complete continuous SPI Data sending
边栏推荐
- 【MySQL 14】使用DBeaver工具远程备份及恢复MySQL数据库(Linux 环境)
- yarn link 是如何帮助开发者对 NPM 包进行 debug 的?
- [MySQL 13] if you change your password for the first time after installing mysql, you can skip MySQL password verification to log in
- 技术干货|昇思MindSpore初级课程上线:从基本概念到实操,1小时上手!
- Technical dry goods Shengsi mindspire elementary course online: from basic concepts to practical operation, 1 hour to start!
- Pat class a 1032 sharing
- 微软安全响应中心
- Go language foundation ------17 ----- channel creation, read-write, security shutdown, multiplexing select
- Lucene hnsw merge optimization
- Project experience sharing: realize an IR Fusion optimization pass of Shengsi mindspire layer
猜你喜欢
Technical dry goods | reproduce iccv2021 best paper swing transformer with Shengsi mindspire
Technical dry goods Shengsi mindspire operator parallel + heterogeneous parallel, enabling 32 card training 242 billion parameter model
PAT甲级 1029 Median
Research shows that breast cancer cells are more likely to enter the blood when patients sleep
Pat grade a 1029 median
Pat class a 1028 list sorting
[MySQL 14] use dbeaver tool to remotely backup and restore MySQL database (Linux Environment)
Go language foundation ----- 02 ----- basic data types and operators
Harmonyos third training notes
Technology dry goods | luxe model for the migration of mindspore NLP model -- reading comprehension task
随机推荐
Structure of golang
什么是定义?什么是声明?它们有何区别?
yarn link 是如何帮助开发者对 NPM 包进行 debug 的?
Professor Zhang Yang of the University of Michigan is employed as a visiting professor of Shanghai Jiaotong University, China (picture)
Lucene merge document order
Client server model
PHP wechat red packet grabbing algorithm
Traversal in Lucene
优质博客——
Go language foundation ----- 06 ----- anonymous fields, fields with the same name
Hnsw introduction and some reference articles in lucene9
LwIP learning socket (API)
[at] abc 258G - Triangle 三元組可達-暴力
Go language foundation ------ 12 ------ JSON
Technical dry goods | thinking about the unification of dynamic and static diagrams of AI framework
[MySQL 13] if you change your password for the first time after installing mysql, you can skip MySQL password verification to log in
HDMI2.1与HDMI2.0的区别以及转换PD信号。
Technical dry goods Shengsi mindspire dynamic transformer with variable sequence length has been released!
在浏览器输入url后执行什么
What to do after the browser enters the URL