|
使用DMA+SPI驱动DAC芯片DAC8830,一次只发送一个数据
不使用DMA的时候SPI可以正常输出,加上DMA上就不行,直接SPI没有任何输出clk也没有,下面是我的代码,请问下是什么原因导致的呀
#include "./BSP/SPI/spi_DAC8830.h"
#include "./BSP/LED/led.h"
static SPI_HandleTypeDef g_SPI2_handle = {0};
static SPI_HandleTypeDef g_SPI3_handle = {0};
static DMA_HandleTypeDef g_DMA2_SPI2_handle = {0};
static HAL_DMA_MuxSyncConfigTypeDef dmamux_syncParams;
extern uint16_t triangle_data_out[N_TRIANGLE];
/*
*********************************************************************************************************
* 函 数 名: HAL_SPI_MspInit和HAL_SPI_MspDeInit
* 功能说明: 用于SPI底层的初始化和复位初始化
* 形 参: SPI_HandleTypeDef 类型指针变量
* 返 回 值: 无
*********************************************************************************************************
*/
void HAL_SPI_MspInit(SPI_HandleTypeDef *_hspi)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* SPI和GPIO时钟 */
SPI2_CLK_ENABLE();
SPI2_GPIO_CLK_ENABLE();
/* SPI SCK */
GPIO_InitStruct.Pin = SPI2_CLK_GPIO_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.Alternate = SPI2_CLK_GPIO_AF;
HAL_GPIO_Init(SPI2_CS_MOSI_CLK_GPIO_PORT, &GPIO_InitStruct);
/* SPI MOSI */
GPIO_InitStruct.Pin = SPI2_MOSI_GPIO_PIN;
GPIO_InitStruct.Alternate = SPI2_MOSI_GPIO_AF;
HAL_GPIO_Init(SPI2_CS_MOSI_CLK_GPIO_PORT, &GPIO_InitStruct);
/* SPI NSS */
GPIO_InitStruct.Pin = SPI2_CS_GPIO_PIN;
//GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Alternate = SPI2_CS_GPIO_AF;
HAL_GPIO_Init(SPI2_CS_MOSI_CLK_GPIO_PORT, &GPIO_InitStruct);
//使能SPI3对应的IO口
SPI3_CLK_ENABLE();
SPI3_CS_GPIO_CLK_ENABLE();
SPI3_CLK_MOSI_GPIO_CLK_ENABLE();
GPIO_InitStruct.Pin = SPI3_CLK_GPIO_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.Alternate = SPI3_CLK_GPIO_AF;
HAL_GPIO_Init(SPI3_CLK_MOSI_GPIO_PORT, &GPIO_InitStruct);
/* SPI MOSI */
GPIO_InitStruct.Pin = SPI3_MOSI_GPIO_PIN;
GPIO_InitStruct.Alternate = SPI3_MOSI_GPIO_AF;
HAL_GPIO_Init(SPI3_CLK_MOSI_GPIO_PORT, &GPIO_InitStruct);
/* SPI NSS */
GPIO_InitStruct.Pin = SPI3_CS_GPIO_PIN;
GPIO_InitStruct.Alternate = SPI3_CS_GPIO_AF;
HAL_GPIO_Init(SPI3_CS_GPIO_PORT, &GPIO_InitStruct);
//初始化DMA配置
#if USE_DMA
/* 使能DMA时钟 */
DMA2_CLK_ENABLE();
/* SPI DMA发送配置 */
g_DMA2_SPI2_handle.Instance = SPI2_TX_DMA_STREAM; /* 例化使用的DMA数据流 */
g_DMA2_SPI2_handle.Init.FIFOMode = DMA_FIFOMODE_DISABLE; /* 使能FIFO*/
g_DMA2_SPI2_handle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; /* 用于设置阀值, 如果禁止FIFO此位不起作用*/
g_DMA2_SPI2_handle.Init.MemBurst = DMA_MBURST_SINGLE; /* 用于存储器突发,如果禁止FIFO此位不起作用*/
g_DMA2_SPI2_handle.Init.PeriphBurst = DMA_PBURST_SINGLE; /* 用于外设突发,禁止FIFO此位不起作用 */
g_DMA2_SPI2_handle.Init.Request = SPI2_TX_DMA_REQUEST; /* 请求类型 */
g_DMA2_SPI2_handle.Init.Direction = DMA_MEMORY_TO_PERIPH; /* 传输方向是从存储器到外设 */
g_DMA2_SPI2_handle.Init.PeriphInc = DMA_PINC_DISABLE; /* 外设地址自增禁止 */
g_DMA2_SPI2_handle.Init.MemInc = DMA_MINC_DISABLE; /* 存储器地址自增使能 */
g_DMA2_SPI2_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; /* 外设数据传输位宽选择字节,即8bit */
g_DMA2_SPI2_handle.Init.MemDataAlignment = DMA_PDATAALIGN_HALFWORD; /* 存储器数据传输位宽选择字节,即8bit */
g_DMA2_SPI2_handle.Init.Mode = DMA_NORMAL; /* 正常模式 */
g_DMA2_SPI2_handle.Init.Priority = DMA_PRIORITY_LOW; /* 优先级低 */
HAL_DMA_DeInit(&g_DMA2_SPI2_handle);
HAL_DMA_Init(&g_DMA2_SPI2_handle);
__HAL_LINKDMA(&g_SPI2_handle, hdmatx, g_DMA2_SPI2_handle);
// 配置DMA中断
HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
// 配置SPI中断
HAL_NVIC_SetPriority(SPI2_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(SPI2_IRQn);
#endif
}
/********************* 复位SPI函数 **********************/
void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi)
{
}
void bsp_InitSPI3_Param(void)
{
/* 设置SPI参数 */
g_SPI3_handle.Instance = SPI3; /* 例化SPI */
g_SPI3_handle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; /* AHB时钟频率200MHz,4分频以后50MHz */
g_SPI3_handle.Init.Direction = SPI_DIRECTION_2LINES_TXONLY; /* 仅发送 */
g_SPI3_handle.Init.CLKPhase = SPI_POLARITY_LOW; /* 配置时钟相位 */
g_SPI3_handle.Init.CLKPolarity = SPI_PHASE_1EDGE; /* 配置时钟极性 */
g_SPI3_handle.Init.DataSize = SPI_DATASIZE_16BIT; /* 设置数据宽度 */
g_SPI3_handle.Init.FirstBit = SPI_FIRSTBIT_MSB; /* 数据传输先传高位 */
g_SPI3_handle.Init.TIMode = SPI_TIMODE_DISABLE; /* 禁止TI模式 */
g_SPI3_handle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; /* 禁止CRC */
g_SPI3_handle.Init.CRCPolynomial = 7; /* 禁止CRC后,此位无效 */
g_SPI3_handle.Init.CRCLength = SPI_CRC_LENGTH_8BIT; /* 禁止CRC后,此位无效 */
g_SPI3_handle.Init.FifoThreshold = SPI_FIFO_THRESHOLD_04DATA; /* 设置FIFO大小是一个数据项 */
g_SPI3_handle.Init.NSS = SPI_NSS_HARD_OUTPUT; /* 使用硬件方式管理片选引脚 */
g_SPI3_handle.Init.NSSPMode = SPI_NSS_PULSE_ENABLE; /* 使能脉冲输出 */
g_SPI3_handle.Init.NSSPolarity = SPI_NSS_POLARITY_LOW; /* 低电平有效 */
g_SPI3_handle.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE; /* MSS, 插入到NSS有效边沿和第一个数据开始之间的额外延迟,单位SPI时钟周期个数 */
g_SPI3_handle.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_01CYCLE; /* MIDI, 两个连续数据帧之间插入的最小时间延迟,单位SPI时钟周期个数 */
g_SPI3_handle.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_ENABLE; /* 禁止SPI后,SPI相关引脚保持当前状态 */
g_SPI3_handle.Init.Mode = SPI_MODE_MASTER; /* SPI工作在主控模式 */
/* 复位配置 */
if (HAL_SPI_DeInit(&g_SPI3_handle) != HAL_OK)
{}
/* 初始化配置 */
if (HAL_SPI_Init(&g_SPI3_handle) != HAL_OK)
{}
}
/*
*********************************************************************************************************
* 函 数 名: 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_InitSPI2_Param(void)
{
/* 设置SPI参数 */
g_SPI2_handle.Instance = SPI2; /* 例化SPI */
g_SPI2_handle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; /* AHB时钟频率200MHz,4分频以后50MHz */
g_SPI2_handle.Init.Direction = SPI_DIRECTION_2LINES_TXONLY; /* 仅发送 */
g_SPI2_handle.Init.CLKPhase = SPI_POLARITY_LOW; /* 配置时钟相位 */
g_SPI2_handle.Init.CLKPolarity = SPI_PHASE_1EDGE; /* 配置时钟极性 */
g_SPI2_handle.Init.DataSize = SPI_DATASIZE_16BIT; /* 设置数据宽度 */
g_SPI2_handle.Init.FirstBit = SPI_FIRSTBIT_MSB; /* 数据传输先传高位 */
g_SPI2_handle.Init.TIMode = SPI_TIMODE_DISABLE; /* 禁止TI模式 */
g_SPI2_handle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; /* 禁止CRC */
g_SPI2_handle.Init.CRCPolynomial = 7; /* 禁止CRC后,此位无效 */
g_SPI2_handle.Init.CRCLength = SPI_CRC_LENGTH_8BIT; /* 禁止CRC后,此位无效 */
g_SPI2_handle.Init.FifoThreshold = SPI_FIFO_THRESHOLD_04DATA; /* 设置FIFO大小是一个数据项 */
g_SPI2_handle.Init.NSS = SPI_NSS_HARD_OUTPUT; /* 使用硬件方式管理片选引脚 */
g_SPI2_handle.Init.NSSPMode = SPI_NSS_PULSE_ENABLE; /* 使能脉冲输出 */
g_SPI2_handle.Init.NSSPolarity = SPI_NSS_POLARITY_LOW; /* 低电平有效 */
g_SPI2_handle.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE; /* MSS, 插入到NSS有效边沿和第一个数据开始之间的额外延迟,单位SPI时钟周期个数 */
g_SPI2_handle.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_01CYCLE; /* MIDI, 两个连续数据帧之间插入的最小时间延迟,单位SPI时钟周期个数 */
g_SPI2_handle.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_ENABLE; /* 禁止SPI后,SPI相关引脚保持当前状态 */
g_SPI2_handle.Init.Mode = SPI_MODE_MASTER; /* SPI工作在主控模式 */
/* 复位配置 */
if (HAL_SPI_DeInit(&g_SPI2_handle) != HAL_OK)
{}
/* 初始化配置 */
if (HAL_SPI_Init(&g_SPI2_handle) != HAL_OK)
{}
}
void DAC8830_SPI2_init(void)
{
bsp_InitSPI2_Param();
}
// DAC8830_DAC1写入函数
void DAC8830_DAC1_Write(uint16_t tx_data) {
// // 拉低CS引脚,选择DAC_8830
HAL_SPI_Transmit_DMA(&g_SPI2_handle, (uint8_t*)&tx_data, 1);
}
#if USE_DMA
/**
* @brief Tx Transfer completed callback.
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval None
*/
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{
if(hspi->Instance == SPI2) LED0_TOGGLE();
}
/**
* @brief This function handles SPI2 global interrupt.
*/
void SPI2_IRQHandler(void)
{
HAL_SPI_IRQHandler(&g_SPI2_handle);
}
/**
* @brief This function handles DMA2 stream3 global interrupt.
*/
void DMA2_Stream3_IRQHandler(void)
{
HAL_DMA_IRQHandler(&g_DMA2_SPI2_handle);
}
#endif
|
|