打印

急求 高手解答, PWM 控制風扇速度

[复制链接]
楼主: meetof4
手机看帖
扫描二维码
随时随地手机跟帖
21
看你的照片,好象接错线了吧?控制端和输出端不是同一个?

使用特权

评论回复
22
meetof4|  楼主 | 2012-12-22 19:18 | 只看该作者
fp123123 发表于 2012-12-22 18:19
这种风扇不是普通直流风扇,其实是无刷直流风扇,里面有调速电路,有的还用单片机控制,只用脉冲方波时,频 ...

是否改成这样

#include <reg52.h>
unsigned char timer1;
int time;
sbit PWM=P1^2;
void system_Ini()
{
    TMOD = 0x10;
TH1 = 0xfe;
TL1 = 0x33;
TR1 = 1;
    IE = 0x8A;


}
/************************************************* *
Function: delay_us();
Description:延? ?位:微秒
/************************************************* */
void delay_us(unsigned int x)
{
    unsigned int i=0;
    for(i=0;i<x;i++)
    {;}
}
main()
{ time=50;
  system_Ini();
  while(1)
  {
                          PWM=1;
  }
}
/*************************************
[ t1 (0.5ms)中?] 中?中做 PWM ?出
  ------------1000/(0.02ms*250)=200Hz
*************************************/
void T1zd(void) interrupt 3 //3 ?定?器1的中??
{
TH1 = 0xfe; //11.0592
TL1 = 0x33;
timer1++;
}


直接在电机两端加一个100UF电解电容,是否像这样不用ULN2803了,直接连在P1^2




我是一个菜鸟,很多野也不会,但我真的希望解决这个问题, 希望大家不要感到反感



使用特权

评论回复
23
meetof4|  楼主 | 2012-12-22 19:21 | 只看该作者
fp123123 发表于 2012-12-22 18:41
看你的照片,好象接错线了吧?控制端和输出端不是同一个?

只是影这张是不小心接错了
后来在测试时,控制端和输出端是在同一个

使用特权

评论回复
24
fp123123| | 2012-12-22 19:57 | 只看该作者
程序先按上面的方式,电路接成下面的方式,P1.2要设置成推勉输出或者加一个上拉电阻

使用特权

评论回复
评分
参与人数 1威望 +2 收起 理由
meetof4 + 2 很给力!
25
meetof4|  楼主 | 2012-12-22 20:15 | 只看该作者
fp123123 发表于 2012-12-22 19:57
程序先按上面的方式,电路接成下面的方式,P1.2要设置成推勉输出或者加一个上拉电阻
...



这个是什么?

使用特权

评论回复
26
fp123123| | 2012-12-22 20:25 | 只看该作者
100UF电解电容,用来把方波转换成连续的直流电压

使用特权

评论回复
27
meetof4|  楼主 | 2012-12-22 21:33 | 只看该作者
fp123123 发表于 2012-12-22 20:25
100UF电解电容,用来把方波转换成连续的直流电压

因为手头上的资源不足, 今日未能测试上面的野


前辈想问一下有关 pwm 风扇的知识

其实如果用4PIN pwm 风扇是否会方便很多

例如用在我的线路上:PWM风扇一只脚接12V一只脚接GND一只脚接出PWM的P1^ 2,余下的一只脚接在哪里
这样接驳是否正确?

用4线风扇还需要ULN吗?

程序方面又是否需要改动?

使用特权

评论回复
28
fp123123| | 2012-12-22 21:57 | 只看该作者
用4线风扇不需要ULN,4线风扇的4条线分别是红:12V,黑:GND,黄:转速输出信号,白: PWM调速输入信号,你只要把P1.2接到白线输入一个20KHz的占空比可调的方波

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
meetof4 + 1 很给力!
29
meetof4|  楼主 | 2012-12-22 22:06 | 只看该作者
fp123123 发表于 2012-12-22 21:57
用4线风扇不需要ULN,4线风扇的4条线分别是红:12V,黑:GND,黄:转速输出信号,白: PWM调速输入信号,你只要 ...

