/////////舵机调试程序//////////////
/////////servo1.c/////////
#include <C8051F040.h>
#define CEX0PORT p07//舵机控制信号管脚,为P0.7管脚
//系统时钟为24500KHZ/8=3062.5KHZ
//周期为20ms,则频率为50HZ,则tmph+tmpl=61250可以保证产生50HZ PWM
#define CONST_W 61250
#define FORMAT_ANG temp=6125L*angval;temp/=180;tmph=(uint)temp+1531;tmpl=(uint)CONST_W-tmph
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long ulong;
sfr16 RCAP2=0xca;
sfr16 RCAP3=0xca;
sfr16 RCAP4=0xca;
sfr16 TMR4=0xcc;
sfr16 TMR3=0xcc;
sfr16 TMR2=0xcc;
sfr16 PCA0CP0=0xfb;
sfr16 PCA0CP1=0xfd;
sfr16 PCA0CP2=0xe9;
sfr16 PCA0CP3=0xeb;
sfr16 PCA0CP4=0xed;
sfr16 PCA0CP5=0xe1;
sbit p07=P0^7;
sbit p00=P0^0;
bit iscex0H;
uchar temppage;
xdata uint cex0L,cex0H;
xdata uint tmph,tmpl;
ulong temp;
int xdata angval;//1800表示180度,使得精度为0.1度
//转化计算:tmph=6125*angval/180+1531,但是由于计算时超过65535就会溢出
//,所以不能直接这样计算,可定义ulong型变量temp,
//temp=6125L*angval;temp/=180;tmph=(uint)temp+1531实现
void delay1ms(uint time){//延迟1ms
uint i;
uint j;
for (i=0;i<time;i++){
for(j=0;j<300;j++);
}
}
void pca0ini(){//CEX0为高速输出模式
SFRPAGE = 0x00;
PCA0CPM0=0X4d;
}
void CEX0_out(uint h,uint l){//设置高电平值和低电平值
cex0L=l;
cex0H=h;
CEX0PORT=1;
iscex0H=1;
}
void CEX0_set(uint pram){//设置高速模式下一次中断的间隔为pram个PCA时钟
SFRPAGE = 0x00;
PCA0CP0+=pram;
PCA0CPM0|=0x40;//注意编译的时候sfr16先写高地址,再写低地址
//所以编译结果使得最后写PCA0CPL0,将使得ECOM0清零,故加此句置1
}
void pcaini(){
SFRPAGE=0x00;
PCA0MD=0x09;//PCA时钟为系统时钟
PCA0CN=0x40;//开PCA时钟
EIE1|=0x08;//开PCA中断
}
void config(){//PCA管脚不配置输出到crossbar
WDTCN = 0x07; // 看门狗禁止
WDTCN = 0xDE; // Disable WDT
WDTCN = 0xAD;
SFRPAGE = 0x0F;
XBR0 = 0x00; // XBAR0: Initial Reset Value
XBR1 = 0x00; // XBAR1: Initial Reset Value
XBR2 = 0x40; // XBAR2: Initial Reset Value
XBR3 = 0x00; // XBAR3: Initial Reset Value
SFRPAGE = 0x0F;
P0MDOUT = 0x00; // Output configuration for P0
P1MDOUT = 0x00; // Output configuration for P1
P2MDOUT = 0x00; // Output configuration for P2
P3MDOUT = 0x00; // Output configuration for P3
P4MDOUT = 0x00; // Output configuration for P4
P5MDOUT = 0x00; // Output configuration for P5
P6MDOUT = 0x00; // Output configuration for P6
P7MDOUT = 0x00; // Output configuration for P7
P1MDIN = 0xFF; // Input configuration for P1
P2MDIN = 0xFF; // Input configuration for P2
P3MDIN = 0xFF; // Input configuration for P3
SFRPAGE = 0x0F;
CLKSEL = 0x00; // Oscillator Clock Selector
OSCXCN = 0x00; // EXTERNAL Oscillator Control Register
OSCICN = 0x84; // Internal Oscillator Control Register
}
void main(void){
config();
pca0ini();
pcaini();
CEX0PORT=0;//将控制信号输出置0
//0度对应:tmph=1531,tmpl=CONST_W-tmph
//180度对应:tmph=7656,tmpl=CONST_W-tmph,
angval=0;
FORMAT_ANG;//计算出tmph和tmpl的值
EA=1;
CEX0_out(tmph,tmpl);
delay1ms(1000);
while(1){
for(angval=0;angval<=180;angval+=30){//每隔2秒正转30度
FORMAT_ANG;
CEX0_out(tmph,tmpl);
delay1ms(2000);
}
for(angval=180;angval>=0;angval-=30){//每隔2秒反转30度
/*注意angval不能定义成uint型,否则angval>=0条件恒真*/
FORMAT_ANG;
CEX0_out(tmph,tmpl);
delay1ms(2000);
}
}
}
void PCA_ISR(void) interrupt 9 {
temppage=SFRPAGE;
SFRPAGE = 0x00;
if(CF){
CF=0;
}
if(CCF0){
if(iscex0H){
CEX0_set(cex0L);//隔cex0L个PCA时钟后发生中断,则低电平持续时间为
//cex0L个PCA时钟
iscex0H=0;
}
else{
CEX0_set(cex0H);//隔cex0H个PCA时钟后发生中断,则高电平持续时间为
//cex0H个PCA时钟
iscex0H=1;
}
CEX0PORT=iscex0H;
CCF0=0;
}
SFRPAGE=temppage;
}
评论0