[单片机芯片] 【CH32F207VCT6】开发例程+15 使用DAC功能输出不同的波形

[复制链接]
177|0
聪聪哥哥 发表于 2025-10-31 09:30 | 显示全部楼层 |阅读模式
本帖最后由 聪聪哥哥 于 2025-10-31 13:12 编辑

 最近想制作一个波形发生器,手头正好有CH32的开发板,正好用来弄一下使用DAC输出不同的波形。
一:DAC的基础知识
 数字/模拟转换模块(DAC),包含2个可配置 8/12 位数字输入转换2路模拟电压输出的转换器内置三角波、噪声波形发生器,支持多种事件触发转换,DMA 功能等。
二:主要特征:
 2 个 DAC 转换器,每个转换器对应1个输出通道
 三角波、噪声波形发生器
 可配置 8 位或 12 位输出
   12 位数据左对齐或右对齐
   双 DAC 同时或分别转换
   支持 DMA 功能
   多种触发事件
三:DAC的模块结构
  15-1.png
四:输出不同的波形
4.1 使用DMA的方式转换输出
 DAC 通道具有 DMA 功能。设置 DAC_CTLR 寄存器的 DMAENx 位为1,开启对应通道的 DMA 功能。当有触发事件(不包括软件触发)发生,则产生一个 DMA 请求,然后 DAC_DORx 寄存器的数据将被更新。
4.1.1 DAC初始化:
  1. void Dac_Init( void )
  2. {
  3.     GPIO_InitTypeDef GPIO_InitStructure = {0};
  4.     DAC_InitTypeDef DAC_InitType = {0};

  5.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE );
  6.     RCC_APB1PeriphClockCmd( RCC_APB1Periph_DAC, ENABLE );

  7.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
  8.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  9.     GPIO_Init( GPIOA, &GPIO_InitStructure );

  10.     DAC_InitType.DAC_Trigger = DAC_Trigger_T8_TRGO;
  11.     DAC_InitType.DAC_WaveGeneration = DAC_WaveGeneration_None;
  12.     DAC_InitType.DAC_OutputBuffer = DAC_OutputBuffer_Disable ;
  13.     DAC_Init( DAC_Channel_1, &DAC_InitType );

  14.     DAC_Cmd( DAC_Channel_1, ENABLE );
  15.     DAC_DMACmd( DAC_Channel_1, ENABLE );
  16. }
4.1.2 DMA的初始化:
  1. void DAC1_DMA_Init( void )
  2. {
  3.     DMA_InitTypeDef DMA_InitStructure = {0};
  4.     RCC_AHBPeriphClockCmd( RCC_AHBPeriph_DMA2, ENABLE );

  5.     DMA_StructInit( &DMA_InitStructure );
  6.     /* Note:DAC1--->DMA2.CH3   DAC2--->DMA2.CH4 */
  7.     DMA_InitStructure.DMA_PeripheralBaseAddr = ( u32 ) & ( DAC->R12BDHR1 );
  8.     DMA_InitStructure.DMA_MemoryBaseAddr = ( u32 )&dacbuff16bit;
  9.     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  10.     DMA_InitStructure.DMA_BufferSize = 8;
  11.     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  12.     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  13.     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  14.     DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  15.     DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  16.     DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
  17.     DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

  18.     DMA_Init( DMA2_Channel3, &DMA_InitStructure );
  19.     DMA_Cmd( DMA2_Channel3, ENABLE );
  20. }
4.1.3 定时器的初始化:
  1. void TIM8_Init( u16 arr, u16 psc )
  2. {
  3.     TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure = {0};

  4.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_TIM8, ENABLE );

  5.     TIM_TimeBaseInitStructure.TIM_Period = arr;
  6.     TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
  7.     TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  8.     TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Down;
  9.     TIM_TimeBaseInitStructure.TIM_RepetitionCounter =  0x00;
  10.     TIM_TimeBaseInit( TIM8, &TIM_TimeBaseInitStructure );

  11.     TIM_SelectOutputTrigger( TIM8, TIM_TRGOSource_Update );
  12.     TIM_Cmd( TIM8, ENABLE );
  13. }
