1、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;void delay(uint j) /* 简易延时函数 */ for(j;j0;j-);void main() uchar i;TMOD=0x02; /* 设定T0的工作模式为2 */ TH0=0x9B; /* 装入定时器的初值 */ TL0=0x9B;EA=1; /* 开中断 */ ET0=1; /* 定时器0允许中断
2、 */ TR0=1; /* 启动定时器0 */ while(1) /* 电机实际控制演示 */ for(i=0;ii-) /* 正转减速 */ i+) /* 反转加速 */ motor(1,-i);motor(2,-i);i-) /* 反转减速 */ void timer0() interrupt 1 /* T0中断服务程序 */ if(t=0) /* 1个PWM周期完成后才会接受新数值 */ tmp1=m1;tmp2=m2;if(t=100) t=0; /* 1个PWM信号由100次中断产生 */ 参考链接:无线控制的PWM方式控制直流电机C51程序用于测试基本的开关、PWM产生等等功能。#
3、include regx51.H#ifndef MOTOR_PWM#define MOTOR_PWM/Type define for the project:typedef unsigned long u32;typedef unsigned short u16;typedef unsigned char u08;/System hardware settings:staticfloat osc= 20.0000;floatmachine_cycle = 1;VOL_MAX= 28;VOL_MIN= 9;/the code table for the controller:#defineKEY
4、_START0xFA/B11111010KEY_MODE10xFE/B11111110KEY_MODE20xF1/B11110001KEY_MODE30xF9/B11111001KEY_INC_SP0xF5/B11110101KEY_DEC_SP0xFD/B11111101KEY_STOP0xF3/B11110011/Global variable:bit_is_clearP0_0 = 0#define bit_is_setP0_0 = 1#define set_bit()P0_0 = 1#define clr_bit()P0_0 = 0set_enable()enable_flag = 1;
5、set_disable()enable_flag = 0;ENABLEenable_flag = 1DISABLEenable_flag = 0#define there_is_no_intint_flag = 0there_is_intint_flag = 1clr_int()int_flag = 0set_int()int_flag = 1PWM_frequency2000u16PWM_cycle= 500;/(1/PWM_frequency)*1000000;/#define mt_times(X)(X)*PWM_frequency)/flip times for the certain
6、 timeu08 flag = 0;tmp_Data u08Running_Mode /to record the running modeu32 counter_PWMint_flag/indicate the soft interrupt statusenable_flag;key_press;ratiou16 mt_times(int X)return (X*2000);/2000 is PWM_frequency/*u08 GetKeys(void)key_press=P1;return key_press;*/Interrupts:/This part is for the keys
7、 input (Not for serial controller)void INT0_Interrupt_Server() interrupt 0 using 0/make theu08 tmp=3;while(-tmp);P2_1 = 1;key_press = P1;int_flag = 1;P3 = 0xFF;/Timer0 Interrupt function:/*void T0_Interrupt_Server() interrupt 1 using 1/COM1 Interrupt server:/*void COM1_server() interrupt 4 using 2if
8、(RI)RI = 0;key_press=SBUF;set_int();/Sub-Functions:/TimeMaintain() to make the CPU busy for a certain time/ref to the article in the motor directoryvoid TimeMaintain(u16 mt_time)/the parameter mt_time is measured by uswhile(-mt_time);/change the certain velocity to DC voltage, velocity is measured b
9、y r/sfloat Ve2DC(float velocity)u08 tmp;tmp=(int)(velocity*100);switch(tmp)case 100:return 3.0;case 200:return 6.0;case 300:return 9.0;case 400:return 12.0;case 500:return 15.5;case 600:return 20.2;/This part should be re-measured if wanna be used for other cases/change the certain DC voltage to Rat
10、io of PWMfloat DC2Ratio(float dc_vol)float compe = 0.02;/compe is the compesation of the system voltage wastagereturn (dc_vol+compe)/VOL_MAX;/PWM generate from Duty-ratio and fixed frequency and the maintain time(using the conter times);void generate_PWM(float ratio, u08 time)/para time is measured
11、by unit su16 ON_Time;u16 OFF_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);/asked by the delay functionclr_bit();TimeMaintain(OFF_Time);counter_PWM+;elsecounter_PWM = 0;break;*/belo
12、w for test:while(there_is_no_int)TimeMaintain(30);void generate_PWM_Run(float velocity, u08 time)float DC_Vol, Ratio_tmp;DC_Vol=Ve2DC(velocity);Ratio_tmp=DC2Ratio(DC_Vol);/ratio=Ratio_tmp;generate_PWM(Ratio_tmp,time);/The 2 modes:void running_at_mode1(void)/*2/s(10s)3/s(10)4/s(5)3/s(5)*/Running_Mode
13、 = 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);void running_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);void running_at_mode3(void)/*no-level
14、speed control*/Running_Mode = 3;generate_PWM_Run(5, 1);/The no-level speed control:void speed_inc(void)/generate_PWM(ratio+0.15,);/This value should be revised when usingclr_int();Running_Mode=3)generate_PWM(ratio+0.01,1);ratio=ratio+0.01;void speed_dec(void)generate_PWM(ratio-0.01,1);ratio=ratio-0.
15、01;/Main function:void main(void)/*This part is for the final product.*/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)case KEY_START:/5set_enable();P2_0 = P2_0;case KEY_M
16、ODE1:/7running_at_mode1();case KEY_MODE2:/8running_at_mode2();case KEY_MODE3:/9running_at_mode3();case KEY_INC_SP:/10speed_inc();case KEY_DEC_SP:/11speed_dec();case KEY_STOP:/12set_disable();P2_1 = 0;default:P2_6 = P2_6;#endif直流电机PWM闭环控制实验(完整的C51程序)C源代码:#include /*定义字型字位口*/#define DIGPORT P2#define
17、WORDPORT P0/*定义键盘口*/#define KEYPORT P1#define uint unsigned int#define uchar unsigned char#define uong unsigned longsbit P_7=P37; /PWM信号输出bit OVER;uint k,dt;uong KEYNUM;uchar qu,NUM;void Delay(uint ms) while(-ms);void timer0(void) interrupt 1 using 1 TL0=-(10248%256); TH0=-(10248%256); NUM+=1; if(NU
18、M=10) TR1=0; TR0=0; OVER=1; uint CK(void) uint number=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);void Display_LED(uong nu) uint ii=0; uong aa,bb; uint xx=-0x10,-0x10,-0x10,
19、-0x10,-0x10,-0x10,-0x10,-0x10; do bb=nu/10; aa=nu-bb*10; xxii=aa; nu=bb;ii+; while(nu0); DIGPORT=0xf0; WORDPORT=0x30+xx0; DIGPORT=0xf1; WORDPORT=0x30+xx1; DIGPORT=0xf2; WORDPORT=0x30+xx2; DIGPORT=0xf3; WORDPORT=0x30+xx3; DIGPORT=0x0f; WORDPORT=0x30+xx4; DIGPORT=0x1f; WORDPORT=0x30+xx5; DIGPORT=0x2f;
20、 WORDPORT=0x30+xx6; DIGPORT=0x3f; WORDPORT=0x30+xx7;void getkey()qu=0;k=0;KEYNUM=0;do switch(KEYPORT) case 0xbd: KEYNUM=KEYNUM*10; break; case 0xf6: KEYNUM=KEYNUM*10+1; case 0xf5: KEYNUM=KEYNUM*10+2; case 0xf3: KEYNUM=KEYNUM*10+3; case 0xee: KEYNUM=KEYNUM*10+4; case 0xed: KEYNUM=KEYNUM*10+5; case 0xeb: KEYNUM=KEYNUM*10+6; case 0xde: KEYNUM=KEYNUM*10+7; case 0xdd: KEYNUM=KEYNUM*10+8; case 0xdb: KEYNUM=KEYNUM*10+9; case 0xbe: KEYNUM=KEYNUM/10; case 0xbb:qu=1; Delay(6000); if(KEYNUM100000000) brea
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1