你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

利用STM32F103精确控制步进电机

[复制链接]
STMCU-管管 发布时间:2021-6-25 13:30
利用STM32F103精确控制步进电机
一、用到的元器件& \3 I0 u& j& D1 {
STM32F103C8T6! k2 ]+ E5 Q4 S6 g/ Z/ o/ T
42步进电机(42SHDC4040-17B)
" n* c( \5 C4 w+ i; C* L' p( ?TB6600电机驱动器升级版0 M" N' @4 |6 N3 `+ T6 C

5 a5 C/ r9 w' f3 t6 ?4 d
+ z- R7 S' ^, d& H" ]7 B+ n$ b/ ~
二、42步进电机/ f8 o! T- T$ s1 }( v
1.步进电机的基本知识1 Q, N5 f) g! J4 \, D, F
(1)拍数——每一次循环所包含的通电状态数(电机转过一个齿距角所需脉冲数)
! b/ |, w- a2 \7 ~! {; m(2)单拍制分配方式——状态数=相数
$ x& `6 i* z; u4 B: v7 c/ Q(3)双拍制分配方式——状态数=相数的两倍) b3 {5 j/ b5 @) }$ v9 _  F# L! b
(4)步距角 ——步进机通过一个电脉冲转子转过的角度  k- l1 |# I* P+ e, e; \5 m  T
11.png
N:一个周期的运行拍数0 K- h' c* ?. {5 U9 p# x  C, W
Zr:转子齿数% F6 M) J9 h" m; Z& C* n/ w
拍数:N=km
" o' x/ o( q* m2 s$ z3 z, C8 Qm:相数
! h  G7 v! T+ yk=1单拍制
. I, g, V7 g9 F3 M3 D* bk=2双拍制
2 T. j3 F  s; H% d(5)转速
* S6 h& I. R+ \
12.png
(6)角度细分的原理
/ o% J, B' a% O- W
# @+ j7 o) E( U2 X' Y
# G  h; {' H5 P* w6 I) r; [
电磁力的大小与绕组通电电流的大小有关。
' _" _* g  }; V当通电相的电流并不马上升到位,而断电相的电流也非立即降为0时,它们所产生的磁场合力,会使转子有一个新的平衡位置,这个新的平衡位置是在原来的步距角范围内。
% M* w, B: \5 B# c1 T2. 42步进电机参数: W  ^4 A  E- |' @7 h% v
无法查找到42SHDC4040-17B型号的详细资料,以通用42步进电机为例:
2 N& C/ M7 s- }# T4 F6 M# q' B步距角 1.8°
% y0 ?/ P9 |& i0 ^: K9 [) y步距角精度 ±5%
0 _/ _1 ]/ \) t; p4 r相数 2相
4 W- a% D% ]: y1 O励磁方式 混合式
6 C9 x0 |) @( w) I9 X( g转子齿数 50
' K. N! ~$ B/ N$ N拍制 双拍制  b( D9 w: K9 {; A+ ^
其他参数:无
2 o, d# {' Z. H! d$ L由步距角=1.8°推算出转子齿数为50,拍制为双拍制
7 u* e9 z* G! [6 j1 g( L% y' ^" {7 R6 H0 T5 S" m

$ c9 V, b8 k& J0 Z% H3 n3. 42步进电机速度与角度控制: }0 W( V5 ^; N: |/ I
电机的转速与脉冲频率成正比,电机转过的角度与脉冲数成正比。所以控制脉冲数和脉冲频率就可以精确调速。
$ T; Q& f) Y3 `4 ?2 ]6 C0 \3 f理论上步进电机转速 = 频率 * 60 /((360/T)*x)$ I1 Q$ T5 i4 b2 ]8 G% A
21.png
% B/ h/ R9 b! Q$ m3 i​       
4 Y4 X* J$ ?% l8 o$ U6 k+ @# l转速单位: 转/ 分1 L6 j' W% H. Y
频率单位:赫兹
+ P4 b, Y! p. E5 ?x 细分倍数# T- [0 ^% _' |5 H
T 步距角
* F: l# u+ k, f. i' g& r! K9 W. e例如,在本实验中,32细分;频率72000 赫兹;步距角1.8°;套用公式72000 ∗ 60 ( ( 360 / 1.8 ) ∗ 32 ) = 112.5 \frac{72000*60}{((360/1.8)*32)}=112.5 6 q5 w' a8 E1 B: f
((360/1.8)∗32)( I5 D: w/ n- `4 y
72000∗60
# P5 S) Q+ c% m1 C0 @5 U​       
7 @' @* k. W/ w7 Z% H4 G2 H, } =112.5rad/ min,即1.875 rad/s.0 O2 G. m. R$ p! c- f
13.png
三、TB6600电机驱动器升级版参数- {* [4 T7 S5 c' s
TB6600步进电机驱动器升级版是一款专业的两相步进电机驱动,可实现正反转控制。通过S1,S2,S3 3位拨码开关选择7档细分控制(1,2/A,2/B,4,8,16,32,),通过S4,S5,S6 3位拨码开关选择8 档电流控制(0.5A,1A,1.5A,2A,2.5A,2.8A,3.0A,3.5A)。适合驱动57,42 型两相、四相混合式步进电机。
8 l: i, {0 L0 A: m0 _/ k) ]) S' X5 ~& m1 i! L, v* h2 |/ O# J5 R
. W9 a' V$ |1 t' s
1.信号输入端6 \/ g. M5 {/ T$ ]& y; Y# C2 o
PUL+:脉冲信号输入正。( CP+ )
9 f. X1 v6 ^2 W1 W6 u, x  ~4 wPUL-:脉冲信号输入负。( CP- )
: K( O6 e7 ]4 p- p& b' bDIR+:电机正、反转控制正。) V3 F# L6 E8 u: @5 X1 g0 _) v
DIR-:电机正、反转控制负。
1 V+ ]' d( @. k6 \  H7 N% {5 ~4 a9 tEN+:电机脱机控制正。
6 @9 J1 m3 s, I# P5 M+ q! OEN-:电机脱机控制负。/ P/ N# L" I" I1 }8 t
- J# Q1 k$ w6 s. ]( P$ ^% O

' Z" x" `2 Q7 [% ?0 u' _共阳极接法:分别将PUL+,DIR+,EN+连接到控制系统的电源上, 如果此电源是+5V则可直接接入,如果此电源大于+5V,则须外部另加限流电阻R,保证给驱动器内部光藕提供8—15mA 的驱动电流。
3 f% w& T) r$ J: s( Y共阴极接法:分别将 PUL-,DIR-,EN-连接到控制系统的地端;脉冲输入信号通过PUL+接入,方向信号通过DIR+接入,使能信号通过EN+接入。若需限流电阻,限流电阻R的接法取值与共阳极接法相同。' y+ d/ E8 X/ o) H9 w: z+ J. |
注:EN端可不接,EN有效时电机转子处于自由状态(脱机状态),这时可以手动转动电机转轴。
) ^9 N5 q6 g7 [9 M( K2.电机绕组连接
( G# G' z2 j9 J3 `, j0 a/ eA+:连接电机绕组A+相。
% X! T$ L( ^" QA-:连接电机绕组A-相。
! i8 _) b# l9 r* qB+:连接电机绕组B+相。
) x- i; V; M9 ]  OB-:连接电机绕组B-相。1 J" ]6 |- W0 `( r& |: j, j

0 }  a+ t3 X, M
$ U1 X% \7 E* d
3.电源电压连接
1 S/ J, o1 a9 o* E# VVCC:电源正端“+”5 y5 f# w+ u! h: g  _4 K9 h# y
GND:电源负端“-”% f, u+ z& H2 m" v( @" z
注意:DC直流范围:9-32V。不可以超过此范围,否则会无法正常工作甚至损坏驱动器.
) K4 g. {: M3 F; t3 I8 Z" Q/ v7 [1 b2 q+ G# [! f* ]

  b; {; c- ]# \9 q9 ~9 S- B  J4.拨码开关# q% A$ u. c/ h1 N
14.png
" P, H6 N+ |( U电流大小设定) T/ w% p2 E8 U# U; r$ D- F. P4 k
15.png . c9 K5 @' I) O, }* i/ `0 m: j- M
三、STM32F1031 b/ |) b$ A* Z( d
------说明:引脚部分在文章末尾有解释--------( R$ o. s4 L! j/ n- r- a

  V+ w7 A. I, D
, P1 M: p: r. a+ D* M- V
1.引脚连接
4 Y; P5 o+ J5 g5 [. ?3 w! HA 0——PUL+
1 d0 J5 w' M: F& v$ \* a* ZA 3——KEY1——V3) D, a0 w! ]# s  E1 \) N* N
A12——DIR+
7 F9 A# b, v- I9 iA11——EAN+
6 z" a- v' G5 o& P" z& xGND——EAN- ——KEY07 v+ A) @3 I/ P( |

; i# w, Z1 ?2 p$ p" j- x& @
7 T+ C9 E1 S) n$ M5 J) }7 k
2.引脚功能
( j, z- c' X* V1 |& D& K3 HA0控制电机转速
6 `% N3 D0 T' j0 V  J8 FA3控制按键
3 n) k: C2 [" G. Z" rA9
( A* G6 @7 c' g0 o% A, OA11
+ s2 s1 e7 O  G6 {  I' u" _* y! J" nA11控制电机是否为锁死状态* R# J7 t3 y# m8 {3 K7 ^
A12控制电机正反转
) i+ X; P# A: E" G& e
9 U) t5 p0 x$ P
/ ^( L% F4 n+ n6 b
3.定时器' s, J% V( q+ j& }5 `5 I
1.本实验利用定时器TIM2和定时器TIM3构造一个主从定时器,TIM2作为主定时器控制电机的转速,TIM3作为从定时器控制电机的转动角度。# v8 O& ?3 C( N
2.电机的转速和转角还与驱动器自身的细分数有关,但是驱动器细分数是通过影响电机的步距角来影响转速和转角,而TIM2和TIM3是控制步进电机的频率和脉冲数来控制转速转角5 `6 o1 r% j4 x' O
3.电机的转速和角度与定时器的关系(在不考虑电机自身的细分数下), p. y7 j3 c# d; K9 d6 ~% ]3 Y
4 o: k5 ^# r4 m  F
# m1 e% v- i% \- v3 t4 m
设TIM2的定时周期(即重装值)为nPDTemp2,预分频值为OCPolarity2( t) d9 `% h" n* Q4 \3 K
 TIM3的定时周期(即重装值)为nPDTemp3,预分频值为OCPolarity3,7 S" X8 W1 g6 e, n7 h1 R
则单片机产生一个脉冲所需要的时间为:" X! c4 g  n6 p, k0 }4 ?
23.png
& V, ]' w! Y8 O  D9 Y7 Y​        7 a: Z. s8 C0 x, I
  本实验中设TIM2的定时周期nPDTemp2=72000/5000-1,预分频值OCPolarity2=999,TIM3的定时周期nPDTemp3=6399,预分频值OCPolarity3为0。即/ D$ k& d5 p/ W- F6 G
