如何利用定时器产生PWM信号?其c程序是怎样的?

如何利用定时器产生PWM信号?其c程序是怎样的?,第1张

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

模块名称:PWM.c

功能:可调PWM波

说明:按键AN1增加占空比,按键AN2减小占空比,P0^2口输出PWM波

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

#include <reg52.h >

#define uchar unsigned char

#define uint unsigned int

uint T_1 = 10000 //定时器1初值变量

uchar flag //按键返回变量

sbit PWM = P0^2 //PWM输出口

sbit AN1 = P0^0 //增加占空比

sbit AN2 = P0^1 //减小占空比

//调节占空比函数

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

函 数 名:timer_init()

功能:定时器初始化函数

说明:无

入口参数:无

返 回 值:无

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

void timer_init()

{

TMOD = 0x11 //定时器0、定时器1工作于模式1

EA = 1 //开总中断

ET0 = 1 //定时中断0允许

ET1 = 1 //定时中断1允许

TH0 = (65536-20000)/256 //定时器0装初值:20ms

TL0 = (65536-20000)%256

TH1 = (65536-T_1)/256 //定时器1装初值:10ms

TL1 = (65536-T_1)%256

TR0 = 1 //开启定时中断0

}

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

函 数 名:timer0()

功能:定时中断0中断服务函数

说明:产生高电平,中断固定时间20ms,频率50HZ

入口参数:无

返 回 值:无

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

void timer0() interrupt 1

{

TR0 = 0 //关闭定时中断0

PWM = 1 //脉冲高电平

TH0 = (65536-20000)/256 //定时器0装初值:20ms

TL0 = (65536-20000)%256

TR1 = 1 //开启定时中断1

TR0 = 1 //开启定时中断0

}

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

函 数 名:timer1()

功能:定时中断1中断服务函数

说明:产生低电平,中断时间可变

入口参数:无

返 回 值:无

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

void timer1() interrupt 3

{

TR1 = 0 //关闭定时中断1

PWM = 0 //脉冲低电平

TH1 = (65536-T_1)/256 //定时器1装初值:10ms

TL1 = (65536-T_1)%256

}

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

函 数 名:keyscan()

功能:键盘扫描函数

说明:无

入口参数:无

返 回 值:无

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

uchar keyscan(void)

{

if(AN1==0) //AN1按下

{

while(AN1==0) //AN1松开

return 1 //返回 1

}

if(AN2==0) //AN2按下

{

while(AN2==0) //AN2松开

return 2 //返回 2

}

else return 0 //返回 0

}

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

函 数 名:change()

功能:调节占空比函数

说明:无

入口参数:无

返 回 值:无

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

void change(void)

{

flag = keyscan() //按键返回值保存

if(flag==1) //按键返回值为1,即AN1按下

{

if(T_1>=65435) //定时器初值变量大于等于65525

{

T_1 = 65530 //定时器初值变量等于65535

}

if(T_1<65525) //定时器初值变量小于65525

{

T_1 = T_1+100 //定时器初值变量加10

}

}

if(flag==2) //按键返回值为2,即AN2按下

{

if(T_1<=100) //定时器初值变量小于等于10

{

T_1 = 5 //定时器初值变量等于0

}

if(T_1>100) //定时器初值变量大于10

{

T_1 = T_1-100 //定时器初值变量减10

}

}

}

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

函 数 名:main()

功能:主函数

说明:无

入口参数:无

返 回 值:无

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

void main()

{

timer_init() //定时器初始化

while(1)

{

change() //改变占空比

}

}

你用Protues软件的示波器按照程序引脚图连一下,就是一个PWM波了,且占空比可调

哥们,这个已经很详细了;

大概说说吧,PWM[54]是定义的一组PWM脉宽输出数组,PWM脉宽输出是0-255;0的时候脉宽输出最大,255的时候脉宽输出最小;

然后那个初始化PCA,初始化定时器0就不说了,你自己下一个手册看下就明白;

然后是中断,每中断一次index加1,然后判断index是不是等于54,意思就是PWM[54]整个数组里面的PWM是不是都送了一次CCAP寄存器;如果都数组都送了一次,将index置零,从头开始送;标志位取反,如果标志位zf=1,让P14输出PWM,P13关闭;,如果zf=0,让P13输出PWM,P14关闭;if(zf==0)后面的语句就是让PWM[54]中的每一个数都送CCAP寄存器一次;

其实按这个程序注释的话,他本意是PWM波形从小变大P14输出,PWM波形有大变小P13输出;但是这个程序的实际效果是P14由小变大再由大变小。然后P14关闭,P13由小变大再由大变小

如此循环;

你最关心的PWM怎么输出:就是这两个语句,CCAP0H=pwm[index] CCAP1H=pwm[index] index每中断一次加1,那么index是由0加到54,假如说index=0 ,那么CCAP0H=pwm[0],pwm[0]对应数字里面的255,寄存器CCAP0H=255;这个寄存器等于255,PWM输出就是一个小脉宽;下一次中断CCAP0H=240了,脉宽有增加了一点;至于CCAP0H送一个数据就有脉宽输出,这个是由单片机硬件本身决定的;你看看手册就知道了;

这个已经说得很明白了吧;累死,打字都打了20分钟;


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

原文地址: http://outofmemory.cn/yw/12032264.html

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

发表评论

登录后才能评论

评论列表(0条)

保存