帮我详细的注释一下PWM? 谢谢。

帮我详细的注释一下PWM? 谢谢。,第1张

介绍了PWM 技术的基本原理,并详细介绍了在智能充电器中采用的PWM技术的方法和其优缺点,并针对问题提出了更加合理的解决方案,本文介绍的方法主要面向镍氢和镍镉电池充电器等应用

PWM技术的基本原理

随着电子技术的发展,出现了多种PWM技术,其中包括:相电压控制PWM、脉宽PWM法、随机PWM、SPWM法、线电压控制PWM等,而本文介绍的是在镍氢电池智能充电器中采用的脉宽PWM法。它是把每一脉冲宽度均相等的脉冲列作戚缓睁为PWM波形,通过改变脉冲列的周期可以调频,改变脉冲的宽度或占空比可以调压,采用适当控制方法即可使电压与频率协调变化。可以通过调整PWM的周期、PWM的占空比而达到控制充电电流的目的。

PWM技术的具体应用

PWM软件法控制充电电流

本方法的基本思想就是利用单片机具有的PWM端口,在不改变PWM方波周期的前提下,通过软件的方法调整单片机的PWM控制寄存器来调整PWM的占空比,从而控制充电电流。本方法所要求的单片机必须具有ADC端口和PWM端口这两个必须条件,另外ADC的位数尽量高,单片机的工作速度尽量快。在调整充电电流前,单片机先快速读取充电电流的大小,然后把设定的充电电流与实际读取到的充电电流进行比较,若实际电流偏小则向增加充电电流的方向调整PWM的占空比;若实际电流偏大则向减小充电电流的方向调整PWM的占空比。在软件PWM的调整过程中要注意ADC的读数偏差和电源工作电压等引入的纹波干扰,合理采用算术平均法等数字滤波技术。软件PWM法具有以下优缺点。

优点:

简化了PWM的硬件电路,降低了硬件的成本。利用软件PWM不用外部的硬件PWM和电压比较器,只需要功率MOSFET、续流磁芯、储能电容等元器件,大大简化了外围电路。

可控制涓流大小。在PWM控制充电的过程中,单片机可实时检测ADC端口上充电电流的大小,并根据充电电流大小与设定的涓流进行比较,以决定PWM占空比的调整方向。

电池唤醒充电。单片机利用ADC端口与PWM的寄存器可以任意设定充电电流的大小,所以,对于电池电压比较低的电池,在上电后,可以采取小电流充一段时间的方式进行充电唤醒,并且在小电流的情况下可以近似认为恒流,对电池的冲击破坏也较小。

缺点:

电流控制精度低。充电电流的大小的感知是通过电流采样电阻来实现的,采样电阻上的压降传到单片机的ADC输入端口,哪颂单片机读取本端口的电压就可以知道充电电流的大小。若设定采样电阻为Rsample(单位为Ω),采样电阻的压降为Vsample(单位为mV), 10位ADC的参考电压为5.0V。则ADC的1 LSB对应的电压值为 5000mV/1024≈5mV。一个5mV的数值转换成电流值就是50mA,所以软件PWM电流控制精度最大为50mA。若想增加软件PWM的电流控制精度,可以设法降低ADC的参考电压或采用10位以上ADC的单片机。

PWM采用软启动的方式。在进行大电流快速充电的过程中,充电从停止到重新启动的过程中,由于磁芯上的反电动势的存在,所以在重新充电时必须降低PWM的有效占空比,以克服由于软件调整PWM的速度比较慢而带来的无法控制充电电流的问题。

充电效率不是很高。在快速充电时,因为采用了充电软启动,再加上单片机的PWM调整速度比较慢,所以实际上停止充电或小电流慢速上升充电的时间是比较大高岁的。

为了克服2和3缺点带来的充电效率低的问题,我们可以采用充电时间比较长,而停止充电时间比较短的充电方式,例如充2s停50ms,再加上软启动时的电流慢速启动折合成的停止充电时间,设定为50ms,则实际充电效率为(2000ms-100ms)/2000ms=95%,这样也可以保证充电效率在90%以上。

纯硬件PWM法控制充电电流