22.png ! m" Q+ A/ L( H
  定时器共产生nPDTemp3+1=6400个脉冲,电机转过的角度为6400*1.8°=11520°,即电机转了32圈。
. z, p+ D) r5 [8 K+ B2 d. a$ w  转动速度
  o& L$ K' U1 M 24.png
1 ~1 c  u3 O% |) Q6 R  ^5 b5 I  h# V  P8 B2 X# X, i" g

3 q: I0 l$ r! O4.在32细分的情况下电机1rad/s和转1°需要的重装值为nPDTemp2=11.25,nPDTemp3=17.7778。
$ B% g$ R8 C: p/ q3 H6 L* d+ F9 G+ |7 b8 O
$ n; d' U9 j. O4 l
四、程序实现
. k$ P6 [- B2 F8 j' M1.main.c程序
5 @) ]' I+ Z! @1 j3 a9 F
  1. #include "main.h"
    6 m1 Q+ f) m+ K
  2. #include "sys.h"
    4 X. |) z( e+ ^! s: w
  3. #include "usart1.h"
    - ~! p- {' T/ A; |+ F/ D
  4. #include "delay.h"  n0 L" ?4 `2 L
  5. #include "math.h"
    0 I( w1 {, T7 R0 t' k1 N* d: V
  6. , D, N  b( Q* Q2 @% G; V$ {
  7. u16 t;  
    : v; H) r4 _. A& D5 ~+ d% l% F2 |
  8. u16 len;                    //接收到的数据长度5 J+ [" d0 K! x, {* A* [6 ?1 r- l
  9. u16 times=0;
    : Z1 @5 [/ ]" f6 Q* x7 j( e
  10. char receive_data[60];        //接收到的字符
    - s3 `$ s. Q& ~0 z  J
  11. char state;                                //电机正反转标志位0正转,1反转
    # W/ z  q+ v9 h* R0 ?( P+ v
  12. int speed,angle;                //旋转速度,角度$ \4 n4 n( _& Q8 l
  13. int a=0;                        //判断是否接收到数据
    5 G4 [6 v' d$ L. Z  P, A
  14. int r,data=0;                          //用于数据转换
    4 ]0 n5 Y( i2 S  a- R3 h
  15. int type;                                //转换后的数据   
    4 ~! o6 p$ I% t+ l: d! J: @
  16. extern u16 USART_RX_STA;7 n% c6 v; W" a7 H* w/ \8 K2 U" p

  17. : I# K5 v3 ^' d0 h" f
  18. /**************************
    : w" A) }1 d; G/ K8 F7 m9 T
  19. * 函数名:delay! v" O) l/ M6 M4 z8 u& {
  20. * 描述  :延时函数4 [- y) M, ^2 X
  21. * 输入  :无 1 W  D5 P- ^( t4 I! G; S6 F! ~9 ~
  22. * 输出  :无
    / v7 P6 c) F! C/ l5 p
  23. * 返回值:无- V0 j  q  V  Y! x- N' C7 U
  24. ****************************/  W2 e! u# H' _" _
  25. void delay()//延时
    ' D! H% Z0 b' S( g
  26. {, V9 ~' U7 Z2 P; r
  27.          int i,j;
    7 M. r! G& E- B
  28.          for(i=0;i<2000;i++)1 y: g2 h9 G4 H/ T. B' h; Q$ b
  29.          for(j=0;j<1000;j++);
    , A) m: l! V1 z% I# k
  30. }
    ) l1 _; ~1 ~* S8 q4 B" N
  31. 0 K2 |# f. @% h
  32. /**************************
    7 L  l2 r$ K- m( ]* \# ~" }
  33. * 函数名:Waiting_receptio5 c& V0 c7 p* j% S3 L
  34. * 描述  :等待串口接收数据
    + e/ [+ D3 @, `
  35. * 输入  :无 - o6 r5 l0 u/ b6 z& p+ W  j
  36. * 输出  :无" C& e5 f$ R$ o: b, M4 W
  37. * 返回值:无$ K8 S4 Z, C' a2 `
  38. ****************************/; W$ q; V) R! W7 E! H' X
  39. void Waiting_reception(void)& h" z% C; ^, A2 K9 z
  40. {
    % z8 G+ y) W6 f/ T! \
  41.         while(a==0)//等待数据发送完成6 _' @! E1 G% x& i" a8 B# [4 t% [' D
  42.         {
    8 t# P; ]! R1 \6 x7 E9 M
  43.                 delay_ms(100);! d" i* Z7 G8 m, z* s# X
  44.                 if(a==1)//接收到数据
    % E8 i6 w% N  e( R
  45.                 {" m% b* `: P4 p  [
  46.                         if(USART_RX_STA&0x8000)//(串口接收用到了正点原子的例程)2 t& H7 `5 J+ M0 e% }$ _3 k
  47.                         {
    $ e9 N/ g7 ~; ?& D
  48.                                 len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
    ; x2 }8 r7 u3 l& q
  49.                                 r=len;                               
    + e. Y4 R% s1 E& [6 r
  50.                                 type=0;  E: v4 g! K! w/ }# j: h
  51.                                 for(t=0;t<len;t++)//拷贝数据,将字符转换为十进制数
    & f6 ?) z% H( I8 j6 [6 s2 v
  52.                                 {( H+ R: l' h2 p  P. p
  53.                                         receive_data[t]=USART_RX_BUF[t];
    & X* b8 w8 D! E$ j, Y
  54.                                         data=(int)receive_data[t]-48;
    6 L- v: a* H# k# \5 k0 t% |- f
  55.                                         r=r-1;
    ( o' b1 Y" w0 b
  56.                                         type=type+data*(pow(10,r));; x$ P7 G& d# @0 {) {1 R8 R3 c4 J
  57.                                 }
    9 j( L6 m3 w' B' U) z/ Q
  58.                                 USART_RX_STA=0;" s5 i+ Z9 J- |. r. ]9 R
  59.                                 a=0;
    ! P  ]/ v5 r. m% G
  60.                                 delay_ms(500);! T! q2 U) t; C8 F0 w
  61.                                 break;& r, `+ s/ Z. k7 L
  62.                         }
    , V$ Y6 }8 Y. p7 O, w1 F# d
  63.                 }4 u" f- k9 X. P" L! w0 ]0 \3 {) O) u
  64.         }
    & s8 s4 }9 T' f
  65. }
    2 n( E$ w" q! d( t3 ]
  66. /**************************( [5 x$ U3 F) ?4 p
  67. * 函数名:KeyStates0 ^/ r6 D5 \. `; p" @" O
  68. * 描述  :监测按键状态" d" K1 p) n0 P4 {$ V
  69. * 输入  :无 * l. V" m# z, N) g# I) {' w6 W
  70. * 输出  :无' \( W. a. p" o
  71. * 返回值:0/1, b. C( _5 D& f* K5 _: K
  72. ****************************/
    8 z5 Q! F& i7 }& }/ C
  73. u8 KeyStates()//按键状态
    9 f  ]5 e  c# p; B6 ?, Y: \
  74. {; y3 F! {6 Q  z, s! ?
  75.         static u8 i = 0;
    2 U7 h1 Z$ L  L0 c# Y2 p$ A# [) R2 D
  76.         if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)==0)
    9 k4 l, I4 s: l" }, L. {7 ?
  77.         {
    % Z) ^  t  c# @% A' M3 @" K
  78.                 delay();+ ]$ ^5 ]* ?2 z# k6 m
  79.                 if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)==0)) K5 n0 h4 m+ z7 Y, j4 @$ s0 l& q, d
  80.                         while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)==0);, d+ T5 A& H1 K/ U9 L, ]
  81.                         i = ~i;
      o4 V  t" s1 g9 j
  82.         }0 u3 s/ n* }4 F
  83.         return i;
    $ ~/ f' ~: c5 L" W1 g0 K
  84. }$ H( d0 T/ {2 f0 G' N5 F
  85. /****************" K& b+ Z( P9 b* X% J" ~8 O: P1 K
  86. * 函数名:main
    6 V" b/ B1 ?6 |
  87. * 描述  :主函数
    9 G+ Q5 m9 Y/ E6 S0 Y9 I
  88. * 输入  :无
    ; t9 O3 C/ ~( P5 R7 l( @$ x4 N
  89. * 输出  :无
    7 d6 P% M; a6 g! [- Q7 O5 v
  90. ******************/# f( u2 J. k8 V! l5 a* T6 q, |2 R
  91. int main(void)
    ' L  Y+ ?" `, A; {8 E0 S
  92. {, q5 {2 I/ M5 ?$ s
  93.         NVIC_Configuration();                        //中断初始化; H" M, H  f( d. i3 g" Q
  94.         GPIO_Config();                                        //IO口初始化- e. U8 @( e" P( D9 u8 e' j8 q
  95.         USART1_Config();                                //串口初始化4 \) E# O6 [" K- ^# O5 J' ?
  96.     delay_init();                                   //延时函数初始化        8 \1 H9 p) r1 j4 a
  97.         GPIO_ResetBits(GPIOA, GPIO_Pin_11);//A11置零  A11——EAN+
    . j9 ^$ r$ K3 A. i# C
  98.         GPIO_ResetBits(GPIOA, GPIO_Pin_12);//A12置零  A12——DIR+  K! ~- G  s; Y
  99.         while(1)  c7 G$ {* h/ a# F  w
  100.         {
    " a0 a( T/ R2 j
  101.                 delay_ms(100);4 F, X. ?6 v' l, u0 A7 E
  102.                 Initial_state:                printf("\r\n 请选择正反转,正转输入0,反转输入1 (以新行作为结束标志)\r\n");       
    ) q' P0 c) ^! _
  103.                 Waiting_reception();
    0 s( F6 x# v4 Y. n
  104.                 state=type;//将接收到的数据给type. g8 l/ b+ ^, {1 X9 a- T
  105.                 if(type==0)//电机正转
      {. W  I7 a1 f3 C, G
  106.                 {
    / T% c; p1 e" p. n1 S
  107.                         GPIO_SetBits(GPIOA, GPIO_Pin_12);//电机正转3 _( g# L" v' i4 K
  108.                         printf("\r\n 电机为正转模式,请输入旋转速度(rad/s),输入0返回初始模式 \r\n");
    , |7 D) Z$ d8 ^9 X& C( ]
  109.                         * J  L7 X% M4 y" d) {* \$ u
  110. /*********************************************此模块用于配置速度参数********************************************************/
    4 w5 `& U9 u6 ~3 G
  111. 5 A& V' G! g5 A8 ?$ J
  112.                         part1:Waiting_reception();2 |% ~  W/ S' h9 E2 `
  113.                         speed =type;//将接收到的数据给speed/ K" r# M" T$ c9 M# x  T* @
  114.                         if(speed==0)goto Initial_state;//如果是0则返回初始模式
    $ b3 n. h0 \" ^# |6 C. _! G
  115.                                 else{
    ; K5 J$ c! N; [  O' V
  116.                                         if(speed>=15)5 P) c* l6 e5 ~6 ?; O/ U  `
  117.                                         {
    4 Y) T) B4 w; z" F
  118.                                                 printf("\r\n 旋转速度>15rad/s,请重新选择旋转速度。\r\n");
    ( z% P" e; b5 F3 {/ ~
  119.                                                 goto part1;  P4 P4 i% V  s0 R) H4 q7 ~% _0 J
  120.                                         }
    0 J# @, ^' W4 _5 P' a! j/ M
  121.                                                 else printf("\r\n 电机旋转速度为%d rad/s,请输入旋转角度,输入0返回初始模式 \r\n",speed);
    1 U7 u- o  G: P0 H
  122.                                 }
    4 \; _4 S& e% L& ?; `5 o
  123.         $ N% \0 {( A1 n
  124. /*********************************************此模块用于配置角度参数********************************************************/                : N) J2 J* L$ w, N* }4 ~

  125. ! L) x3 l- v4 ?/ N3 f
  126.                         Waiting_reception();
    ; F' y( d6 B" E
  127.                         angle =type;//将接收到的数据给type* c; K4 B  g: V) Y8 i: U  _( v# l+ G
  128.                         for(;;)4 V3 A' a0 N9 r  X
  129.                         {7 z  P  A8 b% g3 ^+ Q
  130.                                 if(angle>0)//接收到的数据不是0
    ; ]! D& H) }* D# B  P
  131.                                 {
    6 M: y; V: S2 u9 c- r. w" y2 }
  132.                                         TIM2_Master__TIM3_Slave_Configuration(speed,angle);        // 配置TIM2和TIM3的重装值 ,改变电机转动速度和角度
    + k) k. Y- o! w
  133.                                         delay_ms(20000);//电机保护; Z; |! O4 @' v7 ]1 ]) H$ [! n
  134.                                         printf("\r\n 电机已旋转%d °,请输入下一次旋转角度,输入0返回初始模式; \r\n",angle);+ g/ m! r# d# k$ J, K/ @
  135.                                         angle=0;
    ( l/ D- H/ \7 T( m6 y0 E) v! r2 r
  136.                                         Waiting_reception();               
    * I( Y2 ]/ x  r, H; c: H1 F  Y
  137.                                         angle =type;                                        . A' {- ]: I; |9 k
  138.                                 }else{
    # f$ c; s7 `/ O
  139.                                         if(angle==0)goto Initial_state;//返回初始状态        & X- B8 v* o/ d. ^  U0 N4 U+ w
  140.                                         else {6 a$ s" \4 w( \1 {  f; _& {  I
  141.                                                 printf("\r\n 角度错误,已返回初始模式 \r\n");               
    7 A* D( ^9 x  {3 ~9 P4 o
  142.                                                 goto Initial_state;" L& h4 w+ j# ~
  143.                                         }                                               
      C; _; Y7 b' w. q8 p& a8 }' _
  144.                                 }
    # U: `3 O. o! Z/ V) ~
  145.                         }
    0 w/ _. K8 \8 S2 m/ p6 x" o
  146.                 }                & O9 d1 Z( K+ C: ~# Q: n/ r- n* V
  147. /*********************************************反转模式********************************************************/                : |+ l2 o' J  e5 i( n
  148.                 else{2 Y- \; C- ]7 P  j
  149.                         if(type==1)
    ) }' i  R! B0 T) W  |
  150.                         {
    % H2 F/ d' _+ Q7 n
  151.                                 GPIO_ResetBits(GPIOA, GPIO_Pin_12);//电机反转
    ' S7 i- ^+ `6 Z- m' i
  152.                                 printf("\r\n 电机为正转模式,请输入旋转速度(rad/s),输入0返回初始模式 \r\n");9 h0 x, {( T) c
  153.                                
    + N( I6 {- {! U6 s8 E
  154. /*********************************************此模块用于配置速度参数********************************************************/7 H: m% A" b! o: i: X2 U
  155.                                 part2:                                Waiting_reception();
    4 [' l& |1 U' r7 T0 `( M4 q: L3 s
  156.                                 speed =type;//将接收到的数据给speed
    ! a9 D: K8 h" M4 m" X" y5 N. T
  157.                                 if(speed==0)goto Initial_state;//如果是0则返回初始模式
    2 O" O/ A$ l, b: p. i
  158.                                         else{! I: m8 ~, A  k( n
  159.                                                 if(speed>=15)
    % \6 C- K, `" }. g# x2 R' @1 f
  160.                                                 {
    6 Z, l/ T9 \; F1 Q! x
  161.                                                         printf("\r\n旋转速度>15rad/s,请重新选择旋转速度。\r\n");: T& Z/ Y4 v3 r
  162.                                                         goto part2;
    . c. z5 c# U' w: H, H% F& T( \
  163.                                                 }else printf("\r\n 电机旋转速度为%d rad/s,请输入旋转角度,输入0返回初始模式  \r\n",speed);- \  U* J) Q3 v! V  x3 f9 c
  164.                                         }        4 A; c& u) H9 |9 w7 k& A( `
  165. /*********************************************此模块用于配置角度参数********************************************************/                ) T0 U8 H( h7 K7 U; s+ b
  166.                                 Waiting_reception();7 i" r4 {" y, x
  167.                                 angle =type;//将接收到的数据给type
    $ \% P0 M% X, S- ^. u7 ?
  168.                                 for(;;)1 s# G! q% t8 z2 L' ?( U
  169.                                 {
    - Y, r+ i8 C- L: O
  170.                                         if(angle>0)//接收到的数据不是0' D5 x: N7 {  C" X* P; J2 |3 `/ A
  171.                                         {
    # B. w2 [$ D  }0 d% c3 e( ~) H( R4 s7 Y
  172.                                                 TIM2_Master__TIM3_Slave_Configuration(speed,angle);        // 配置TIM2和TIM3的重装值 ,改变电机转动速度和角度
    , l. F/ K, ~9 `( y4 Q; V
  173.                                                 delay_ms(20000);//电机保护
    $ p( \: u+ k0 a1 T0 d+ a- l# d
  174.                                                 printf("\r\n 电机已旋转%d °,请输入下一次旋转角度,输入0返回初始模式;\r\n",angle);
    $ O: Z. s- k1 y4 A
  175.                                                 angle=0;) J& }- n8 k, M1 u0 E
  176.                                                 Waiting_reception();               
    + _; A. u% a9 }" b6 s. A: j6 [
  177.                                                 angle =type;                                       
    ' ?+ L  X; K/ w- D
  178.                                         }else{
    . ?5 [3 E9 [5 }( O
  179.                                                 if(angle==0)goto Initial_state;//返回初始状态        + y1 `. W/ \% `# `* n5 \+ |
  180.                                                 else {
    " R7 n! m3 t7 P0 |
  181.                                                         printf("\r\n 角度错误,已返回初始模式 \r\n");                # E6 n. J% t+ v5 }
  182.                                                         goto Initial_state;
    : g3 g" F9 I# s5 a
  183.                                                 }                                                                & |7 {& U8 t7 C5 ~0 ]2 B
  184.                                         }6 E) n; `: `" g+ X3 d. Q- ]
  185.                                 }+ h, S& R: Q9 O$ N+ C! C1 p
  186. /****************************************************************************************************************************/                                       
    & B3 S! z3 j$ S  O, U( ]) e0 B
  187.                 }else{//if(a!=0)&(a!=1)8 h. K9 Q0 J. a( y
  188.                         type=NULL;
    6 ^  l- `$ m7 h, o2 W! L$ u, Z1 \
  189.                         printf("\r\n 输入无效 \r\n");" B( W; u3 f! m5 p6 m
  190.                         goto Initial_state;//返回初始状态
    " ?; h! W7 X+ ?; R2 E! q
  191.                         }
    ; K( P5 B) s1 e/ c
  192.                 }
    4 V! A0 P( n+ l: ]6 A0 m
  193.         }
    $ u* F* I* \* D' _
  194. }" x0 V- R9 T& i4 Y: o
复制代码
2.main.h程序
5 P6 O2 K2 {/ _
  1. #ifndef _MAIN_H0 d/ j. {# a* i8 L$ \7 b
  2. #define        _MAIN_H
    ' y" S; y$ ]1 A- R$ t0 D6 D
  3. #include <stm32f10x.h>( {3 G( G! |% W5 P: y
  4. #include <usart1.h>
    % @' F" E3 z, ^1 H4 P$ l" r9 i" [
  5. #include <misc.h>
    3 S5 f4 h( b$ Y, Y5 V' C
  6. #include <nvic.h>( f% `1 [/ y8 S  K! V
  7. #include <stdio.h>+ f7 y. |/ ^7 p3 h7 F* g, v+ r
  8. #include "stm32f10x_tim.h": a( e6 i1 x/ @0 `
  9. #include "timer.h"
    + Z: z. }" a! ?
  10. #endif
    % J# P# D7 N! B! I8 `& F; a
复制代码
3.time.c程序
# h) C/ `; N/ x4 C9 }7 f  |
  1. #include "timer.h"
    & }1 w) S9 F3 z# z
  2. /**************************
    * I7 \2 }# D# N" U# G; U0 o; l
  3. * 函数名:GPIO_Config
    , F3 ~8 U: b& `% z0 a- v
  4. * 描述  :无
    ! _/ A! P9 u4 m9 V6 j" }9 }0 M
  5. * 输入  :无 $ x5 u# @' J, y; m2 S. o0 a3 p
  6. * 输出  :无
    ( ?0 v: ~" Z4 h% E; ]# j
  7. * 调用  :主函数
    5 L( p7 ~* r6 S6 c* Q, Y
  8. * 返回值:无3 J+ }/ j: u5 l
  9. ****************************/
    " ~7 B: J  G+ Q+ M( [; U, U; D1 t
  10. void GPIO_Config(void)
    + p: `  s, ]+ [6 F
  11. { 2 M  t9 ~( x6 E  b' P
  12.                 GPIO_InitTypeDef GPIO_InitStructure; - O3 a) H' V: @2 Z  h
  13.                 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); //使能IOA$ s4 T: b- P# T9 O& L
  14.                 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3, ENABLE); //使能TIM2,TIM3
    6 a0 }) \! \2 Z7 V& q
  15.                 ; B2 x+ p2 \& d- o9 {: Q
  16.             /* Timer2 Channel 1, PA0 */
    ( R; O  U8 W, S' D; c1 y
  17.             GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_0;
    . _0 `- T2 D% ]6 u$ t: b
  18.             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用输出
    ! G6 T$ {: M; q: V  g/ [1 t
  19.             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 2 m2 |) q& b% l, a5 W& m; c3 J5 R
  20.             GPIO_Init(GPIOA, &GPIO_InitStructure);. l+ w3 W+ P& C1 k
  21.                  
    0 p5 O. L5 n; G7 e
  22.                 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_11|GPIO_Pin_12;
    6 c8 X8 J, A% j' |0 Y& J' y- ~
  23.                 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         //通用推挽输出模式5 A& M* Z( v7 N, c# J9 x3 f
  24.                 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //指定GPIO引脚可输出的最高频率为50MHZ0 b6 C% r& g$ D$ t, i& K
  25.                 GPIO_Init(GPIOA, &GPIO_InitStructure);                   /// \" J' q; B3 `# {  i+ m/ V
  26.                 GPIO_ResetBits(GPIOA, GPIO_Pin_1);//指定引脚输出低电平,此时灯全灭,方向
    ) t5 T& h: n. `' W8 U1 q' B" R
  27.                 GPIO_ResetBits(GPIOA, GPIO_Pin_2);//指定引脚输出低电平,此时灯全灭        使能
    & C1 r2 J  J, T0 J" ]! g
  28.                 GPIO_SetBits(GPIOA, GPIO_Pin_11);//指定引脚输出低电平,此时灯全灭,方向, \9 S  c* `! d/ R
  29.                 GPIO_SetBits(GPIOA, GPIO_Pin_12);//指定引脚输出低电平,此时灯全灭        使能1 @! ?0 M5 z7 n# W: R
  30.         5 d6 \( v% q- v9 p
  31.          
    * Z; p8 z6 b% ?0 j. T
  32.                 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;4 Q5 y9 t9 c" r: f9 G
  33.                 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;         //通用推挽输出模式4 w& e+ t# `) z+ D# F5 ^1 G
  34.                 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //指定GPIO引脚可输出的最高频率为50MHZ
    6 k1 u2 H& ^( e8 s" g
  35.                 GPIO_Init(GPIOA, &GPIO_InitStructure);                   //
    1 D9 a( b- L% U7 L/ P
  36.                
    ( C4 T9 H) m5 d
  37.                 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); # b) |0 o# t0 d
  38.                 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    . S" U! n2 X" J: D" u  u
  39.                 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         //通用推挽输出模式  z- y0 B) P! p, @4 H- z, u
  40.                 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //指定GPIO引脚可输出的最高频率为50MHZ
    6 I4 S# c2 f8 s# l- d
  41.                 GPIO_Init(GPIOB, &GPIO_InitStructure);                   //
      d/ N1 s  C; H3 Q8 ~: l8 J
  42.                 GPIO_ResetBits(GPIOB, GPIO_Pin_12);//指定引脚输出低电平,此时灯全灭        使能$ u/ G* a0 m2 K, g' `3 g
  43.                
    / m% ]7 k9 N7 l, D- q" z* k, ?0 N
  44.                 //GPIO_ResetBits  GPIO_SetBits
    & _" ?: b- \9 B/ }! s- s$ F0 A
  45. }/ b0 D, ?) B6 ?2 U. x0 w
  46. ; V/ l8 D& @1 e3 }
  47. //================================================================================+ A8 H$ U$ b  f; v: j3 Z. w
  48. /**************************
    4 W4 B% I/ h# K: g$ T
  49. * 函数名:TIM2_Master__TIM3_Slave_Configuration
    / _. U$ Q7 [+ D
  50. * 描述  :主从定时器配置% Z) b5 i. S: @% {1 F3 M6 f' f
  51. * 输入  :电机转速speed,转角angle
    : |* U3 v2 j7 s6 {8 r# d6 Q8 z
  52. * 输出  :无1 ^0 o  J/ q. y0 ?) g) C9 k
  53. * 调用  :主函数7 o( F. Q7 k* d+ ]: |( H5 @0 H
  54. * 返回值:无& N) ^. D  J" u8 X% h( m. J% E
  55. ****************************/
    ( I5 L2 @6 d5 O/ e
  56. void TIM2_Master__TIM3_Slave_Configuration(u32 PulseFrequency, u32 pulse) / {, I8 s' |3 f( h8 X6 @
  57. {
    1 c1 Q7 n& ?% T, x6 o5 O+ f
  58.         TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; ) j. g4 P2 h% N# G+ p7 @
  59.         TIM_OCInitTypeDef TIM_OCInitStructure; / A- P9 k& \2 R" R5 \5 D! W
  60.         : F% C) ^2 }5 K( E2 M' E
  61.         u16 nPDTemp ;
    2 j) C$ C0 u2 f/ W, H9 H
  62.         u16 pulse_number;$ e# |, ]- x1 l) Z- g( H
  63.         float p=PulseFrequency;
    . `6 F3 m9 a# h8 W6 i3 L0 _
  64.         TIM_Cmd(TIM2, DISABLE);
    % x- [6 d( ~! L8 Q7 p0 d8 U# `, h
  65.         nPDTemp = (11.25/p);                            //TIM2重装值是11.25时1s转一圈(电机32细分下)5 t; C/ S! F5 m/ V7 D
  66.         pulse_number = (16.7778*pulse);//TIM3重装值是16.7778时转1°(电机32细分下): X0 ]" v! G" l1 ~2 B) i4 ]
  67.        
    0 S$ N( u2 l) r. Y
  68.         // 时基配置:配置PWM输出定时器——TIM2 $ s8 d- f& g3 _6 U2 H# d4 w1 o
  69.         /* Time base configuration */
    ( e- e+ j8 H  b$ }8 F6 V
  70.         TIM_TimeBaseStructure.TIM_Period = nPDTemp; //定时周期为nPDTemp
    ! u: u% f; m+ U6 m8 P" f
  71.         TIM_TimeBaseStructure.TIM_Prescaler = 999; //预分频值1000,即f=72khz2 |( f- p+ Q7 b+ V+ n! S0 F) Y
  72.         TIM_TimeBaseStructure.TIM_ClockDivision = 0; //时钟分频因子,会影响滤波器采样频率,与本实验无影响  C* b' {- z1 i5 A$ z
  73.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
    2 @4 L3 e# ?6 s# ]8 T
  74.         TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; //指定重复计数器值
    - y$ ]! @' s3 g% |
  75.         TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); ' t  V2 k& j1 b7 B
  76.        
    : L- T, D: G& k
  77.         // 输出配置:配置PWM输出定时器——TIM2 ! n" O# Q1 k" H: I/ o0 K! r
  78.         /* PWM1 Mode configuration: Channel1 */    + P. c& h9 f. V' p. S
  79.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //TIM 脉冲宽度调制模式 18 _1 j3 ]" E4 I+ z
  80.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //高电平有效2 l$ w( l1 n: c' Z1 a& _7 Q9 t
  81.         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //使能输出
    . w4 A0 I% O9 Y% E$ n7 f
  82.         TIM_OCInitStructure.TIM_Pulse = nPDTemp>>1;//50% //比较tim_ccr的值,输出脉冲发生跳变) i6 Z) c; I5 v7 Q* ?
  83.         TIM_OC1Init(TIM2, &TIM_OCInitStructure); //初始化
    ! d$ P" z4 z$ ^( |6 u
  84.         TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); //使能 TIMx 在 CCR1 上的预装载寄存器
    9 D8 N8 S7 K, S/ Q- U5 p6 C
  85.         TIM_ARRPreloadConfig(TIM2, ENABLE); //使能或者失能 TIMx 在 ARR 上的预装载寄存器
    / Z! a3 K1 W6 v# k4 b' f& {: o
  86.         : o/ q" F# {% I: w+ l
  87.         // 时基配置:配置脉冲计数寄存器——TIM3 ! \! q& D% t, b$ [" V- h$ h
  88.         TIM_TimeBaseStructure.TIM_Period = pulse_number;      //0x1900是360°;//改变给电机的脉冲个数                     0 A( f$ d  P; Q- b+ p7 b/ g
  89.         TIM_TimeBaseStructure.TIM_Prescaler = 0;
    2 {6 {) z1 i: u8 I9 D
  90.         TIM_TimeBaseStructure.TIM_ClockDivision = 0; " G* `1 [( _8 V+ {( D$ b6 w. i
  91.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    2 X2 h; ^! B, h+ g: T$ K
  92.         TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
    * r( X% O- ~+ I8 c& v& E/ Z
  93.         TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
    3 I7 L1 _  T4 d1 V$ F) v, N% T  O) n
  94.         // 输出配置:配置输出比较非主动模式定时器——TIM3
    + l7 l9 N" C- f, x8 u
  95.         // Output Compare Active Mode configuration: Channel1 7 r* t3 y2 z7 W( X
  96.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Inactive; //输出比较非主动模式,(匹配时设置输出引脚为无效        电平,当计数值为比较/捕获寄存器值相同时,强制输出为低电平)      2 {& y* [* h" q
  97.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; ) v! {, p- n; U1 `. [; C( N  k4 Y
  98.         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; % m; I& e: C2 L- x5 R1 E: v9 k
  99.         TIM_OCInitStructure.TIM_Pulse = 0xFFFF; // 这里的配置值意义不大   2 p! @8 q$ y' ^  }" c- U, V
  100.         TIM_OC1Init(TIM3, &TIM_OCInitStructure); # ]! G. I; U  Q, i0 n% \
  101. 2 [( \7 j5 d3 f6 Z
  102.         // 配置TIM2为主定时器 . ]: k7 S/ b6 j% @: R) h2 e5 H' W* s3 \
  103.         // Select the Master Slave Mode 5 z$ `! p4 O% X4 I
  104.         TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable); //设置 TIM2 主/从模式并使能
      `, u* c' \$ f5 i* k
  105.         // Master Mode selection  , _* y. V2 j% i% P! C( W6 |6 R% n, s
  106.         TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update); //使用更新事件作为触发输出0 ]8 Z6 q7 r4 v
  107.         0 N* E) N# ^/ X+ T+ Y
  108.         // 配置TIM3为从定时器 $ l7 P% w: t) o; z1 B+ J" O( d
  109.         // Slave Mode selection: TIM3
    % e- M7 M4 `6 y, ^3 ?; n' g
  110.         TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Gated); //选择 TIM3为从模式   TIM_SlaveMode_Gated-当触发信号(TRGI)为高电平时计数器时钟使能
    0 E+ b* l4 @  m$ D3 r1 b7 P" M
  111.         TIM_SelectInputTrigger(TIM3, TIM_TS_ITR1); //选择 TIM3 输入触发源    TIM_TS_ITR1-TIM 内部触发 1
    ) L, o1 H1 J. Q0 C5 i; [. G' M7 o
  112.         TIM_ITRxExternalClockConfig(TIM3, TIM_TS_ITR1);//设置 TIM3 内部触发为外部时钟模式   TIM_TS_ITR1-TIM 内部触发 1
    , l8 D8 s2 \" W5 ?" S8 W
  113.         TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE); //使能TIM3     TIM 捕获/比较 1 中断源          8 Z: v4 {3 o& ?. W
  114.           Z' F4 o* d2 N) o0 u1 r
  115.         TIM_Cmd(TIM2, ENABLE); $ G( g3 C: c2 y2 Q% S, T( [0 g
  116.         TIM_Cmd(TIM3, ENABLE); 1 c) _3 S- }! h. E* ]0 z, d
  117. } ! D- c0 L: C# N8 l8 `- X& Y6 m3 y

  118. $ D+ Q* l9 Q. N& g' M8 @
  119. /****************************************************, X0 a* W7 o" P; x+ f+ Z2 g+ h6 v( w7 y
  120. * 函数名:Output_Pulse
    9 \" q5 C0 \# e
  121. * 描述  :无+ c/ `* C& L. p3 U2 H
  122. * 输入  :无
    3 h& L" d  s% o: s* ^; h  Y7 M' j* A
  123. * 输出  :无
    ( f  H# w% V8 X/ u
  124. * 返回值:无4 M8 V, R  v5 J. ^. x7 E
  125. ******************************************************/0 t6 R7 r3 e& e, k5 D
  126. void Output_Pulse(u16 Num)
    . J2 ~; Y; D2 g5 i" @6 p
  127. {
    + k6 E3 _, S* ^  r: `* d+ M( |
  128.                 GPIO_ResetBits(GPIOA, GPIO_Pin_2);//指定引脚输出低电平,此时灯全灭        使能3 L; U7 i" G6 l, F  S. Z4 B; N
  129.                 TIM3->CCR1 = Num;
    ) Y( z" _7 N: Q6 |0 ?
  130.                 TIM3->CNT = 0; # K! c+ t2 j0 k* ~1 E
  131.                 TIM_Cmd(TIM3, ENABLE);
    2 O6 w- ?. \5 P% p7 J# b8 D9 G
  132.                 TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE); - t, I% Z2 M! Z; U& ?
  133.                 TIM_Cmd(TIM2, ENABLE);
    " ?! q; P! p* N, J3 r9 b' b# ~
  134. }
    ; x3 k# b4 W8 E2 R8 S" q1 P

  135. ) C7 H9 {& P, H2 D% ~/ q* E6 A; P
  136. /****************************************************
    . c$ {% l9 g! n, i' k* J$ }2 H
  137. * 函数名:angle_set9 Z. ], K" M) p9 C! W+ |
  138. * 描述  :无
    . v5 Q- m2 [2 d0 i2 e3 z
  139. * 输入  :无 # X/ ^, B( x( A8 A' t$ s
  140. * 输出  :无! w6 f6 W1 f; ~$ b
  141. * 返回值:无: f, c' k# U! r  c5 J0 r: G7 i
  142. ******************************************************/
    3 v2 I6 {* _. ?' `7 ~* ~
  143. void angle_set(u8 dir,u8 angle)
      z% C# J3 d% x& z) b: c. z0 c- {
  144. {
    * B* p6 }+ i: r, s3 N
  145.         if(dir==0)
      M5 g1 f- O$ H* w0 E, Q' s
  146.                                 GPIO_ResetBits(GPIOA, GPIO_Pin_1);//指定引脚输出低电平,此时灯全灭,方向* v0 }3 d- @1 K; V
  147.         else1 N  j1 C# v; d* @  ~
  148.                                 GPIO_SetBits(GPIOA, GPIO_Pin_1);//指定引脚输出低电平,此时灯全灭,方向
    6 f: U/ r2 x3 j3 e: x5 ^! A
  149.        
    # O) `- V. v, z% _: p+ S
  150.         Output_Pulse(angle*6400);: i8 l/ z9 D+ [/ D# ?/ k/ L; F* `0 ]
  151. }2 V5 K! k8 v% _4 K) _
