OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4445|回复: 1

定时器产生特定频率PWM信号的算法及疑点

[复制链接]

1

主题

1

帖子

0

精华

新手入门

积分
8
金钱
8
注册时间
2023-3-13
在线时间
1 小时
发表于 2023-3-13 18:33:59 | 显示全部楼层 |阅读模式
2金钱
lz写了一份能够计算产生特定频率pwm的代码,相对误差大约在1%以内。但是我并不清楚这个算法的数学依据是什么,希望各位能够帮忙解决一下。
  1. struct {
  2.         unsigned long int prescale;
  3.         unsigned long int autoreload;
  4.         unsigned long int err;
  5. }pwm, pwm_calc;

  6. void pwm_generate(unsigned long int freq)
  7. {
  8.         memset(&pwm, 0x00, sizeof(pwm));
  9.         memset(&pwm_calc, 0x00, sizeof(pwm_calc));
  10.         pwm.err = pwm.err - 1;
  11.         for (pwm_calc.prescale = 1; pwm_calc.prescale < 65535UL && pwm_calc.prescale; pwm_calc.prescale++) {
  12.                 pwm_calc.autoreload = (80000000UL / ((pwm_calc.prescale + 1) * freq)) - 1;
  13.                 if (pwm_calc.autoreload > 65535UL || pwm_calc.autoreload < 100)
  14.                         continue;
  15.                 if (pwm_calc.autoreload * pwm_calc.prescale > freq)
  16.                         pwm_calc.err = pwm_calc.autoreload * pwm_calc.prescale - freq;
  17.                 else
  18.                         pwm_calc.err = freq - pwm_calc.autoreload * pwm_calc.prescale;
  19.                 if (pwm_calc.err < pwm.err)
  20.                         memcpy(&pwm, &pwm_calc, sizeof(pwm));
  21.         }
  22.         return;
  23. }
复制代码
附件里为测试结果

测试结果

测试结果
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

10

主题

3281

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8206
金钱
8206
注册时间
2020-5-11
在线时间
3700 小时
发表于 2023-3-14 17:23:32 | 显示全部楼层
分频值(prescale) 与 重装值(autoreload) 决定PWM频率;
看起来,这段代码就是遍历(挨个偿试)不同的分频值,再根据所需频率算出重装值,再根据当前的 分频值与重装值算出实际频率,
与所需频率相减得到误差,最后保存误差最小的那一组分频值与重装值。
专治疑难杂症
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-24 14:47

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表