由于单片机的工作频率一般都在4MHz左右,由单片机产生的PWM的工作频率是很低的,再加上单片机用ADC方式读取充电电流需要的时间,因此用软件PWM的方式调整充电电流的频率是比较低的,为了克服以上的缺陷,可以采用外部高速PWM的方法来控制充电电流。现在智能充电器中采用的PWM控制芯片主要有TL494等,本PWM控制芯片的工作频率可以达到300kHz以上,外加阻容元件就可以实现对电池充电过程中的恒流限压作用,单片机只须用一个普通的I/O端口控制TL494使能即可。另外也可以采用电压比较器替代TL494,如LM393和LM358等。采用纯硬件PWM具有以下优缺点。

优点:

电流精度高。充电电流的控制精度只与电流采样电阻的精度有关,与单片机没有关系。不受软件PWM的调整速度和ADC的精度限制。

充电效率高。不存在软件PWM的慢启动问题,所以在相同的恒流充电和相同的充电时间内,充到电池中的能量高。

对电池损害小。由于充电时的电流比较稳定,波动幅度很小,所以对电池的冲击很小,另外TL494还具有限压作用,可以很好地保护电池。

缺点:

硬件的价格比较贵。TL494的使用在带来以上优点的同时,增加了产品的成本,可以采用LM358或LM393的方式进行克服。

涓流控制简单,并且是脉动的。电池充电结束后,一般采用涓流充电的方式对电池维护充电,以克服电池的自放电效应带来的容量损耗。单片机的普通I/O控制端口无法实现PWM端口的功能,即使可以用软件模拟的方法实现简单的PWM功能,但由于单片机工作的实时性要求,其软件模拟的PWM频率也比较低,所以最终采用的还是脉冲充电的方式,例如在10%的时间是充电的,在另外90%时间内不进行充电。这样对充满电的电池的冲击较小。

单片机 PWM控制端口与硬件PWM融合

对于单纯硬件PWM的涓流充电的脉动问题,可以采用具有PWM端口的单片机,再结合外部PWM芯片即可解决涓流的脉动性。

在充电过程中可以这样控制充电电流:采用恒流大电流快速充电时,可以把单片机的PWM输出全部为高电平(PWM控制芯片高电平使能)或低电平(PWM控制芯片低电平使能);当进行涓流充电时,可以把单片机的PWM控制端口输出PWM信号,然后通过测试电流采样电阻上的压降来调整PWM的占空比,直到符合要求为止。

你那个地方毕森不明白?能具体说说吗?我看程序已经有不少注释了啊?

下面的比较多,复杂些,先简单的说下吧:

一、加速减速,就是增加或减少脉冲宽度,改变电机速度!脉冲的宽度由

1、CLK=0的状态持续,由T1的定时决定;

2、CLK=1的状态持续,由(T0-T1)的时间决定;

二、定时器中断TH0=0x00    TL0=0x00 

1、T0定时器工作1方式,T0定时器启动后,从TH0、TL0赋值的计数值开始增加,增加到0XFFFF后,T0中断!

2、T0溢出后(中断),T0计数器不会自动停止,所以需要重新给T0定时器赋值!赋值后,进入下一个计数周期!

3、例子中,T0定时器从0x0000开始计数,也就是增加0xFFFF后进行中断!定时时间为 (0xFFFF / ( 晶振周期/12 ))) 秒,若晶振为12M,则定时为,65.536ms!

分析程序槐数备,从main开始分析,先将起始开始的时序图画出铅毁:

如下图!

从时序图可以看出,CLK为PWM输出,

1、CLK=0的状态持续,由T1的定时决定;

2、CLK=1的状态持续,由T0-T1的时间决定;

而   main   函数中的  while(1)   部分,进行的就是PWM调整程序。

1、  if (K3==0)   //高电平逆时钟转,低电平顺时钟转

{

ZF=0

}

else

{

ZF=1

}

根据程序推测,程序若为电机控制,K3开关为0时,ZF=0,顺时针转,K3开关为1时,ZF=1,逆时针转。

2、

if(K1==0)   //按下加速键

{

delay(1)

PWML++   //调宽值低四位加1

if(PWML==0x00)

{

PWMH++

}   //调宽值高四位加1

if (PWMH==0xFF) //最大值时

{

PWMH=0xFE

}

}

K1按键,加速按键,增加T1定时器计数起始时间,也就是减少T1计数时间,减少CLK=0的时间。

3、

if(K2==0) //按下减速键

