單片機控制18路舵機的C程序
問:定時器1控制著9路pwm 以前聽高手幫我講解 一般8路之內是合適的 因為好像是把舵機的一個周期分成8分來分別控制 超出8路的話 好像周期就有可能改變
本文引用地址:http://m.butianyuan.cn/article/201612/324215.htm答:是的,每路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。
恩 這個中斷程序沒有結束另外的中斷有發(fā)生 就會造成后面的中斷打失 所以得用性能好的單片機哈哈
注意本程序在編譯的時候要選擇pdata模式不然會失敗這是工程文件下載已經設置好了模式的:http://www.51hei.com/f/duoji_c.rar
程序源碼:
/**************************************************************************
文 件 名:pwm_18out.c
功能描述:利用STC89C52RC做下位機,控制18路舵機PWM
雙倍速,機器周期0.5us
日 期:2012-3-19
作 者:cazy peach-ATP
備 注: 18路舵機控制下位機
**************************************************************************/
#define uint unsigned int
#define uchar unsigned char
#include
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;
//***************************參數(shù)申明******************************
//指令格式:兩byte為一路PWM,前一個為PWM高電平定時器TH值、后一個為TL的值,由上位機計算所得,共20組。最后兩組分別為每9路PWM低電平和。
uintdatapwm_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, 0XD3, 0X04};
uchar zhilin[61];
uchar *point;
uchar data pwm_select=0;
uchar data pwm_scan=0; //timer1使用
uchar data pwm_scan1=0; //timer2使用
uchardataSCI_get=0;
//**************************函數(shù)聲明****************************
void SCI_INT(void) ;
void timer_INT(void) ;
//***************************主函數(shù)*****************************
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];
}
}
}
評論