复制代码
4.time.h程序: d' h9 r8 D! W; v4 L! N
  1. #ifndef __TIMER_H
    " d& e$ y- \0 b8 L1 Y
  2. #define        __TIMER_H+ R0 a- Z& _, o' j. n/ l
  3. #include "main.h"
    ; Z  `" B) V- t% S
  4. extern unsigned char Flag;
    % y+ Z, L2 g" x+ N$ b$ g% |
  5. extern unsigned char TIM2_Pulse_TIM3_Counter_OK;3 o9 h( Z* h1 y4 q) b  Q! e
  6. void GPIO_Config(void);
      r! K/ v, M2 l8 ]* S9 f
  7. void TIM2_Master__TIM3_Slave_Configuration(u32 PulseFrequency,u32 pulse);
    7 D5 t; _) A+ p) j
  8. void Frequence_Setting(u32 PulseFrequency);9 x/ {) j3 P3 Y
  9. void Output_Pulse(u16 Num);- |0 d: j$ z3 n; G7 }# S, X
  10. void angle_set(u8 dir,u8 angle);
    / B2 `( z! a; s6 ?# e' b0 b
  11. #endif5 f! I- [6 J; T
复制代码
5.usart1.c程序- T* A1 H. s: Q* D$ G0 E" L
  1. #include <main.h>' s2 o! Q) E0 E6 _! R! ]
  2. #include <usart1.h>
    , m) T3 n, V1 \0 b  x
  3. #include <string.h>! y. s- k. G* `1 W: {
  4. #include <math.h>
    7 @: H8 H) K. b

  5. ; Z/ ~* i. i5 x/ O
  6. /******************************************************: ~1 g# k# g% k# _
  7. * 函数名:USART1_Config+ S. E1 U- |' J4 ^* m* y
  8. * 描述  :USART1 GPIO 配置,工作模式配置6 [" H8 ~( ?* L  H
  9. * 输入  :无7 j  f3 Y/ F, h1 Y
  10. * 输出  : 无
    & m2 ^% p$ [- M" a
  11. * 调用  :外部调用2 K3 k  F- `8 t
  12. ***************************************************** */
    & }* d% p! Z; ]; t) L+ D
  13. void USART1_Config(void)
    6 \, c$ L4 A; j
  14. {
    6 I, j2 x- {4 ^* X6 \$ j
  15.         GPIO_InitTypeDef GPIO_InitStructure;
    % i4 ?: f  }' E# A1 G! @; {) C
  16.         USART_InitTypeDef USART_InitStructure;
    * n! ^8 [- J& I( o5 V7 ^0 G
  17.           B7 w3 U( o1 J3 L  ?; H
  18.         /* config USART1 clock */  u2 i6 t( m/ L, K
  19.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);2 S/ I1 T! Z4 k$ D4 d: q- l) h
  20.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);/ \9 @/ O- J& J% M. w+ Q
  21. # Y: k+ K+ I8 Z- @6 P
  22.         /* USART1 GPIO config */
    * Y% c; W) a) l
  23.         /* Configure USART1 Tx (PA.09) as alternate function push-pull */2 K4 J3 D! `& Y: g0 S+ K
  24.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;' O; G( N! z" D# J
  25.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    5 _% S; O- I5 L, Y
  26.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    ) ~3 Z# ~5 {  p% _; K1 H5 I5 J
  27.         GPIO_Init(GPIOA, &GPIO_InitStructure);   
    3 X# w( z+ K) K9 M
  28.         /* Configure USART1 Rx (PA.10) as input floating */
    ( J+ s; D# }& Y3 o! r7 e
  29.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    1 i% Y! X5 s  C+ X; z1 U* V- k
  30.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    ! K. O+ B" @3 q6 G$ @
  31.         GPIO_Init(GPIOA, &GPIO_InitStructure);
    . R/ n2 L; R2 w
  32.        
    ; T6 C+ f" a" n- S8 ?" u+ O7 ~8 I
  33.         /* USART1 mode config */
    5 t2 z! X: {& P8 Z0 p3 V5 E* ]
  34.         USART_InitStructure.USART_BaudRate = 115200;
    7 u; ?* E3 I: x4 W. o8 W
  35.         USART_InitStructure.USART_WordLength = USART_WordLength_8b;2 P8 L+ ]" l; c. k  v
  36.         USART_InitStructure.USART_StopBits = USART_StopBits_1;+ F& g7 r4 ?+ }# e. s6 _( B* E
  37.         USART_InitStructure.USART_Parity = USART_Parity_No ;
    ) Z  d3 [! m& D9 R
  38.         USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;9 Z, |0 K& I* ]! G6 C1 ~
  39.         USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;0 r/ }2 A# Z2 c7 t% a
  40.         USART_Init(USART1, &USART_InitStructure);, G; e5 \) U9 r9 e
  41.         USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
    & ~; R0 T& \! l5 ]5 W
  42.         ' h# d( i0 Q! K9 i
  43.         USART_Cmd(USART1, ENABLE);
    ; `' X2 x9 b0 r9 W
  44. }
    5 a4 \6 b2 a0 e, U! y: Y" G. a
  45. ) p2 Q1 m: }3 ]) u. [: v9 P2 c
  46. /******************************************************( _9 i2 U  a/ J5 k
  47. * 函数名:fputc- E9 E9 w1 }( e: V( M, L& j
  48. * 描述  :重定向c库函数printf到USART1  f5 W8 P! H) g0 j
  49. * 输入  :无
    : }. k! T; ^7 R, S7 @/ l) Y
  50. * 输出  :无. u7 t* e7 D- j8 {0 \
  51. * 调用  :由printf调用% ]6 Y$ b8 Z! A% T: R  u8 g
  52. ***************************************************** */
    ( o8 ]6 T& d2 N7 N4 j
  53. int fputc(int ch, FILE *f)! ?: ^' l2 d$ V: F) k
  54. {
    4 k. P: j5 J+ `  N1 n4 V1 h
  55.         /* 将Printf内容发往串口 */4 `! m) r2 O# C& a; D+ a
  56.         USART_SendData(USART1, (unsigned char) ch);
    3 {5 B! K3 y! e6 J! A) V
  57.         while (!(USART1->SR & USART_FLAG_TXE));3 a; H3 ?/ m  U- f9 S& q1 \
  58.        
    & t1 {  ~& ~- J( E% p" ?
  59.         return (ch);3 R0 n" |7 r& l0 y! |/ L4 s
  60. }- \9 |4 _) p2 w+ g6 ]/ C9 k* H
  61. ; H' J+ g' p& v$ }* p& @9 `
  62. /*-------------------------------------------------------------------------------*/1 u9 N1 Y; q; h/ J
  63. /******************************************************
    % g  x, M5 N. n6 Z; V0 m
  64. * 函数名:USART1_IRQHandler6 y  K/ k5 v4 c: Z9 p) w6 k( Z. {
  65. * 描述  :USART1中断服务函数
    ' Z5 O1 y3 K& n& P& ^) z
  66. * 输入  :无. Z# g+ `5 b! Z. j
  67. * 输出  :无
    ) Y. Y  \' O/ p+ c- P' v1 d- a
  68. * 调用  :中断调用
    # ]# }- b6 E& S7 I1 Z$ z% V
  69. ***************************************************** */
    5 T0 W9 J6 [1 k9 I% M3 g
  70. u8 Res;; X" c5 s" T- B" `" h
  71. extern int a;
    ' {  F% ]0 M; @$ n2 e
  72. u16 USART_RX_STA=0;       //接收状态标记         ) h: T. y' s) o  g4 H
  73. u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
    , ?" I7 c" N1 m! D
  74. void USART1_IRQHandler(void)                        //串口1中断服务程序
    ! k' d/ ^; a# `
  75.         {
    " t2 a5 k+ g0 \4 ]* Z( a1 e
  76.                 ( U% l' @7 K' Z, Y' R9 _: Z6 g
  77.                 Res =USART_ReceiveData(USART1);        //读取接收到的数据5 D4 y* b; a* s+ o' n; c
  78.                 ! q3 Z" `( e7 m2 W3 r
  79.                 if((USART_RX_STA&0x8000)==0)//接收未完成, {; K. W0 Z+ }+ s& M0 c7 G
  80.                         {6 }. q3 _9 F* V$ N$ x8 w; n8 c
  81.                         if(USART_RX_STA&0x4000)//接收到了0x0d, R# L- t4 e3 P3 T/ K. y- p# o7 x
  82.                                 {
    : h5 r4 x! l3 W: |5 R
  83.                                 if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
    " _" V8 y; B: i  t
  84.                                 else USART_RX_STA|=0x8000;        //接收完成了
    2 I) U/ G% k0 f2 {: p" o
  85.                                 }
    % n8 P8 L0 L' u8 }7 A2 i- B
  86.                         else //还没收到0X0D
    , V5 ?% J# }# ^& U  L- O) R
  87.                                 {        $ H4 h$ T) M0 I# g0 ^5 B7 g
  88.                                 if(Res==0x0d)USART_RX_STA|=0x4000;
    $ o% b' R1 \2 t
  89.                                 else- w7 o' h- ?" b% f+ O
  90.                                         {
    ; p! W4 a% [" \  s; A% {. O; K
  91.                                         USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;. M% m& U6 g3 J
  92.                                         USART_RX_STA++;9 S( c. h5 y8 J: y) M
  93.                                         if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收          
    0 X5 s8 F  c! k) }1 a0 E3 M( _
  94.                                         }                 - [8 _/ N% }" V9 b! L- g$ J
  95.                                 }6 v- ]! Z) w9 w/ D' B
  96.                         }               
    & W( j% H; g+ O  I5 v
  97.                                 a=1;           S0 A9 G7 C3 ~% O1 \2 ]+ B+ ]
  98.         } . t- n; z6 H+ S% P
  99. #if SYSTEM_SUPPORT_OS         //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.3 N" n9 m; w3 H+ i9 q1 W1 V0 [
  100.         OSIntExit();                                                                                           ) q, m7 x6 Q" M
  101. #endif( o5 P* T$ N/ l: P

  102. 7 n2 o7 P0 K2 ~: ]8 k( w
  103. /******************* (C) COPYRIGHT 2012 WildFire Team *****END OF FILE************/
    ) I% L! H! Y& H. D
