本次评测STM32U545RE-Q的DMA方式的DAC输出,产生1个正弦波信号输出。
TIM1配置TRGO事件作为DAC的触发源。在每次触发定时器时,DAC向DMA发送一个请求,DMA响应这个请求
以循环模式将数据从sin_data[]缓冲区传输正弦波数据到DAC DHR寄存器。DAC_通道1产生50hZ正弦波,幅度~3V。
配置系统时钟160MHZ
配置DAC1
配置GPDMA1
配置LINKEDLIST Queue
配置LINKEDLIST DACNode
主函数中添加DAC相关函数
MX_DACQueue_Config();
if( HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel10, &DACQueue)!= HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(&hdac1, DMA_Handle1, handle_GPDMA1_Channel10);
DAC_Ch1_SineConfig();
编译、下载、运行,PA4输出50HZ正弦波
主要代码
static void DAC_Ch1_SineConfig(void)
{
DAC_ChannelConfTypeDef sConfig = {0};
hdac1.Instance = DAC1;
if (HAL_DAC_Init(&hdac1) != HAL_OK)
{
Error_Handler();
}
sConfig.DAC_Trigger = DAC_TRIGGER_T1_TRGO;
sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE;
sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_EXTERNAL;
if (HAL_DAC_ConfigChannel(&hdac1, &sConfig, DAC_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
if (HAL_DACEx_SelfCalibrate(&hdac1, &sConfig, DAC_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
if (HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_1, &data_sin[0], 128, DAC_ALIGN_12B_R) != HAL_OK)
{
Error_Handler();
}
}
void MX_DAC1_Init(void)
{
DAC_ChannelConfTypeDef sConfig = {0};
DAC_AutonomousModeConfTypeDef sAutonomousMode = {0};
hdac1.Instance = DAC1;
if (HAL_DAC_Init(&hdac1) != HAL_OK)
{
Error_Handler();
}
sConfig.DAC_HighFrequency = DAC_HIGH_FREQUENCY_INTERFACE_MODE_DISABLE;
sConfig.DAC_DMADoubleDataMode = DISABLE;
sConfig.DAC_SignedFormat = DISABLE;
sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE;
sConfig.DAC_Trigger = DAC_TRIGGER_T1_TRGO;
sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_EXTERNAL;
sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY;
if (HAL_DAC_ConfigChannel(&hdac1, &sConfig, DAC_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
sAutonomousMode.AutonomousModeState = DAC_AUTONOMOUS_MODE_DISABLE;
if (HAL_DACEx_SetConfigAutonomousMode(&hdac1, &sAutonomousMode) != HAL_OK)
{
Error_Handler();
}
if (HAL_DACEx_SelfCalibrate(&hdac1, &sConfig, DAC_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
}
void MX_TIM1_Init(void)
{
TIM_SlaveConfigTypeDef sSlaveConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
htim1.Instance = TIM1;
htim1.Init.Prescaler = 0;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 25000;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
sSlaveConfig.SlaveMode = TIM_SLAVEMODE_DISABLE;
sSlaveConfig.InputTrigger = TIM_TS_ITR1;
if (HAL_TIM_SlaveConfigSynchro(&htim1, &sSlaveConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_Base_Start(&htim1) != HAL_OK)
{
Error_Handler();
}
}
void MX_GPDMA1_Init(void)
{
__HAL_RCC_GPDMA1_CLK_ENABLE();
HAL_NVIC_SetPriority(GPDMA1_Channel10_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(GPDMA1_Channel10_IRQn);
handle_GPDMA1_Channel10.Instance = GPDMA1_Channel10;
handle_GPDMA1_Channel10.InitLinkedList.Priority = DMA_LOW_PRIORITY_LOW_WEIGHT;
handle_GPDMA1_Channel10.InitLinkedList.LinkStepMode = DMA_LSM_FULL_EXECUTION;
handle_GPDMA1_Channel10.InitLinkedList.LinkAllocatedPort = DMA_LINK_ALLOCATED_PORT1;
handle_GPDMA1_Channel10.InitLinkedList.TransferEventMode = DMA_TCEM_LAST_LL_ITEM_TRANSFER;
handle_GPDMA1_Channel10.InitLinkedList.LinkedListMode = DMA_LINKEDLIST_CIRCULAR;
if (HAL_DMAEx_List_Init(&handle_GPDMA1_Channel10) != HAL_OK)
{
Error_Handler();
}
if (HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel10, DMA_CHANNEL_NPRIV) != HAL_OK)
{
Error_Handler();
}
}
HAL_StatusTypeDef MX_DACQueue_Config(void)
{
HAL_StatusTypeDef ret = HAL_OK;
DMA_NodeConfTypeDef pNodeConfig;
pNodeConfig.NodeType = DMA_GPDMA_LINEAR_NODE;
pNodeConfig.Init.Request = GPDMA1_REQUEST_DAC1_CH1;
pNodeConfig.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
pNodeConfig.Init.Direction = DMA_PERIPH_TO_MEMORY;
pNodeConfig.Init.SrcInc = DMA_SINC_INCREMENTED;
pNodeConfig.Init.DestInc = DMA_DINC_FIXED;
pNodeConfig.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD;
pNodeConfig.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD;
pNodeConfig.Init.SrcBurstLength = 1;
pNodeConfig.Init.DestBurstLength = 1;
pNodeConfig.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT0;
pNodeConfig.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
pNodeConfig.TriggerConfig.TriggerPolarity = DMA_TRIG_POLARITY_MASKED;
pNodeConfig.DataHandlingConfig.DataExchange = DMA_EXCHANGE_NONE;
pNodeConfig.DataHandlingConfig.DataAlignment = DMA_DATA_RIGHTALIGN_ZEROPADDED;
pNodeConfig.SrcAddress = 0;
pNodeConfig.DstAddress = 0;
pNodeConfig.DataSize = 0;
ret |= HAL_DMAEx_List_BuildNode(&pNodeConfig, &DACNode);
ret |= HAL_DMAEx_List_InsertNode_Tail(&DACQueue, &DACNode);
ret |= HAL_DMAEx_List_SetCircularMode(&DACQueue);
return ret;
}
|
后期会制作
期待了
参考学习了,可以搞个DAC播放声音了