【嵌入式】HC32F定时器PWM捕获+APC芯片实现模拟AD采样

这篇具有很好参考价值的文章主要介绍了【嵌入式】HC32F定时器PWM捕获+APC芯片实现模拟AD采样。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一 项目背景

二 原理说明

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

四 设计实现——PWM捕获

五 梳理总结


一 项目背景

        目前使用了TI的ADC采样芯片ADS1018实现模拟量4-20mA/0-20mA的采样,原理是将外部输入的模拟量信号4-20mA,经由并联的两个100Ω电阻,转换为0.2-1V的电压信号传递到模数转换芯片的入口,再由ADS1018(全量程设置为FS=±1.024V,对应码为0x7FF)将0.2-1V电压信号转换为数据码0x190-0x7D0(400-2000),即可以将外部输入4-20mA与内部采集数据400-2000对应上,如下图所示:

【嵌入式】HC32F定时器PWM捕获+APC芯片实现模拟AD采样

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

        又因为这边AD采样的是DCS或者PLC发出来的4-20mA/0-20mA信号,必须需要外加隔离,所以不能采用MCU自带的ADC外设直接采样的方案(MCU的ADC外设没有隔离功能,必须外接隔离芯片才行),所以该方案舍弃。

        找到一款客益电子(http://www.guestgood.com/)的APC/PAC芯片,可以将输入的模拟信号转化为PWM波的占空比输出,这边选用的APC芯片为GP9101。

二 原理说明

【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)。 

【嵌入式】HC32F定时器PWM捕获+APC芯片实现模拟AD采样

【2】芯片特性:

        这边采用的芯片GP9101将输入0-VCC的信号转化为占空比0-100%,频率默认为1KHz的PWM波输出

【嵌入式】HC32F定时器PWM捕获+APC芯片实现模拟AD采样

【3】采样原理:

        参考上面ADC采样的思路,将外部输入的模拟量信号4-20mA,经由并联的两个400Ω电阻,转换为0.8-4V的电压信号传递到APC芯片的入口,再由GP9101(供电Vcc=5V)将0.8-4V电压信号转换为占空比为16-80%的PWM交由MCU进行捕获,即可以将外部输入4-20mA与内部采集数据对应上,如下图所示:

【嵌入式】HC32F定时器PWM捕获+APC芯片实现模拟AD采样

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

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

【嵌入式】HC32F定时器PWM捕获+APC芯片实现模拟AD采样

        初始化程序如下:

/* TIMER6 unit and clock definition */
#define TIMER6_UNIT1                    (M4_TMR61)
#define TIMER6_UNIT1_CLOCK              (PWC_FCG2_PERIPH_TIM61)
/* 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_APC_Config(void)  //APC测试,采样0.8V-4V电压,APC输出16%-80%占空比,经过64分频定时器捕获,输出比较值为420-2100(输入K/B需要调整为2100/400)
{
    stc_timer6_basecnt_cfg_t         stcTIM6BaseCntCfg;
    stc_timer6_port_input_cfg_t      stcTIM6CapxCfg;
    
    MEM_ZERO_STRUCT(stcTIM6BaseCntCfg);
    MEM_ZERO_STRUCT(stcTIM6CapxCfg);
    
    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/64(256分频也可以试一试)
    Timer6_Init(TIMER6_UNIT1, &stcTIM6BaseCntCfg);                          //timer6 PWM frequency, count mode and clk config

    Timer6_SetPeriod(TIMER6_UNIT1, Timer6PeriodA, 0xFFFFu);               //Period set

    stcTIM6CapxCfg.enPortSel  = Timer6xCHB;                            //Capture Input Port: PWM B port
    stcTIM6CapxCfg.enPortMode = Timer6ModeCaptureInput;                //Capture input function
    stcTIM6CapxCfg.bFltEn     = true;                                  //Input filter enable
    stcTIM6CapxCfg.enFltClk   = Timer6FltClkPclk0Div16;                //Filter clock
    Timer6_PortInputConfig(TIMER6_UNIT1, &stcTIM6CapxCfg);                 //Input config

    Timer6_ConfigHwCaptureB(TIMER6_UNIT1, Timer6HwTrigPWMBRise);       //HW Capture: Timer6 PWMB port rise trig

    Timer6_ConfigHwClear(TIMER6_UNIT1, Timer6HwTrigPWMBFall);          //HW Clear: Timer6 PWMB port fall trig
    Timer6_EnableHwClear(TIMER6_UNIT1);
    
    /*start timer6*/
    Timer6_StartCount(TIMER6_UNIT1);
}

【注】也可以使用中断进行捕获:

