本帖最后由 chenyuanjiyi 于 2020-8-21 16:16 编辑
前段时间在弄 SPI+DMA 配置好后,(刚开始是软件控制片选)我直接在读写数据前后加上拉低/拉高电平,但是出现这个现象,如图1/2。然后我就在读写函数后加上了等待,然后出现如图3/4现象。在片选拉低后,要等比较长时间才能开始读写数据。所以我就想通过控制硬件片选来读写数据,但是每读写一个数据,片选就自动拉高了,那么有什么方法可以拉低硬件片选,读写完多个字节再拉高吗?下面代码是 硬件片选和SPI+DMA的配置
/* SPI1 init function */
void MX_SPI1_Init(void)
{
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER; //设置SPI工作模式,设置为主模式
hspi1.Init.Direction = SPI_DIRECTION_2LINES; //设置SPI单向或者双向的数据模式:SPI设置为双线模式
hspi1.Init.DataSize = SPI_DATASIZE_8BIT; //设置SPI的数据大小:SPI发送接收8位帧结构
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; //串行同步时钟的空闲状态为低电平
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; //串行同步时钟的第一个跳变沿(上升或下降)数据被采样
hspi1.Init.NSS = SPI_NSS_HARD_OUTPUT; //NSS信号由软件控制 SPI_NSS_HARD_OUTPUT SPI_NSS_SOFT
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; //定义波特率预分频的值:波特率预分频值为4
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
hspi1.Init.TIMode = SPI_TIMODE_DISABLE; //关闭TI模式
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; //关闭硬件CRC校验
hspi1.Init.CRCPolynomial = 7; //CRC值计算的多项式
hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;//SPI_NSS_PULSE_DISABLE; //
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(spiHandle->Instance==SPI1)
{
/* USER CODE BEGIN SPI1_MspInit 0 */
/* USER CODE END SPI1_MspInit 0 */
/* SPI1 clock enable */
__HAL_RCC_SPI1_CLK_ENABLE();
/**SPI1 GPIO Configuration
PB3 ------> SPI1_SCK
PB4 ------> SPI1_MISO
PB5 ------> SPI1_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = A7106_SCK_Pin|A7106_MISO_Pin|A7106_MOSI_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* SPI1 DMA Init */
/* SPI1_TX Init */
hdma_spi1_tx.Instance = DMA1_Channel3; //通道选择
hdma_spi1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; //存储器到外设
hdma_spi1_tx.Init.PeriphInc = DMA_PINC_DISABLE; //外设非增量模式
hdma_spi1_tx.Init.MemInc = DMA_MINC_ENABLE; //存储器增量模式
hdma_spi1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; //外设数据长度:8位
hdma_spi1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; //存储器数据长度:8位
hdma_spi1_tx.Init.Mode = DMA_NORMAL; //DMA普通模式
hdma_spi1_tx.Init.Priority = DMA_PRIORITY_HIGH;
if (HAL_DMA_Init(&hdma_spi1_tx) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
__HAL_LINKDMA(spiHandle,hdmatx,hdma_spi1_tx);
/* SPI1_RX Init */
hdma_spi1_rx.Instance = DMA1_Channel2;
hdma_spi1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_spi1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi1_rx.Init.Mode = DMA_NORMAL;
hdma_spi1_rx.Init.Priority = DMA_PRIORITY_HIGH;
if (HAL_DMA_Init(&hdma_spi1_rx) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
__HAL_LINKDMA(spiHandle,hdmarx,hdma_spi1_rx);
/* USER CODE BEGIN SPI1_MspInit 1 */
/* USER CODE END SPI1_MspInit 1 */
}
}
D:\Documents\Desktop\1.png
D:\Documents\Desktop\2.png
D:\Documents\Desktop\3.png
D:\Documents\Desktop\4.png |