5464|8

85

帖子

0

TA的资源

一粒金砂(高级)

【HC32F448测评】+用高级定时器6输出PWM [复制链接]

本帖最后由 dmzdmz666666 于 2023-8-31 19:46 编辑

第六篇:用高级定时器6输出PWM波

这篇文章将来测评HC32F448的高级定时器6输出任意频率和占空比的PWM波、一组互补的PWM波、一组互补的带死区PWM波。

image-20230831193658-15.png

首先Timer6支持的时钟为200MHz,理论上在锯齿波计数模式下,最高能输出单边对齐的占空比50%的100MHz方波;在三角波计数模式下,最高能输出对称的占空比50%的50MHz方波。原因在于在锯齿波计数模式下,周期值可以设置为2,对比值为1,当上溢到周期值后,一个PWM波就生成完毕了。而在锯齿波计数模式下,周期值可以设置为2,对比值为1,当上溢到周期值后,只生成了半个PWM波,当下溢到周期值后,又生成了半个,这样才是完整的PWM波。(以计数值从0到溢出再到0为例)

 

image-20230831193658-16.png   image-20230831193658-17.png  

 

1、这里面有意思的是这个缓存功能,分为单缓存和双缓存。

这里需要知道人家通用周期基准值寄存器有3个(TMR6_PERAR、TMR6_PERBR、TMR6_PERCR),通用比较基准值寄存器有6个(TMR6_GCMAR、TMR6_GCMBR、TMR6_GCMCR、TMR6_GCMDR、TMR6_GCMER、TMR6_GCMFR

而单缓存的作用在于在发生递加计数上溢点或递减计数下溢点等缓存传送节点时将PERBR的值更新至PERAR,将GCMCR的值更新至GCMAR,将GCMDR的值更新至GCMBR

双缓存是在缓存传送节点时将PERCR的值更新至PERBR,将PERBR的值更新至PERAR,将GCMER的值更新至GCMCR,将GCMCR的值更新至GCMAR,将GCMFR的值更新至GCMDR。将GCMDR的值更新至GCMBR

上面说的是比较输出,捕获输入的方向与之相反。

我认为缓存的意义在于可以快速的准确的更新比较值大小,也就是占空比,因为它是在一个完整的PWM波过后更新的,不会影响前一个PWM波的完整性。但经过实际测试,我感觉优势不大,或者说在我这种使用常见下并没有什么用,下面我会说的。

2、HC32F448的死区分为软件死区和硬件死区软件死区就是设置合理的比较值(GCMAR、GCMBR)和极性,使其产生带死区的互补PWM波。硬件死区就是设置合理的比较值(GCMAR)和死区时间值(DTUAR、DTDAR),而GCMBR是根据这3个寄存器(GCMAR、DTUA、DTDAR)计算出来的。具体的说,在上溢过程中,GCMBR=GCMAR-DTUAR,下溢过程中,GCMBR=GCMAR-DTDAR,同时也支持单缓存,具体怎么样呢,下面会测试。

3、其他特色功能我没怎么用,所以就不赘述了。

--------------------开始移植-------------------

这里需要用到的资源包括定时器6。

首先,在Hardware文件夹中新建Timer6.c等C文件及其对应的h头文件。同时还要添加hc32_ll_tmr6.c的库函数。还要记得使能hc32f4xx_conf.h的对应组件。

Timer6的初始化大致分为

  1. 使能对应时钟FCG2_PERIPH_TMR6_1
  2. 开启GPIO复用功能
  3. 设置时钟源
  4. 设置周期值
  5. 设置死区(可选)
  6. 设置缓存模式及传送节点
  7. 设置PWM的起始、溢出等极性
  8. 设置比较值
  9. 设置PWM模式,是比较输出还是捕获输入。
  10. 使能PWM输出
  11. 开启定时器

这里我挑几个讲,其他可以看我提供的测试程序。

首先是设置时钟源,这个设置合适的分频数和周期数,因为周期基准寄存器(如TMR6_PERAR)只有16位,PeriodValue最多设置65536,所以你的最低频率是200MHz / ClockDiv / 65536,最低频率是200MHz / ClockDiv ,我这里就选择不分频,这样好计算一些,同时频率可以设置较高。然后设置周期数PeriodValue,也就是决定输出频率,有两种方式,如下图所示,我推荐第2种,这样修改起来更方便。还有一点需要注意,在三角波计数模式下,实际输出的频率为200MHz / (2*PeriodValue),具体原因如开头介绍的。

 

image-20230831193658-18.png

缓存模式我这里选择不使能,具体原因我下面会测试。

 

image-20230831193658-19.png  

缓存时间配置有下面4种,下图1,具体寄存器及定义如下图2

 

image-20230831193658-20.png

 

image-20230831193658-21.png

设置PWM的起始、溢出等极性,个人觉得比较重要的是CompareValue、StartPolarity、StopPolarity、CountUpMatchAPolarity、CountDownMatchAPolarity、CountUpMatchBPolarity、CountDownMatchBPolarity。CompareValue也就是比较值也有两种方式,推荐第二种

 

image-20230831193658-22.png

 

StartPolarity、StopPolarity决定了起始和停止的输出极性,

如果StartPolarity=TMR6_PWM_HIGH,StopPolarity=TMR6_PWM_HIGH,

么你设置的比较值决定了正占空比;

如果StartPolarity=TMR6_PWM_LOW,StopPolarity=TMR6_PWM_LOW

那么你设置的比较值决定了负占空比;
CountUpMatchAPolarity、CountDownMatchAPolarity、CountUpMatchBPolarity、CountDownMatchBPolarity这4个参数决定了上溢或者下溢时的PWM极性。有以下4种配置

#define TMR6_PWM_LOW                        (0x00U)

#define TMR6_PWM_HIGH                       (0x01U)

#define TMR6_PWM_HOLD                       (0x02U)

#define TMR6_PWM_INVT                       (0x03U)

对于PWMA,其对应的比较值寄存器为GCMAR时,当溢出时要翻转,当比较值寄存器GCMBR溢出时要保持;同样的,对于PWMB,其对应的比较值寄存器为GCMBR时,当溢出时要翻转,当比较值寄存器GCMAR溢出时要保持,具体程序如下图。

image-20230831193658-23.png  

 

 

-------------------------实际测试---------------------

 

1、首先输出10KHz的PWM波,PWMA也就是PA8输出正占空比为40%;PWMB也就是PA7输出负占空比为40%

TMR6_SetPeriodValue(CM_TMR6_1, TMR6_PERIOD_REG_A, 10000);

TMR6_SetCompareValue(CM_TMR6_1, TMR6_CMP_REG_A, 4000U);

TMR6_SetCompareValue(CM_TMR6_1, TMR6_CMP_REG_B, 4000U);

 

image-20230831193658-24.png

 

还可以通过按键来切换成输出100KHz的PWM波,PWMA输出正占空比为20%;PWMB输出负占空比为90%

 

image-20230831193658-25.png

 

image-20230831193658-26.png

 

这里也测试了一下缓存传送,

设置stcBufConfig.u32BufTransCond = TMR6_BUF_TRANS_UDF;

然后在初始化程序和按键中关于TMR6_SetCompareValue函数改成

TMR6_SetCompareValue(CM_TMR6_1, TMR6_CMP_REG_C, 2000U);

TMR6_SetCompareValue(CM_TMR6_1, TMR6_CMP_REG_D, 9000U);

还有使能对应缓存传送

TMR6_GeneralBufCmd(CM_TMR6_1, TMR6_CH_A, ENABLE);

TMR6_GeneralBufCmd(CM_TMR6_1, TMR6_CH_B, ENABLE);

其他保持一致,发现效果跟不开启缓存是一致,我个人觉得还不如不开启缓存传送来的方便,还不需要配置缓存模式,直接修改更方便。

这里需要注意,如果要使用周期基准的缓存传送,需要用到TMR6_PeriodBufConfig()和TMR6_PeriodBufCmd(),上面的程序只配置比较值基准的缓存传送。

然后测试一下死区,具体配置如下

 

image-20230831193658-27.png

 

实际测量死区时间为500 *1/200M=2.5us,符合设置。PWMB的负占空比变为了35%。但是我发现不开启死区时间设定,直接将PWMB的比较值改成3500是同样的效果,所以说实际上硬件死区就是确定了PWMA的比较值和死区时间,系统自动算PWMB的比较值,其实道理都一样的。

 

image-20230831193658-28.png

至此,定时器6和PWM输出就测评好啦,功能还是很强的。

HC32F448_TIMER6_PWM.zip

1.31 MB, 下载次数: 22

最新回复

UUC
感谢楼主的分享,学习了,学习了~~~  详情 回复 发表于 2023-9-25 18:47

回复
举报

85

帖子

0

TA的资源

一粒金砂(高级)

欢迎大家交流和提出问题


回复

5637

帖子

6

TA的资源

版主

死区时间是固定的吗?更改不同的频率死区会变化吗?  

点评

死区时间是固定的 你改变了频率 那死区时间是不会改变的 改变的只是死区时间在整个周期里面的占比  详情 回复 发表于 2023-9-1 11:41
个人签名

在爱好的道路上不断前进,在生活的迷雾中播撒光引


回复

6763

帖子

9

TA的资源

版主

Timer6的初始化大致分为

  1. 使能对应时钟FCG2_PERIPH_TMR6_1
  2. 开启GPIO复用功能
  3. 设置时钟源
  4. 设置周期值
  5. 设置死区(可选)
  6. 设置缓存模式及传送节点
  7. 设置PWM的起始、溢出等极性
  8. 设置比较值
  9. 设置PWM模式,是比较输出还是捕获输入。
  10. 使能PWM输出
  11. 开启定时器

回复

85

帖子

0

TA的资源

一粒金砂(高级)

秦天qintian0303 发表于 2023-9-1 08:51 死区时间是固定的吗?更改不同的频率死区会变化吗?  

死区时间是固定的 你改变了频率 那死区时间是不会改变的 改变的只是死区时间在整个周期里面的占比


回复

7274

帖子

18

TA的资源

五彩晶圆(中级)

没有直接干的库函数吗?好复杂

点评

这就是库函数呀  详情 回复 发表于 2023-9-22 10:16
个人签名

默认摸鱼,再摸鱼。2022、9、28


回复

85

帖子

0

TA的资源

一粒金砂(高级)

freebsder 发表于 2023-9-21 20:07 没有直接干的库函数吗?好复杂

这就是库函数呀

点评

看代码看晕了。  详情 回复 发表于 2023-9-25 18:44

回复

7274

帖子

18

TA的资源

五彩晶圆(中级)

看代码看晕了。

个人签名

默认摸鱼,再摸鱼。2022、9、28


回复

891

帖子

0

TA的资源

纯净的硅(中级)

感谢楼主的分享,学习了,学习了~~~



回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
推荐帖子
ARM 系列内核介绍

ARM 系列内核介绍

LED灯驱动电源设计-郭春明-上海会议演讲稿下载

48317

今天把基于C8051F320的湿度计完工,公布所有代码!

做了C8051F320的湿度计的个人收尾工作: 1、加了一块锂充电电池,修改了充电电路。修改方法见我其他的帖子,不再罗嗦了。这个 ...

一次“血”的教训之Xilinx FPGA菊花链

这篇文章主要是还原一个“事故”现场,具体原因有待进一步分析。 遇难芯片:1片Xilinx FPGA XC5VSX95T、1片PROM XCF32P、2片 ...

Altium designer 圆弧形阵列粘贴和极坐标的使用

是这样的,今天下午(6/11)有个朋友问到我一个圆弧形阵列粘贴的问题,提出了如下图所示的要求, 所以我在想可能做LED行业和其 ...

ESK32-360 – HT32F1653/1654的开发板

ESK32-360 – HT32F1653/1654的开发板 ESK32-360开发板是为HT32F1653/1654系列MCU设计,使用一颗HT32F ...

数字下变频的FPGA实现

525551

lierda 的NB-IOT模组 是基于海思的BOUDICA芯片组开发的,请问lierda 加了什么东西

下图是 一个利尔达的产品介绍,请问lierda 的NB-IOT模组 是基于海思的BOUDICA芯片组开发的,请问lierda 在海思芯片组的基础上 加 ...

PCB

PCB布局流程怎么考虑

蓄电池供电升压降压电路方案请教

电路要求蓄电池供电,升降压电压波动范围为10-13V之间,现在需要12V的稳定输出,要求自动升降压,能实现自动稳压和不间断输出。 ...

关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表