請問我的程序要改那部分才可以做到输入一个20KHz的占空比?

使用特权

评论回复
30
zhangliming420| | 2012-12-22 22:55 | 只看该作者
fp123123 发表于 2012-12-22 18:23
另外也有可能是风扇启动时,电流太大,把VCC拉低,你的单片机一直在反复RESET ...

有可能,不知道楼主用的是什么电源

使用特权

评论回复
31
fp123123| | 2012-12-22 22:57 | 只看该作者
本帖最后由 fp123123 于 2012-12-22 23:00 编辑

给你改了程序参考一下,不使用延时和中断,频率你自己调

#include <reg52.h>

sbit PWM = P1^2;

// 修改1000成其他数值可以改变方波频率
#define _MAX_TIMER_ 1000

void main()
{
  unsigned int time;
  unsigned int timer;
  unsigned int key_debounce1; // 按键1消抖动计数器
  unsigned int key_debounce2; // 按键2消抖动计数器
  unsigned char key1_state; // 按键1状态 0表示没按下 1表示按下
  unsigned char key2_state; // 按键2状态

  timer = 0;
  time = _MAX_TIMER_ / 2; // 开始时 50% 占空比
  key_debounce1 = 0;
  key_debounce2 = 0;
  key1_state = 0;
  key2_state = 0;

  for(;;)
  {
    if( key1_state==0 && (P2 & 0x01)==0 )
    {
      // 从没按下变成按下,开始计数
      key1_state = 1;
      key_debounce1 = 0;
    }

    if( key1_state==1 )
    {
      key_debounce1 += 1;
      if( (P2 & 0x01)==0x01 && key_debounce1>500 )
      {
        // 从按下变成没按下,而且时间超过设定数值,认为是有效按键
        // 修改500成其他数字可改变消抖动时间
        key1_state = 0;

        if( time<_MAX_TIMER_ ) time += _MAX_TIMER_ / 30; // 30级调速
      }
    }

    if( key2_state==0 && (P2 & 0x02)==0 )
    {
      // 从没按下变成按下,开始计数
      key2_state = 1;
      key_debounce2 = 0;
    }

    if( key2_state==1 )
    {
      key_debounce2 += 1;
      if( (P2 & 0x02)==0x02 && key_debounce2>500 )
      {
        // 从按下变成没按下,而且时间超过设定数值,认为是有效按键
        // 修改500成其他数字可改变消抖动时间
        key2_state = 0;

        if( time>=_MAX_TIMER_ / 30 ) time -= _MAX_TIMER_ / 30; // 30级调速
      }
    }

    timer += 1;
    timer = (timer % _MAX_TIMER_);

    if( timer<time ) PWM = 1;
    else PWM = 0;
  }
}

使用特权

评论回复
评分
参与人数 1威望 +2 收起 理由
meetof4 + 2 很给力!
32
meetof4|  楼主 | 2012-12-22 23:40 | 只看该作者
fp123123 发表于 2012-12-22 22:57
给你改了程序参考一下,不使用延时和中断,频率你自己调

#include


#include <reg52.h>

sbit PWM = P1^2;

// 修改1000成其他数值可以改变方波频率
#define _MAX_TIMER_ 1000  <---这个就是控制频率吗? 如果要20KHz 是否将1000 改成20000 ?

