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

利用STM32F103精确控制步进电机

[复制链接]
STMCU-管管 发布时间:2021-6-25 13:30
利用STM32F103精确控制步进电机
一、用到的元器件( d1 q; h0 t* w9 e% }- H7 A( B' w% z3 \
STM32F103C8T6* O8 f( y/ W( }( z  P; `* p7 K
42步进电机(42SHDC4040-17B)
, h+ P; ?9 j+ y! t+ H0 I1 DTB6600电机驱动器升级版
$ I6 Q. K& }2 x* B6 u+ a' y3 i+ ?2 f' |6 e9 Q) m) j
3 J+ E4 `, Y$ H% I
二、42步进电机
' L8 C7 w3 z4 I7 J: o4 E7 j1.步进电机的基本知识/ l% g  v- J% T9 x8 J0 t/ U4 N3 ]
(1)拍数——每一次循环所包含的通电状态数(电机转过一个齿距角所需脉冲数)1 q1 J3 X4 |  v% v* A
(2)单拍制分配方式——状态数=相数% ~2 ~8 E" }+ }6 M' Q' {* B0 x5 X
(3)双拍制分配方式——状态数=相数的两倍$ |6 [- M2 w# L6 }  ]- |, r
(4)步距角 ——步进机通过一个电脉冲转子转过的角度4 u& M# p1 \4 y& ~0 Q
11.png
N:一个周期的运行拍数
$ j$ j7 h9 q& M# xZr:转子齿数" I! m2 g  O, L$ F8 }3 \, g0 |
拍数:N=km# A0 L- D6 y7 |. h4 G* m+ o( m& Y
m:相数
" j0 c& T8 c. x4 g. ~) E7 q$ zk=1单拍制
+ W( {- ?; p2 [/ ^  ~; @; [  v! tk=2双拍制
: ?* t8 L, }; n9 b(5)转速: }" `; ?$ Z4 w. q( [
12.png
(6)角度细分的原理4 o! p6 G& o& T0 o6 O$ \

) {& ?2 [* J( Z

( P' y- o1 D* {. E1 W/ X2 s电磁力的大小与绕组通电电流的大小有关。
5 w) j( Z' `- u# X# _当通电相的电流并不马上升到位,而断电相的电流也非立即降为0时,它们所产生的磁场合力,会使转子有一个新的平衡位置,这个新的平衡位置是在原来的步距角范围内。
. R" h6 z, N& _' u: ?- B2. 42步进电机参数" q: a! o8 L+ U& Z0 ?
无法查找到42SHDC4040-17B型号的详细资料,以通用42步进电机为例:; J; {4 y" X) R. j: V. q( ]/ Q
步距角 1.8°4 n0 U% r/ a5 Q
步距角精度 ±5%
! L6 S% o4 U% T/ F9 b) z- \4 W) W相数 2相4 N9 s* k1 A; T  u8 b6 f$ q  ]  H! T
励磁方式 混合式
- q+ o3 c" `- M6 ~9 J" W转子齿数 50
1 Y# o8 o. R" n# j, I# Q0 ^拍制 双拍制- ~8 {$ K7 W4 g* {% N
其他参数:无9 X9 ^2 `. k' {7 K' ~/ z( ^# h
由步距角=1.8°推算出转子齿数为50,拍制为双拍制
3 i+ z+ F, d% z  [
% ]  @' c+ o0 E% S
0 K& l1 c3 G$ r2 t1 a* [5 P( n
3. 42步进电机速度与角度控制& q, q/ h9 q5 \, |
电机的转速与脉冲频率成正比,电机转过的角度与脉冲数成正比。所以控制脉冲数和脉冲频率就可以精确调速。
" G7 ?, k' D  G1 E" m2 \( C/ J- V理论上步进电机转速 = 频率 * 60 /((360/T)*x)
+ L0 A( w( G0 U: e, U5 F  y 21.png
! U& ]" O0 H& B0 u1 C1 `) [8 P- _​       
# [* H! I5 B! c) S6 T- d转速单位: 转/ 分# ]. U3 @9 M- E% `4 u  X0 C: \3 d
频率单位:赫兹- `- {6 R. s4 n: Z0 E
x 细分倍数: S2 N: Q! j/ I. h$ u  I* V2 M
T 步距角
$ C- R% w& K! Q: _- n/ M例如,在本实验中,32细分;频率72000 赫兹;步距角1.8°;套用公式72000 ∗ 60 ( ( 360 / 1.8 ) ∗ 32 ) = 112.5 \frac{72000*60}{((360/1.8)*32)}=112.5 7 W) W! s3 D) a( V6 R
((360/1.8)∗32). H: a( s3 |$ u+ `+ ~" i5 _) M  j
72000∗602 e# Z3 s0 w& c# D: o( M
​       
! \) v) b* Y- { =112.5rad/ min,即1.875 rad/s.; U+ P" ~2 i3 D, T1 ^% v  A( F
13.png
三、TB6600电机驱动器升级版参数2 e/ V' Y; ^- L! W7 p  y
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 型两相、四相混合式步进电机。/ r9 v6 F& ]2 I9 v5 O9 h2 @

; r# Z" c, @/ h/ u/ g' N

& y2 v/ y4 ]; `1.信号输入端
) A. K9 H0 H. [" `PUL+:脉冲信号输入正。( CP+ )
9 o* y5 P+ {9 S" k9 XPUL-:脉冲信号输入负。( CP- )
& g9 o6 y, p: r+ n1 M8 U3 w$ r& }0 BDIR+:电机正、反转控制正。
- N# i) s4 t8 b$ {' lDIR-:电机正、反转控制负。
4 |* K! I; E8 l  s& P$ hEN+:电机脱机控制正。+ L) |! n) a5 a7 @% @2 h
EN-:电机脱机控制负。6 z) y, M  x! b0 J( A

& k6 M* }1 f8 V' k2 m
. ]+ c, j0 z9 d( l
共阳极接法:分别将PUL+,DIR+,EN+连接到控制系统的电源上, 如果此电源是+5V则可直接接入,如果此电源大于+5V,则须外部另加限流电阻R,保证给驱动器内部光藕提供8—15mA 的驱动电流。1 u7 \7 ]4 v8 J) P/ w
共阴极接法:分别将 PUL-,DIR-,EN-连接到控制系统的地端;脉冲输入信号通过PUL+接入,方向信号通过DIR+接入,使能信号通过EN+接入。若需限流电阻,限流电阻R的接法取值与共阳极接法相同。0 u# [7 B* J' ~$ R. ]
注:EN端可不接,EN有效时电机转子处于自由状态(脱机状态),这时可以手动转动电机转轴。5 J( L3 U% o# m
2.电机绕组连接
- T7 z: p( D! T' }+ v7 b( uA+:连接电机绕组A+相。2 \2 g' @' Z' M9 f/ p9 b6 A9 m  _  ]& [
A-:连接电机绕组A-相。% x3 W# T/ i: r5 w+ \
B+:连接电机绕组B+相。$ m" `* a; s' r8 I8 f! J7 |
B-:连接电机绕组B-相。$ Y( p- G* h% O+ n) s

7 f& P- R) ]' q6 k  D- U
7 n) H% i2 T# z. t4 g* m. |
3.电源电压连接4 [  f) r& J  X/ ]' P, j7 s* g0 ^
VCC:电源正端“+”2 h4 t5 y6 _5 P4 {# A
GND:电源负端“-”7 ~0 w( ]) y' H' C
注意:DC直流范围:9-32V。不可以超过此范围,否则会无法正常工作甚至损坏驱动器.! D. b: Z3 U+ w
: l6 M8 G8 w3 v$ x/ p

