打印

单片机如何判断输入信号是0还是PWM(100HZ,占空比5%~95%)

[复制链接]
11224|26
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
WOAILYMD|  楼主 | 2008-10-14 09:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
具体就是:

一调光电路中,灯灭的时候,对应一个信号是0;
而灯亮的时候,对应该信号则是PWM(100HZ,占空比5%~95%,仅有1,0电平构成PWM)波,灯的亮度与此PWM占空比成比例;

现欲将此信号作为输入给单片机(C51),单片机只需据此判断出任意时刻时,灯是灭呢?还是开(任意亮度)?

若通过判断0,1,则一是要引入过零判断,而是比较容易误判,PWM里有0,也有1,视过零点和占空比;

若能计算一个周期内值的总和,则还要引入过零检测,若为0,则是关状态,若不为0,则为开,但应如何设这采样率?尤其占空比较大即1电平时间较短(例如5%)时候,如何设置采样率才不会误判?

请各位大侠不吝赐教!多谢!

相关帖子

沙发
sz_kd| | 2008-10-14 09:40 | 只看该作者

读到IO口有高不就知道灯亮了吗

用中断口可以

使用特权

评论回复
板凳
红心j| | 2008-10-14 11:29 | 只看该作者

根据PWM周期来检验信号是否发生逻辑变化

使用特权

评论回复
地板
农民讲习所| | 2008-10-14 11:52 | 只看该作者

RC滤波为直流电压

使用特权

评论回复
5
WOAILYMD|  楼主 | 2008-10-14 15:23 | 只看该作者

感谢楼上各位大侠!

RC滤波为直流电压方案实验:

由于原PWM信号还有别的用途,故用了个或门,另一个输入接地,则输出就等于该PWM,把输出处理,则不改变原PWM信号的波形。

或门输出端焊了个RC滤波回路,RC串联,R取10K,C取100UF电解电容,取电解电容电压作为取样电压,由于该PWM占空比可调,则示波器观察到取样电压随着PWM占空比的改变而变化,最大输出值只有2.5V.

说明:PWM是高电平=3.3V,低电平=0V的方波。

无论PWM占空比是多少,RC滤波均能输出其高电压3.3V吗?如能,请推荐个参数。

使用特权

评论回复
6
谈的元| | 2008-10-14 19:01 | 只看该作者

用电容隔直后,用三极管转换,再RC滤波

当PWM为5%时,直接RC滤波的电压 可能低于 单片机 高电平门槛,导致误读为0

使用特权

评论回复
7
lyjian| | 2008-10-14 19:09 | 只看该作者

有没必要这么麻烦

只需要判断是否有没PWM而已,有没必要又虑波又比较的?
典型的简单事情复杂化。
只需要简单计数一下20MS内有没脉冲就知道是0还是PWM了。

使用特权

评论回复
8
5880527| | 2008-10-14 19:14 | 只看该作者

如果不判断亮度,那就扫描或中断都可以

才两K的信号嘛,开个定时器10K,随便都能扫到它

使用特权

评论回复
9
onlooker| | 2008-10-15 10:21 | 只看该作者

做个定时中断,多检测几次管脚电平,

多统计几次不就玩了? 哈哈

如果都是0,则是关闭状态。。。否则,相反。

使用特权

评论回复
10
农民讲习所| | 2008-10-15 10:39 | 只看该作者

如果不判断PWM宽度

最简单方式:将PWM直接接51的中断IO,但不打开中断。这样只要检查中断标志有无出现,就知道PWM有无输出。
如果需要判断PWM,5L的可以简单的用非门反向,电压就是从高到低变化。

使用特权

评论回复
11
红心j| | 2008-10-15 13:34 | 只看该作者

根据PWM周期来检验信号是否发生逻辑变化

只需用到信号外部中断和内部定时器中断即可完成,很简单的

使用特权

评论回复
12
WOAILYMD|  楼主 | 2008-10-15 17:30 | 只看该作者

再次非常感谢各位的建议!

判断输入信号是0还是PWM(100HZ,占空比5%~95%)最后采用如下方法:

用“农民讲习所”的办法,先用一或门将该信号引出,因其还要去驱动MOSFET管呢(具体方法见上贴5楼);然后查该IC(51内核)芯片手册,该芯片对输入的信号判断为0还是1不是根据电压(Vil和Vih),而是根据电流(Iil和Iih)大小来定的,大喜,这样即使PWM占空比最大95%(此时1电平5%,0电平95%,以前占空比的定义搞反,特别更正,不好意思,哈哈),RC滤波只有1.6V, 经实验,该51内核的IC依然可以判断为1,问题解决!

感谢诸位,特别感谢“农民讲习所”!
最后还要感谢铁岭TV,CCTV(:),大家开心下)!

