本帖最后由 l爱学习 于 2023-10-10 16:18 编辑
1、关于DAC CH32V307的数字/模拟转换模块(DAC),包含 2 个可配置 8/12 位数字输入转换 2 路模拟电压输出的转换器。内置三角波、噪声波形发生器,支持多种事件触发转换,DMA 功能等。
2、关于DAC DMA使用 关于DMA功能,手册介绍如下图: 即使用DAC DMA的时候,必须使用定时器触发或EX ti触发,程序配置的时候不可配置为软件触发或无触发。测试例程以定时器8 TRG0事件作为触发源。
3、关于DAC DMA程序配置
(1)DAC初始化配置- /*********************************************************************
- * @fn Dac_Init
- *
- * [url=home.php?mod=space&uid=2666770]@Brief[/url] Initializes DAC collection.
- *
- * [url=home.php?mod=space&uid=1141835]@Return[/url] none
- */
- void DAC1_Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure={0};
- DAC_InitTypeDef DAC_InitType={0};
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE );
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- GPIO_SetBits(GPIOA,GPIO_Pin_4);
- DAC_InitType.DAC_Trigger=DAC_Trigger_T8_TRGO;
- DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None;
- DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;
- DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable ;
- DAC_Init(DAC_Channel_1,&DAC_InitType);
- DAC_Cmd(DAC_Channel_1, ENABLE);
- DAC_DMACmd(DAC_Channel_1,ENABLE);
- }
复制代码 DAC初始化主要对对应GPIO引脚以及DAC进行初始化配置。
GPIO初始化配置引脚选择PA4引脚,对应DAC_OUT1,根据外设的GPIO配置要求,注意PA4的GPIO配置模式要配置为模拟输入模式。
![]()
DAC初始化配置中DAC触发源配置选择定时器8,必须使用触发功能,不使用波形发生,使能开启对应DAC功能以及DMA功能。
(2)DAC DMA初始化配置- /*********************************************************************
- * @fn DAC1_DMA_INIT
- *
- * @brief Initializes DMA of DAC1 collection.
- *
- * @return none
- */
- void DAC1_DMA_Init(void)
- {
- DMA_InitTypeDef DMA_InitStructure={0};
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
- DMA_StructInit( &DMA_InitStructure);
- /* Note:DAC1--->DMA1.CH3 DAC2--->DMA1.CH4 */
- DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&(DAC->R12BDHR1);
- DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&dacbuff16bit;
- DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
- DMA_InitStructure.DMA_BufferSize = 8;
- DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
- DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
- DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
- DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
- DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
- DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
- DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
- DMA_Init(DMA2_Channel3, &DMA_InitStructure);
- DMA_Cmd(DMA2_Channel3, ENABLE);
- }
复制代码 DMA初始化配置主要对DMA传输的源地址、目标地址、传输方向等进行配置,主要注意一下DAC1对应的DMA及通道是DMA2的通道3,其中BufferSize的大小根据每次需要传输的数据数量来定,一般是输出波形一个周期的采样点数,该点数越大波形越平滑。DMA的模式配置为循环模式,当DMA传输完成一组波形数据后,DMA通道传输数量寄存器将会自动重新加载为之前配置时的数值。内部的当前外设/存储器地址寄存器也被重新加载为外设/存储器地址寄存器设定的初始基地址,再次开启传输,不断循环。DAC若要输出连续的波形,需要开启循环模式。
![]()
(3)定时器初始化配置- /*********************************************************************
- * @fn TIM8_Init
- *
- * @brief Initializes TIM3 collection.
- *
- * [url=home.php?mod=space&uid=3142012]@param[/url] arr - TIM_Period
- * psc - TIM_Prescaler
- *
- * @return none
- */
- void TIM8_Init(u16 arr,u16 psc)
- {
- TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure={0};
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_TIM8, ENABLE );
- TIM_TimeBaseInitStructure.TIM_Period = arr;
- TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
- TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
- TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Down;
- TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0x00;
- TIM_TimeBaseInit( TIM8, &TIM_TimeBaseInitStructure);
- TIM_SelectOutputTrigger(TIM8, TIM_TRGOSource_Update);
- TIM_Cmd(TIM8, ENABLE);
- }
复制代码 定时器配置主要用来控制触发DAC通过DMA输出的频率。其中定时器触发输出选择更新事件作为触发源。触发频率由重装载值arr和与预分频器值psc决定。
触发频率的计算公式为:
f1=APB2CLK/((arr+1)*(psc+1))
DAC输出波形频率的计算公式为:
f2=f1/DMA_BufferSize
以本次例程为例,主频72M,则APB2的时钟PCLK2经过1分频也为72M,arr值为72,psc的值为0,则触发频率为1M,即f1大小为1M
DAC DMA传输BufferSize 的大小例程设置为8,则波形的频率f2=1M/8=125KHz,实测波形频率也是125KHz,如下图
![]()
(4)main函数配置- int main(void)
- {
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
- SystemCoreClockUpdate();
- Delay_Init();
- USART_Printf_Init(115200);
- printf("SystemClk:%d\r\n",SystemCoreClock);
- printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
- printf("DAC DMA TEST\r\n");
- DAC1_Init();
- DAC1_DMA_Init();
- TIM8_Init(72-1,0);
- while(1)
- {
- Delay_Ms(1000);
- printf("run\r\n");
- printf("DAC->R12BDHR1:0x%04x\r\n",DAC->R12BDHR1);
- printf("DAC->DOR1:0x%04x\r\n",DAC->DOR1);
- printf("TIM8->CNT:%d\r\n",TIM8->CNT);
- }
- }
复制代码 main函数主要进行初始化以及将一些信息在while循环里循环打印出来
|