当前位置: 首页> 房产> 建筑 > 生活分类信息网站大全_揭阳建网站_搜索引擎优化的技巧_深圳网络推广公司排名

生活分类信息网站大全_揭阳建网站_搜索引擎优化的技巧_深圳网络推广公司排名

时间:2025/7/13 9:01:39来源:https://blog.csdn.net/LongRunning/article/details/143478710 浏览次数:0次
生活分类信息网站大全_揭阳建网站_搜索引擎优化的技巧_深圳网络推广公司排名

1. SPI基础

  1. 物理层

在这里插入图片描述

  • 片选线 :选中拉低
  • SCK: 时钟线
  • MOSI:主出从入
  • MISO:主入从出
  1. 协议层
    在这里插入图片描述
    CPOL:时钟极性:空闲电平高低
    CPHA:时钟相位:第一个还是第二个边沿采样
    在这里插入图片描述

在这里插入图片描述

2. 示例SPI-W25Q16 (见模组分类下文章)

3. SPI+DMA

//返回当前DMA通道传输中剩余数据单元的数量
/*** @brief  Return the number of remaining data units in the current DMA Channel transfer.* @param  __HANDLE__ DMA handle* @retval The number of remaining data units in the current DMA Channel transfer.*/
#define __HAL_DMA_GET_COUNTER(__HANDLE__) ((__HANDLE__)->Instance->CNDTR)//判断DMA中数据传输是否完成
while(__HAL_DMA_GET_COUNTER(&hdma_spi1_tx) != 0);
  1. SPI使用软件控制片选,使用DMA,一定等传输完成之后才能拉高片选
    请看下面的代码举例:
 while (1){/* USER CODE END WHILE */HAL_GPIO_WritePin(GPIOA,GPIO_PIN_15,GPIO_PIN_RESET);HAL_SPI_TransmitReceive_DMA(&hspi1,txbuff,rxbuff,8);HAL_GPIO_WritePin(GPIOA,GPIO_PIN_15,GPIO_PIN_SET);}

在这里插入图片描述
发现现象: SPI数据还没有传输完成,但片选已经拉高了。。。

  • 解决思路1:判断DMA传输是否完成
//拉低片选
//SPI-DMA传输
//传输完成
//拉高片选
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_15,GPIO_PIN_RESET);
HAL_SPI_TransmitReceive_DMA(&hspi1,txbuff,rxbuff,8);
while(__HAL_DMA_GET_COUNTER(&hdma_spi1_rx)!=0);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_15,GPIO_PIN_SET);
  • 解决思路2:在发送完成中断回调中拉高片选
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{LOG_OUT("SPI tx finish\r\n");//拉高片选
}
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{LOG_OUT("SPI rx finish\r\n");//拉高片选
}
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{LOG_OUT("SPI rx finish\r\n");//拉高片选
}
  • SPI,中断,DMA相关的函数接口如下

/** @addtogroup SPI_Exported_Functions_Group2* @{*/
/* I/O operation functions  ***************************************************/
HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size,uint32_t Timeout);
HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData,uint16_t Size);
HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData,uint16_t Size);
HAL_StatusTypeDef HAL_SPI_DMAPause(SPI_HandleTypeDef *hspi);
HAL_StatusTypeDef HAL_SPI_DMAResume(SPI_HandleTypeDef *hspi);
HAL_StatusTypeDef HAL_SPI_DMAStop(SPI_HandleTypeDef *hspi);
/* Transfer Abort functions */
HAL_StatusTypeDef HAL_SPI_Abort(SPI_HandleTypeDef *hspi);
HAL_StatusTypeDef HAL_SPI_Abort_IT(SPI_HandleTypeDef *hspi);void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi);
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi);
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi);
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi);
void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi);
void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi);
void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi);
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi);
void HAL_SPI_AbortCpltCallback(SPI_HandleTypeDef *hspi);

网友链接

4. W25Q16-SPI-DMA示例


void spi_dma_wait_tx_end(uint32_t time_t)
{uint32_t ret = 0;uint32_t time = 0;do{SPI_Delay(1);ret = __HAL_DMA_GET_COUNTER(&hdma_spi1_tx);time++;}while(ret !=0 && time < time_t);LOG_OUT("t=%d %d\r\n",ret,time);
}
void spi_dma_wait_rx_end(uint32_t time_t)
{uint32_t ret = 0;uint32_t time = 0;do{SPI_Delay(1);ret = __HAL_DMA_GET_COUNTER(&hdma_spi1_rx);time++;}while(ret !=0 && time < time_t);LOG_OUT("r=%d %d\r\n",ret,time);
}/*
函数参数: SPI-DMA1、T_pData:发送数据缓冲区中取出数据发送出去2、T_Size :需要发送的数据的长度
*/
static HAL_StatusTypeDef bsp_w25q_Transmit(uint8_t * T_pData, uint16_t T_Size)
{
#if  USE_SPI_DMAuint8_t ret = HAL_SPI_Transmit_DMA(&W25Q_SPI, T_pData, T_Size);spi_dma_wait_tx_end(0xFFFF);return ret;
#elsereturn HAL_SPI_Transmit(&W25Q_SPI, T_pData, T_Size, 0xFFFF);
#endif
}/*
函数参数: SPI-DMA1、R_pData:接收数据并放置到接收数据缓冲区中2、R_Size :需要接收的数据的长度
*/
static HAL_StatusTypeDef bsp_w25q_Receive(uint8_t * R_pData, uint16_t R_Size)
{
#if  USE_SPI_DMAuint8_t ret = HAL_SPI_Receive_DMA(&W25Q_SPI, R_pData, R_Size);spi_dma_wait_rx_end(0xFFFF);return ret;
#elsereturn HAL_SPI_Receive(&W25Q_SPI, R_pData, R_Size, 0xFFFF);
#endif
}

/*
读ID描述:读3个字节分别是生产厂家、存储器类型、容量
*/
HAL_StatusTypeDef Bsp_Read_Jedec_ID(uint8_t * R_Jedec_ID)
{uint8_t read_id[3] = {0};uint8_t cmd = W25Q_JEDEC_ID;HAL_StatusTypeDef STD = HAL_ERROR;Bsp_Judge_Busy();W25Q_CS_Level(0);SPI_Delay(1);if(bsp_w25q_Transmit(&cmd, 1) == HAL_OK){if(bsp_w25q_Receive(read_id, 3) == HAL_OK){STD = HAL_OK;}}W25Q_CS_Level(1);if(STD == HAL_OK){LOG_OUT("read_id= %x %x %x\r\n", read_id[0], read_id[1], read_id[2]);}else{LOG_OUT("read_id= err\r\n");}return STD;
}
关键字:生活分类信息网站大全_揭阳建网站_搜索引擎优化的技巧_深圳网络推广公司排名

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: