Pwm程序流程图.docx
- 文档编号:24729228
- 上传时间:2023-06-01
- 格式:DOCX
- 页数:20
- 大小:67.39KB
Pwm程序流程图.docx
《Pwm程序流程图.docx》由会员分享,可在线阅读,更多相关《Pwm程序流程图.docx(20页珍藏版)》请在冰豆网上搜索。
Pwm程序流程图
Pwm程序流程图
首先我们要确定频率和占空比,我们选用12MHZ晶振,让PWM输出频率为1KHZ,让定时中断次数为C=100,即0.01MS中断一次,则TH0=FF,TL0=F6;由于设定中断时间为0.01ms,这样可以设定占空比可从1-100变化,即0.01ms*100=1ms.TH0和TL0是计数器0的高8位和低8位计数器,计算方法:
TL0=(65536—C)%256;TH0=(65536-C)/256,其中C为所要计数的次数;TMOD是计数工作模式选择,TMOD=0X01表示选用模式1,它有16位计数器,最大计数脉冲为65536,最长时间为65.536ms。
开始
是
否
#include〈REGX51.H〉
#defineucharunsigned?
char
#defineV_TH00XFF
#defineV_TL00XF6
#defineV_TMOD0X01
voidinit_sys(void);/*系统初始化函数*/
voidDelay5Ms(void);
unsignedcharclick,ZKB1,ZKB2;
voidmain(void)
{
init_sys();
ZKB1=40;/*占空比初始值设定*/
ZKB2=70;/*占空比初始值设定*/
while
(1)
{
if(!
P1^0)/*如果按了+键,增加占空比*/
{
Delay5Ms();
if(!
P1^0)
{
ZKB1++;
ZKB2=100-ZKB1;
}
}
if(!
P1^1)/*如果按了-键,减少占空比*/
{
Delay5Ms();
if(!
P1^1)
{
ZKB1—-;
ZKB2=100—ZKB1;}}/*对占空比值限定范围*/
if(ZKB1〉99)ZKB1=1;
if(ZKB1<1)ZKB1=99;}}
/*函数功能:
对系统进行初始化,包括定时器初始化和变量初始化*/
voidinit_sys(void)/*系统初始化函数*/
{/*定时器初始化*/
TMOD=V_TMOD;
TH0=V_TH0;
TL0=V_TL0;
TR0=1;
ET0=1;
EA=1;}/*延时*/
voidDelay5Ms(void)
{
unsignedintTempCyc=1000;
while(TempCyc——);}
/*中断函数*/
voidtimer0(void)interrupt1using2{
TH0=V_TH0;/*恢复定时器初始值*/
TL0=V_TL0;
++click;
if(click>=100)click=0;
if(click<=ZKB1)/*当小于占空比值时输出低电平,高于时是高电平,从而实现占空比的调整*/
P2=0xff;
elseP2=0x00;
}
正反转
voidzhengzhuan()/*正转函数*/
{p0。
0=HA;p0.1=HB;p0.2=HC;{switch(hall)
{case0X05:
p1=21H;break
pwm();
while(p0.2)case0X04:
p1=22H;break
do{p0。
4=1;p0.5=1;}case0X06:
p1=0AH;break
while(p1.1)case0X02:
p1=0BH;break
do{p0.2=1;p0。
3=1;}case0X03:
p1=14H;break
while(p1。
1;p1。
2)case0X01:
p1=11H;break}}
do{p0。
3=1;p0.4=1;}
while(p1.0)
do{p0.0=1;p0。
1=1;}
while(p1。
0;p1.2)
do{p0.0=1;p0.5=1;}
while(p1.0;p1.1)
do{p0。
1=1;p0。
2=1;}
PWM=PHASE&&pwm();
}
voidfanzhuan()/*反转函数*/
{p1。
0=HA;p1。
1=HB;p1。
2=HC;
pwm();
while(p1.2)
do{p0.1=1;p0。
2=1;}
while(p1。
1)
do{p0。
0=1;p0.5=1;}
while(p1.1;p1。
2)
do{p0。
0=1;p0。
1=1;}
while(p1.0)
do{p0.3=1;p0。
4=1;}
while(p1。
0;p1。
2)
do{p0。
2=1;p0。
3=1;}
while(p1。
0;p1.1)
do{p0。
4=1;p0。
5=1;}
PWM=PHASE&&pwm();
}
主程序
voidmain(void)
{
TMOD=0x59;/*T1软件启动,T0软件+脉冲启动,T1计数器,T0定时器
T1工作在方式1,T0工作在方式1*/
TCON=0x20;TH1=0x00;
TL1=0x00;
TH0=0xD8;
TL0=0xF0;
IE=0x82;/*中断允许总控制,禁止T1中断*/
keyget();
if(tag==1)start();
elsestop();}
按键查询
KEYIN:
MOVP2,0FFH
MOVA,P2
CJNEA,#0FFH,QUDOU
LJMPRETURN
QUDOU:
MOVR3,A
LCALLDELAY10
MOVA,P2
CJNEA,R3,RETURN
KEY0:
MOVC,P2.0
JCKEY1
LJMPPKEY0(启动)
KEY1:
MOVC,P2。
1
JCKEY2
LJMPPKEY1(停止)
KEY2:
MOVC,P2。
2
JCKEY3
LJMPPKEY2(正转)
KEY3:
MOVC,P2。
3反转
。
。
。
。
。
.。
。
。
。
。
...
KEY5:
MOVC,P2。
5
JCRETURN
LJMPPKEY5(减速)
RETURN:
RET
过压过流
K1:
MOVC,P1。
2
JCK2
LJMPRETURN
Pkey1K2:
CLRP1。
0
CLRP1.1
CLRP1。
2
SETBP1。
3
SETBP1.4
SETBP1.5
JMPGONGZUO
RET
void stop() /*停止函数*/
{ P0=0;
P1=0;
P2=0;
TR0=0;
TR1=0;
}
voidkeyget()/*键盘扫描函数*/
{
ucharx;/*定义变量*/
P2=0XC0;/*键盘扫描,看是否有键按下*/
if((P2&0XC0)==0)/*有键按下*/
{
P2=0X80;/*P2。
7置1,扫描第一行*/
if((P2&0X80)==0)/*第一行有键按下*/
{
d_ms(1500);/*延时去抖*/
x=P2;/*读P2口*/
}
else
P2=0X40;/*P2.6置1,扫描第二行*/
if((P2&0X40)==0)/*第二行有键按下*/
{d_ms(1500);/*延时去抖*/
x=P2;/*读P2口*/}
}
switch(x)
{
case0xA0:
start();break;/*启动*/
case0x90:
up();break;/*向上箭头*/
case0x88:
fanzhuan();break;/*反转*/
case0x60:
left();break;/*左移*/
case0x50:
down();break;/*向下箭头*/
case0x48:
right();break/*右移*/
}
}
用MCS-51单片机成功产生PWM波的方法
PWM是“脉冲宽度调制”的意思。
PWM实际上是在单片机的某个引脚输出一系列的矩形波,其周期一般是固定的;而其高电平、低电平所占用的时间,是可以受控调整的.
高电平与周期占用的时间之比,称为占空比,其值为0~1之间。
PWM的应用很广,简单的说,它可以控制灯光的亮度、可以控制直流电机的转速,甚至还可以输出语音信号.
新型的单片机,往往都含有硬件的PWM模块,编写程序就很简单;而老式的MCS-51系列,就不具备这个条件。
其实,在没有PWM硬件的单片机上实现PWM,也并不难,只需一个定时器,令其工作在中断方式即可.
题目:
AT89C52单片机输出可调PWM波。
要求:
1。
单片机的晶振是12MHz,输出周期为1s.
2。
用两个开关控制占空比的增加和减少,分20等级.
针对这个题目,做而论道设计了一个简单的实验电路:
在P2口的8条线输出PWM波形;
在/INT1、/INT0外接了两个按键,用来调整占空比;
在P0口外接了两个BCD数码显示器,用来显示当前的占空比的等级。
实验的时候,可以使用示波器来观察P2口输出的波形。
如果把PWM波形的频率提高,也可以用LED观察到渐亮渐暗的效果,目前看,只是闪烁的时间发生变化.
//程序如下:
//==========================================
#include〈reg52。
h〉
unsignedinta,b;
//-——---—-—--—-—————---—-—---—-————-——-—---—
voidmain()
{
TMOD=0x01; //T0定时方式1
TH0=(65536-50000)/256; //50ms@12MHz
TL0=(65536—50000)%256;
TR0=1;
ET0=1;
EX0=1;
EX1=1;
IT0=1;IT1=1;
EA=1;
a=0;
b=10;
while
(1);
}
//—-——-——-—--—————-—--———-—-———--—-———-—---—
voidtime0()interrupt1
{
TL0=(65536—50000)%256;
TH0=(65536—50000)/256; //50ms@12MHz
a++;
if(a==20)a=0; //在这里调整周期.
if(a
else P2=0x00;
P0=((b/10)<<4)+b%10;//显示占空比等级
}
//---———-——————-—--—-----————-————-—————-——-
voidX0_INT()interrupt0
{
b++;
if(b〉19)b=19; //占空比等级最大为19
}
//-—-———-————-----———-—-—————-——-——-----—--—
voidX1_INT()interrupt2
{
b-—;
if(b<1)b=1; //占空比等级最小为1.
}
//==========================================
电路以及仿真效果如下图:
用16产生了10K,50%占空比的PWM波,但是用按键无法控制PWM的占空比
#include〈iom16v。
h>
#include〈macros。
h>
#defineucharunsignedchar
#defineuintunsignedint
intnum=50;
//*******延时函数*******//
voiddelay(uintMS)//约为1MS的延时函数
{
uinti,j;
for(i=0;i for(j=0;j〈1141;j++);//1141是在8MHz晶振下为MS毫秒 } //******PWM初始化******// voidKPWM(void) { DDRD=0x30;//PD5,PD6输出 PORTD=0x00;//不带上拉输出 TCCR1A=0xA3;//两路PWM,匹配清零 TCCR1B=0x19;//快速PWM模式,位数可调,预分频1 OCR1A=100;//频率为10K OCR1B=num;//匹配初值,占空比为50%左右 } //*******按键程序********// voidkey() { DDRB=0x00;//PB口输入状态 PORTB=0XFF;//PB口带上拉输入 if(PINB==0XFE)//如果PB0按下 { delay(10);//延时1毫秒,按键防抖 if(PINB==0XFE) { num=num+5;//比较值加5,即占空比增加5% if(num==90)//判断占空比是否到90% { num=90;//占空比钳位在90% } } while(PINB==0XFE);//按键释放程序 } if(PINB==0XFD)//如果PB1按下 { delay(10);//延时10毫秒,按键防抖 if(PINB==0XFD) { num=num-5;//比较值减5,即占空比减少5% if(num==10)//判断占空比是否到10% { num=10;//占空比钳位在10% } } while(PINB==0XFD);//按键释放程序 } } //*******主函数********// voidmain() { while (1) { KPWM();//PWM产生函数 key();//按键函数 } } voidinit_key() { DDRD=0X00; PORTD=0XFF; } voiddelay_ms(uintz) { uintx,y; for(x=z;x〉0;x--) for(y=1140;y>0;y——); } voidkeyscan(void) { if((PIND&0x01)==0) { while(! (PIND&0x01));//松手检测 delay_ms(50); num+=5; if(num==255) num=0; } if((PIND&0x02)==0) { while(! (PIND&0x02)); delay_ms(50); num-=5; if(num==0) num=255; } if((PIND&0x08)==0) { while(! (PIND&0x01)); delay_ms(50); num=128; } } voidmain(void) { ucharwide; pwm0_init(); init_key(); while (1) { OCR0=num; keyscan(); } } 16、定时器0快速PWM模式快速PWM可以的到比较高频率的PWM输出但占空比的调节精度稍微差一些。 此时计数器仅工作在单程正向计数方式计数器的上限值决定PWM的频率而比较匹配寄存器的值决定了占空比的大小。 PWM频率的计算公式为PWM频率=系统时钟频率/分频系数*1+计数器上限值快速PWM模式适合要求输出PWM频率较高但频率固定占空比调节精度要求不高的应用。 /*定时器0快速PWM模式由OC0输出PWM波*//*PWM频率=系统时钟频率/分频系数*1+计数器上限值*//*本程序中频率=8000000/(8*(1+255))=3。 91KHZ频率固定*//*占空比为OCR0/0XFF=OCR0/256,占空比可调*//*TCNT0从BOTTOM计数到MAX,然后回到BOTTOM重新开始;TCNT0计数到与OCR0相等时OC0清零在BOTTOM时置位1*/#include h> #defineuintunsignedint #defineucharunsignedchar volatileucharnum; voidpwm0_init(void) {DDRB=0X10;//将PB4设置为输出 TCCR0=0X00;//关闭num=64;//设置输出比较寄存器的初值 TCNT0=0;//计数器初值为0 TCCR0=0X6A;//设置为快速pwm模式采取8分频 } /*键盘初始化*/ voidinit_key() {DDRD=0X00; PORTD=0XFF;}/*延时函数*/ voiddelay_ms(uintz) {uintx,y; for(x=z;x>0;x——) for(y=1140;y>0;y--); }/*键盘扫描*/ voidkeyscan(void) {if((PIND&0x01)==0) {while(! (PIND&0x01));//松手检测 delay_ms(50); num+=5; if(num==255) num=0; } if((PIND&0x02)==0) { while(! (PIND&0x02)); delay_ms(50); num—=5; if(num==0) num=255; } if((PIND&0x08)==0) {while(! (PIND&0x01)); delay_ms(50); num=128; } } voidmain(void) {ucharwide; pwm0_init(); init_key(); while (1) {OCR0=num; keyscan();}} #include h〉 #defineucharnsignedchar #defineuintunsigndeint sbitled=p1.0; //延时 voiddelayms(uintx) { uchari; while(x—-) {for(i=0;i<120;i++); } } 主程序 voidmain() {led=0; while (1) {led=—led; delayms(150); } }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Pwm 程序 流程图