{

delay(1)

PWML--    //调宽值低四位减1

if (PWML==0x00)

{

PWMH--

}    //调宽值高四位减1

if (PWMH==0x00)

{

PWMH=0x01

}   //最小值时

}

K2按键,减速按键,降低T1定时器计数起始时间,也就是增加T1计数时间,增加CLK=0的时间。

4、不论加速、减速,T0的时间都不变,CLK=0和CLK=1总持续时间不变{ (Tclk0+Tclk1)=T0 }。

程序不难,图不好画啊!

#include <reg52.h>//头文件

#define uchar unsigned char

#define uint unsigned int

sbit KEY1= P3^4 //定义按钮

sbit KEY2= P3^5 //定义按钮

sbit PWM= P1^7//PWM输出的管脚定义

#define PERIOD 1000 //pwm周期

#define MIN_POSITIVE 100 //最小占空比100/1000

#define MAX_POSITIVE 900 //最大占空比900/1000

#define STEP 10 //步长

uint POSITIVE=MIN_POSITIVE

void delay(uint i)//延时函数

{

while(--i)

}

void init_timer0()//设置定时器

{

TMOD=0X01

TL0=(POSITIVE-PERIOD)%256//具体此袜数怎么实现的你看一下51单片机定时器的东西,TLO,THO。

TH0=(POSITIVE-PERIOD)/256

ET0=1

}

void init_timer1() // 初始化定时器

{

TMOD|=0X10

TL1=(0-POSITIVE)%256

TH1=(0-POSITIVE)/256

ET1=1

EA=1

}

void TIMER0_ISR(void)interrupt 1 //中断响应函数

{

TL0=(POSITIVE-PERIOD)%256

TH0=(POSITIVE-PERIOD)/256

TR0=0

TR1=1

PWM=0

}

void TIMER1_ISR(void)interrupt 3 //中断响应函数

{

TL1=(0-POSITIVE)%256

TH1=(0-POSITIVE)/256

TR1=0

TR0=1

PWM=1

}

void key_scan()按钮扫描函数

{

uint step=0

step=(PERIOD-MIN_POSITIVE-100)/STEP

KEY1=1

KEY2=1

if(KEY1==0||KEY2==0)

{

delay(100)

if(KEY1==0)

{

POSITIVE+=step

if(POSITIVE>MAX_POSITIVE)

POSITIVE=MAX_POSITIVE

}

if(KEY2==0)

{

POSITIVE-=step

if(POSITIVE<MIN_POSITIVE)

POSITIVE=MIN_POSITIVE

}

while(KEY1==0||KEY2==0)

}

}

void main() //主函数

{

init_timer0()

init_timer1()

TR0=1

while(1)key_scan()

}

//这里的意思就是高电森首平使用一个定时器,低电平使用一个定时器,其实可以使用一个定时器就可以完成这个任务。他的左右只是1ms响应一个中断,然后计数。

/****************************************/

#include <REGX51.H>

#define TIMER0_COUNT 0xFC18 //每秒中端1000次

unsigned long int m,a

static void timer0_isr(void) interrupt 1 using 1

{

TR0=0

TL0=(TIMER0_COUNT &0x00FF)

TH0=(TIMER0_COUNT >>8)

TR0=1

m++

}

static void timer0_initialize(void)

{

EA=0/* 设定系统不接好陆受所有的中断 */

m=0

TR0=0 /* 关闭Timer0 */

TMOD =0x01 /* 设定计时器0为16位的工作模式 */

TL0=(TIMER0_COUNT &0x00FF) /* 设定TL0的数值 */

TH0=(TIMER0_COUNT >>8) /* 设定TH0的数值 */

PT0=0 /* 设定计时器0有比较高的优先级 */

ET0=1 /* 设定接受Timer0的中断 */

TR0=1 /* 启动Timer0 */

EA=1/* 设定系统接受中断 */

}

void main (void)

{

timer0_initialize()

P2_0=0

P2_1=1

P3_0=0

P3_1=1

a=25

while(1)

{

if(m==a)

{

P2_2=0

P3_2=0

}

if(m==50)

{

P2_2=1

P3_2=1

m=0

}

}

}

/****************************************/

这是我之前写的程序,你看看吧。希望对你有帮助,这个好理解点


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/12296827.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-24
下一篇 2023-05-24

发表评论

登录后才能评论

评论列表(0条)

保存