stm8s tim2使用的一个例子 9: |K]y
ZV^J5wYE
int CurPos;//current position 75-187-300 ( 0-90-180°) 1? hd
unsigned char Re_buf[11],counter=0;//UASRT data vl(v1[pU
unsigned char isRead=0; 9i[2z:4HJ
float a[3],w[3],angle[3],T; P FFw$\j
>!p K94
BRLU&@G`1
void Timer2_Init(void) !3v"7l{LF
{ ;{7lc9uRj
CLK_ICKR|=0x01; //开启内部HSI j/IZm)\
while(!(CLK_ICKR&0x02));//HSI准备就绪 C`<} nx1
CLK_SWR=0xe1; //HSI为主时钟源 >f05+%^[
CLK_CKDIVR=0x00; //外设时钟8分频=2MHz qtQ:7WO
1mPS)X_
TIM2_PSCR=0x07; //Timer2时钟128分频,计算一次8us )H,<i{80c
TIM2_ARRH=25; //自动重装的值 &Gwh<%=U
TIM2_ARRL=196; //PWM周期为20000us :DpK{$eCb
TIM2_CCER1=bit0 | bit4; // high level,OC1 ojqX#>0K
TIM2_CCMR1=bit3|bit5|bit6; //MODE E1v<-UPbA
TIM2_CCR1H=0x00; //占空比 Ntrn("!
TIM2_CCR1L=0x00; jCv+m7Z
ul&7hHp_u%
TIM2_CCER1 |= 0x10; //开启OC2信号输出脚 ?6]ZQ\,
TIM2_CCMR2 = 0x60; //PWM1模式 pr89zkYw
TIM2_CCMR2 |= 0x08; //输出比较2预装载使能 F5q1VEe
TIM2_CCR2H=0x00; //占空比 Vta;ibdeqW
TIM2_CCR2L=0x00; s'=]a-l~
XdVC>6
TIM2_IER=0x00; //更新中断使能 sjkl? _
TIM2_CR1=bit0; //enable counter /7)G"qG~F~
} #7"5Y_0-
Bq8<FZr#!
void GPIO_Init(void) iW$i%`>
{ raZRa*C;
PB_DDR|=0x20; 'Em($A(
PB_CR1|=0x20; ;9sVWJJCw
PB_CR2|=0x00; #(4hX6?5AI
} "t`e68{Ls
e%>E| 9*u
void ServoPosition(int pos)//position 40 75-187-300 2400, 0 means no torque @V u[Tg}J
{ lv&w p@
TIM2_CCR1H=pos/256; //占空比 #Og_q$})f
TIM2_CCR1L=pos%256; hlEvL
} Wm_-T]#_
I2Q?7p
void ServoPT(int pos,int time)//time about 10 o#b9M4O
{ ']Y:gmM"
int k,i,j,d; Ob+c*@KiW
if(CurPos>pos) qeGOSGc_
{ 9V!K._Cb
d=CurPos-pos;
fE}}>
for(k=0;k<d;k++) zg"ZXZ
{ Rznr9L
ServoPosition(--CurPos); `8Ix&d3F
for(i=0;i<time;i++) 4B(qVf&M
for(j=0;j<5000;j++); 2O>iAzc
} h|Qh/jCX
} >8-
`
else H^0KNMf(
{ v4^VYi,.-
d=pos-CurPos; #=m5*}=
for(k=0;k<d;k++) ,)8Hl[y
{ !;oBvE7Kh
ServoPosition(++CurPos); $^F2
for(i=0;i<time;i++) ]F!,Jx
for(j=0;j<5000;j++); Rk^&ras_
} 0't)fnI#
} s3S73fNOk
} fN;y\!q5
SY.V_O$l}
void StopRotate() ps[rYy
{ |ESe=G
TIM2_CCR2H=0; //占空比 +(T,d ]o]
TIM2_CCR2L=0; Zs)9OJu
} 7EUaf;d^
void RotateClockwise() {fs(+
0ei
{ Dc5XU3Eu`
TIM2_CCR2H=0; //占空比 u)ItML
TIM2_CCR2L=50; lU3wIB
} Z~<V>b
void RotaetClockwiseTime(int t)//rotate clockwisely with given time(no unit) /);6 j,x
{ J<D =\
int i,j,k; UlR7_
for(i=0;i<t;i++) Px`yD3
for(j=0;j<500;j++) 8cl!8gfv
{ .7q#{`K^=
StopRotate(); >"b"K{t
for(k=0;k<4;k++); `Jo}/c5R
RotateClockwise(); Rp1 OC
for(k=0;k<4;k++);
~j_H2+!
} 6AY%onY
StopRotate(); ?*HlAVDcFT
} /on p<u
void RotateCntrClockwise() 0td;Ag
{ qW9|&GuZ$
TIM2_CCR2H=600/256; //占空比 .x&>H
TIM2_CCR2L=600%256; )yJjJ:re
} uxBk7E%6
void RotateTo0() v%r! }s
{ 0Pe.G0 #
TIM2_CCR2H=0; //占空比 Oc1ZIIkh\
TIM2_CCR2L=187; :Wln$L$
} gNJ\*]SY
`|4{|X*U.
void Init_UART1(void)//Baud Rate 9600 Hmz[pTQ|87
{ /V^S)5r
UART1_CR1=0x00; ["z$rk
UART1_CR2=0x00; ]pb3
Fm{
UART1_CR3=0x00; /W;;7k
// 设置波特率,必须注意以下几点: iw%DQ }$
// (1) 必须先写BRR2 Wr;)3K
// (2) BRR1存放的是分频系数的第11位到第4位, 6%? NNEM
// (3) BRR2存放的是分频系数的第15到12位,和第3到0位 iJcl0)|
// 例如对于波特率位9600时,分频系数=2000000/9600=208 (NP=5lLH
// 对应的十六进制数为00D0,BBR1=0D,BBR2=00 ^^Y0 \3.
UART1_BRR2=0x00; X^?-Une
UART1_BRR1=0x0d; 8w$cj'
'(Pbz
UART1_CR2=0x2c;//允许接收,发送,开接收中断 *asm("rim");开中断,sim为关中断 6*%lnd+_
} w
^A0l.{
rq=R},p
void UART1_sendchar(unsigned char c) d 1z
{ t]V)3Ww
while((UART1_SR & 0x80)==0x00); 7Sokn?~i
UART1_DR=c; fK[9<"PC0
} 0\/7[nwS
u%2u%-w
N24+P5
#pragma vector= UART1_R_OR_vector//0x19 D/U o?,>8
__interrupt void UART1_R_OR_IRQHandler(void) E-RbFTVBA
{ H_x35|"
Re_buf[counter]=UART1_DR;//不同单片机略有差异 <1ai0]
if((counter==0)&&(Re_buf[0]!=0x55)) return; //第 0 号数据不是帧头,跳过 0 X@5W$x
counter++; wM><DrQ
if(counter==11) //接收到 11 个数据 G|o-C:~
{ #SL/Jr
DZ
counter=0; //重新赋值,准备下一帧数据的接收 n_5g:`Y
isRead=1; PRs[:we~~
} ]O 2_&cs
return; *H;&hq
} E3`KO'v%
q.#aeqKBP
void decodeIMU() //decode UASRT data from IMU Kl^Yq
{ 3p7*UVR"
if(isRead) OuX/BMG
{ i;)88
isRead=0; luV%_[F
if(Re_buf[0]==0x55) //检查帧头 vWow^g
{ [QeKT8
switch(Re_buf [1]) NvYgRf}uh
{ l_DPlY
case 0x51: //acceleration S6cSeRmw
//a[0] = ((short)(Re_buf [3]<<8| Re_buf [2]))/32768.0*16;//x WS;3a}u
//a[1] = ((short)(Re_buf [5]<<8| Re_buf [4]))/32768.0*16;//y ]SK (cfA`
//a[2] = ((short)(Re_buf [7]<<8| Re_buf [6]))/32768.0*16;//z l*h6JgU
//T = ((short)(Re_buf [9]<<8| Re_buf [8]))/340.0+36.25;//Temperature qoOHWh&
break; qlSMg;"Ghw
case 0x52: //rotational speed -5.>9+W8I
w[0] = ((short)(Re_buf [3]<<8| Re_buf [2]))/32768.0*2000; Y5K!DMKY
w[1] = ((short)(Re_buf [5]<<8| Re_buf [4]))/32768.0*2000; F|V?Z
//w[2] = ((short)(Re_buf [7]<<8| Re_buf [6]))/32768.0*2000; jAF
DkqH
//T = ((short)(Re_buf [9]<<8| Re_buf [8]))/340.0+36.25; T
`N(=T^*
break; Oyz=|[^,W
case 0x53: //angle i3YAK$w;&
angle[0] = ((short)(Re_buf [3]<<8| Re_buf [2]));//*180/32768.0; fz<Y9h=
angle[1] = ((short)(Re_buf [5]<<8| Re_buf [4]))*180/32768.0; enZW2o97c
angle[2] = ((short)(Re_buf [7]<<8| Re_buf [6]))*180/32768.0; NAL%qQ
//T = ((short)(Re_buf [9]<<8| Re_buf [8]))/340.0+36.25; 0ro)e~_@*
break; N:=D@x~]
} S7-?&[oeJ
} !m78 /[LW
} 0(teplo&P
} 594$X@!v
void setZas0() 1298&C@
{ H3MT.Cpd
UART1_sendchar(0xFF); CKj3-rcF(
UART1_sendchar(0xAA); )00#Rrt9
UART1_sendchar(0x52); .nT"f>S&'
} )-[X^l
j
void KeepOrientationX(float x) //Stablize Angle of x axis, PD control Jg^tr>I~
{ mh|M O(
int u; ?jy^WF`
decodeIMU(); A9F Z`
//u=(int)(P*(-angle[0]-x)+D*w[1]); 0!xD+IA!8
//ServoPosition((CurPos-=u)); ~d28"p.7
if((-angle[0])>x) V5R``Tp
ServoPosition(225); Bf[D&O
if((-angle[0])<x) C!v0*^i
ServoPosition(150); fyT! /
if((-angle[0])==x) O=ci"2!\-
ServoPosition(180); S tn[M|
for(u=0;u<5000;u++); i9w xP i
} >[ywrB ?T
%x L3=4\
@ -g^R4e<
int main( void ) cND2(<jx:
{ 6]na#<
int i,j; h1J-AfV
Timer2_Init(); kf^Wzp
Init_UART1(); UI |D?z<
GPIO_Init(); ePB=aCZ
//ServoPosition(187);//servo homming W&6ye
//RotateTo0(); fH}`
for(i=0;i<1000;i++) rXvvJIbi
for(j=0;j<5000;j++); HA"LU;5>2J
CurPos=187; n8J';F
=P
setZas0(); vP?"MG
Kq{9:G
while(1) @^/JNtbH!
{ 5h1FvJg
//PB_ODR^=0xf0; ,NKDEcw]
KeepOrientationX(0); "0nto+v
X=_N7!
} XA>@0E>1r
}