复制代码
6.usart1.h程序5 x/ {4 p; ?7 W' _! D$ M( L+ |' v
  1. #ifndef __USART1_H
    ) U; c* A( M8 g& C
  2. #define        __USART1_H) B$ R) Z$ S- _$ x
  3. #include <main.h>4 s+ b; p! J8 u2 F0 G# I9 k+ r
  4. #include <stdio.h>
    ) e% k! A3 m: i5 u6 k9 o
  5. * N# w" S% L) S7 b( l7 O3 E6 l% b
  6. #define USART_REC_LEN                          200          //定义最大接收字节数 2009 x; V) ^6 {( z# ^4 h
  7. #define EN_USART1_RX                         1                //使能(1)/禁止(0)串口1接收2 _' M1 s9 r' a8 w# ~
  8. extern u8  USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 , l' p5 q0 @/ R6 r" }5 \
  9. extern u16 USART_RX_STA;                         //接收状态标记
    3 l, O" a  o% t# c. e7 f0 r/ E
  10. int simple_atoi(char *source);
    5 J+ E5 F# n1 z- N/ c6 E
  11. void USART1_Config(void);
    2 y9 K$ `3 C& x! _7 M0 Y
  12. #endif /* __USART1_H */
    & H% Y* T. N9 u
复制代码
源码:
$ T7 k( {( R! U2 k 步进电机程序—串口控制速度角度.zip (4.75 MB, 下载次数: 51)
收藏 1 评论0 发布时间:2021-6-25 13:30

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版