利用的T0产生双路PWM信号文档格式.docx
《利用的T0产生双路PWM信号文档格式.docx》由会员分享,可在线阅读,更多相关《利用的T0产生双路PWM信号文档格式.docx(13页珍藏版)》请在冰豆网上搜索。
s1=0;
s2=1;
}
else/*不为负数则正转*/
s1=1;
s2=0;
if(index==2)/*电机2的处理*/
m2=abs(speed);
/*电机2的速度控制*/
0)/*电机2的方向控制*/
s3=0;
s4=1;
else
s3=1;
s4=0;
voiddelay(uintj)/*简易延时函数*/
for(j;
j>
0;
j--);
voidmain()
uchari;
TMOD=0x02;
/*设定T0的工作模式为2*/
TH0=0x9B;
/*装入定时器的初值*/
TL0=0x9B;
EA=1;
/*开中断*/
ET0=1;
/*定时器0允许中断*/
TR0=1;
/*启动定时器0*/
while
(1)/*电机实际控制演示*/
for(i=0;
i<
=100;
i++)/*正转加速*/
motor(1,i);
motor(2,i);
delay(5000);
for(i=100;
i>
i--)/*正转减速*/
i++)/*反转加速*/
motor(1,-i);
motor(2,-i);
i--)/*反转减速*/
voidtimer0()interrupt1/*T0中断服务程序*/
if(t==0)/*1个PWM周期完成后才会接受新数值*/
tmp1=m1;
tmp2=m2;
if(t<
tmp1)en1=1;
elseen1=0;
/*产生电机1的PWM信号*/
tmp2)en2=1;
elseen2=0;
/*产生电机2的PWM信号*/
t++;
if(t>
=100)t=0;
/*1个PWM信号由100次中断产生*/
参考链接:
无线控制的PWM方式控制直流电机C51程序
用于测试基本的开关、PWM产生等等功能。
#include"
regx51.H"
#ifndefMOTOR_PWM
#defineMOTOR_PWM
//Typedefinefortheproject:
typedefunsignedlong
u32;
typedefunsignedshort
u16;
typedefunsignedchar
u08;
//Systemhardwaresettings:
static
float
osc
=20.0000;
float
machine_cycle
=1;
VOL_MAX
=28;
VOL_MIN
=9;
//thecodetableforthecontroller:
#define
KEY_START
0xFA//B11111010
KEY_MODE1
0xFE//B11111110
KEY_MODE2
0xF1//B11110001
KEY_MODE3
0xF9//B11111001
KEY_INC_SP
0xF5//B11110101
KEY_DEC_SP
0xFD//B11111101
KEY_STOP
0xF3//B11110011
//Globalvariable:
bit_is_clear
P0_0==0
#definebit_is_set
P0_0==1
#defineset_bit()
P0_0=1
#defineclr_bit()
P0_0=0
set_enable()
enable_flag=1;
set_disable()
enable_flag=0;
ENABLE
enable_flag==1
DISABLE
enable_flag==0
#define
there_is_no_int
int_flag==0
there_is_int
int_flag==1
clr_int()
int_flag=0
set_int()
int_flag=1
PWM_frequency
2000
u16
PWM_cycle
=500;
//(1/PWM_frequency)*1000000;
//#define
mt_times(X)
((X)*PWM_frequency)
//fliptimesforthecertaintime
u08
flag
=0;
tmp_Data
u08
Running_Mode
//torecordtherunningmode
u32
counter_PWM
int_flag
//indicatethesoftinterruptstatus
enable_flag;
key_press;
ratio
u16mt_times(intX)
{
return(X*2000);
//2000isPWM_frequency
}
/*u08GetKeys(void)
key_press=P1;
returnkey_press;
}*/
//Interrupts:
//Thispartisforthekeysinput(Notforserialcontroller)
voidINT0_Interrupt_Server()interrupt0using0
//makethe
u08tmp=3;
while(--tmp);
P2_1=1;
key_press=P1;
int_flag=1;
P3=0xFF;
//Timer0Interruptfunction:
//
/*
voidT0_Interrupt_Server()interrupt1using1
//COM1Interruptserver:
/*voidCOM1_server()interrupt4using2
if(RI)
RI=0;
key_press=SBUF;
set_int();
//Sub-Functions:
//TimeMaintain()tomaketheCPUbusyforacertaintime
//reftothearticleinthemotordirectory
voidTimeMaintain(u16mt_time)
//theparametermt_timeismeasuredbyus
while(--mt_time);
//changethecertainvelocitytoDCvoltage,velocityismeasuredbyr/s
floatVe2DC(floatvelocity)
u08tmp;
tmp=(int)(velocity*100);
switch(tmp)
case100:
return3.0;
case200:
return6.0;
case300:
return9.0;
case400:
return12.0;
case500:
return15.5;
case600:
return20.2;
}//Thispartshouldbere-measuredifwannabeusedforothercases
//changethecertainDCvoltagetoRatioofPWM
floatDC2Ratio(floatdc_vol)
floatcompe=0.02;
//compeisthecompesationofthesystemvoltagewastage
return(dc_vol+compe)/VOL_MAX;
//PWMgeneratefromDuty-ratioandfixedfrequencyandthemaintaintime(usingthecontertimes);
voidgenerate_PWM(floatratio,u08time)
//paratimeismeasuredbyunit'
s'
u16ON_Time;
u16OFF_Time;
ON_Time=(int)(PWM_cycle*ratio);
OFF_Time=PWM_cycle-ON_Time;
if(ENABLE)
while((counter_PWM<
mt_times(time)))
if(there_is_no_int)
set_bit();
TimeMaintain(ON_Time);
//askedbythedelayfunction
clr_bit();
TimeMaintain(OFF_Time);
counter_PWM++;
else
counter_PWM=0;
break;
*/
//belowfortest:
while(there_is_no_int)
TimeMaintain(30);
voidgenerate_PWM_Run(floatvelocity,u08time)
floatDC_Vol,Ratio_tmp;
DC_Vol=Ve2DC(velocity);
Ratio_tmp=DC2Ratio(DC_Vol);
//ratio=Ratio_tmp;
generate_PWM(Ratio_tmp,time);
//The2modes:
voidrunning_at_mode1(void)
/*2/s(10s)→3/s(10)→4/s(5)→3/s(5)*/
Running_Mode=1;
while(there_is_no_int&
ENABLE)
generate_PWM_Run(2,10);
generate_PWM_Run(3,10);
generate_PWM_Run(4,5);
generate_PWM_Run(3,5);
voidrunning_at_mode2(void)
/*2/s(7)→6/s(5)→4/s(5)→6/s(3)*/
Running_Mode=2;
generate_PWM_Run(2,7);
generate_PWM_Run(6,5);
generate_PWM_Run(6,3);
voidrunning_at_mode3(void)
/*no-levelspeedcontrol*/
Running_Mode=3;
generate_PWM_Run(5,1);
//Theno-levelspeedcontrol:
voidspeed_inc(void)
//generate_PWM(ratio+0.15,);
//Thisvalueshouldberevisedwhenusing
clr_int();
Running_Mode==3)
generate_PWM(ratio+0.01,1);
ratio=ratio+0.01;
voidspeed_dec(void)
generate_PWM(ratio-0.01,1);
ratio=ratio-0.01;
//Mainfunction:
voidmain(void)
/*Thispartisforthefinalproduct...*/
tmp_Data=4000;
while(--tmp_Data);
EA=1;
IT0=1;
EX0=1;
P0=0xAA;
P2=0x00;
while
(1)
if(int_flag==1)
//
tmp_Data=1;
P2_2=1;
int_flag=0;
key_press=key_press|0xF0;
switch(key_press)
caseKEY_START:
//5
set_enable();
P2_0=~P2_0;
caseKEY_MODE1:
//7
running_at_mode1();
caseKEY_MODE2:
//8
running_at_mode2();
caseKEY_MODE3:
//9
running_at_mode3();
caseKEY_INC_SP:
//10
speed_inc();
caseKEY_DEC_SP:
//11
speed_dec();
caseKEY_STOP:
//12
set_disable();
P2_1=0;
default:
P2_6=~P2_6;
#endif
直流电机PWM闭环控制实验(完整的C51程序)
C源代码:
#include<
reg52.h>
/*定义字型字位口*/
#defineDIGPORTP2
#defineWORDPORTP0
/*定义键盘口*/
#defineKEYPORTP1
#defineuintunsignedint
#defineucharunsignedchar
#defineuongunsignedlong
sbitP_7=P3^7;
//PWM信号输出
bitOVER;
uintk,dt;
uongKEYNUM;
ucharqu,NUM;
voidDelay(uintms)
while(--ms);
voidtimer0(void)interrupt1using1
TL0=-(10248%256);
TH0=-(10248%256);
NUM+=1;
if(NUM>
=10){
TR1=0;
TR0=0;
OVER=1;
}
uintCK(void)
uintnumber=0;
P_7=1;
OVER=0;
NUM=0;
EA=1;
TH0=(10203/256);
TH0=(10203%256);
TH1=0;
TL1=0;
TMOD=0x51;
TR0=1;
TR1=1;
Delay(dt);
P_7=0;
while(!
OVER);
number=TH1*256+TL1;
return(number);
voidDisplay_LED(uongnu)
uintii=0;
uongaa,bb;
uintxx[]={-0x10,-0x10,-0x10,-0x10,-0x10,-0x10,-0x10,-0x10};
do
{
bb=nu/10;
aa=nu-bb*10;
xx[ii]=aa;
nu=bb;
ii++;
}while(nu>
0);
DIGPORT=0xf0;
WORDPORT=0x30+xx[0];
DIGPORT=0xf1;
WORDPORT=0x30+xx[1];
DIGPORT=0xf2;
WORDPORT=0x30+xx[2];
DIGPORT=0xf3;
WORDPORT=0x30+xx[3];
DIGPORT=0x0f;
WORDPORT=0x30+xx[4];
DIGPORT=0x1f;
WORDPORT=0x30+xx[5];
DIGPORT=0x2f;
WORDPORT=0x30+xx[6];
DIGPORT=0x3f;
WORDPORT=0x30+xx[7];
voidgetkey()
qu=0;
k=0;
KEYNUM=0;
do
switch(KEYPORT)
case0xbd:
KEYNUM=KEYNUM*10;
break;
case0xf6:
KEYNUM=KEYNUM*10+1;
case0xf5:
KEYNUM=KEYNUM*10+2;
case0xf3:
KEYNUM=KEYNUM*10+3;
case0xee:
KEYNUM=KEYNUM*10+4;
case0xed:
KEYNUM=KEYNUM*10+5;
case0xeb:
KEYNUM=KEYNUM*10+6;
case0xde:
KEYNUM=KEYNUM*10+7;
case0xdd:
KEYNUM=KEYNUM*10+8;
case0xdb:
KEYNUM=KEYNUM*10+9;
case0xbe:
KEYNUM=KEYNUM/10;
case0xbb:
qu=1;
Delay(6000);
if(KEYNUM>
100000000)brea