void main()
{
  unsigned int time;
  unsigned int timer;
  unsigned int key_debounce1; // 按键1消抖动计数器
  unsigned int key_debounce2; // 按键2消抖动计数器
  unsigned char key1_state; // 按键1状态 0表示没按下 1表示按下
  unsigned char key2_state; // 按键2状态

  timer = 0;
  time = _MAX_TIMER_ / 2; // 开始时 50% 占空比
  key_debounce1 = 0;
  key_debounce2 = 0;
  key1_state = 0;
  key2_state = 0;

  for(;;)
  {
    if( key1_state==0 && (P2 & 0x01)==0 ) <----这个如果无解读错,就是P2.0按下
    {
      // 从没按下变成按下,开始计数
      key1_state = 1;
      key_debounce1 = 0;
    }

    if( key1_state==1 )
    {
      key_debounce1 += 1;
      if( (P2 & 0x01)==0x01 && key_debounce1>500 )
      {
        // 从按下变成没按下,而且时间超过设定数值,认为是有效按键
        // 修改500成其他数字可改变消抖动时间
        key1_state = 0;

        if( time<_MAX_TIMER_ ) time += _MAX_TIMER_ / 30; // 30级调速
      }
    }

    if( key2_state==0 && (P2 & 0x02)==0 ) <----这个就是P2.1按下
    {
      // 从没按下变成按下,开始计数
      key2_state = 1;
      key_debounce2 = 0;
    }

    if( key2_state==1 )
    {
      key_debounce2 += 1;
      if( (P2 & 0x02)==0x02 && key_debounce2>500 )
      {
        // 从按下变成没按下,而且时间超过设定数值,认为是有效按键
        // 修改500成其他数字可改变消抖动时间
        key2_state = 0;

        if( time>=_MAX_TIMER_ / 30 ) time -= _MAX_TIMER_ / 30; // 30级调速
      }
    }

    timer += 1;
    timer = (timer % _MAX_TIMER_);

    if( timer<time ) PWM = 1;
    else PWM = 0;
  }
}

用单片机测试 将LED 连在P1^2 , 结果 led 没有反应 , 按键也没有反应

是否我解错了d code 还有一些地方要自己填写?










使用特权

评论回复
33
fp123123| | 2012-12-23 00:15 | 只看该作者
本帖最后由 fp123123 于 2012-12-23 00:29 编辑

你理解是对的

使用特权

评论回复
34
logokfu| | 2012-12-23 00:22 | 只看该作者
fp123123 发表于 2012-12-22 18:23
另外也有可能是风扇启动时,电流太大,把VCC拉低,你的单片机一直在反复RESET ...

有可能是

使用特权

评论回复
35
fp123123| | 2012-12-23 00:29 | 只看该作者
刚才看了AT89S52的PDF,不需要端口设置,但是驱动能力很小,需要外接三极管来驱动LED,直接把LED接到P1.2只有很小的电流,驱动不了。你换一个STC的单片机吧,可以设置为推勉输出,直接点亮LED,你现在的风扇不转,可能是因为单片机驱动不了ULN2803

使用特权

评论回复
36
fp123123| | 2012-12-23 00:32 | 只看该作者
我贴的程序漏了把P2的上拉电阻打开,检测不了按键,在for(;;)前面加上P2=0xFF;

使用特权

评论回复
37
fp123123| | 2012-12-23 00:35 | 只看该作者
这个程序用你现在的硬件,不用ULN2803应该可以直接驱动4线风扇,频率不一定要20KHz,多试验几个数字,找到能控制的就可以

使用特权

评论回复
38
meetof4|  楼主 | 2012-12-23 00:43 | 只看该作者
fp123123 发表于 2012-12-23 00:29
刚才看了AT89S52的PDF,不需要端口设置,但是驱动能力很小,需要外接三极管来驱动LED,直接把LED接到P1.2只 ...

现在换了 STC 12C5A60S2,
在for(;;)前面加上P2=0xFF;
LED还是未能点亮

使用特权

评论回复
39
fp123123| | 2012-12-23 00:52 | 只看该作者
不会吧?你临时这样测试一下:把程序改为只有几句

#include <reg52.h>

sbit PWM = P1^2;

void main()
{
  PWM = 1;
  for(;;){}
}

这样应该可以让LED微弱亮起来,而且不需要电解电容,可以让ULN2803输出12V的

使用特权

评论回复
40
fp123123| | 2012-12-23 00:54 | 只看该作者
本帖最后由 fp123123 于 2012-12-23 00:57 编辑

或者把PWM=1,改为PWM=0,LED负极接P1.2,正极接一个50欧电阻再接5V,好象51只能吸电流,这样驱动才行。确定你的LED没烧掉再试

使用特权

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

本版积分规则