使用特权

评论回复
13
WOAILYMD|  楼主 | 2008-10-15 17:40 | 只看该作者

接上延伸问题

接下来的延伸问题是:

当判断为PWM波后,有何最简单的方法计算出PWM的宽度值(精度要求一般)?

......

if(!pwm)

{

  function_whenpwmiszero();
   
}

else

{

  calculate_widthofpwm();

  function(widthofpwm);


}
......


再次请各位不吝赐教!

使用特权

评论回复
14
lyjian| | 2008-10-15 18:01 | 只看该作者

哎!!!

使用特权

评论回复
15
xc_cz| | 2008-10-16 12:11 | 只看该作者

哈哈

使用特权

评论回复
16
WOAILYMD|  楼主 | 2008-10-16 14:13 | 只看该作者

我的问题是不是太简单了,见谅!

14楼的为什么叹气呢?

另,我的IC(基于80C51内核)是一款比较“霸道”的芯片,所以,并不像通用C51芯片那样,资源任意,写程序任意,函数任意编写。

所以,烦请诸位大侠就一般判断PWM宽度的常规方法,各抒其见,越简单适用越好,我好根据芯片本身特点选用。

多谢!

使用特权

评论回复
17
WOAILYMD|  楼主 | 2008-10-16 15:13 | 只看该作者

除51通用测量脉冲宽度方法之外还有更简便的吗?

当需要INT0引脚控制计数器时  令TR0=1  GATE0=1  这样INT0脚为高电平时计数,低电平时停止计数,这样可以很方便的测量脉冲宽度。

那位大侠有比此通用办法更简单易行的算法?再次提请各位不吝赐教!

使用特权

评论回复
18
lyjian| | 2008-10-16 19:15 | 只看该作者

10楼能否解释一下

为什么“如果需要判断PWM,5L的可以简单的用非门反向,电压就是从高到低变化”?
为什么一定要反向?为什么一定要电压高到低变化才能判断PWM?

使用特权

评论回复
19
lyjian| | 2008-10-16 19:23 | 只看该作者

我叹气是因为

我看到竟然有人用这样的方法去判断一个PWM信号的有无!

使用特权

评论回复
20
WOAILYMD|  楼主 | 2008-10-17 09:21 | 只看该作者

主要我IC不是标准80C51内核,是精简后的

lyjian:

只需要判断是否有没PWM而已,有没必要又虑波又比较的?
典型的简单事情复杂化。
只需要简单计数一下20MS内有没脉冲就知道是0还是PWM了。
 
 
---------------------------------------------------------------------

是这样,我的这颗IC只是部分嵌入了原80C51的内核,所以,我只能在各位大侠提供的宝贵意见里面选一可行办法。

若想计数下20ms内有无脉冲,则当来个脉冲,其占空比最大,例如95%,此时1电平5%,0电平95%,而又不巧调用程序是(这个几率很大的)从0电平开始检测有无脉冲的话,则需等到20×95%=19ms后,才能检测到1电平,从时序上讲,浪费掉了19ms,而且如果在此19ms期间,又不巧来个中断的话,则这个脉冲就要晃过去了,就会产生误判,例如该不巧的中断耗时大于20ms,就检测不到1电平,从而误判。

而且每需要一次查询就要废掉20ms,有点可惜。而RC滤波的方法简单随用随查,不占用系统资源。但您的提醒很重要,很感谢,我将老化观察下该RC滤波方法是否可靠,简单的办法如不能经得住实践的考验,那也不能用不是,毕竟是产品,而不是科研,哈哈。

另外启动一个20ms重复查询一个I/0管脚(即PWM脉冲),您能给出个例程吗?

我所能想到的:

1、如果用定时器,只能控制20ms后是否产生中断,并不能写出一直查询0,1的语句;

2、如果用循环查询语句例如for语句,这到是个办法,根据器件振荡周期算出执行一次for语句的时间(肯定小于1的最短延迟时间20×5%=1ms,所以一个for语句肯定能查询到1如果是方波的话),再除20ms,得出需要执行for语句的次数,然后在for循环中查询,例程如下:

......
void checkpwm(void)  //开20ms,反复查询PWM是0还是方波(此时PWM有1有0)
{
  for(i=0;i<N;i++)   //N为计算出20ms需要执行for语句的次数
  {
     if(P1.X=1)
     { 
        PWM=1;
      }
  }
}

void dosth_accordingpwm(void)
{
  if(PWM=1)
  {
    ......
  }
  else
  {
    ......
  }
}

void main(void)
{
  ......
  dosth_accordingpwm();
  ......
}

继续欢迎lyjian及各位大侠就此问题和后续测量脉宽问题提出宝贵意见,谢谢!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

28

主题

203

帖子

0

粉丝