资讯详情

单片机控制18路舵机的C程序

关于本程序: 问:定时器1控制着9路pwm 以前听高手帮我讲解 一般8路之内是合适的 因为好像是把舵机的一个周期分成8分来分别控制 超出8路的话 好像周期就有可能改变

答:是的,每路PWM有大约2.5ms是要独立侵占timer时间的,8*2.5刚好20ms,每路舵机范围我只用到0.7~2.0左右,所以9路之间没有干扰。但是个timer之间有干扰。

问:看到个小bug pwm0到pwm8再到pwm0可能不是20ms的一个周期

答:嘿嘿,我把每路的低电平时间合在一起了,然后看它的汇编代码,修正中断中语句用去的时间,上位机算好,用keil的仿真出来是很准的。 在两个timer没有同时中断的情况下精度为0.5us,一旦同时中断,有一路PWM的误差将达到7、8us。 恩 这个中断程序没有结束另外的中断有发生 就会造成后面的中断打失 所以得用性能好的单片机 哈哈 注意本程序在编译的时候要选择pdata模式不然会失败这是工程文件下载已经设置好了模式的: http://www.51hei.com/f/duoji_c.rar 程序源码: /************************************************************************** 文 件 名:pwm_18out.c 功能描述:利用C89C52RC做下位机,控制18路舵机PWM 双倍速,机器周期0.5us 日 期:2012-3-19 作 者:cazy peach- 备 注: 18路舵机控制下位机 **************************************************************************/ #define uint unsigned int #define uchar unsigned char #include<reg52.h> sbit pwm9=P1^0; sbit pwm10=P1^1; sbit pwm11=P1^2; sbit pwm12=P1^3; sbit pwm13=P1^4; sbit pwm14=P1^5; sbit pwm15=P1^6; sbit pwm16=P1^7; sbit pwm17=P0^7; sbit pwm0=P2^7; sbit pwm1=P2^6; sbit pwm2=P2^5; sbit pwm3=P2^4; sbit pwm4=P2^3; sbit pwm5=P2^2; sbit pwm6=P2^1; sbit pwm7=P2^0; sbit pwm8=P0^6; //***************************参数申明****************************** //指令格式:两byte为一路PWM,前一个为PWM高电平定时器TH值、后一个为TL的值,由上位机计算所得,共20组。最后两组分别为每9路PWM低电平和。 uint data pwm_val[40]={ 0XF4, 0XF0, 0XF7, 0X9B, 0XF6, 0XAE, 0XF4, 0XF9, 0XF8, 0X01, 0XF6, 0X8F, 0XF5, 0X02, 0XF7, 0X2B, 0XF6, 0X9D, 0XF4, 0XF0, 0XF3, 0X1D, 0XF3, 0X16, 0XF4, 0XF9, 0XF2, 0X8B, 0XF3, 0XB0, 0XF5, 0X02, 0XF2, 0XE9, 0XF3, 0X9B, 0XBB, 0X55, 03, 0X04}; uchar zhilin[61]; uchar *point; uchar data pwm_select=0; uchar data pwm_scan=0; //timer1使用 uchar data pwm_scan1=0; //timer2使用 uchar data SCI_get=0; //**************************函数声明**************************** void SCI_I(void) ; void timer_INT(void) ; //***************************主函数***************************** void main() { uchar j; P0=0X00; P1=0x00; P2=0X00; point=zhilin; SCI_INT(); timer_INT(); for(j=0;j<61;j++){zhilin[j]=0;} while(1) { for(;;) //指令接收 { if(RI){RI=0;SCI_get=SBUF;*point++=SCI_get;j++;}else{continue;} if(SCI_get==0xff){point=zhilin;break;} //0xff指令结束符 } for(j=0;j<21;j++) //指令处理 { if(zhilin[j*3]==255){break;} //判断是否为指令结束符 pwm_select=zhilin[j*3]; pwm_val[pwm_select]=zhilin[j*3+1]; pwm_val[pwm_select+1]=zhilin[j*3+2]; } } } //***************************定时器中断************************** void timer0() interrupt 1 using 1 { if(pwm_scan==1) //第1路pwm。 { pwm0=1; TH0=pwm_val[0]; TL0=pwm_val[1]; } else if(pwm_scan==2) //第2路pwm。 { pwm0=0; pwm1=1; TH0=pwm_val[2]; TL0=pwm_val[3]; } else if(pwm_scan==3) //第3路pwm。 { pwm1=0; pwm2=1; TH0=pwm_val[4]; TL0=pwm_val[5]; } else if(pwm_scan==4) //第4路pwm。 { pwm2=0; pwm3=1; TH0=pwm_val[6]; TL0=pwm_val[7]; } else if(pwm_scan==5) //第5路pwm。 { pwm3=0; pwm4=1; TH0=pwm_val[8]; TL0=pwm_val[9]; } else if(pwm_scan==6) //第6路pwm。 { pwm4=0; pwm5=1; TH0=pwm_val[10]; TL0=pwm_val[11]; } else if(pwm_scan==7) //第7路pwm。 { pwm5=0; pwm6=1; TH0=pwm_val[12]; TL0=pwm_val[13]; } else if(pwm_scan==8) //第8路pwm。 { pwm6=0; pwm7=1; TH0=pwm_val[14]; TL0=pwm_val[15]; } else if(pwm_scan==9) //第9路pwm。 { pwm7=0; pwm8=1; TH0=pwm_val[16]; TL0=pwm_val[17]; } else if(pwm_scan==10) //低电平。 { pwm8=0; TH0=pwm_val[36]; TL0=pwm_val[37]; pwm_scan=0; } pwm_scan++; } void timer1() interrupt 3 using 2 { if(pwm_scan1==1) //第10路pwm。 { pwm9=1; TH1=pwm_val[18]; =pwm_val[19]; } else if(pwm_scan1==2) //第11路pwm。 { pwm9=0; pwm10=1; TH1=pwm_val[20]; TL1=pwm_val[21]; } else if(pwm_scan1==3) //第12路pwm。 { pwm10=0; pwm11=1; TH1=pwm_val[22]; TL1=pwm_val[23]; } else if(pwm_scan1==4) //第13路pwm。 { pwm11=0; pwm12=1; TH1=pwm_val[24]; TL1=pwm_val[25]; } else if(pwm_scan1==5) //第14路pwm。 { pwm12=0; pwm13=1; TH1=pwm_val[26]; TL1=pwm_val[27]; } else if(pwm_scan1==6) //第15路pwm。 { pwm13=0; pwm14=1; TH1=pwm_val[28]; TL1=pwm_val[29]; } else if(pwm_scan1==7) //第16路pwm。 { pwm14=0; pwm15=1; TH1=pwm_val[30]; TL1=pwm_val[31]; } else if(pwm_scan1==8) //第17路pwm。 { pwm15=0; pwm16=1; TH1=pwm_val[32]; TL1=pwm_val[33]; } else if(pwm_scan1==9) //第18路pwm。 { pwm16=0; pwm17=1; TH1=pwm_val[34]; TL1=pwm_val[35]; } else if(pwm_scan1==10) //低电平。 { pwm17=0; TH1=pwm_val[38]; TL1=pwm_val[39]; pwm_scan1=0; } pwm_scan1++; } //********************************函数************************ void timer_INT(void) //timer0、timer1初始化 { uchar a,b,c; TMOD|=0X11; IE|=0X8A; //EA=1;ET0=1;ET1=1; TH0=256; TL0=255; TH1=256; TL1=255; TR0=1; for(c=1;c>0;c--) { for(b=38;b>0;b--) { for(a=130;a>0;a--); } } TR1=1; }

void SCI_INT(void) //timer2 { SC=0X50; T2CON=0X30; TL2=P2L=0XB2; //9600 0XFFB2, 19200 0XFFD9 TH2=RCAP2H=0XFF; PCON=0X00; TR2=1; }

-电子元器件采购网(www.ruidan.com)是本土元器件目录分销商,采用“小批量、现货、样品”销售模式,致力于满足客户多型号、高质量、快速交付的采购需求。 自建高效智能仓储,拥有自营库存超过50,000种,提供一站式正品现货采购、个性化解决方案、选型替代等多元化服务。
锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台