CH32V307 DAC输出 - RISC-V MCU技术社区 - 电子技术论坛 - 广受欢迎的专业电子论坛
分享 收藏 返回

[文章]

CH32V307 DAC输出

本帖最后由 l爱学习 于 2023-10-10 16:18 编辑

1、关于DAC
CH32V307的数字/模拟转换模块(DAC),包含 2 个可配置 8/12 位数字输入转换 2 路模拟电压输出的转换器。内置三角波、噪声波形发生器,支持多种事件触发转换,DMA 功能等。

2、关于DAC DMA使用
关于DMA功能,手册介绍如下图:
即使用DAC DMA的时候,必须使用定时器触发或EXti触发,程序配置的时候不可配置为软件触发或无触发。测试例程以定时器8 TRG0事件作为触发源。

3、关于DAC DMA程序配置
(1)DAC初始化配置
  1. /*********************************************************************
  2. * @fn      Dac_Init
  3. *
  4. * [url=home.php?mod=space&uid=2666770]@Brief[/url]   Initializes DAC collection.
  5. *
  6. * [url=home.php?mod=space&uid=1141835]@Return[/url]  none
  7. */
  8. void DAC1_Init(void)
  9. {
  10.     GPIO_InitTypeDef GPIO_InitStructure={0};
  11.     DAC_InitTypeDef  DAC_InitType={0};
  12.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );
  13.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE );
  14.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
  15.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  16.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  17.     GPIO_Init(GPIOA, &GPIO_InitStructure);
  18.     GPIO_SetBits(GPIOA,GPIO_Pin_4);
  19.     DAC_InitType.DAC_Trigger=DAC_Trigger_T8_TRGO;
  20.     DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None;
  21.     DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;
  22.     DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable ;
  23.     DAC_Init(DAC_Channel_1,&DAC_InitType);
  24.     DAC_Cmd(DAC_Channel_1, ENABLE);
  25.     DAC_DMACmd(DAC_Channel_1,ENABLE);
  26. }
DAC初始化主要对对应GPIO引脚以及DAC进行初始化配置。
GPIO初始化配置引脚选择PA4引脚,对应DAC_OUT1,根据外设的GPIO配置要求,注意PA4的GPIO配置模式要配置为模拟输入模式。

DAC初始化配置中DAC触发源配置选择定时器8,必须使用触发功能,不使用波形发生,使能开启对应DAC功能以及DMA功能。

(2)DAC DMA初始化配置
  1. /*********************************************************************
  2. * @fn      DAC1_DMA_INIT
  3. *
  4. * @brief   Initializes DMA of DAC1 collection.
  5. *
  6. * @return  none
  7. */
  8. void DAC1_DMA_Init(void)
  9. {
  10.     DMA_InitTypeDef DMA_InitStructure={0};
  11.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
  12.     DMA_StructInit( &DMA_InitStructure);
  13.     /* Note:DAC1--->DMA1.CH3   DAC2--->DMA1.CH4 */
  14.     DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&(DAC->R12BDHR1);
  15.     DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&dacbuff16bit;
  16.     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  17.     DMA_InitStructure.DMA_BufferSize = 8;
  18.     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  19.     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  20.     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  21.     DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  22.     DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  23.     DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
  24.     DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  25.     DMA_Init(DMA2_Channel3, &DMA_InitStructure);
  26.     DMA_Cmd(DMA2_Channel3, ENABLE);
  27. }
DMA初始化配置主要对DMA传输的源地址、目标地址、传输方向等进行配置,主要注意一下DAC1对应的DMA及通道是DMA2的通道3,其中BufferSize的大小根据每次需要传输的数据数量来定,一般是输出波形一个周期的采样点数,该点数越大波形越平滑。DMA的模式配置为循环模式,当DMA传输完成一组波形数据后,DMA通道传输数量寄存器将会自动重新加载为之前配置时的数值。内部的当前外设/存储器地址寄存器也被重新加载为外设/存储器地址寄存器设定的初始基地址,再次开启传输,不断循环。DAC若要输出连续的波形,需要开启循环模式。


(3)定时器初始化配置
  1. /*********************************************************************
  2. * @fn      TIM8_Init
  3. *
  4. * @brief   Initializes TIM3 collection.
  5. *
  6. * [url=home.php?mod=space&uid=3142012]@param[/url]   arr - TIM_Period
  7. *          psc - TIM_Prescaler
  8. *
  9. * @return  none
  10. */
  11. void TIM8_Init(u16 arr,u16 psc)
  12. {
  13.     TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure={0};
  14.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_TIM8, ENABLE );
  15.     TIM_TimeBaseInitStructure.TIM_Period = arr;
  16.     TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
  17.     TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  18.     TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Down;
  19.     TIM_TimeBaseInitStructure.TIM_RepetitionCounter =  0x00;
  20.     TIM_TimeBaseInit( TIM8, &TIM_TimeBaseInitStructure);
  21.     TIM_SelectOutputTrigger(TIM8, TIM_TRGOSource_Update);
  22.     TIM_Cmd(TIM8, ENABLE);
  23. }
定时器配置主要用来控制触发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函数配置
  1. int main(void)
  2. {
  3.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  4.     SystemCoreClockUpdate();
  5.     Delay_Init();
  6.     USART_Printf_Init(115200);
  7.     printf("SystemClk:%d\r\n",SystemCoreClock);
  8.     printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
  9.     printf("DAC DMA TEST\r\n");
  10.     DAC1_Init();
  11.     DAC1_DMA_Init();
  12.     TIM8_Init(72-1,0);
  13.     while(1)
  14.     {
  15.         Delay_Ms(1000);
  16.         printf("run\r\n");
  17.         printf("DAC->R12BDHR1:0x%04x\r\n",DAC->R12BDHR1);
  18.         printf("DAC->DOR1:0x%04x\r\n",DAC->DOR1);
  19.         printf("TIM8->CNT:%d\r\n",TIM8->CNT);
  20.     }
  21. }
main函数主要进行初始化以及将一些信息在while循环里循环打印出来


更多回帖

×
发帖