CH32V307 DAC输出

发布时间 2023-04-24 17:08:03作者: ZaiLi

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

 

2、关于DAC DMA使用
关于DMA功能,手册介绍如下:

即使用DAC DMA的时候,必须使用定时器触发或EXTI触发,程序配置的时候不可配置为软件触发或无触发。测试例程以定时器8 TRG0事件作为触发源。

 

3、关于DAC DMA程序配置
(1)DAC初始化配置

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_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初始化配置

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)定时器初始化配置

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循环里循环打印出来