4.1.4 实物测试如下所示:
15-2.png
4.2   输出三角波形
模块内置了一个三角波生成器,可以在基准信号上加上一个小幅度的三角波。设置 WAVEx[1:0]位为'10’选择 DAC 的三角波生成功能。设置 DAC_CTLR 寄存器的 MAMPx[3:0]位来选择三角波的幅度。
系统内部包含一个从0开始的三角波计数器,在每次触发事件后3个PB1 时钟周期后累加1。计数器的值与 DAC DHRx 寄存器的数值相加并丢弃溢出位后写入 DAC DORx 寄存器。在传入 DAC DORx寄存器的数值小于 MAMPx[3:0]位定义的最大幅度时,三角波计数器逐步累加,一旦达到设置的最大幅度,则计数器开始递减,达到0后再开始累加,周而复始。将 WAVEx[1:0]位置'00’,可以复位三角波的生成。
注:1.为了产生三角波,必须使能 DAC 触发,即设 DAC CTLR寄存器的 TENx 位为 1。
2. MAMPx[3:0]位必须在使能 DAC 之前设置,否则其值不能修改。
4.2.1 DAC的初始化
  1. void Dac_Init( void )
  2. {
  3.     GPIO_InitTypeDef GPIO_InitStructure = {0};
  4.     DAC_InitTypeDef DAC_InitType = {0};

  5.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE );
  6.     RCC_APB1PeriphClockCmd( RCC_APB1Periph_DAC, ENABLE );

  7.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
  8.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  9.     GPIO_Init( GPIOA, &GPIO_InitStructure );

  10.     DAC_InitType.DAC_Trigger = DAC_Trigger_Software;
  11.     DAC_InitType.DAC_WaveGeneration = DAC_WaveGeneration_Triangle;
  12.     DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude = DAC_TriangleAmplitude_4095;
  13.     DAC_InitType.DAC_OutputBuffer = DAC_OutputBuffer_Disable ;
  14.     DAC_Init( DAC_Channel_1, &DAC_InitType );
  15.     /* TEN = 1 */
  16.     DAC->CTLR |= 0x04;
  17.     DAC_Cmd( DAC_Channel_1, ENABLE );

  18.     DAC_SetChannel1Data( DAC_Align_12b_R, 0 );
  19. }
4.2.2 三角函数如下所示:
  1. void DAC1_Triangle_Gen_Test( void )
  2. {
  3.     DAC->SWTR |= 0x01;                   /* Set by software, Reset by hardware */
  4.     __asm volatile( "nop" );
  5.     // printf("DOR1=0x%04x\r\n",DAC->DOR1);
  6. }
4.2.3 实物测试如下所示:
1031-3.jpg
4.3 DAC 正常输出不同电压:
4.3.1 DAC初始化:
  1. void Dac_Init( void )
  2. {
  3.     GPIO_InitTypeDef GPIO_InitStructure = {0};
  4.     DAC_InitTypeDef DAC_InitType = {0};

  5.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE );
  6.     RCC_APB1PeriphClockCmd( RCC_APB1Periph_DAC, ENABLE );

  7.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
  8.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  9.     GPIO_Init( GPIOA, &GPIO_InitStructure );

  10.     DAC_InitType.DAC_Trigger = DAC_Trigger_None;
  11.     DAC_InitType.DAC_WaveGeneration = DAC_WaveGeneration_None;
  12.     DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;
  13.     DAC_InitType.DAC_OutputBuffer = DAC_OutputBuffer_Disable ;
  14.     DAC_Init( DAC_Channel_1, &DAC_InitType );
  15.     DAC_Cmd( DAC_Channel_1, ENABLE );

  16.     DAC_SetChannel1Data( DAC_Align_12b_R, 0 );
  17. }
4.3.2 主程序中调用:
  1. u16 DAC_Value[Num] = {64, 128, 256, 512, 1024, 2048, 4095};
  1.         for( i = 0; i < Num; i++ ){
  2.             DAC_SetChannel1Data( DAC_Align_12b_R, DAC_Value[i] );
  3.             Delay_Ms(5000);
  4.         }
可见,使用CH32的DAC功能,可以快速实现不同波形,电压的输出。
4.4 输出正弦波
  1.         w += (PI / freq);
  2.         if (w >= (2 * PI))
  3.         {
  4.             w = 0;
  5.         }
  6.         dac_value = (sin(w) + 1) / 2 * 4095;
15-4.png

这个波形看起来有点问题,看起来不是很平滑。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

111

主题

316

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部