【嵌入式】HC32F定时器PWM输出+PAC芯片实现模拟DA输出

news2024/12/23 19:39:32

目录

一 项目背景

二 原理说明

三 设计实现——定时器初始化

四 设计实现——PWM输出

五 梳理总结


一 项目背景

        目前使用了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模拟电流输出:

         电流公式为:

IOUT=Duty*5V*10/Rset

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

【3】输出原理:

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

TIMER6_COUNT_OVERFLOW1=168000000/2/64/50=26250

        这样,在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);                \
            }                                   \

/**************************************************************************
* 函数名称: analogOutputHandle
* 功能描述: 模拟量输出处理
* 输入参数: p_analog_ctrl->output_ui为需要输出的模拟值,范围0-20mA
* 输出参数:
* 返 回 值:
* 其它说明:
**************************************************************************/
void analogOutputHandle(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,所以输出的精度也在需求的范围之内。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/455512.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

执行composer update报错(Segmentation fault php “${dir}/composer.phar“ “$@“)

在php项目中执行composer update&#xff0c;出现如图报错 可在php.ini文件中开启xdebug扩展&#xff0c;即可更新成功

(数字图像处理MATLAB+Python)第六章图像平滑-第二节:频域平滑滤波

文章目录 一&#xff1a;理想低通滤波&#xff08;1&#xff09;概述&#xff08;2&#xff09;程序 二&#xff1a;巴特沃斯低通滤波&#xff08;1&#xff09;概述&#xff08;2&#xff09;程序 三&#xff1a;指数低通滤波&#xff08;1&#xff09;概述&#xff08;2&…

Day1_vue集成elementUI主体布局

本次&#xff0c;将从0开始带你手撸一套SpringBootVue后台管理系统 从前端到后端&#xff0c;手把手搭建&#xff0c;方便学习从0学会基础实战&#xff01;&#xff01;&#xff01; 目录 软件版本 前端开发环境安装&#xff1a; vue-cli安装 : npm设置淘宝镜像加速: 创建v…

vue2+vue3——1~35

vue2vue3 尚硅谷vue2vue2 课程简介【02:24】vue2 Vue简介【17:59】vue2 Vue官网使用指南【14:07】vue2 搭建Vue开发环境【13:54】vue2 Hello小案例【22:25】了解&#xff1a; 不常用常用&#xff1a;id 更常用 简单class 差值总结vue 实例vue 模板 &#xff1a; 先 取 &#xf…

【香橙派+DHT11】香橙派(全志H616)+ DHT11温湿度传感器的驱动教程

目录 一、前言产品概述特点数据传送逻辑DHT11通信时序 二、代码GPIO初始化起始信号读取数据整体代码执行结果 一、前言 最近写DHT11的代码到香橙派&#xff08;全志H616&#xff09;上&#xff0c;发现网上案例基本上都是树莓派DHT11的居多&#xff0c;香橙派的少&#xff0c;…

Linux进程通信:无名管道

进程通信目的&#xff1a; &#xff08;1&#xff09;数据传输&#xff1a;进程间数据传输&#xff1b; &#xff08;2&#xff09;通知事件&#xff1a;一个进程向另一个或一组进程发送消息&#xff0c;通知某个事件的发生&#xff08;如子进程终止时需通知父进程&#xff0…

使用Lim测试平台快速完成批量造数

一、前言 在我们平时的测试过程中&#xff0c;经常遇到需要造大量数据的情况&#xff0c;比如&#xff1a;测试分页功能&#xff0c;性能压测、数据准备等。 这时我们可以通过写脚本或jmeter这类的工具来实现&#xff0c;但这些方式在团队协作的时候并不友好&#xff0c;当别人…

MySQL 函数和运算符

文章目录 一、MySQL 函数二、MySQL 运算符总结 一、MySQL 函数 MySQL 有很多内置的函数&#xff0c;以下列出了这些函数的说明。 二、MySQL 运算符 算术运算符 比较运算符 逻辑运算符 位运算符算术运算符 MySQL 支持的算术运算符包括: 除法运算和模运算中&#xf…

(2)elasticsearch环境搭建(win10)

安装jdk 版本选择&#xff1a;最好是java 8、java11或者java14 jdk兼容性&#xff1a;https://www.elastic.co/cn/support/matrix#matrix_jvm 操作系统兼容性&#xff1a;https://www.elastic.co/cn/support/matrix 自身兼容性&#xff1a;https://www.elastic.co/cn/suppo…

Linux下版本控制器(SVN) -服务器端环境搭建步骤

文章目录 进阶知识-Linux下版本控制器(SVN)4、服务器端环境搭建步骤4.1 安装服务器端程序4.2 验证是否安装成功4.3 创建并配置版本库4.4 配置 SVN对应的服务4.5 启动 SVN服务 本人其他相关文章链接 进阶知识-Linux下版本控制器(SVN) 4、服务器端环境搭建步骤 4.1 安装服务器端…

AD7356_SPI驱动程序设计_5MSPS_Verilog

好久没动手了&#xff0c;使用Verilog编写一个AD7356的SPI驱动程序。 AD7356是一个双通道、12位、低功耗的ADC。最高采样速率可达5MSPS&#xff0c;全功率输入带宽为110MHz。AD7356的引脚图如下。 SPI的时序图如下&#xff0c;为了使单通道的采样速率达到最高的5MSPS&#xff…

mac m1的docker nacos2.0.3访问宿主机器的mysql

一、环境介绍&#xff1a; 我的mac系统&#xff1a;m1芯片 macOs Ventura 13.1 我的docker版本&#xff1a;v20.10.8 本机msyql&#xff1a;8.0.25 端口&#xff1a;3306。 mysql版本查询脚本&#xff1a;select version() from dual; 二、准备安装nacos2.0.3 m1版本的镜像 …

Vue+Echarts 项目演练(中)后台数据接口的创建

全局引用Echarts与axios 后台接口创建express路由 api接口数据创建 全局引用Echarts与axios vue3.0的挂载方式&#xff1a;使用Provide/Inject依赖注入&#xff0c;将替代vue2中在原型链上挂载一些属性在app.vue中使用provider来给后代们提供数据 <script> import { p…

组态王与FX3U之间无线通讯(485BD口)

设备与设备之间互相通信&#xff0c;需要一座桥梁把二者连接起来&#xff0c;那就是传输通路与通信协议。 传输通路由传输介质与传输接口组成&#xff0c;传输介质可分为有线和无线传输介质两大类。传输接口即通信模块。传输接口常见的有三种RS-232、RS-485和RS-422通信模块。…

干货|英国专利申请

英国是世界上公认的一个实施现代专利制度的国家。英国1624年颁布的《垄断法案》被认为是世界上一部具有现代意义的专利法&#xff0c;并成为现代专利保护制度系的起点。英国现行的专利法于1977年颁布&#xff0c;并于1978年生效。英国的专利制度在保护发明创造&#xff0c;促进…

21.Java网络通信

目录 1. Java基本介绍 2. JDK下载安装及其环境配置 3. 一个简单的java程序 4. Eclipse基本使用、数据类型、运算符 5. 控制语句&#xff08;if、switch、for、while、foreach&#xff09; 6. Java数组 7. Java字符串对象(String|StringBuffer|StringBuilder|StringJoiner…

Asp.NET CORE实验室信息管理系统源码,支持LIS独立部署,Docker部署

技术架构&#xff1a;Asp.NET CORE 3.1 MVC SQLserver Redis等 基于B/S架构的实验室管理系统源码&#xff0c;整个系统的运行基于WEB层面&#xff0c;只需要在对应的工作台安装一个浏览器软件有外网即可访问。全套系统采用云部署模式&#xff0c;部署一套可支持多家医院检验科…

Java ---Object根类

(一&#xff09;定义 官方说法&#xff1a; 在Java中&#xff0c; Object 类是所有类的父类&#xff0c;即Java 的所有类都继承了 Object&#xff0c;子类可以使用 Object 的所有方法。 注意&#xff1a; Object类型的变量与除Object以外的任意引用数据类型的对象都多态引用 所…

youdiancms 9.5.0 版本 SQL注入(vulfocus复现)

启动服务 从上述信息&#xff0c;可以看到&#xff0c;web服务的80端口被映射到62461端口&#xff0c;并且该服务对外开启了3306端口并映射到20130 端口。并且给了数据库的相关信息。 配置web数据库 登陆后台&#xff0c;后台如下&#xff1a; 探测注入点 上述提到注入点是M…

OpenGL教程之 纹理练习

网址 LearnOpenGL 练习一 修改片段着色器&#xff0c;仅让笑脸图案朝另一个方向看。  解析&#xff1a;朝向另一个方向很简单&#xff0c;即让上文中的图片进行左右对称变换即可&#xff0c;即将片段着色器中笑脸的纹理坐标从textCord转换为vec2( 1 - textCord.x, text.y …