/* TIMER6 unit and clock definition */
#define TIMER6_UNIT1                    (M4_TMR61)
#define TIMER6_UNIT1_CLOCK              (PWC_FCG2_PERIPH_TIM61)
/* 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)

uint16_t u16CaptureA;
void Timer61_CapInputCallBack(void)
{
    u16CaptureA = Timer6_GetGeneralCmpValue(TIMER6_UNIT1, TIMER6_UNIT1_CHB);
}

void Timer6_APC_Config(void)  //APC测试,采样0.8V-4V电压,APC输出16%-80%占空比,经过64分频定时器捕获,输出比较值为420-2100(输入K/B需要调整为2100/400)
{
    stc_timer6_basecnt_cfg_t         stcTIM6BaseCntCfg;
    stc_timer6_port_input_cfg_t      stcTIM6CapxCfg;
    stc_irq_regi_conf_t              stcIrqRegiConf;
    
    MEM_ZERO_STRUCT(stcTIM6BaseCntCfg);
    MEM_ZERO_STRUCT(stcTIM6CapxCfg);
    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/64(256分频也可以试一试)
    Timer6_Init(TIMER6_UNIT1, &stcTIM6BaseCntCfg);                          //timer6 PWM frequency, count mode and clk config

    Timer6_SetPeriod(TIMER6_UNIT1, Timer6PeriodA, 0xFFFFu);               //Period set

    stcTIM6CapxCfg.enPortSel  = Timer6xCHB;                            //Capture Input Port: PWM B port
    stcTIM6CapxCfg.enPortMode = Timer6ModeCaptureInput;                //Capture input function
    stcTIM6CapxCfg.bFltEn     = true;                                  //Input filter enable
    stcTIM6CapxCfg.enFltClk   = Timer6FltClkPclk0Div16;                //Filter clock
    Timer6_PortInputConfig(TIMER6_UNIT1, &stcTIM6CapxCfg);                 //Input config

    Timer6_ConfigHwCaptureB(TIMER6_UNIT1, Timer6HwTrigPWMBRise);       //HW Capture: Timer6 PWMB port rise trig

    Timer6_ConfigHwClear(TIMER6_UNIT1, Timer6HwTrigPWMBFall);          //HW Clear: Timer6 PWMB port fall trig
    Timer6_EnableHwClear(TIMER6_UNIT1);

    /*config interrupt*/
    Timer6_ConfigIrq(TIMER6_UNIT1, Timer6INTENB, true);

    stcIrqRegiConf.enIRQn = Int003_IRQn;                    //Register INT_TMR61_GUDF Int to Vect.No.002
    stcIrqRegiConf.enIntSrc = INT_TMR61_GCMB;               //Select Event interrupt function
    stcIrqRegiConf.pfnCallback = &Timer61_CapInputCallBack; //Callback function
    enIrqRegistration(&stcIrqRegiConf);                     //Registration IRQ

    NVIC_ClearPendingIRQ(stcIrqRegiConf.enIRQn);            //Clear Pending
    NVIC_SetPriority(stcIrqRegiConf.enIRQn, DDL_IRQ_PRIORITY_04);//Set priority
    NVIC_EnableIRQ(stcIrqRegiConf.enIRQn);                   //Enable NVIC

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

四 设计实现——PWM捕获

        因为输入到MCU的PWM频率为1KHz,所以捕获定时器的周期值为:

        捕获到的PWM比较值即为:

        所以由上面方案中采样到的4-20mA对应的占空比16-80%,计算得到的比较值即为:

        程序中的PWM捕获采用Timer6_GetGeneralCmpValue接口:

/**************************************************************************
* 函数名称: analogInputHandle
* 功能描述: 模拟量输入处理
* 输入参数:
* 输出参数:
* 返 回 值:
* 其它说明:
**************************************************************************/
float analogInputHandle(STRU_ANALOG_IO_CTRL *p_analog_ctrl)
{
    //...
    //这边捕获到的比较值是根据输入进来的PWM计算得到的
    remote_ctrl.AI1_read = Timer6_GetGeneralCmpValue(TIMER6_UNIT1, TIMER6_UNIT1_CHB);
    //...
}

        采集得到的remote_ctrl.AI1_read再经过公式(本例中,K=2100,B=420),对应得到4-20:

【嵌入式】HC32F定时器PWM捕获+APC芯片实现模拟AD采样

五 梳理总结

        这个APC替代ADC用于采样模拟量输入的方案,使用比较简单方便,但是精度并没有之前使用的ADS1018(12位精度)那么好,适用于对精度要求不高的场景。文章来源地址https://www.toymoban.com/news/detail-423815.html

