|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区
您需要 登录 才可以下载或查看,没有账号?立即注册
×
stm8s tim2使用的一个例子
int CurPos;//current position 75-187-300 ( 0-90-180°)
unsigned char Re_buf[11],counter=0;//UASRT data
unsigned char isRead=0;
float a[3],w[3],angle[3],T;
void Timer2_Init(void)
{
CLK_ICKR|=0x01; //开启内部HSI
while(!(CLK_ICKR&0x02));//HSI准备就绪
CLK_SWR=0xe1; //HSI为主时钟源
CLK_CKDIVR=0x00; //外设时钟8分频=2MHz
TIM2_PSCR=0x07; //Timer2时钟128分频,计算一次8us
TIM2_ARRH=25; //自动重装的值
TIM2_ARRL=196; //PWM周期为20000us
TIM2_CCER1=bit0 | bit4; // high level,OC1
TIM2_CCMR1=bit3|bit5|bit6; //MODE
TIM2_CCR1H=0x00; //占空比
TIM2_CCR1L=0x00;
TIM2_CCER1 |= 0x10; //开启OC2信号输出脚
TIM2_CCMR2 = 0x60; //PWM1模式
TIM2_CCMR2 |= 0x08; //输出比较2预装载使能
TIM2_CCR2H=0x00; //占空比
TIM2_CCR2L=0x00;
TIM2_IER=0x00; //更新中断使能
TIM2_CR1=bit0; //enable counter
}
void GPIO_Init(void)
{
PB_DDR|=0x20;
PB_CR1|=0x20;
PB_CR2|=0x00;
}
void ServoPosition(int pos)//position 40 75-187-300 2400, 0 means no torque
{
TIM2_CCR1H=pos/256; //占空比
TIM2_CCR1L=pos%256;
}
void ServoPT(int pos,int time)//time about 10
{
int k,i,j,d;
if(CurPos>pos)
{
d=CurPos-pos;
for(k=0;k<d;k++)
{
ServoPosition(--CurPos);
for(i=0;i<time;i++)
for(j=0;j<5000;j++);
}
}
else
{
d=pos-CurPos;
for(k=0;k<d;k++)
{
ServoPosition(++CurPos);
for(i=0;i<time;i++)
for(j=0;j<5000;j++);
}
}
}
void StopRotate()
{
TIM2_CCR2H=0; //占空比
TIM2_CCR2L=0;
}
void RotateClockwise()
{
TIM2_CCR2H=0; //占空比
TIM2_CCR2L=50;
}
void RotaetClockwiseTime(int t)//rotate clockwisely with given time(no unit)
{
int i,j,k;
for(i=0;i<t;i++)
for(j=0;j<500;j++)
{
StopRotate();
for(k=0;k<4;k++);
RotateClockwise();
for(k=0;k<4;k++);
}
StopRotate();
}
void RotateCntrClockwise()
{
TIM2_CCR2H=600/256; //占空比
TIM2_CCR2L=600%256;
}
void RotateTo0()
{
TIM2_CCR2H=0; //占空比
TIM2_CCR2L=187;
}
void Init_UART1(void)//Baud Rate 9600
{
UART1_CR1=0x00;
UART1_CR2=0x00;
UART1_CR3=0x00;
// 设置波特率,必须注意以下几点:
// (1) 必须先写BRR2
// (2) BRR1存放的是分频系数的第11位到第4位,
// (3) BRR2存放的是分频系数的第15到12位,和第3到0位
// 例如对于波特率位9600时,分频系数=2000000/9600=208
// 对应的十六进制数为00D0,BBR1=0D,BBR2=00
UART1_BRR2=0x00;
UART1_BRR1=0x0d;
UART1_CR2=0x2c;//允许接收,发送,开接收中断 *asm("rim");开中断,sim为关中断
}
void UART1_sendchar(unsigned char c)
{
while((UART1_SR & 0x80)==0x00);
UART1_DR=c;
}
#pragma vector= UART1_R_OR_vector//0x19
__interrupt void UART1_R_OR_IRQHandler(void)
{
Re_buf[counter]=UART1_DR;//不同单片机略有差异
if((counter==0)&&(Re_buf[0]!=0x55)) return; //第 0 号数据不是帧头,跳过
counter++;
if(counter==11) //接收到 11 个数据
{
counter=0; //重新赋值,准备下一帧数据的接收
isRead=1;
}
return;
}
void decodeIMU() //decode UASRT data from IMU
{
if(isRead)
{
isRead=0;
if(Re_buf[0]==0x55) //检查帧头
{
switch(Re_buf [1])
{
case 0x51: //acceleration
//a[0] = ((short)(Re_buf [3]<<8| Re_buf [2]))/32768.0*16;//x
//a[1] = ((short)(Re_buf [5]<<8| Re_buf [4]))/32768.0*16;//y
//a[2] = ((short)(Re_buf [7]<<8| Re_buf [6]))/32768.0*16;//z
//T = ((short)(Re_buf [9]<<8| Re_buf [8]))/340.0+36.25;//Temperature
break;
case 0x52: //rotational speed
w[0] = ((short)(Re_buf [3]<<8| Re_buf [2]))/32768.0*2000;
w[1] = ((short)(Re_buf [5]<<8| Re_buf [4]))/32768.0*2000;
//w[2] = ((short)(Re_buf [7]<<8| Re_buf [6]))/32768.0*2000;
//T = ((short)(Re_buf [9]<<8| Re_buf [8]))/340.0+36.25;
break;
case 0x53: //angle
angle[0] = ((short)(Re_buf [3]<<8| Re_buf [2]));//*180/32768.0;
angle[1] = ((short)(Re_buf [5]<<8| Re_buf [4]))*180/32768.0;
angle[2] = ((short)(Re_buf [7]<<8| Re_buf [6]))*180/32768.0;
//T = ((short)(Re_buf [9]<<8| Re_buf [8]))/340.0+36.25;
break;
}
}
}
}
void setZas0()
{
UART1_sendchar(0xFF);
UART1_sendchar(0xAA);
UART1_sendchar(0x52);
}
void KeepOrientationX(float x) //Stablize Angle of x axis, PD control
{
int u;
decodeIMU();
//u=(int)(P*(-angle[0]-x)+D*w[1]);
//ServoPosition((CurPos-=u));
if((-angle[0])>x)
ServoPosition(225);
if((-angle[0])<x)
ServoPosition(150);
if((-angle[0])==x)
ServoPosition(180);
for(u=0;u<5000;u++);
}
int main( void )
{
int i,j;
Timer2_Init();
Init_UART1();
GPIO_Init();
//ServoPosition(187);//servo homming
//RotateTo0();
for(i=0;i<1000;i++)
for(j=0;j<5000;j++);
CurPos=187;
setZas0();
while(1)
{
//PB_ODR^=0xf0;
KeepOrientationX(0);
}
} |
|