( Y( o/ \  y. U, I) |4.拨码开关
4 q% ^8 r; G- @2 ^ 14.png
( m$ E. H$ Q8 o  s# W# g电流大小设定) ~- `8 f, q! n  C8 u
15.png
! i" x) b! K: H) A三、STM32F103
0 _, Q; l3 ?+ b" C  ~' A------说明:引脚部分在文章末尾有解释--------+ C0 M# U: S; D% l$ O& o$ O

9 ~9 c- `; Y9 X6 R' ^- L# ^
% S! q3 y0 L. ?3 t
1.引脚连接. d- ~) t4 W$ H; g3 R1 v: ?/ X
A 0——PUL+* v/ A2 D. t! D" g* A/ J0 u
A 3——KEY1——V3
  O& m( G! w# |7 J8 fA12——DIR+
/ {5 j# g* Q3 }7 t$ pA11——EAN+6 T5 Z8 Y- U! C, ]: {6 D
GND——EAN- ——KEY0$ \: Z* @+ z0 k$ T
& z# r7 m6 _1 n$ V$ S# {5 O# s4 i
+ \6 j  y* e# l% y. G! ]1 D; `
2.引脚功能; M1 B4 }. x# h9 i) {# q2 j
A0控制电机转速) ]+ l7 ~# b, r# Y" V( ?
A3控制按键
9 G* p  [; ^: y  RA9
" S9 V. ^- ~' `& sA11
. @6 P) h# [: \3 ZA11控制电机是否为锁死状态9 T0 r+ S: g$ h4 f: r  R
A12控制电机正反转& ]8 {; R" h7 P) f

7 a% |5 y# [: `5 F: x

7 Z7 e2 ~( `8 Y5 M6 n3.定时器
" [# I- B! `# V8 t- V+ N0 x4 G8 n1.本实验利用定时器TIM2和定时器TIM3构造一个主从定时器,TIM2作为主定时器控制电机的转速,TIM3作为从定时器控制电机的转动角度。
7 r3 c/ I! @) ^2 `2 |2.电机的转速和转角还与驱动器自身的细分数有关,但是驱动器细分数是通过影响电机的步距角来影响转速和转角,而TIM2和TIM3是控制步进电机的频率和脉冲数来控制转速转角
! r4 g9 x1 Y" t5 B4 o4 K3.电机的转速和角度与定时器的关系(在不考虑电机自身的细分数下)
+ J) ?% M( }) E2 F% p3 }" _6 q! e! C0 _
' D2 @. \  Q, P: ~1 q# j
设TIM2的定时周期(即重装值)为nPDTemp2,预分频值为OCPolarity2
$ a, V- u4 B+ b$ i' d TIM3的定时周期(即重装值)为nPDTemp3,预分频值为OCPolarity3,
" E" R" y. q+ D' E$ [则单片机产生一个脉冲所需要的时间为:
3 S, }8 k% ~/ j1 ?( H 23.png
; O0 C5 y! U% j​       
$ Q' G8 ~- Y0 t+ M! s. J  本实验中设TIM2的定时周期nPDTemp2=72000/5000-1,预分频值OCPolarity2=999,TIM3的定时周期nPDTemp3=6399,预分频值OCPolarity3为0。即% w$ k/ c+ u, P% Y8 x
22.png
+ Y' G( Y' }5 A( j2 v- S  定时器共产生nPDTemp3+1=6400个脉冲,电机转过的角度为6400*1.8°=11520°,即电机转了32圈。
6 ^8 y1 i" p! l; B9 h  转动速度
. [1 U( u: u' A 24.png ! V# n, m9 a$ n5 _6 f$ ]$ v
1 o! q- D% Y) |
. F8 n9 R% W/ x" U5 _
4.在32细分的情况下电机1rad/s和转1°需要的重装值为nPDTemp2=11.25,nPDTemp3=17.7778。4 b! R, D) G" p8 p- G+ p
" r; H( \0 f: }( Q3 F. }7 L* S* ^

2 e% J1 t1 {) F7 W! b! E四、程序实现
" W) r% g- \$ O( b1.main.c程序: y$ r/ s) o) j8 h  |4 d3 R0 b7 k
  1. #include "main.h") O- J: d1 w) |6 s, O4 }
  2. #include "sys.h"
    / [- M. J& G. \5 n4 z2 o; [4 Y
  3. #include "usart1.h"
    ! Y6 n1 b$ }7 `3 J# {! I
  4. #include "delay.h"
    6 b4 ?* b9 @, X% |# {2 E- ]
  5. #include "math.h"
    9 C9 S6 A6 R  c% ~3 w( v

  6. 1 e, Q- x5 h% y5 v
  7. u16 t;  . y! B$ |# j# M$ N# C4 I
  8. u16 len;                    //接收到的数据长度
    + g$ }% Q5 a. Y; o$ D5 D6 g
  9. u16 times=0;
    ( i. q: D3 {  h' @
  10. char receive_data[60];        //接收到的字符 & D$ H( v# z$ K' z
  11. char state;                                //电机正反转标志位0正转,1反转
    . A) ~. @- `* J7 _6 g: b
  12. int speed,angle;                //旋转速度,角度/ r6 \# `/ s0 ^4 T
  13. int a=0;                        //判断是否接收到数据' Q8 B0 l/ g: m$ M: U/ H$ i
  14. int r,data=0;                          //用于数据转换  M0 }1 x4 r) V2 S" ]3 K
  15. int type;                                //转换后的数据    + @/ i' o1 E! R" s- C
  16. extern u16 USART_RX_STA;/ M: d5 O6 \& m

  17. : D3 b% E/ n" ]6 G8 v. Y* ^. l
  18. /**************************
    + H& S) l! |! Z2 m$ W
  19. * 函数名:delay! y5 M% B1 H& [0 M" R% f
  20. * 描述  :延时函数( A& W8 W6 j4 V+ b# X6 ~% g% |
  21. * 输入  :无
    2 i& N/ ^, g& I$ w
  22. * 输出  :无
    2 U4 j' w1 M) v0 ]& z5 P; C9 E4 F
  23. * 返回值:无+ w4 z  v& v) c$ E2 S! W' M# t5 n
  24. ****************************/
    & q/ p0 Z% d* E! x7 I& v
  25. void delay()//延时
    $ z8 Q0 ^: s1 E# \/ k7 y5 [
  26. {
    - i6 G8 B( k4 R; o$ K- A
  27.          int i,j;, A/ p% p0 i4 T5 n& p+ p% C( [
  28.          for(i=0;i<2000;i++), G0 D' A9 N' M
  29.          for(j=0;j<1000;j++);4 z' H  P& v6 [
  30. }
    % z+ P* n0 P1 ]# N) ^

  31. 9 y9 G! l3 r) f# F
  32. /**************************
    5 D/ q+ h! t3 _; M$ a' e; N
  33. * 函数名:Waiting_receptio' n* z- ~/ P! ]9 h
  34. * 描述  :等待串口接收数据! F8 v8 t3 `9 {5 E9 D
  35. * 输入  :无
    8 u4 s, e9 Z3 H
  36. * 输出  :无1 Q9 a+ y7 f3 }. H8 M$ @0 `( ~3 C
  37. * 返回值:无
    4 ~+ }4 I2 \7 u
  38. ****************************/
    ; P1 ~7 U* c% f9 L) c3 S  A
  39. void Waiting_reception(void)6 ]. K6 L3 L1 y+ C# m) e% v' @
  40. {; R: X0 X# g# U2 y# x
  41.         while(a==0)//等待数据发送完成7 N& v  O6 U% g8 J1 `
  42.         {
    ! @, |# t- o& U9 A) V  T" Q8 b
  43.                 delay_ms(100);
    0 @7 l# U1 e" m& U) g" q3 W7 v, q
  44.                 if(a==1)//接收到数据
    % c) G7 w7 n0 E+ ]$ f- I
  45.                 {
    1 d! w. D3 r( s/ z3 D% t) L
  46.                         if(USART_RX_STA&0x8000)//(串口接收用到了正点原子的例程)) T; ]$ _; `+ |7 o) i
  47.                         {, h& s, k! B4 l. k
  48.                                 len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度5 d% ?' l3 M- R
  49.                                 r=len;                                9 l3 q2 E+ y3 Z. y* Z/ G+ |
  50.                                 type=0;8 |+ j/ G! J; m& C* W" [- X
  51.                                 for(t=0;t<len;t++)//拷贝数据,将字符转换为十进制数
    2 [0 W; y9 }$ _( L, D' d
  52.                                 {
    0 S' ]0 P- o4 n4 @
  53.                                         receive_data[t]=USART_RX_BUF[t];
    ) b; D4 E$ a% m5 K
  54.                                         data=(int)receive_data[t]-48;
    & Z% S) i6 q  j) R
  55.                                         r=r-1;
    & L' u) Z- i0 i- e" m! t
  56.                                         type=type+data*(pow(10,r));4 L) l/ f: c( N2 t0 S7 U* D: k: C
  57.                                 }
    ) c' R8 I* ]( F. t0 V7 N8 ~( a- b* }
  58.                                 USART_RX_STA=0;  d( n* U3 `1 A9 {
  59.                                 a=0;
    9 K. i8 c7 D/ a1 z  j# G$ ?
  60.                                 delay_ms(500);
    / r& g5 x: r+ v8 k/ j
  61.                                 break;
    0 W  C& @  Y. T
  62.                         }
    9 p% N( Y4 K" ~2 s- R9 |1 W# E$ S
  63.                 }6 h) [# v. B" G
  64.         }6 r5 T* i4 ?: |5 e$ y: E3 J2 x+ ~
  65. }
    ' g- H6 m/ Q+ w+ c; X: z
  66. /**************************
    & ?+ Y# ?; _  w$ a$ q: B+ Z
  67. * 函数名:KeyStates
    $ P7 J8 a8 f# b$ B* w1 l2 x
  68. * 描述  :监测按键状态
    ! D/ \0 p7 q% K
  69. * 输入  :无 # x3 M' b% H$ c7 x
  70. * 输出  :无3 \. `1 W$ e7 G  I3 U
  71. * 返回值:0/1
    0 L. J4 m, Z' {* g( v% s
  72. ****************************/
    6 g+ m, \# W) ?) v$ v
  73. u8 KeyStates()//按键状态
    ) q! V4 ^  p) ?7 B! A+ q' I& W3 I
  74. {+ _& C* r3 M# k9 c* G! D. U" W; w( A
  75.         static u8 i = 0;+ u, }% j; e" p+ S# v$ y
  76.         if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)==0)- B1 i+ G. f/ G4 |. @& t4 Y% a
  77.         {# m5 [* f$ C( `& P  w% @7 _- C
  78.                 delay();
    : ]% I* a  Z. X' e# C5 {: z0 N) W( W! i
  79.                 if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)==0)
    ) R6 L2 w) m( ?9 M8 H$ M
  80.                         while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)==0);: k8 q% R* g, d! Y! ~" k
  81.                         i = ~i;
    0 _0 P1 _. r  b6 r0 k/ ?( a) X# s
  82.         }
    / M5 \; C& m0 r9 P
  83.         return i;
    6 M: Z& B2 \3 I* ^7 F( B
  84. }
    4 v; N- V7 u+ f2 |7 k
  85. /****************
    ; h6 x8 R8 u2 o0 V2 C
  86. * 函数名:main7 b, i9 H3 a! N% E7 V# P3 P
  87. * 描述  :主函数4 F8 S: S$ b+ d! o8 L" V0 y
  88. * 输入  :无 8 I  `6 X$ A; ?- k) {: E# A
  89. * 输出  :无
    6 w- W/ O% S4 v9 q4 j8 \$ k. k; i
  90. ******************/9 j  t  Y$ l7 Q$ ~" |* q
  91. int main(void)
    3 b/ D) z" p7 E6 B0 ^( X) R, _
  92. {
    2 q+ j# G2 ]) b1 p& k( D8 Z
  93.         NVIC_Configuration();                        //中断初始化
    6 J  S1 N) n, ?+ U" j+ S. ]; e
  94.         GPIO_Config();                                        //IO口初始化# B9 L, I% v3 U# [1 C( y2 C
  95.         USART1_Config();                                //串口初始化5 ?3 y5 U  [  S: `  t5 Q( w
  96.     delay_init();                                   //延时函数初始化       
    + y2 @! Q; L+ |$ Z' p
  97.         GPIO_ResetBits(GPIOA, GPIO_Pin_11);//A11置零  A11——EAN+, r( M$ x0 F/ E6 I
  98.         GPIO_ResetBits(GPIOA, GPIO_Pin_12);//A12置零  A12——DIR+
    7 ]* |% x( N" X" v  L9 y/ ?
  99.         while(1)
    ; O  S/ P& ]7 d: l+ v" f! S0 D
  100.         {3 C/ S/ Y" g& d- H- ], \9 z% t
  101.                 delay_ms(100);2 @/ v7 N& ~* w6 U4 k( p5 Q
  102.                 Initial_state:                printf("\r\n 请选择正反转,正转输入0,反转输入1 (以新行作为结束标志)\r\n");        & ]' _3 }0 o3 y: Y# n" d
  103.                 Waiting_reception();/ V6 g) e5 g) U2 K4 y: E
  104.                 state=type;//将接收到的数据给type
    - t/ o" k8 n- _8 {
  105.                 if(type==0)//电机正转
    / r* R5 A5 A0 o# V8 E! d/ ~
  106.                 {% G# l+ S# ~* n9 p$ |
  107.                         GPIO_SetBits(GPIOA, GPIO_Pin_12);//电机正转0 l; ?7 Z5 w$ C* d
  108.                         printf("\r\n 电机为正转模式,请输入旋转速度(rad/s),输入0返回初始模式 \r\n");
    ( ?% G$ ^6 t" E1 V
  109.                        
    ) F% D3 Z' _! b
  110. /*********************************************此模块用于配置速度参数********************************************************/
    1 j( y) T1 y3 i- D$ L
  111. % b( u7 v) H1 `
  112.                         part1:Waiting_reception();
    5 l* P  }; ~- G' v
  113.                         speed =type;//将接收到的数据给speed) r5 {; \' a, w; c1 q$ \
  114.                         if(speed==0)goto Initial_state;//如果是0则返回初始模式
    2 F4 Z0 R7 j6 k: B4 A; _
  115.                                 else{) D7 j6 ]6 H+ v
  116.                                         if(speed>=15)0 x, |. t% O. i- {7 S
  117.                                         {
    0 g% Y8 D+ I0 x
  118.                                                 printf("\r\n 旋转速度>15rad/s,请重新选择旋转速度。\r\n");
    ( P. s: }/ ~) F* V+ {8 z; {0 o: k
  119.                                                 goto part1;8 e  I0 D- G, f8 o- z0 `! I
  120.                                         }2 \; L( {! w" x' e1 p7 j
  121.                                                 else printf("\r\n 电机旋转速度为%d rad/s,请输入旋转角度,输入0返回初始模式 \r\n",speed);
    ( e# }/ c9 Y1 [% \3 N/ K( l
  122.                                 }
    8 k# O- M% V4 p8 m* h- i
  123.        
    # @7 g5 g. E( Z& u2 n# z6 _
  124. /*********************************************此模块用于配置角度参数********************************************************/                : i* ^& D4 c9 J1 t
  125. 8 U' P  q( k3 b' N" T3 n8 W( H
  126.                         Waiting_reception();' C: v) h  V% [% Q0 B: V" N
  127.                         angle =type;//将接收到的数据给type
    ; S& f& E+ `6 v
  128.                         for(;;)8 E; w- \% [, L8 H& T
  129.                         {' P" t" a& s4 `* L& N; p* j/ n
  130.                                 if(angle>0)//接收到的数据不是0
    9 _3 S$ s* v0 l7 c+ A* R
  131.                                 {, S3 `* N3 }% G* l: t
  132.                                         TIM2_Master__TIM3_Slave_Configuration(speed,angle);        // 配置TIM2和TIM3的重装值 ,改变电机转动速度和角度, q/ L6 W5 |3 e+ T$ w) L2 P
  133.                                         delay_ms(20000);//电机保护8 n' E8 B7 j* v( Y2 N
  134.                                         printf("\r\n 电机已旋转%d °,请输入下一次旋转角度,输入0返回初始模式; \r\n",angle);
    " _$ V8 [; i. N2 c! d. b' x
  135.                                         angle=0;
    2 F4 U1 u( D; }' J
  136.                                         Waiting_reception();               
    9 k) [4 r$ F% b6 }' z. J
  137.                                         angle =type;                                        / |3 t7 W. I) z
  138.                                 }else{
    % K) M' p3 P# s) P/ [% O4 ?# t
  139.                                         if(angle==0)goto Initial_state;//返回初始状态        ! u: z8 h2 U! @
  140.                                         else {" y5 A3 l$ Z8 e! E1 s0 m1 c, ]5 g
  141.                                                 printf("\r\n 角度错误,已返回初始模式 \r\n");                3 K4 m: g1 w0 V0 N  }/ U5 f
  142.                                                 goto Initial_state;
      B7 ~$ P9 z9 ]
  143.                                         }                                                # V9 z7 ?1 \( `% }3 S" b0 o
  144.                                 }
    ) U' Q  f/ u' V# l
  145.                         }
    9 ]. U* k' a- y3 b$ y  l
  146.                 }                + l0 B' f( T5 f# ]# b5 s
  147. /*********************************************反转模式********************************************************/               
    + K6 Q6 g+ x% q7 Q
  148.                 else{. B4 V: J1 a! x+ ]  q5 w2 w
  149.                         if(type==1)# J  @2 A2 d! r' n$ P5 ~+ V
  150.                         {
    $ C! v* J# h% e1 r
  151.                                 GPIO_ResetBits(GPIOA, GPIO_Pin_12);//电机反转
    ) y7 v" ]9 d8 g; }
  152.                                 printf("\r\n 电机为正转模式,请输入旋转速度(rad/s),输入0返回初始模式 \r\n");
    & [4 }  ^' ~/ z( r
  153.                                
    # E: H9 l1 y+ R- f; R
  154. /*********************************************此模块用于配置速度参数********************************************************/. w0 C9 {- y6 `) }; q4 n; z$ x2 {
  155.                                 part2:                                Waiting_reception();
    : A5 I  C1 |2 b; Y
  156.                                 speed =type;//将接收到的数据给speed
    % o: D2 v7 r' b! c0 C7 v
  157.                                 if(speed==0)goto Initial_state;//如果是0则返回初始模式
    1 L* G: O9 R* q3 r+ ~& p
  158.                                         else{
      g: |$ n5 G1 N$ k" A6 ^& z
  159.                                                 if(speed>=15)) G- {* G6 i' V0 h: @: y  O
  160.                                                 {7 A6 D( A6 s' c4 h
  161.                                                         printf("\r\n旋转速度>15rad/s,请重新选择旋转速度。\r\n");' ?- J9 H7 i  V0 e  P
  162.                                                         goto part2;! o/ L. r1 W, K8 _* J
  163.                                                 }else printf("\r\n 电机旋转速度为%d rad/s,请输入旋转角度,输入0返回初始模式  \r\n",speed);; X- I( S' U8 X. @$ N8 U
  164.                                         }        ( g0 ^& L& ]5 e2 k! K6 _+ v
  165. /*********************************************此模块用于配置角度参数********************************************************/               
      j7 x0 P" |9 [
  166.                                 Waiting_reception();: B) P, b" h9 J
  167.                                 angle =type;//将接收到的数据给type
    ( @  K; z5 {( \% x' R: W3 _/ g) V
  168.                                 for(;;)  q, l5 Z1 u, o- Y2 C, Q8 \* P+ z- x. p
  169.                                 {6 J! @' I4 V0 t
  170.                                         if(angle>0)//接收到的数据不是0. t( ?  P$ M' ]% B8 X
  171.                                         {7 q3 z. ^+ p7 V7 ~% N% _
  172.                                                 TIM2_Master__TIM3_Slave_Configuration(speed,angle);        // 配置TIM2和TIM3的重装值 ,改变电机转动速度和角度. y/ O" f* b+ i1 X1 N! f7 b7 d
  173.                                                 delay_ms(20000);//电机保护
    4 C0 V& W, L  S; p. d+ K
  174.                                                 printf("\r\n 电机已旋转%d °,请输入下一次旋转角度,输入0返回初始模式;\r\n",angle);, ~$ Y' j' i& ^% F! ?! u3 d! e
  175.                                                 angle=0;; @+ M8 L9 Z, e/ N" o: U% o1 V9 W
  176.                                                 Waiting_reception();               
    8 d" S5 d+ S; J' Q. Z) `( M
  177.                                                 angle =type;                                        ; E! @9 r$ f4 i
  178.                                         }else{  u+ C9 x! K  ~7 }5 X: X
  179.                                                 if(angle==0)goto Initial_state;//返回初始状态       
    , Y8 W8 r& D3 {( X
  180.                                                 else {
    3 ]; q& J" Z# w9 R/ q' B# }4 U
  181.                                                         printf("\r\n 角度错误,已返回初始模式 \r\n");               
    7 P% k" I, X* ?8 h: s  ]
  182.                                                         goto Initial_state;
    - }: B+ C+ i. ?& x7 m& D/ V
  183.                                                 }                                                               
    : X# O9 K- m9 p) U( P0 B
  184.                                         }% k4 ]3 Q. b* I1 [( W  a8 \
  185.                                 }; c! H! _. e3 B
  186. /****************************************************************************************************************************/                                        . v' j3 V% r  C* E- U* I( j
  187.                 }else{//if(a!=0)&(a!=1)
    4 f% \! e6 a, b4 r! A9 I  @
  188.                         type=NULL;
    " ?9 Y; u+ a' X$ y: v; U- N
  189.                         printf("\r\n 输入无效 \r\n");/ Q! H$ S- N0 g% ?2 m
  190.                         goto Initial_state;//返回初始状态' Z7 j2 y+ W; X9 X% b
  191.                         }/ Z: \* k% X3 ~: ~& B
  192.                 }+ U+ n. {5 U! L/ a6 K
  193.         }
    % G& L3 Q2 `: B" @; x
  194. }5 ^' u6 L3 l7 s4 Z: O
复制代码
2.main.h程序0 q1 @4 V: g8 ~& ^
  1. #ifndef _MAIN_H+ @5 V% R/ D5 o3 W9 Q
  2. #define        _MAIN_H
    ( H. B5 h7 K7 c$ ?
  3. #include <stm32f10x.h>. r( |- h1 C1 X8 Z1 Q) N
  4. #include <usart1.h>
    : {: C2 G( t. x: s
  5. #include <misc.h>9 R' l: p; P* q9 P2 H0 x/ y% F
  6. #include <nvic.h>
    0 M5 S) _% ]" e7 G- S; k
  7. #include <stdio.h>
    ! Z! ^2 _2 F: W/ k8 b9 C# j& E$ r! x7 B
  8. #include "stm32f10x_tim.h"% o& w# u8 l8 X
  9. #include "timer.h"3 D: W' s8 C" }3 ]5 _0 o
  10. #endif
    7 E: W% ^, s0 @4 w# {' h
复制代码
3.time.c程序
/ D1 p" R. j# [7 U/ i
  1. #include "timer.h") x7 n5 |6 S: W$ a4 _$ E4 s
  2. /**************************
    4 }6 z  V$ H4 K& c# F
  3. * 函数名:GPIO_Config4 b, _6 n4 M8 n' A8 [' V! q
  4. * 描述  :无
    ' Y" B# I* E6 m4 C  Y4 n
  5. * 输入  :无
    5 P  A( _1 m. e" Y" a$ q
  6. * 输出  :无
    5 H4 S2 Y& B9 B
  7. * 调用  :主函数9 l0 @" |) L; R% T; ?7 j2 O
  8. * 返回值:无
    ' V5 W. O, R% s1 g# m8 E/ t% @
  9. ****************************/. C' ?" S/ R1 e4 [6 @( D: d  S4 w
  10. void GPIO_Config(void)
    3 d; x. c5 T9 L1 ]1 I+ Y
  11. { 5 b9 I# |! n- m9 \+ L/ O, |
  12.                 GPIO_InitTypeDef GPIO_InitStructure;
    1 ~' l/ {, X# b5 @
  13.                 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); //使能IOA
    ; u( K# Q& e! h% _' n( ?
  14.                 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3, ENABLE); //使能TIM2,TIM3- J9 S. t4 V; _) r9 w/ x2 r7 p; @, a
  15.                
    5 Q# d7 X+ N, Y. k* y
  16.             /* Timer2 Channel 1, PA0 */ + F: P, b' A# b4 Q: Y" q% S
  17.             GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_0;
    0 _9 [/ |% j& B
  18.             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用输出" {! T6 W- n& J) I: @
  19.             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 9 F) U0 T2 l0 m* D! a3 k3 j' |! u& l
  20.             GPIO_Init(GPIOA, &GPIO_InitStructure);6 @- c8 ?* u" R# e* x
  21.                  
    ; ]# J: q. `; W; a
  22.                 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_11|GPIO_Pin_12;
    , f; _& N: H3 G: l3 ?
  23.                 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         //通用推挽输出模式* A0 ]- g/ M5 G4 `( ^; u
  24.                 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //指定GPIO引脚可输出的最高频率为50MHZ
    2 f$ h& Q( F  x  G' d8 E$ v
  25.                 GPIO_Init(GPIOA, &GPIO_InitStructure);                   //$ h$ b* l4 {* r: W9 Q2 {9 a$ h
  26.                 GPIO_ResetBits(GPIOA, GPIO_Pin_1);//指定引脚输出低电平,此时灯全灭,方向
    # N) p! A$ d+ F# L( G4 y: X
  27.                 GPIO_ResetBits(GPIOA, GPIO_Pin_2);//指定引脚输出低电平,此时灯全灭        使能
    & E. C  |+ m0 I! b" ]& M- B
  28.                 GPIO_SetBits(GPIOA, GPIO_Pin_11);//指定引脚输出低电平,此时灯全灭,方向" [9 U" |" \5 H9 Y
  29.                 GPIO_SetBits(GPIOA, GPIO_Pin_12);//指定引脚输出低电平,此时灯全灭        使能+ X3 D" W7 }+ I: {( Y5 {. C! r2 f7 Q9 s, p/ q
  30.         8 t) \1 Q# s5 K* R
  31.          
    7 Q- u5 `3 d' e1 g9 f2 \; C
  32.                 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    " r5 `. V9 P7 r; ^1 W
  33.                 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;         //通用推挽输出模式
    7 J, `7 ?- V' e% D1 g2 F
  34.                 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //指定GPIO引脚可输出的最高频率为50MHZ. V2 k7 n# Y" R4 u/ U7 m
  35.                 GPIO_Init(GPIOA, &GPIO_InitStructure);                   //
    % o4 |2 ?, G. [5 n+ y: O$ @
  36.                 ! i4 m3 [$ _8 V: z
  37.                 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); ( z% l9 p1 Q1 i+ P/ Q
  38.                 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;; F8 N  n) O  |
  39.                 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         //通用推挽输出模式
    : |/ F* d7 ?# V1 q% o
  40.                 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //指定GPIO引脚可输出的最高频率为50MHZ1 h# I  \! A4 B6 F/ Q; f+ a
  41.                 GPIO_Init(GPIOB, &GPIO_InitStructure);                   //
    % y6 _9 O: h2 M- t1 A+ Q" u
  42.                 GPIO_ResetBits(GPIOB, GPIO_Pin_12);//指定引脚输出低电平,此时灯全灭        使能
    * f& I5 X+ l# o
  43.                 : Y7 Y% [0 o' d
  44.                 //GPIO_ResetBits  GPIO_SetBits
    0 P" m# X- z, [. ?( k3 A
  45. }$ Z5 g+ Z6 R( u6 N3 F
  46. # u% D) b9 m# c9 R1 }. f% n
  47. //================================================================================, N1 V( g2 c. d
  48. /**************************& |2 ^& g# A; T: P4 w# |1 _
  49. * 函数名:TIM2_Master__TIM3_Slave_Configuration4 }$ ~9 {% e. Y; a! ?7 Y$ U* h
  50. * 描述  :主从定时器配置7 L+ J9 i. p5 o5 I
  51. * 输入  :电机转速speed,转角angle 9 v/ B2 b/ P, @% D
  52. * 输出  :无
    & d4 H( P% p, b! ?3 u. }
  53. * 调用  :主函数7 {' H9 V8 |: X' l( _$ v
  54. * 返回值:无5 I8 u) [: g# P/ ~/ x
  55. ****************************/
    : t: h# g, s' ^- E4 `
  56. void TIM2_Master__TIM3_Slave_Configuration(u32 PulseFrequency, u32 pulse) 3 V: h- ]3 N3 M' h
  57. {0 |- j1 L5 G' f/ s/ f! K' x% r2 f8 Z7 i3 |
  58.         TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    5 A: ]# \2 N0 \9 X) p5 R; L
  59.         TIM_OCInitTypeDef TIM_OCInitStructure; ) W% _0 ]1 R) A- A5 x" U: i4 [
  60.         7 `; @- |$ y: Q. l/ [" O
  61.         u16 nPDTemp ; 3 r- {- |! \: U$ w: o  g( w0 i
  62.         u16 pulse_number;
    6 u0 r* {% \3 r+ c5 u+ P0 @0 Z' S
  63.         float p=PulseFrequency;7 G+ D% H& t! ~
  64.         TIM_Cmd(TIM2, DISABLE); $ U4 H7 G1 x" \$ E8 T
  65.         nPDTemp = (11.25/p);                            //TIM2重装值是11.25时1s转一圈(电机32细分下)  w4 q3 L+ R% y6 f( I
  66.         pulse_number = (16.7778*pulse);//TIM3重装值是16.7778时转1°(电机32细分下)
    6 i/ J$ o2 \2 U5 i" e
  67.         + z7 o3 s* k* ~; t; e7 [8 p& L
  68.         // 时基配置:配置PWM输出定时器——TIM2 2 S$ V9 ~6 _  R5 w+ ?
  69.         /* Time base configuration */
    % t; C8 X0 @3 v1 r
  70.         TIM_TimeBaseStructure.TIM_Period = nPDTemp; //定时周期为nPDTemp
    ! R+ z8 o0 B  u% c! c
  71.         TIM_TimeBaseStructure.TIM_Prescaler = 999; //预分频值1000,即f=72khz' L0 P) M( A: }: e) n
  72.         TIM_TimeBaseStructure.TIM_ClockDivision = 0; //时钟分频因子,会影响滤波器采样频率,与本实验无影响8 Q. W5 a( L6 z8 l! E% m
  73.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式1 }. G3 |) R7 l' Q4 G
  74.         TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; //指定重复计数器值
    2 T* ~: l$ B1 j9 J4 V
  75.         TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
    8 ]4 q; W- U: H3 K' n
  76.         : @7 J6 O4 i' W8 p' P" f2 E/ O
  77.         // 输出配置:配置PWM输出定时器——TIM2 ; p- m  i/ u" Z2 I; ]
  78.         /* PWM1 Mode configuration: Channel1 */   
    3 w: y) ?1 n- Y. k. [
  79.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //TIM 脉冲宽度调制模式 1, A4 }1 C" M( _9 ]- B
  80.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //高电平有效/ K! [- L0 c* w0 i# e
  81.         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //使能输出$ v1 \) ~" @+ n  l
  82.         TIM_OCInitStructure.TIM_Pulse = nPDTemp>>1;//50% //比较tim_ccr的值,输出脉冲发生跳变' }& }5 Z2 s3 T$ R
  83.         TIM_OC1Init(TIM2, &TIM_OCInitStructure); //初始化
    9 w" [$ l9 f' X3 I/ C8 y  Z+ F
  84.         TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); //使能 TIMx 在 CCR1 上的预装载寄存器
    $ C; X; a$ D! H3 I* O/ ]  @
  85.         TIM_ARRPreloadConfig(TIM2, ENABLE); //使能或者失能 TIMx 在 ARR 上的预装载寄存器  _( w! _. T& F1 P, y3 O
  86.        
    ! f1 A7 k$ s$ s6 X3 N" G: }
  87.         // 时基配置:配置脉冲计数寄存器——TIM3
    ) P' O8 D4 a* Q& g1 `- I5 X
  88.         TIM_TimeBaseStructure.TIM_Period = pulse_number;      //0x1900是360°;//改变给电机的脉冲个数                     . w% \# b0 C2 o4 h
  89.         TIM_TimeBaseStructure.TIM_Prescaler = 0;
    ( A9 h6 Q$ n2 F' d$ b( R
  90.         TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    9 m1 d* x' Z- @+ Y$ F
  91.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; : b9 q/ X9 o0 [& U: V$ G' Z
  92.         TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; 7 d" b/ `8 C% I( C' v
  93.         TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
    " {* K# {' f) `, [! l+ |
  94.         // 输出配置:配置输出比较非主动模式定时器——TIM3
    / I2 S6 ?6 U" n1 q+ Q
  95.         // Output Compare Active Mode configuration: Channel1
    / B7 x9 Q( K# }" y
  96.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Inactive; //输出比较非主动模式,(匹配时设置输出引脚为无效        电平,当计数值为比较/捕获寄存器值相同时,强制输出为低电平)      
    + V9 y+ ?9 y$ o  s  A
  97.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; 4 z- w& `% k4 q* O. V4 _& O. H
  98.         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    * @1 c% D7 i# P8 q& y
  99.         TIM_OCInitStructure.TIM_Pulse = 0xFFFF; // 这里的配置值意义不大   ( [, z2 r& x( _
  100.         TIM_OC1Init(TIM3, &TIM_OCInitStructure);
    , b" @0 u+ ~( W0 h* b

  101. ! v/ Z, x5 c5 N2 x7 E- B8 ^( Y# |
  102.         // 配置TIM2为主定时器
    3 n$ L& a+ E! b0 J$ v  {
  103.         // Select the Master Slave Mode # M! O4 m* b6 A! X% G- h- _
  104.         TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable); //设置 TIM2 主/从模式并使能" ^, A- P5 t" Q* Q+ N$ l$ Y
  105.         // Master Mode selection  $ @* F+ U8 o+ M6 d1 H2 z- M& K" i! V
  106.         TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update); //使用更新事件作为触发输出
    0 D7 e" _- m: x; K' Z( f* t9 o
  107.        
    * A& I3 C' j' [2 J* |. o
  108.         // 配置TIM3为从定时器 5 c: @3 p& H5 P
  109.         // Slave Mode selection: TIM3 , M% @& {! q  x
  110.         TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Gated); //选择 TIM3为从模式   TIM_SlaveMode_Gated-当触发信号(TRGI)为高电平时计数器时钟使能
    - @4 E6 M" P( F" n
  111.         TIM_SelectInputTrigger(TIM3, TIM_TS_ITR1); //选择 TIM3 输入触发源    TIM_TS_ITR1-TIM 内部触发 1
    3 {3 X% ]. H# h- b/ g
  112.         TIM_ITRxExternalClockConfig(TIM3, TIM_TS_ITR1);//设置 TIM3 内部触发为外部时钟模式   TIM_TS_ITR1-TIM 内部触发 1
    5 p  b* C# y+ n/ _5 o
  113.         TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE); //使能TIM3     TIM 捕获/比较 1 中断源          
    7 c- m5 |9 O5 ^& G! i  l7 R
  114.         * B9 [% N$ v2 ?
  115.         TIM_Cmd(TIM2, ENABLE); ' ~' B9 |$ A  m( d
  116.         TIM_Cmd(TIM3, ENABLE);
    & d: {" S! n, M- H/ ^
  117. }
    - V6 o! s: Y3 S

  118. " \; n5 V5 a7 V7 I2 u6 Y# D
  119. /****************************************************
    - H- D& k$ G$ D+ O; x& Q
  120. * 函数名:Output_Pulse2 R& ?, ]; y  E8 I; J2 q4 h6 i
  121. * 描述  :无
    ! ~3 h4 ]& L5 Z# S6 v- v, q; V& t
  122. * 输入  :无
    8 \$ ?  j2 W- G1 x2 }" a; N
  123. * 输出  :无3 J+ B" L2 ~# [1 T4 ]
  124. * 返回值:无
    7 l4 R- R! v& h: S( l' [2 p, e+ b  u
  125. ******************************************************/
    3 K7 q: T( C( T
  126. void Output_Pulse(u16 Num)/ \$ H: ]# y( h* e& h
  127. {, M) V2 ^0 y- l! Q( Y$ O( N
  128.                 GPIO_ResetBits(GPIOA, GPIO_Pin_2);//指定引脚输出低电平,此时灯全灭        使能
    1 J2 G0 k0 q  |) p- ]" r3 I
  129.                 TIM3->CCR1 = Num; , T' q  _7 W: D/ I3 ]+ {
  130.                 TIM3->CNT = 0;
    # n& p4 z' U) o; b
  131.                 TIM_Cmd(TIM3, ENABLE); 8 T. Q& p( y" I9 G
  132.                 TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE);
      w' n3 P( f* M0 F9 S" T! S
  133.                 TIM_Cmd(TIM2, ENABLE);
    ) _! i0 h* e! d/ W$ v
  134. }
    $ d6 Q( C4 z/ N
  135. : x8 z* w6 Z  w8 f# N0 d
  136. /****************************************************
    5 X7 ?+ R+ v: q% g% n" |
  137. * 函数名:angle_set
    0 r6 n+ Y$ X1 v# \. D
  138. * 描述  :无! m! }! E3 M; J- m
  139. * 输入  :无 . i9 d% g4 ?9 a
  140. * 输出  :无* ~) ]8 t% D# E0 d) h
  141. * 返回值:无. |9 p, q0 G/ T, x: J. [% g1 X" I
  142. ******************************************************/
    ) B. o$ Y8 I" G8 q+ A" }" k* N
  143. void angle_set(u8 dir,u8 angle)
    . Y  S7 n4 I7 h8 _
  144. {5 g' b+ d3 A3 D* u1 [9 L$ N% W
  145.         if(dir==0)( F" {. _9 o2 E& x5 O
  146.                                 GPIO_ResetBits(GPIOA, GPIO_Pin_1);//指定引脚输出低电平,此时灯全灭,方向" S5 m/ U4 s& D, N  O6 h" h
  147.         else
    . H/ f* b: N. |  r5 f2 m
  148.                                 GPIO_SetBits(GPIOA, GPIO_Pin_1);//指定引脚输出低电平,此时灯全灭,方向# c$ _  Y3 W( |. k
  149.         % w3 V1 M2 ~  \5 A
  150.         Output_Pulse(angle*6400);
    ! Y6 R& }( v% \) L/ c3 C7 r
  151. }# l. Y# E( L3 h0 S
复制代码
4.time.h程序
: V% j! L$ [/ Y
  1. #ifndef __TIMER_H: v0 L, ]; }6 x8 ~( \# Z; h
  2. #define        __TIMER_H
    * y3 }5 y; S9 T
  3. #include "main.h"
    & a# b. c' I  |9 g, i+ d, L; D
  4. extern unsigned char Flag;
    # \3 S  V. I) e# Y7 }9 t
  5. extern unsigned char TIM2_Pulse_TIM3_Counter_OK;+ W; ^" c& T' m: F8 ]: V8 q
  6. void GPIO_Config(void);. k# U( u% K- Q3 s  L9 `+ I, S
  7. void TIM2_Master__TIM3_Slave_Configuration(u32 PulseFrequency,u32 pulse);5 M2 p! X0 ~* h/ x. o' o
  8. void Frequence_Setting(u32 PulseFrequency);
    4 n5 @7 \+ c% R3 S1 g
  9. void Output_Pulse(u16 Num);
    , A9 U' g0 k5 t& a# h4 W. n' K6 ~
  10. void angle_set(u8 dir,u8 angle);: k9 C' [; H$ o3 U
  11. #endif
    # G+ O# F! j4 T3 I$ m! ]
复制代码
5.usart1.c程序- l/ S; p8 g9 L
  1. #include <main.h>5 P) a$ o) o) b; l7 M$ ?8 p
  2. #include <usart1.h>
    ( H/ ^, j" y% r/ S9 x( b
  3. #include <string.h>, I: I5 B+ L6 m, ^7 G
  4. #include <math.h>* s2 j  x. W6 }! z$ ]

  5. 7 e; K" r! j* }9 t/ C6 M) E2 m* ~
  6. /******************************************************
    9 G; z5 R# ^6 [: w; Y7 R% _
  7. * 函数名:USART1_Config! G3 X" N" h& b9 e
  8. * 描述  :USART1 GPIO 配置,工作模式配置
    / i6 q2 `+ h: t: ~2 E
  9. * 输入  :无- _9 n. e/ M' P6 [3 S' R
  10. * 输出  : 无& i4 k5 s  J8 u7 D
  11. * 调用  :外部调用( d- E! d2 @" I. E' n- G. X
  12. ***************************************************** */) q/ y+ A2 U  ]% E# j
  13. void USART1_Config(void)
    7 f) }- B) \! r) L+ H% f+ q
  14. {
    / X# u! {% b1 J) p& e9 z
  15.         GPIO_InitTypeDef GPIO_InitStructure;
    9 z/ M+ p! P7 H) q0 p) h9 I
  16.         USART_InitTypeDef USART_InitStructure;+ i4 T8 Y5 J& c5 L/ t3 z, \& C  x
  17.         ; w; s& f& }0 n: S2 g7 f/ k. ~
  18.         /* config USART1 clock */: }. j$ Y# B5 D; Z; A& Y! f
  19.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    6 Q' W. S5 W9 V, ~
  20.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  L* I+ Q$ x7 j' a9 y
  21. : W+ l# [' u6 C2 a1 q5 x" ]
  22.         /* USART1 GPIO config */* J, b8 ?* L: E
  23.         /* Configure USART1 Tx (PA.09) as alternate function push-pull */
    7 b7 i- M& k6 K
  24.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    0 G6 G6 J! B5 `- ~& ?5 [* G
  25.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;$ h" \0 u; U+ y4 T( u
  26.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    2 J/ B1 O; ]1 l8 ^
  27.         GPIO_Init(GPIOA, &GPIO_InitStructure);    3 c8 u) V: o- h: e  H6 I) r
  28.         /* Configure USART1 Rx (PA.10) as input floating */- w7 h/ t, `8 g7 z7 x* m
  29.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    7 N, |, H- H2 G7 H& D
  30.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;9 i3 W) r. P6 p: g2 U" O- E
  31.         GPIO_Init(GPIOA, &GPIO_InitStructure);" ~3 R+ x5 L3 s% x
  32.         % X4 _0 t* d( X. M; L
  33.         /* USART1 mode config */
    ' B9 z, c7 V/ Y% o3 A
  34.         USART_InitStructure.USART_BaudRate = 115200;! E: x: d" L! R7 S; ?7 K" B
  35.         USART_InitStructure.USART_WordLength = USART_WordLength_8b;, c1 {9 j& E# M3 [: i
  36.         USART_InitStructure.USART_StopBits = USART_StopBits_1;7 L3 x; x2 D* b# ^5 Z
  37.         USART_InitStructure.USART_Parity = USART_Parity_No ;
    ! X- t, }# ?7 J8 P
  38.         USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;+ R( ~8 C9 \/ @/ e; i' e6 r" X3 D- U
  39.         USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;" |5 l0 v, l: f9 @; S, r) J
  40.         USART_Init(USART1, &USART_InitStructure);
    , i) A6 f) w0 Q1 Y& X5 C
  41.         USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);9 B9 g8 I4 f" Y0 M( x9 J+ s  T
  42.         % i  @' {- @2 v
  43.         USART_Cmd(USART1, ENABLE);- j7 \; \2 e, V, R2 M( X
  44. }) ]3 n# h/ X0 ^/ v4 x8 P  x
  45. ; V% f$ [. t+ u) E' k( u- U3 l
  46. /******************************************************, M; G9 u5 c5 t5 Y. s4 K1 V) d/ Y
  47. * 函数名:fputc$ {# ~8 N6 b1 f% V8 c% d! {9 o1 f
  48. * 描述  :重定向c库函数printf到USART1
    3 H# U9 ?6 ^0 I+ W5 v2 Z7 i* H. S  l
  49. * 输入  :无2 c# x% F- I; S, u8 @$ \
  50. * 输出  :无# g0 w1 G3 j& @
  51. * 调用  :由printf调用, Q& z- L, }- F, {9 f
  52. ***************************************************** */4 R# }% e+ T: ~
  53. int fputc(int ch, FILE *f); H4 j4 A" O$ E4 v. a* Z& Z
  54. {
    / }0 |, z9 ~3 t1 Z' _/ t1 m) f
  55.         /* 将Printf内容发往串口 */
    & @  n  ^. s9 a, c: Z
  56.         USART_SendData(USART1, (unsigned char) ch);
    0 ~! I+ H- \9 l/ R  S
  57.         while (!(USART1->SR & USART_FLAG_TXE));# Z7 y0 J0 D9 S/ k7 n' @9 o2 p7 t
  58.        
    & }% r# B. I6 a$ {2 w! B1 I
  59.         return (ch);
    0 q0 C  i- `2 E; X7 V& o
  60. }
    ! M( `0 l9 i6 ]  u7 q# h
  61. 9 Y1 n0 |, b" K1 l/ _9 N7 _: q
  62. /*-------------------------------------------------------------------------------*/
    ( G. A5 S3 w/ v# c
  63. /******************************************************9 w8 \2 l8 I' \! p4 R
  64. * 函数名:USART1_IRQHandler
    ! [% P$ L/ Y8 N3 D
  65. * 描述  :USART1中断服务函数8 I3 _; z5 k4 H& _& o2 n
  66. * 输入  :无
    " e2 H' |# A% u( Q
  67. * 输出  :无
    + b/ h% P8 P, |8 z5 x/ Z
  68. * 调用  :中断调用+ G$ Z( L. n9 u! t2 U  j
  69. ***************************************************** */
    , l3 n9 v& r  z1 J4 T, ]- x
  70. u8 Res;9 a. d* g- ^" i( j0 o* H4 l5 T! Y/ L
  71. extern int a;3 _9 N. p2 d) i% L" V
  72. u16 USART_RX_STA=0;       //接收状态标记         
    $ [- h" j6 B/ b) f6 V1 Y/ [, ]# _
  73. u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
    9 A  {/ \8 `. v# ]
  74. void USART1_IRQHandler(void)                        //串口1中断服务程序: M, \! w, L/ c% r: H  N
  75.         {% ]- W6 ^  r: m, d4 S8 ^3 w
  76.                 ' E/ k% Y6 O7 J
  77.                 Res =USART_ReceiveData(USART1);        //读取接收到的数据
    0 X9 _- A; g. O2 T% T8 [" s+ e
  78.                 1 m# s, D' G. v& o. N
  79.                 if((USART_RX_STA&0x8000)==0)//接收未完成
    - ^, ^7 X/ B( U8 P. D
  80.                         {2 ]  Y- R7 Z7 {- d$ a6 f
  81.                         if(USART_RX_STA&0x4000)//接收到了0x0d
    2 \8 @; O5 y: F' |1 h" Q
  82.                                 {: L5 T5 G6 U5 Z  @- g; e
  83.                                 if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始/ z' M9 n1 f" e0 b
  84.                                 else USART_RX_STA|=0x8000;        //接收完成了
    / I$ u/ d. \# W3 e! x/ T) P
  85.                                 }
    - C- Q$ [8 S! Y5 E7 @: P$ G
  86.                         else //还没收到0X0D
    ( `; W5 k& J) U9 ]
  87.                                 {        ' z& Q5 K# l6 j
  88.                                 if(Res==0x0d)USART_RX_STA|=0x4000;
    9 J# S% g' W2 ?! {
  89.                                 else. F- U) W, q" w! S; T% |
  90.                                         {% G" I( n. T- n3 M5 n; S' h2 h
  91.                                         USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
    : D' H4 A1 k- |" ^
  92.                                         USART_RX_STA++;
    * |" K- G* v2 E+ t) m
  93.                                         if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收          ) F' n9 {2 g0 o: ]6 M' V) ?) L
  94.                                         }                 
    9 F8 I# M( Z  i- l8 t- L
  95.                                 }
    * m" w. m1 V5 ^2 \$ G2 a
  96.                         }                9 E! |  z7 H0 R, J
  97.                                 a=1;         
    / ^' q& C3 u1 w9 Q; \# m+ H
  98.         }
    - F/ U+ V, `( Z5 ?8 {: |
  99. #if SYSTEM_SUPPORT_OS         //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
    ; h, a) B8 l) i) P8 q% }# B
  100.         OSIntExit();                                                                                           
      t  V* P- T$ n! K$ p
  101. #endif
    / r" \! O, z& q0 F/ V; p& ^& s6 u. B
  102. 6 m# ]/ \. ~$ v3 I8 Q# X
  103. /******************* (C) COPYRIGHT 2012 WildFire Team *****END OF FILE************/
    9 l2 G3 y! v2 `9 @/ d
