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;
static float machine_cycle =1;
static float VOL_MAX =28;
static float VOL_MIN =9;
//thecodetableforthecontroller:
#define KEY_START 0xFA//B11111010
#define KEY_MODE1 0xFE//B11111110
#define KEY_MODE2 0xF1//B11110001
#define KEY_MODE3 0xF9//B11111001
#define KEY_INC_SP 0xF5//B11110101
#define KEY_DEC_SP 0xFD//B11111101
#define KEY_STOP 0xF3//B11110011
//Globalvariable:
#define bit_is_clear P0_0==0
#definebit_is_set P0_0==1
#defineset_bit() P0_0=1
#defineclr_bit() P0_0=0
#define set_enable() enable_flag=1;
#define set_disable() enable_flag=0;
#define ENABLE enable_flag==1
#define DISABLE enable_flag==0
#define there_is_no_int int_flag==0
#define there_is_int int_flag==1
#define clr_int() int_flag=0
#define set_int() int_flag=1
#define PWM_frequency 2000
u16 PWM_cycle =500;//(1/PWM_frequency)*1000000;
//#define mt_times(X) ((X)*PWM_frequency) //fliptimesforthecertaintime
u08 flag =0;
u08 tmp_Data =0;
u08 Running_Mode =0;//torecordtherunningmode
u32 counter_PWM =0;
u08 int_flag =0;//indicatethesoftinterruptstatus
u08 enable_flag;
u08 key_press;
float ratio =0;
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 {
if(there_is_no_int)
{
set_bit();
TimeMaintain(ON_Time);//askedbythedelayfunction
clr_bit();
TimeMaintain(OFF_Time);
counter_PWM++;
}
else
{
counter_PWM=0;
break;
}
}
}
counter_PWM=0;
*/
//belowfortest:
while(there_is_no_int)
{
set_bit();
TimeMaintain(30);
clr_bit();
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;
while(there_is_no_int&&ENABLE)
{
generate_PWM_Run(2,7);
generate_PWM_Run(6,5);
generate_PWM_Run(4,5);
generate_PWM_Run(6,3);
}
}
voidrunning_at_mode3(void)
/*no-levelspeedcontrol*/
{
Running_Mode=3;
while(there_is_no_int&&ENABLE)
{
generate_PWM_Run(5,1);
}
}
//Theno-levelspeedcontrol:
voidspeed_inc(void)
{
//generate_PWM(ratio+0.15,);//Thisvalueshouldberevisedwhenusing
clr_int();
while(there_is_no_int&&Running_Mode==3)
{
generate_PWM(ratio+0.01,1);
}
ratio=ratio+0.01;
}
voidspeed_dec(void)
{
clr_int();
while(there_is_no_int&Running_Mode==3)
{
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;
P3=0xFF;
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;
break;
caseKEY_MODE1:
//7
running_at_mode1();
break;
caseKEY_MODE2:
//8
running_at_mode2();
break;
caseKEY_MODE3:
//9
running_at_mode3();
break;
caseKEY_INC_SP:
//10
speed_inc();
break;
caseKEY_DEC_SP:
//11
speed_dec();
break;
caseKEY_STOP:
//12
set_disable();
P2_1=0;
break;
default:
P2_6=~P2_6;
}
}
}
}
#endif
直流电机PWM闭环控制实验(完整的C51程序)
C源代码:
#include
/*定义字型字位口*/
#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;ET0=1;
TH0=(10203/256);
TH0=(10203%256);
TH1=0;
TL1=0;
TMOD=0x51;
TR0=1;
TR1=1;
Delay(dt);
P_7=0;
while(!
OVER);
OVER=0;
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;
break;
case0xf5:
KEYNUM=KEYNUM*10+2;
break;
case0xf3:
KEYNUM=KEYNUM*10+3;
break;
case0xee:
KEYNUM=KEYNUM*10+4;
break;
case0xed:
KEYNUM=KEYNUM*10+5;
break;
case0xeb:
KEYNUM=KEYNUM*10+6;
break;
case0xde:
KEYNUM=KEYNUM*10+7;
break;
case0xdd:
KEYNUM=KEYNUM*10+8;
break;
case0xdb:
KEYNUM=KEYNUM*10+9;
break;
case0xbe:
KEYNUM=KEYNUM/10;
break;
case0xbb:
qu=1;
}
Delay(6000);
Delay(6000);
Delay(6000);
Delay(6000);
Delay(6000);
Delay(6000);
Delay(6000);
Delay(6000);
if(KEYNUM>100000000)brea