本帖最后由 wsy2220 于 2012-6-3 14:06 编辑
最近略蛋疼,弄了一个服务器上拆下来的台达的暴力扇玩,型号AFC1212DE.12V1.6A,全速4000转,支持pwm调速。我打算接到主板的4pin接口来调速,毕竟暴力扇的噪音不是一般的大。等我接上去之后才发现,尼玛坑爹了。
暴力扇:
话说两年前我还是小白一枚,去电脑城被忽悠买了这个板,2敏DEG53-RA,790GX+AM39+DDR3.捷波代工的,做工还过得去,但是二三线厂商的BIOS研发能力实在是太烂了。主板上的温度监控和风扇调速芯片是Fintek F71863,这颗芯片是支持PWM调速的,而且主板上的风扇接口也是4pin的。之前一直用的3pin风扇,电压调控是正常的,没试过PWM风扇,这回把风扇插上去,进BIOS一看,居然没有PWM调速的选项,还是只能电压调速。更坑爹的是用AMIBCP打开BIOS看了下,是有PWM调速的相关字符串的,但是实际上显示不出来。所以买主板还是要选一线大厂的,血的教训啊。
BIOS设置中只有转速调接选项:
AMIBCP里PWM调速的相关选项:
身为穷学生一枚,一直没有足够的预算换主板,所以只能自己想办法解决了。虽然没钱,但是我有折腾的精神。试过改BIOS,甚至试过刷其他厂商的BIOS(http://bbs.pceva.com.cn/thread-44951-1-1.html),但是都没有解决。因此只能想办法DIY了。既然主板能提供12V直流电压输出,那么要实现调速缺少的就是PWM信号了。开始之前,我们先看看PWM风扇调速的原理。
脉冲宽度调制(PWM),是英文“PulseWidth Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。(http://baike.baidu.com/view/168039.htm) 简单说来,就是产生一个方波,在一个周期内高电平的时间越长,对风扇来说,转速越快。当信号全部是高电平的时候达到转速最大,全低则为最低转速。
PWM信号的波形:
那么要怎样获得这样一个可调的方波信号呢?我把目光瞄向了主板上的speaker接口。这个插口为speaker提供一个方波信号,在BIOS自检结束以后发出“哔”的一声。
将风扇pwm信号线单独抽出来:
通过查阅资料了解到,这个接口是由外围接口芯片8255和定时器芯片8253控制的。当然,这是最早期的PC上的情况,现在这些芯片全都集成到主板芯片组里了,但是接口地址依然保持兼容。将61H端口的第0位置0,第1位置1可以输出高电平,第1位置0可输出低电平(实际上是高阻状态)。因此可以通过编程来实现不同占空比的方波输出。
Speaker接口的电路图:
简化的电路(http://www.iteedu.com/plang/asm/asmpcshzhjj/4-1.php):
实际的speaker接口,电容电阻和与门清晰可见:
不得不感叹一下,几十年过去了,这些设计依然保持着最初的状态,呵呵.
有意思的是由于speaker接口是直接与8255相连的,因此高电平时输出电平仅有0.1V,而intel规范中的PWM信号低电平上限是0.8V,因此在风扇看来此处的输出高电平是低电平,而此接口的低电平(高阻)则是高电平。所以在编程序的时候要注意高电平的时间越长,风扇转速越低。
由于在DOS下用汇编语言可以方便的访问IO接口,所以我先用汇编语言写了个小程序,在DOS下试验了一下,效果很好,能够实现无级变速。不过根据intel的PWM规范,提供给PWM风扇的信号频率应该在25KHz左右(感谢R大提供的资料http://bbs.pceva.com.cn/thread-47104-1-1.html)。而主板为了speaker发出的声音更悦耳(汗),在接口上加了个低通滤波器,导致高于20KHz的信号就无法送到插座上,因此我只能用大约几千HZ的PWM信号。不过事实证明,这样的信号依然能够实现调速,风扇也工作得很好,当然,如果把主板上那个电容抠掉,应该能达到更高的频率,也不会有其他副作用。
- 汇编语言代码:
- STACK SEGMENT STACK 'STACK'
- ST1 DB 128 DUP(?)
- TOP EQU LENGTH ST1
- STACK ENDS
- CODE SEGMENT
- ASSUME CS:CODE,SS:STACK
- MAIN PROC FAR
- START: MOV AX,STACK
- MOV SS,AX
- PUSH DS
- MOV AX,0
- PUSH AX
- MOV AL,10110110B
- OUT 43H,AL
- MOV BX,00FFH
- MOV DX,00FFH
- PWM:
- MOV CX,BX
- HI:
- MOV AL,2
- OUT 61H,AL
- LOOP HI
- MOV CX,DX
- LW:
- MOV AL,0
- OUT 61H,AL
- LOOP LW
- MOV AH,02H
- INT 16H
- TEST AL,01000000B
- JNZ RTN
- TEST AL,00000001B
- JNZ HIPLUS
- TEST AL,00000010B
- JNZ HIMNS
- TEST AL,00000100B
- JNZ LWPLUS
- TEST AL,00001000B
- JNZ LWMNS
- JMP PWM
- HIPLUS:
- INC BX
- JMP PWM
- HIMNS:
- DEC BX
- JMP PWM
- LWPLUS:
- INC DX
- JMP PWM
- LWMNS:
- DEC DX
- JMP PWM
- RTN:
- MOV AL,2
- OUT 61H,AL
- RET
- MAIN ENDP
- CODE ENDS
- END
复制代码
折腾无极限,我又想试试在Windows下也实现调速。不过Windows下为了安全,不允许直接访问I/O端口。当然,对于想折腾的我,哪能被这点困难吓倒。又经过一番折腾,才找到一个办法:winio库。对于一个C++初学者来说,这个过程可不容易
好不容易写好了一个小程序,令我纠结的事情又来了,Windows运行在保护模式下,要做到精确定时非常难,所以只能调用精度很差的delay函数,仅精确到毫秒级,pwm信号频率也只有100HZ,而且很容易受其他程序的干扰。结果就是,看网页的时候滚动一下,风扇转速就变一下(泪奔)。而要实现高精度计时,就要让一个CPU满载,得不偿失啊。
好吧,折腾就到此为止吧,这风扇还是留着冲风冷极限用吧,要实现更好的功能,还是单片机更方便。其实我想说,DIY精神在于将手中的东西发挥到极致,在这个过程中动脑筋,折腾,享受折腾思考和学习的乐趣。为了实现这个简单的功能,这几天的折腾查了不少资料,学了不少知识.
最后附上两个程序和源代码。DOS下左shift和左ctrl增加高电平并减小低电平(转速升高),右shift和右ctrl减小高电平并增加低电平(转速降低).Windows下输入转速等级(1-10),回车开始输出,按ctrl+end停止,运行中可用ctrl+(+)和ctrl+(-)来调节,并且需要在启动时按f8禁用驱动程序强制签名.都是入门水平,老鸟勿喷。
全文完,谢谢各位观看
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
评分
-
查看全部评分
|