复制代码
6.usart1.h程序
- i  o( y9 N  W
  1. #ifndef __USART1_H
      j$ r# v) p8 F0 b9 ]
  2. #define        __USART1_H8 O7 S0 ~% f$ u; y
  3. #include <main.h>! ^! Y; z. I3 k1 a
  4. #include <stdio.h>- m3 Y3 ]% |) l# Y' @" I
  5. 8 K; v; c5 |, v0 N) q7 m! Z
  6. #define USART_REC_LEN                          200          //定义最大接收字节数 200; P2 N4 e7 J& \! X
  7. #define EN_USART1_RX                         1                //使能(1)/禁止(0)串口1接收8 e) A$ c; c/ s% {0 U& _0 J
  8. extern u8  USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
    # l. i' M* e9 w) h  e$ j9 y
  9. extern u16 USART_RX_STA;                         //接收状态标记
    + S9 h* z1 t+ Q: ?# k2 _
  10. int simple_atoi(char *source);
    + j1 [8 J! k) T
  11. void USART1_Config(void);
    0 m3 O1 ]6 _6 Q; n; j* M% Y3 M: ]
  12. #endif /* __USART1_H */
    1 r+ O5 H  E1 ~" V
复制代码
源码:7 E: ~" R% z0 F4 A4 W1 G: T) G" Z4 e
步进电机程序—串口控制速度角度.zip (4.75 MB, 下载次数: 115)
收藏 1 评论0 发布时间:2021-6-25 13:30

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版