到了这里,关于【嵌入式】HC32F定时器PWM捕获+APC芯片实现模拟AD采样的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 嵌入式_常见延时方式的差异与选择(for循环延时、定时器延时、汇编延时....)

    这里整理几种常见的延时方式,并做简单测试供大家参考,如果有什么不对的地方,欢迎指正,共同探讨。 测试基于GD32F103CBT6硬件平台,标准的72MHz系统时钟, 使用标准库GD32F10x_Firmware_Library_V1.0.0 提示:(提示:此库坑多、慎用!) 测试方法为: 1:在Debug模式下延时开始于

    2024年02月02日
    浏览(80)
  • 【嵌入式】HC32F460串口接收超时中断+DMA

            项目需要使用一款UART串口编码器,编码器的数据以波特率57600持续向外发送。但这组数据包没有固定的包头和校验尾,仅仅是由多圈圈数和单圈角度组成的六字节数据码,这样接收到的数组无法确定实际的下标,所以这边考虑用串口接收超时中断+DMA来实现。 【

    2024年02月14日
    浏览(34)
  • 【嵌入式】HC32F07X CAN通讯配置和使用&配置不同缓冲器以连续发送

            使用小华(华大)的MCU HC32F07X实现 CAN 通讯配置和使用 【1】 CAN原理说明 (参考文章《CAN通信详解》):         CAN是控制器局域网络(Controller Area Network, CAN)的简称,是一种能够实现分布式实时控制的串行通信网络。         (i) CAN通信形式 :CAN 使用称为 C

    2024年02月06日
    浏览(42)
  • 嵌入式培训机构四个月实训课程笔记(完整版)-Linux ARM驱动编程第二天-ARM中断、定时器、看门狗(物联技术666)

    链接:https://pan.baidu.com/s/1E4x2TX_9SYhxM9sWfnehMg?pwd=1688 提取码:1688 上午:中断           吕峰老师 下午:定时器 教学内容: 一、中断 ARM 中断分为二级,分为一级中断和二级中断,二级中断为子中断,对于 ARM 来说有 50 个中断源, 其中有 32+ ( EINT23-4 ) 23-4+1-2=50 子中断源

    2024年02月19日
    浏览(48)
  • 【小黑嵌入式系统第十五课】μC/OS-III程序设计基础(四)——消息队列(工作方式&数据通信&生产者消费者模型)、动态内存管理、定时器管理

    上一课: 【小黑嵌入式系统第十四课】μC/OS-III程序设计基础(三)——信号量(任务同步资源同步)、事件标记组(与或多个任务) 下一课: 【小黑嵌入式系统第十六课】PSoC 5LP第三个实验——μC/OS-III 综合实验 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣

    2024年01月17日
    浏览(44)
  • STM32F407 滴答定时器

    介绍STM32F407滴答定时器配置方法、使用方式,封装延时函数得到精确的时间。 STM32F407参考手册中第10章介绍了滴答定时器的校准值。 M4权威指南介绍滴答定时器的章节,M3权威指南中与M4权威指南中的介绍一样。 在sys.c文件中增加滴答定时器的代码 在delay.c文件增加以下代码

    2024年02月11日
    浏览(41)
  • STM32F4X 定时器中断

    定时器(Timer)最基本的功能就是定时,比如定时翻转LED灯,定时向串口发送数据等。除此之外,定时器还可以跟GPIO结合使用,利用定时器产生PWM波形,利用定时器捕捉电平信号等。本章先来讲解定时器的最基本的用法,定时功能。 STM32F4X将定时器分成3类,分别是基本定时器,

    2024年02月12日
    浏览(38)
  • GD32F103x 定时器

    STM32的定时器主要分为三种: 高级定时器、通用定时器、基本定时器 。 即:高级定时器具有捕获/比较通道和互补输出,死区时间,通用定时器只有捕获/比较通道,基本定时器没有以上两者。  1. 基本定时器 1.时钟源 时钟源来自RCC的CK_TIMER,就是内部时钟(CK_INT)直接经过控

    2024年02月07日
    浏览(37)
  • 【MT32F006】MT32F006之定时器延时

    本文最后修改时间:2023年03月30日 一、本节简介 本文介绍如何使用MT32F006的定时器做us、ms级的延时。 二、实验平台 库版本:V1.0.0 编译软件:MDK5.37 硬件平台:MT32F006开发板(主芯片MT32F006) 仿真器:JLINK 三、版权声明 1)作者:甜甜的大香瓜 2)声明:喝水不忘挖井人,转载

    2024年02月12日
    浏览(37)
  • STM32F1定时器-PWM输出

    STM32 PWM工作过程 ARR寄存器决定PWM周期,CCR寄存器决定占空比 通道1为例 的PWM输出电路图 CCR1:捕获比较(值)寄存器(x =1,2,3,4):设置比较值。 CCMR1:OC1M[2:0]位:对于PWM方式下,用于设置PWM模式1【110】 或者PWM模式2【111】 CCER:CC1P位:输入/捕获1输出极性。0:高电平有效,1:低电平

    2024年02月09日
    浏览(73)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包