coshi 发表于 2023-9-20 12:03

HC32F定时器PWM输出+PAC芯片实现模拟DA输出

一 项目背景
      目前使用了TI的DAC芯片DAC7311,将MCU的4-20/0-20数据转化电压信号,经由一系列电路,最终输出4-20/0-20mA电流输出。

      但是限于成本和货期的问题,考虑将该款DAC换成国产的其他方案。

      找到一款客益电子(http://www.guestgood.com/)的APC/PAC芯片,可以将输入的PWM信号占空比转化为模拟电流输出,这边选用的PAC芯片为GP8301。(APC替代ADC的方案参考之前的一篇文章【嵌入式】HC32F定时器PWM捕获+APC芯片实现模拟AD采样)

二 原理说明
【1】APC/PAC芯片原理:

      A=Analog,P=PWM,C=Convertor。

      APC=Analog to PWM Convertor 是一种模拟信号转PWM信号的专用芯片,PAC=PWM to Analog Convertor是一种PWM信号转模拟信号的专用芯片。

      在信号调理领域,经常需要面对模拟量信号的传输、采集、控制等问题,传统的信号链芯片包括模数转换器(ADC)、数模转换器(DAC)、运算放大器(OpAmp)、比较器(Comparator)等等,它们扮演着模数混合信号处理的主要角色。信号链芯片的功能基础而强大,经过精心的设计后能形成多种多样优秀的信号处理电路。但即便如此,在很多应用领域,传统的信号链芯片依然存在瓶颈和制约,无法达到理想的电路性能和技术指标,尤其在一些需要PWM信号的领域,传统的方法遇到许多困难。

      客益电子发明了一种新型的模拟信号处理的专用芯片,它实现了模拟信号与PWM信号间的高精度转换功能,我们称它为APC(Analog to PWM Convertor)和PAC(PWM to Analog Convertor)。



【2】芯片特性:

      这边采用的芯片GP8301将输入占空比0-100%信号线性转化为0-20mA模拟电流输出:



         电流公式为:



      相比4-20mA,我这边需要一个更大范围的输出,然后通过两点校准获得精准的4-20mA的信号,所以选择Rset为2KΩ 0.1%,这样的话,输入占空比0-100%对应输出为0-25mA,其中当输入为16%占空比时,对应输出4mA,当输入为80%占空比时,对应输出20mA,并且支持两点校准,满足设想。

【3】输出原理:

      做好定时器PWM输出初始化,预设周期值为:



      这样,在64分频定时器中,输出频率为50*2=100Hz的PWM,占空比根据设置的比较值确定,例如当比较值为4200时,即输出4mA需要的占空比16%。当比较值为21000时,即输出20mA需要的占空比80%。

三 设计实现——定时器初始化
      由上面的方案,首先需要实现的是定时器输出PWM功能的初始化,我这边使用的主控芯片为小华的HC32F460,选用其高级控制定时器Timer6进行PWM输出,端口选用PB13,其功能是TIMER6_1_PWMB(Timer6的1单元B通道):



      初始化程序如下:

/* TIMER6 unit and clock definition */
#define TIMER6_UNIT1                  (M4_TMR61)
#define TIMER6_UNIT1_CLOCK            (PWC_FCG2_PERIPH_TIM61)
#define TIMER6_COUNT_OVERFLOW1          (SystemCoreClock/2U/64U/50U)    //100Hz
/* TIMER6 channel B Port/Pin definition */
#define TIMER6_UNIT1_CHB                (Timer6GenCompareB)
#define TIMER6_UNIT1_CHB_PORT         (PortB)
#define TIMER6_UNIT1_CHB_PIN            (Pin13)
#define TIMER6_UNIT1_CHB_FUNC         (Func_Tim6)


void Timer6_PAC_Config(void)//PAC测试,比较电阻Rset调整为2K,根据公式Iout = Duty * 5 * 10 / Rset,输出占空比0-100%对应输出0-25mA
{
    stc_timer6_basecnt_cfg_t         stcTIM6BaseCntCfg;
    stc_timer6_port_output_cfg_t   stcTIM6PWMxCfg;
    stc_timer6_gcmp_buf_cfg_t      stcGCMPBufCfg;
    stc_port_init_t                  stcPortInit;
    stc_irq_regi_conf_t            stcIrqRegiConf;

    MEM_ZERO_STRUCT(stcTIM6BaseCntCfg);
    MEM_ZERO_STRUCT(stcTIM6PWMxCfg);
    MEM_ZERO_STRUCT(stcGCMPBufCfg);
    MEM_ZERO_STRUCT(stcPortInit);
    MEM_ZERO_STRUCT(stcIrqRegiConf);

    PWC_Fcg2PeriphClockCmd(TIMER6_UNIT1_CLOCK, Enable);

    PORT_SetFunc(TIMER6_UNIT1_CHB_PORT, TIMER6_UNIT1_CHB_PIN, TIMER6_UNIT1_CHB_FUNC, Disable);    //Timer61 PWMA

    stcTIM6BaseCntCfg.enCntMode   = Timer6CntSawtoothMode;            //Sawtooth wave mode
    stcTIM6BaseCntCfg.enCntDir    = Timer6CntDirUp;                     //Counter counting up
    stcTIM6BaseCntCfg.enCntClkDiv = Timer6PclkDiv64;                     //Count clock: pclk0
    Timer6_Init(TIMER6_UNIT1, &stcTIM6BaseCntCfg);                        //timer6 PWM frequency, count mode and clk config
    Timer6_SetPeriod(TIMER6_UNIT1, Timer6PeriodA, TIMER6_COUNT_OVERFLOW1);//period set
    Timer6_SetGeneralCmpValue(TIMER6_UNIT1, TIMER6_UNIT1_CHB, TIMER6_COUNT_OVERFLOW1 * 4 / 5);    //Set General Compare RegisterA Value

    stcTIM6PWMxCfg.enPortMode = Timer6ModeCompareOutput;    //Compare output function
    stcTIM6PWMxCfg.bOutEn   = true;                     //Output enable
    stcTIM6PWMxCfg.enPerc   = Timer6PWMxCompareLow;       //PWMA port output Low level when CNTER value match PERAR
    stcTIM6PWMxCfg.enCmpc   = Timer6PWMxCompareHigh;      //PWMA port output High level when CNTER value match with GCMAR
    stcTIM6PWMxCfg.enStaStp   = Timer6PWMxStateSelSS;       //PWMA output status is decide by STACA STPCA when CNTER start and stop
    stcTIM6PWMxCfg.enStaOut   = Timer6PWMxPortOutLow;       //PWMA port output set low level when CNTER start
    stcTIM6PWMxCfg.enStpOut   = Timer6PWMxPortOutLow;       //PWMA port output set low level when CNTER stop
    stcTIM6PWMxCfg.enDisVal   = Timer6PWMxDisValLow;
    Timer6_PortOutputConfig(TIMER6_UNIT1, Timer6PWMB, &stcTIM6PWMxCfg);

    /*start timer6*/
    Timer6_StartCount(TIMER6_UNIT1);
}

四 设计实现——PWM输出
      通过Timer6_SetGeneralCmpValue设置比较值,即可以实现对输出PWM的占空比进行控制:

uint16_t PacPeriod = 0u, PacDuty = 0u;
unsigned short analog_output_k;
unsigned short analog_output_b;
//无符号数限值处理
#define VARIABLE_LIMIT(var, lower, upper)       \
      do{                                     \
            if((var) < (lower))               \
            {                                 \
                (var) = (lower);                \
            }                                 \
            else if((var) > (upper))            \
            {                                 \
                (var) = (upper);                \
            }                                 \
/**************************************************************************
* 函数名称: ana**utputHandle
* 功能描述: 模拟量输出处理
* 输入参数: p_analog_ctrl->output_ui为需要输出的模拟值,范围0-20mA
* 输出参数:
* 返 回 值:
* 其它说明:
**************************************************************************/
void ana**utputHandle(int dac, STRU_ANALOG_IO_CTRL *p_analog_ctrl)
{
    float acc_adjust;//输出精度校准
    //...
    //参数acc_adjust即为输出占空比,可以通过下面公式通过analog_output_k与analog_output_b值进行校准
    acc_adjust = (((float)((analog_output_k - analog_output_b) / 16.0) / 1000.0) * (p_analog_ctrl->output_ui - 4) + (float)(analog_output_b / 10000.0)) / 5;
    PacDuty = PacPeriod - acc_adjust * PacPeriod;
    VARIABLE_LIMIT(PacDuty, 0, PacPeriod-1);//占空比控制在0-100%。同时占空比最大值必须比周期值小,否则会出问题。这边取周期值减一。
    Timer6_SetGeneralCmpValue(TIMER6_UNIT1, TIMER6_UNIT1_CHB, PacDuty);

    return ;
}

五 梳理总结
      这个PAC替代DAC用于输出模拟量的方案,使用比较简单方便,而且由于该PAC内置12位高精度的DAC,所以输出的精度也在需求的范围之内。
————————————————
版权声明:本文为CSDN博主「公子无缘」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sinat_33408502/article/details/130338030

tpgf 发表于 2023-10-14 11:02

请问APC/PAC芯片是什么功能的芯片呢

wowu 发表于 2023-10-14 11:32

这种输出方式会对单片机有一定的保护作用

磨砂 发表于 2023-10-14 11:54

PAC芯片的功能是将0-100%占空比的PWM信号线性转换为0-5V、0-10V、4-20mA、0-20mA等信号

xiaoqizi 发表于 2023-10-14 12:25

这款芯片可以输出的pwm的频率范围是多少呢

木木guainv 发表于 2023-10-14 22:11

APC系列芯片功能为将模拟信号线性转换成0%-100%的PWM信号

wakayi 发表于 2023-10-15 11:00

PAC芯片应该是PWM到模拟电压转换器
页: [1]
查看完整版本: HC32F定时器PWM输出+PAC芯片实现模拟DA输出