程序如下当将配置文件中的SPI3改为SPI1后HAL_SPI_TransmitReceive能够正常执行,当为SPI3时HAL_SPI_TransmitReceive就返回错误
#define SPIx SPI3
#define SPIx_CLK_ENABLE() __HAL_RCC_SPI3_CLK_ENABLE()
#define DMAx_CLK_ENABLE() __HAL_RCC_DMA2_CLK_ENABLE()
#define SPIx_FORCE_RESET() __HAL_RCC_SPI3_FORCE_RESET()
#define SPIx_RELEASE_RESET() __HAL_RCC_SPI3_RELEASE_RESET()
#define SPIx_SCK_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define SPIx_SCK_GPIO GPIOB
#define SPIx_SCK_PIN GPIO_PIN_3
#define SPIx_SCK_AF GPIO_AF5_SPI3
#define SPIx_MISO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define SPIx_MISO_GPIO GPIOB
#define SPIx_MISO_PIN GPIO_PIN_4
#define SPIx_MISO_AF GPIO_AF5_SPI3
#define SPIx_MOSI_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define SPIx_MOSI_GPIO GPIOB
#define SPIx_MOSI_PIN GPIO_PIN_5
#define SPIx_MOSI_AF GPIO_AF5_SPI3
#define ADE7953SPIx_CS_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
#define ADE7953SPIx_CS_GPIO GPIOE
#define ADE7953SPIx_CS_PIN GPIO_PIN_0
#define ADE7953SPIx_RST_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
#define ADE7953SPIx_RST_GPIO GPIOE
#define ADE7953SPIx_RST_PIN GPIO_PIN_1
#define SPIx_TX_DMA_STREAM DMA2_Stream3
#define SPIx_RX_DMA_STREAM DMA2_Stream2
#define SPIx_TX_DMA_REQUEST DMA_REQUEST_SPI3_TX
#define SPIx_RX_DMA_REQUEST DMA_REQUEST_SPI3_RX
#define SPIx_DMA_TX_IRQn DMA2_Stream3_IRQn
#define SPIx_DMA_RX_IRQn DMA2_Stream2_IRQn
#define SPIx_DMA_TX_IRQHandler DMA2_Stream3_IRQHandler
#define SPIx_DMA_RX_IRQHandler DMA2_Stream2_IRQHandler
#define SPIx_IRQn SPI3_IRQn
#define SPIx_IRQHandler SPI3_IRQHandler
#define AD7953_CS0() HAL_GPIO_WritePin(GPIOE,GPIO_PIN_0,GPIO_PIN_RESET)
#define AD7953_CS1() HAL_GPIO_WritePin(GPIOE,GPIO_PIN_0,GPIO_PIN_SET)
#define AD7953_RST0() HAL_GPIO_WritePin(GPIOE,GPIO_PIN_1,GPIO_PIN_RESET)
#define AD7953_RST1() HAL_GPIO_WritePin(GPIOE,GPIO_PIN_1,GPIO_PIN_SET)
enum {
TRANSFER_WAIT,
TRANSFER_COMPLETE,
TRANSFER_ERROR
};
void delay(uint32_t us)
{
uint32_t i=0;
for(i=us;i>0;i--)
{
__NOP();
}
}
/*
*********************************************************************************************************
* 变量
*********************************************************************************************************
*/
static SPI_HandleTypeDef hspi = {0};
static DMA_HandleTypeDef hdma_tx;
static DMA_HandleTypeDef hdma_rx;
static uint32_t s_BaudRatePrescaler;
static uint32_t s_CLKPhase;
static uint32_t s_CLKPolarity;
uint32_t g_spiLen;
uint8_t g_spi_busy; /* SPI忙状态,0表示不忙,1表示忙 */
__IO uint32_t wTransferState = TRANSFER_WAIT;
/* 查询模式 */
#if defined (USE_SPI_POLL)
uint8_t g_spiTxBuf[SPI_BUFFER_SIZE];
uint8_t g_spiRxBuf[SPI_BUFFER_SIZE];
/* 中断模式 */
#elif defined (USE_SPI_INT)
uint8_t g_spiTxBuf[SPI_BUFFER_SIZE];
uint8_t g_spiRxBuf[SPI_BUFFER_SIZE];
/* DMA模式使用的SRAM4 */
#elif defined (USE_SPI_DMA)
#if defined ( __CC_ARM ) /* IAR *******/
__attribute__((section (".RAM_D3"))) uint8_t g_spiTxBuf[SPI_BUFFER_SIZE];
__attribute__((section (".RAM_D3"))) uint8_t g_spiRxBuf[SPI_BUFFER_SIZE];
#elif defined (__ICCARM__) /* MDK ********/
#pragma location = ".RAM_D3"
uint8_t g_spiTxBuf[SPI_BUFFER_SIZE];
#pragma location = ".RAM_D3"
uint8_t g_spiRxBuf[SPI_BUFFER_SIZE];
#endif
#endif
/*
*********************************************************************************************************
* 函 数 名: bsp_InitSPIBus
* 功能说明: 配置SPI总线。
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void bsp_InitSPIBus(void)
{
g_spi_busy = 0;
bsp_InitSPIParam(SPI_BAUDRATEPRESCALER_64, SPI_PHASE_2EDGE, SPI_POLARITY_HIGH);
}
/*
*********************************************************************************************************
* 函 数 名: bsp_InitSPIParam
* 功能说明: 配置SPI总线参数,时钟分频,时钟相位和时钟极性。
* 形 参: _BaudRatePrescaler SPI总线时钟分频设置,支持的参数如下:
* SPI_BAUDRATEPRESCALER_2 2分频
* SPI_BAUDRATEPRESCALER_4 4分频
* SPI_BAUDRATEPRESCALER_8 8分频
* SPI_BAUDRATEPRESCALER_16 16分频
* SPI_BAUDRATEPRESCALER_32 32分频
* SPI_BAUDRATEPRESCALER_64 64分频
* SPI_BAUDRATEPRESCALER_128 128分频
* SPI_BAUDRATEPRESCALER_256 256分频
*
* _CLKPhase 时钟相位,支持的参数如下:
* SPI_PHASE_1EDGE SCK引脚的第1个边沿捕获传输的第1个数据
* SPI_PHASE_2EDGE SCK引脚的第2个边沿捕获传输的第1个数据
*
* _CLKPolarity 时钟极性,支持的参数如下:
* SPI_POLARITY_LOW SCK引脚在空闲状态处于低电平
* SPI_POLARITY_HIGH SCK引脚在空闲状态处于高电平
*
* 返 回 值: 无
*********************************************************************************************************
*/
void bsp_InitSPIParam(uint32_t _BaudRatePrescaler, uint32_t _CLKPhase, uint32_t _CLKPolarity)
{
/* 提高执行效率,只有在SPI硬件参数发生变化时,才执行HAL_Init */
if (s_BaudRatePrescaler == _BaudRatePrescaler && s_CLKPhase == _CLKPhase && s_CLKPolarity == _CLKPolarity)
{
return;
}
s_BaudRatePrescaler = _BaudRatePrescaler;
s_CLKPhase = _CLKPhase;
s_CLKPolarity = _CLKPolarity;
/* 设置SPI参数 */
hspi.Instance = SPIx; /* 例化SPI */
hspi.Init.BaudRatePrescaler = _BaudRatePrescaler; /* 设置波特率 */
hspi.Init.Direction = SPI_DIRECTION_2LINES; /* 全双工 */
hspi.Init.CLKPhase = _CLKPhase; /* 配置时钟相位 */
hspi.Init.CLKPolarity = _CLKPolarity; /* 配置时钟极性 */
hspi.Init.DataSize = SPI_DATASIZE_8BIT; /* 设置数据宽度 */
hspi.Init.FirstBit = SPI_FIRSTBIT_MSB; /* 数据传输先传高位 */
hspi.Init.TIMode = SPI_TIMODE_DISABLE; /* 禁止TI模式 */
hspi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; /* 禁止CRC */
hspi.Init.CRCPolynomial = 7; /* 禁止CRC后,此位无效 */
hspi.Init.CRCLength = SPI_CRC_LENGTH_8BIT; /* 禁止CRC后,此位无效 */
hspi.Init.NSS = SPI_NSS_SOFT; /* 使用软件方式管理片选引脚 */
hspi.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA; /* 设置FIFO大小是一个数据项 */
hspi.Init.NSSPMode = SPI_NSS_PULSE_DISABLE; /* 禁止脉冲输出 */
hspi.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_ENABLE; /* 禁止SPI后,SPI相关引脚保持当前状态 */
hspi.Init.Mode = SPI_MODE_MASTER; /* SPI工作在主控模式 */
/* 复位配置 */
if (HAL_SPI_DeInit(&hspi) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
/* 初始化配置 */
if (HAL_SPI_Init(&hspi) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
}
/*
*********************************************************************************************************
* 函 数 名: bsp_InitSPIParam
* 功能说明: 配置SPI总线时钟,GPIO,中断,DMA等
* 形 参: SPI_HandleTypeDef 类型指针变量
* 返 回 值: 无
*********************************************************************************************************
*/
void HAL_SPI_MspInit(SPI_HandleTypeDef *_hspi)
{
/* 配置 SPI总线GPIO : SCK MOSI MISO */
{
GPIO_InitTypeDef GPIO_InitStruct;
/* SPI和GPIP时钟 */
SPIx_SCK_CLK_ENABLE();
SPIx_MISO_CLK_ENABLE();
SPIx_MOSI_CLK_ENABLE();
ADE7953SPIx_CS_CLK_ENABLE();
SPIx_CLK_ENABLE();
/* SPI SCK */
GPIO_InitStruct.Pin = SPIx_SCK_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.Alternate = SPIx_SCK_AF;
HAL_GPIO_Init(SPIx_SCK_GPIO, &GPIO_InitStruct);
/* SPI MISO */
GPIO_InitStruct.Pin = SPIx_MISO_PIN;
GPIO_InitStruct.Alternate = SPIx_MISO_AF;
HAL_GPIO_Init(SPIx_MISO_GPIO, &GPIO_InitStruct);
/* SPI MOSI */
GPIO_InitStruct.Pin = SPIx_MOSI_PIN;
GPIO_InitStruct.Alternate = SPIx_MOSI_AF;
HAL_GPIO_Init(SPIx_MOSI_GPIO, &GPIO_InitStruct);
GPIO_InitStruct.Pin = ADE7953SPIx_CS_PIN|ADE7953SPIx_RST_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
HAL_GPIO_Init(ADE7953SPIx_CS_GPIO, &GPIO_InitStruct);
delay(10000);
AD7953_RST0();
delay(10000);
AD7953_RST1();
}
/* 配置DMA和NVIC */
#ifdef USE_SPI_DMA
{
/* 使能DMA时钟 */
DMAx_CLK_ENABLE();
/* SPI DMA发送配置 */
hdma_tx.Instance = SPIx_TX_DMA_STREAM; /* 例化使用的DMA数据流 */
hdma_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; /* 禁止FIFO*/
hdma_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; /* 禁止FIFO此位不起作用,用于设置阀值 */
hdma_tx.Init.MemBurst = DMA_MBURST_SINGLE; /* 禁止FIFO此位不起作用,用于存储器突发 */
hdma_tx.Init.PeriphBurst = DMA_PBURST_SINGLE; /* 禁止FIFO此位不起作用,用于外设突发 */
hdma_tx.Init.Request = SPIx_TX_DMA_REQUEST; /* 请求类型 */
hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; /* 传输方向是从存储器到外设 */
hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE; /* 外设地址自增禁止 */
hdma_tx.Init.MemInc = DMA_MINC_ENABLE; /* 存储器地址自增使能 */
hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; /* 外设数据传输位宽选择字节,即8bit */
hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; /* 存储器数据传输位宽选择字节,即8bit */
hdma_tx.Init.Mode = DMA_NORMAL; /* 正常模式 */
hdma_tx.Init.Priority = DMA_PRIORITY_LOW; /* 优先级低 */
/* 复位DMA */
if(HAL_DMA_DeInit(&hdma_tx) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
/* 初始化DMA */
if(HAL_DMA_Init(&hdma_tx) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
/* 关联DMA句柄到SPI */
__HAL_LINKDMA(_hspi, hdmatx, hdma_tx);
/* SPI DMA接收配置 */
hdma_rx.Instance = SPIx_RX_DMA_STREAM; /* 例化使用的DMA数据流 */
hdma_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; /* 禁止FIFO*/
hdma_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;/* 禁止FIFO此位不起作用,用于设置阀值 */
hdma_rx.Init.MemBurst = DMA_MBURST_SINGLE; /* 禁止FIFO此位不起作用,用于存储器突发 */
hdma_rx.Init.PeriphBurst = DMA_PBURST_SINGLE; /* 禁止FIFO此位不起作用,用于外设突发 */
hdma_rx.Init.Request = SPIx_RX_DMA_REQUEST; /* 请求类型 */
hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; /* 传输方向从外设到存储器 */
hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE; /* 外设地址自增禁止 */
hdma_rx.Init.MemInc = DMA_MINC_ENABLE; /* 存储器地址自增使能 */
hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; /* 外设数据传输位宽选择字节,即8bit */
hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; /* 存储器数据传输位宽选择字节,即8bit */
hdma_rx.Init.Mode = DMA_NORMAL; /* 正常模式 */
hdma_rx.Init.Priority = DMA_PRIORITY_HIGH; /* 优先级低 */
/* 复位DMA */
if(HAL_DMA_DeInit(&hdma_rx) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
/* 初始化DMA */
if(HAL_DMA_Init(&hdma_rx) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
/* 关联DMA句柄到SPI */
__HAL_LINKDMA(_hspi, hdmarx, hdma_rx);
/* 配置DMA发送中断 */
HAL_NVIC_SetPriority(SPIx_DMA_TX_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(SPIx_DMA_TX_IRQn);
/* 配置DMA接收中断 */
HAL_NVIC_SetPriority(SPIx_DMA_RX_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(SPIx_DMA_RX_IRQn);
/* 配置SPI中断 */
HAL_NVIC_SetPriority(SPIx_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(SPIx_IRQn);
}
#endif
#ifdef USE_SPI_INT
/* 配置SPI中断优先级并使能中断 */
HAL_NVIC_SetPriority(SPIx_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(SPIx_IRQn);
#endif
}
/*
*********************************************************************************************************
* 函 数 名: bsp_spiTransfer
* 功能说明: 启动数据传输
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void bsp_spiTransfer(void)
{
if (g_spiLen > SPI_BUFFER_SIZE)
{
return;
}
/* DMA方式传输 */
#ifdef USE_SPI_DMA
wTransferState = TRANSFER_WAIT;
if(HAL_SPI_TransmitReceive_DMA(&hspi, (uint8_t*)g_spiTxBuf, (uint8_t *)g_spiRxBuf, g_spiLen) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
while (wTransferState == TRANSFER_WAIT)
{
;
}
#endif
/* 中断方式传输 */
#ifdef USE_SPI_INT
wTransferState = TRANSFER_WAIT;
if(HAL_SPI_TransmitReceive_IT(&hspi, (uint8_t*)g_spiTxBuf, (uint8_t *)g_spiRxBuf, g_spiLen) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
while (wTransferState == TRANSFER_WAIT)
{
;
}
#endif
/* 查询方式传输 */
#ifdef USE_SPI_POLL
g_spiTxBuf[0]=0xAA;
g_spiTxBuf[0]=0xBB;
g_spiTxBuf[0]=0xCC;
g_spiTxBuf[0]=0xDD;
AD7953_CS0();
if(HAL_SPI_TransmitReceive(&hspi, (uint8_t*)g_spiTxBuf, (uint8_t *)g_spiRxBuf, 4, 1000) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
AD7953_CS1();
#endif
}
|
|