找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3513|回复: 25
打印 上一主题 下一主题
收起左侧

单片机怎样用模拟PWM精确控制脉冲频率,求思路

  [复制链接]
跳转到指定楼层
#
ID:101869 发表于 2021-8-28 18:11 来自手机 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
50黑币
使用STC15F104W 定时器模拟PWM,需要精确到控制频率,也就是指定一个脉冲数,一秒时间到脉冲正好发完。求个思路!谢谢大家!

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶1 踩
回复

使用道具 举报

25#
ID:130230 发表于 2021-8-31 18:13 | 只看该作者
用定时器中断完全可行,自己提前计算好各个占空比的定时器重装载值。到时候查表重新赋值即可。
回复

使用道具 举报

24#
ID:592807 发表于 2021-8-31 16:59 | 只看该作者
Y_G_G 发表于 2021-8-29 18:12
PWMIF是中断标志寄存器,可以在PWM计数器归零时产生中断,打开这个中断充许就可以在每个归零时进入中断,你在 ...

楼主要的是模拟PWM不是硬件PWM,模拟PWM就是手动控制IO口输出高低电平,一般的做法定时器控制IO输出高低电平。
回复

使用道具 举报

23#
ID:161164 发表于 2021-8-31 10:22 | 只看该作者
非凡科技 发表于 2021-8-31 00:35
伺服十几微秒应该可以的

那就當作20us吧
  1. #include <STC15F2K60S2.H>

  2. typedef         unsigned char        u8;  //0 to 255
  3. typedef         unsigned int        u16;  //0 — 65535
  4. typedef         unsigned long        u32;  //0 — 4294967295
  5. sbit Pulse_Out = P3^7;
  6. u16 Pulse_Count, Pulse_Count_Max = 10;
  7. void Timer1Init(void)                //10us@12.000MHz
  8. {
  9.         AUXR |= 0x40;                //Timer clock is 1T mode
  10.         TMOD &= 0x0F;                //Set timer work mode
  11.         TMOD |= 0x20;                //Set timer work mode
  12.         TL1 = 0x88;                //Initial timer value
  13.         TH1 = 0x88;                //Set reload value
  14.         TF1 = 0;                //Clear TF1 flag
  15.         TR1 = 1;                //Timer1 start run
  16. }

  17. void timer1_int (void) interrupt 3  //10us@12.000MHz
  18. {
  19.                 Pulse_Out = (Pulse_Count < 2);  //20us 高电平
  20.                 if(Pulse_Count<Pulse_Count_Max)
  21.                 {
  22.                         Pulse_Count++;
  23.                 }else{
  24.                         Pulse_Count=0;
  25.                 }       
  26. }
复制代码


其中最重要的就是计算Pulse_Count_Max
如要模拟每秒1千脉冲,即1kHz
Pulse_Count_Max就等于1000000us/1000/10us =100
如要模拟每秒5千脉冲,即5kHz
Pulse_Count_Max就等于1000000us/5000/10us =20
但Pulse_Count_Max是由零开始的,所以要减一
即1kHz:Pulse_Count_Max =99
即5kHz:Pulse_Count_Max =19

评分

参与人数 1黑币 +10 收起 理由
非凡科技 + 10 很给力!

查看全部评分

回复

使用道具 举报

22#
ID:624769 发表于 2021-8-31 02:33 | 只看该作者

首先,精度肯定不高。
如果,高低电平占空比一样的话,建议:
直接拿时钟数(如24Mhz)/2/要发的脉冲数,赋值给TH0,TL0,T0也不要用中断方式翻转了IO了,直接用T0CLK_OUT, 来输出时钟, T2 计时 1秒(这个总会吧?12T模式, 定时 31.25ms, 累加32次就是一秒)满1秒关闭TR0,
回复

使用道具 举报

21#
ID:101869 发表于 2021-8-31 00:38 来自手机 | 只看该作者
188610329 发表于 2021-8-30 22:57
仅仅通过定时器,你要绝对的精准是不可能的。
首先,STC15F104W,用的是内部模拟晶振,本身就精度极低。其 ...

差几十个脉冲没事
回复

使用道具 举报

20#
ID:101869 发表于 2021-8-31 00:38 来自手机 | 只看该作者
sinside 发表于 2021-8-30 09:05
不知道我的理解是否正确:
1. 设置PWM的占空比及其频率输出是不难做到的(虽然我没有用过此款芯片), 所以1s  ...

应该芯片没问题  我试过了极限能到390K  
回复

使用道具 举报

19#
ID:101869 发表于 2021-8-31 00:36 来自手机 | 只看该作者
§uperЦser 发表于 2021-8-30 09:01
unsigned char time,duty;
sbit P0_0=P0∧0
void timer1() interrupt3

谢谢指导
回复

使用道具 举报

18#
ID:101869 发表于 2021-8-31 00:35 来自手机 | 只看该作者
lkc8210 发表于 2021-8-30 00:20
速度我知道可变
我问的是脉冲的高电平时间最短要维持多久

伺服十几微秒应该可以的
回复

使用道具 举报

17#
ID:101869 发表于 2021-8-31 00:34 来自手机 | 只看该作者
wulin 发表于 2021-8-30 08:03
按控制频率的范围和精度要求做一个16位数组表格。计算方法:定时器周期=1/频率/2。表格长度取决于频率范 ...

试试谢谢老师指导
回复

使用道具 举报

16#
ID:624769 发表于 2021-8-30 22:57 | 只看该作者
仅仅通过定时器,你要绝对的精准是不可能的。
首先,STC15F104W,用的是内部模拟晶振,本身就精度极低。其次,他的温飘非常严重,同样计时1小时,中午和夜里能相差超过20秒,所以,你真的需要精确的话,建议先换一个能外接晶振的单片机。
回复

使用道具 举报

15#
ID:935919 发表于 2021-8-30 09:05 | 只看该作者
不知道我的理解是否正确:
1. 设置PWM的占空比及其频率输出是不难做到的(虽然我没有用过此款芯片), 所以1s 发的脉冲数其实可以通过 设置PWM的频率解决.
2. 麻烦的是1s发出的脉冲数要刚刚好, 不要多一个也不要少一个: 一个可能的思路是, PWM在设置频率(周期的)时候, 同事启用周期中断---就是一个PWM周期中断一次, 然后在中断函数里面做个计数器, 如果1s的脉冲数量到了, 就停止或者切换PWM输出(频率), 有可能要注意是否提前一两个周期操作, 这个可以实际调.
至于你的芯片是否能够在17K的频率下, 完成这种操作, 就要你自己评估了.
回复

使用道具 举报

14#
ID:959439 发表于 2021-8-30 09:01 | 只看该作者
unsigned char time,duty;
sbit P0_0=P0∧0
void timer1() interrupt3
{
    time++;
    if(time==100)
    {
         time=0;
    }
    if(time>=duty)
        P0_0=1;
    else
        P0_0=0;
}
回复

使用道具 举报

13#
ID:962962 发表于 2021-8-30 08:58 | 只看该作者
网上有源码 用主辅定时器
回复

使用道具 举报

12#
ID:213173 发表于 2021-8-30 08:03 | 只看该作者
非凡科技 发表于 2021-8-29 22:55
我是看别人用89C51做出来了

按控制频率的范围和精度要求做一个16位数组表格。计算方法:定时器周期=1/频率/2。表格长度取决于频率范围和分辨率要求。定时器设置16位自动重装模式,按需直接从数组取对应数据赋值TH0、TL0重装。STC15F104W完全可以胜任。

评分

参与人数 1黑币 +10 收起 理由
非凡科技 + 10 很给力!

查看全部评分

回复

使用道具 举报

11#
ID:161164 发表于 2021-8-30 00:20 | 只看该作者
非凡科技 发表于 2021-8-28 20:18
这是一个同步调速,需要与主轴转速同步调整,也就是主轴转速快  伺服也要按比例加快

速度我知道可变
我问的是脉冲的高电平时间最短要维持多久
回复

使用道具 举报

10#
ID:101869 发表于 2021-8-29 22:55 来自手机 | 只看该作者
npn 发表于 2021-8-28 23:13
频率范围? 多少位的PWM?

我是看别人用89C51做出来了
回复

使用道具 举报

9#
ID:101869 发表于 2021-8-29 22:54 来自手机 | 只看该作者
hejianmin 发表于 2021-8-29 18:32
使用定时器就可以了
sbit pwm_out =p1^2;
unsigned char tim_ji;

您这个做不到精确的发送  比如一秒发送12345个怎么处理 时间到刚好发完
回复

使用道具 举报

8#
ID:342954 发表于 2021-8-29 18:32 | 只看该作者
使用定时器就可以了
sbit pwm_out =p1^2;
unsigned char tim_ji;
void to(void) interrupt 1
{
tim_ji++;
  if(tim_ji>100)
{
tim_ji=0;
}
if(tim_ji>50)
{
pwm_out=1;
}
else

{
pwm_out=0;
}

}
回复

使用道具 举报

7#
ID:57657 发表于 2021-8-29 18:28 | 只看该作者
非凡科技 发表于 2021-8-29 07:50
只求思路  频率17K左右

17K需要硬件PWM,此型号不支持,改用STC其他型号。
回复

使用道具 举报

6#
ID:401564 发表于 2021-8-29 18:12 | 只看该作者
PWMIF是中断标志寄存器,可以在PWM计数器归零时产生中断,打开这个中断充许就可以在每个归零时进入中断,你在中断程序中每次加1不就可以了吗?使用完之后再把加1的归零就可以了
数据手册中是有说明的,你认真看一下
这STC的PWM数据手册太多了,用不着的话,我都不想看.....
回复

使用道具 举报

5#
ID:101869 发表于 2021-8-29 07:50 来自手机 | 只看该作者
npn 发表于 2021-8-28 23:13
频率范围? 多少位的PWM?

只求思路  频率17K左右
回复

使用道具 举报

地板
ID:57657 发表于 2021-8-28 23:13 | 只看该作者
频率范围? 多少位的PWM?
回复

使用道具 举报

板凳
ID:302400 发表于 2021-8-28 21:37 | 只看该作者
非凡科技 发表于 2021-8-28 20:18
这是一个同步调速,需要与主轴转速同步调整,也就是主轴转速快  伺服也要按比例加快





那是闭环控制,可不是简简单单的PWM
回复

使用道具 举报

沙发
ID:101869 发表于 2021-8-28 20:18 来自手机 | 只看该作者
lkc8210 发表于 2021-8-28 19:52
要多快? 脉冲高电平时间是固定还是可变?

这是一个同步调速,需要与主轴转速同步调整,也就是主轴转速快  伺服也要按比例加快
回复

使用道具 举报

楼主
ID:161164 发表于 2021-8-28 19:52 来自手机 | 只看该作者
要多快? 脉冲高电平时间是固定还是可变?
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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