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

利用STM32F103精确控制步进电机

[复制链接]
STMCU-管管 发布时间:2021-6-25 13:30
利用STM32F103精确控制步进电机
一、用到的元器件
0 p0 v5 ?$ Q; n/ T" J; I# M: nSTM32F103C8T65 I, N( u% p7 D6 ]" ?  o" s" ]
42步进电机(42SHDC4040-17B)
) w, _( b! \% ]TB6600电机驱动器升级版% G( S+ S' ]2 g% y
6 f7 F$ M' f% U" C2 ~
3 G* [3 G7 S1 M& X/ C% q
二、42步进电机
4 I! K! B) w2 W) N5 B1.步进电机的基本知识
& M' f) g* q: O( r5 `(1)拍数——每一次循环所包含的通电状态数(电机转过一个齿距角所需脉冲数). I# }8 A$ _. S7 W$ w! `
(2)单拍制分配方式——状态数=相数
+ p, _% H/ i0 ^7 ?2 t- j9 `) I(3)双拍制分配方式——状态数=相数的两倍
$ \5 _( t0 _, [5 X9 f# y9 {$ h( r9 O* [(4)步距角 ——步进机通过一个电脉冲转子转过的角度
" u+ E! H, c  Z8 t/ \: {
11.png
N:一个周期的运行拍数3 N: w7 J( y+ e! l" f- C# Q
Zr:转子齿数* |, N+ y8 s, @+ W5 b
拍数:N=km
% A  m0 u+ s  J4 y5 `  V, i0 W3 [m:相数
6 L+ s8 S7 |0 W: Gk=1单拍制
& Q3 y% [1 i- Dk=2双拍制) y8 g. c1 j: x- {) P
(5)转速
, G( o% j1 ]6 f* o, D- N7 m6 D7 j
12.png
(6)角度细分的原理
" W7 i) e: W" B5 h- B6 \1 ~8 S+ w/ L/ X( P& B- F

& }) X) Y  s6 l# e7 d( {6 }8 u电磁力的大小与绕组通电电流的大小有关。
0 V* t: b% ~  y! e' N+ y. h当通电相的电流并不马上升到位,而断电相的电流也非立即降为0时,它们所产生的磁场合力,会使转子有一个新的平衡位置,这个新的平衡位置是在原来的步距角范围内。
8 _4 j3 ]9 n0 ?, i+ @- R2 ^7 n2. 42步进电机参数  R2 x5 y  @) c3 I3 ]
无法查找到42SHDC4040-17B型号的详细资料,以通用42步进电机为例:) w8 D' H; k1 ~
步距角 1.8°0 I: f0 ~! p3 g" j
步距角精度 ±5%
; Q2 @1 l& V. k- y- J相数 2相* {) ~, _  D! z0 Y- c
励磁方式 混合式! R* A* s( J9 `/ }7 z" k5 b
转子齿数 50
3 r9 R7 q+ Z( {* w. ?2 P; k  z0 G拍制 双拍制
. X  b; Z& j) R. @( I8 W. o其他参数:无
8 e8 A' Z& J; x2 ~1 C, D由步距角=1.8°推算出转子齿数为50,拍制为双拍制, R9 G0 ~0 u7 M' M9 n6 n

5 p: u8 J1 {4 C$ k8 Y

( T5 a9 O. z* V) e* E- {, v3. 42步进电机速度与角度控制- X5 e1 V1 L) U
电机的转速与脉冲频率成正比,电机转过的角度与脉冲数成正比。所以控制脉冲数和脉冲频率就可以精确调速。
2 J4 c* Z" `9 c$ E2 W理论上步进电机转速 = 频率 * 60 /((360/T)*x)4 t6 X+ M9 L7 _7 X
21.png / x4 {3 L$ o& @1 ?4 X  t' c
​        % T, P* I" E. L4 w3 e7 p; c' c3 M; ]
转速单位: 转/ 分3 w, o$ n9 {8 [  W. K2 j5 d
频率单位:赫兹
  G$ R+ S. e3 dx 细分倍数
0 D. L* z4 B' k  zT 步距角
- y* B, L: A/ A: u2 H例如,在本实验中,32细分;频率72000 赫兹;步距角1.8°;套用公式72000 ∗ 60 ( ( 360 / 1.8 ) ∗ 32 ) = 112.5 \frac{72000*60}{((360/1.8)*32)}=112.5   [/ @, }6 _2 N
((360/1.8)∗32)
; E9 F) L# p6 L: r9 q2 v( Y72000∗603 |# T% m( H6 P" s* n% D
​        - }* }0 Y6 G1 A4 B3 Y$ s
=112.5rad/ min,即1.875 rad/s.
, n! j2 z3 e5 A, |1 n5 Y5 |7 J
13.png
三、TB6600电机驱动器升级版参数/ S& N/ U/ @0 m$ p' O2 B
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 型两相、四相混合式步进电机。3 p9 k* G: ~$ q0 i% U8 f

4 o6 Z0 X' C$ |) h; S; ]9 K0 z
2 S: `8 D( n' `. H
1.信号输入端" K) N. y, R: {; f  h$ n
PUL+:脉冲信号输入正。( CP+ )
" D& s! {1 Q) w& H; mPUL-:脉冲信号输入负。( CP- )
5 t' D' {# b6 a7 w/ I; sDIR+:电机正、反转控制正。4 A6 L$ o) k6 G0 `6 l; [
DIR-:电机正、反转控制负。3 o( k( y  c( o6 c# h# a- Z
EN+:电机脱机控制正。
& g) ?. q; e+ J1 pEN-:电机脱机控制负。1 u" e2 M& O; Q5 C( T8 L' Q9 X
& h# m/ P& z- O" e# F; I1 T
- `3 u3 f. @1 ]7 _" P) n, `
共阳极接法:分别将PUL+,DIR+,EN+连接到控制系统的电源上, 如果此电源是+5V则可直接接入,如果此电源大于+5V,则须外部另加限流电阻R,保证给驱动器内部光藕提供8—15mA 的驱动电流。* b1 k8 j0 t( S
共阴极接法:分别将 PUL-,DIR-,EN-连接到控制系统的地端;脉冲输入信号通过PUL+接入,方向信号通过DIR+接入,使能信号通过EN+接入。若需限流电阻,限流电阻R的接法取值与共阳极接法相同。
: W* A5 i: Q- y注:EN端可不接,EN有效时电机转子处于自由状态(脱机状态),这时可以手动转动电机转轴。9 r1 K8 e5 \. o2 L9 d
2.电机绕组连接
* S( i  y# [/ C* X- vA+:连接电机绕组A+相。
% \. e: A, P3 z! u, y+ cA-:连接电机绕组A-相。
/ b* E3 Q2 I3 `5 H' N/ HB+:连接电机绕组B+相。
' U5 H" d! j" f/ ?$ \9 B! q1 }B-:连接电机绕组B-相。# @! O( t7 ]  ]# H' ?

& w$ i5 Z, V$ w
4 D4 ~% X7 Z& P6 y; o" o
3.电源电压连接
1 m7 @3 h" A7 \4 U" ?VCC:电源正端“+”- `2 {  o1 H: K/ o9 C
GND:电源负端“-”9 r! D* ]! s6 {+ r9 ^  k
注意:DC直流范围:9-32V。不可以超过此范围,否则会无法正常工作甚至损坏驱动器.0 S: E( _, b, O

- m% Y( W0 B2 l5 l
$ L1 V- v! O) @& g3 X
4.拨码开关9 d. `" Z) {/ r# a) q. O
14.png
- X# a8 t8 @; K2 e' N3 H; L& j3 n: A电流大小设定
6 r: E4 E+ S3 G8 r 15.png * n; J" C2 I" `; K: Y* c
三、STM32F103) I! c& O% O. z) U4 R* i* v
------说明:引脚部分在文章末尾有解释--------
" ~# S6 Y# O! H4 o* O& L$ o5 B! j( z) m  o% z
# I4 w1 F" i4 q; H! L7 X+ d
1.引脚连接
. p; t4 \% g6 g3 _8 j% s6 \& _A 0——PUL+* F+ n2 N  H' Q7 G5 T) J
A 3——KEY1——V3
; F. _$ I0 S8 Y+ p- z! dA12——DIR+  z; U% P' B3 Y. W) S( ^" b
A11——EAN+- ^! S/ x3 `9 C  ^
GND——EAN- ——KEY0
( {# f% ~1 J- b6 @" P3 W; d/ W6 x% k% F# O9 U- Z1 R; {
/ t! C/ d7 n+ G- G
2.引脚功能
& Z$ U& m7 W; v2 @0 e8 BA0控制电机转速: K7 G. ^0 a; e
A3控制按键0 j1 f+ C' s& ^8 D1 p  o& X
A9
0 S2 i0 z( Q, E9 xA11
- {. u1 U, v& Q$ ^A11控制电机是否为锁死状态1 i! f( n" E" A+ M! S
A12控制电机正反转$ x1 R  C3 c, O7 T4 C

# B3 v& D1 K: w0 c
. M' U& S# R+ ?0 K$ H. A; V! R
3.定时器
: l" f) _) r9 q) S) T- h  ?1.本实验利用定时器TIM2和定时器TIM3构造一个主从定时器,TIM2作为主定时器控制电机的转速,TIM3作为从定时器控制电机的转动角度。
$ R7 V3 q  P- O8 h* F; Z2.电机的转速和转角还与驱动器自身的细分数有关,但是驱动器细分数是通过影响电机的步距角来影响转速和转角,而TIM2和TIM3是控制步进电机的频率和脉冲数来控制转速转角4 u. Q/ e5 \* x. {+ h' _1 \
3.电机的转速和角度与定时器的关系(在不考虑电机自身的细分数下)
' P' P  N, \: |) Q6 C( D6 s2 t- {- ?! `+ c
4 ~5 \8 A' d' x1 i$ \6 I4 D9 t
设TIM2的定时周期(即重装值)为nPDTemp2,预分频值为OCPolarity2/ y) O$ _* n! ?! z
 TIM3的定时周期(即重装值)为nPDTemp3,预分频值为OCPolarity3,
: r6 V" E3 K0 u# ]& h6 v则单片机产生一个脉冲所需要的时间为:$ \* M+ [% S% c
23.png
( M  h9 V$ r4 D" f# v$ f​        # m( Q+ O5 e$ V+ `5 e' B
  本实验中设TIM2的定时周期nPDTemp2=72000/5000-1,预分频值OCPolarity2=999,TIM3的定时周期nPDTemp3=6399,预分频值OCPolarity3为0。即
4 x$ m; P9 X. j- U4 `6 Y5 \ 22.png
: C; ?) ?3 G7 `1 g  定时器共产生nPDTemp3+1=6400个脉冲,电机转过的角度为6400*1.8°=11520°,即电机转了32圈。
' Z0 C% M& I: ~& D8 b  转动速度4 T* T7 x4 L. y' }9 q
24.png
' \. U% {$ d0 `4 C/ o1 u5 B6 S1 q

/ }9 h3 A: A4 T7 M4.在32细分的情况下电机1rad/s和转1°需要的重装值为nPDTemp2=11.25,nPDTemp3=17.7778。0 J* a% R1 u4 [, a8 {

+ z+ Z- M1 o" \1 S3 Y! X8 y

- A* x% [% z5 N' Y* n! m四、程序实现
* m! F4 o/ n2 ^& z# I5 v8 J1.main.c程序% |# i8 t* B, f* s# K# x! z
  1. #include "main.h"
    5 L8 H, G& _- G, L# `7 m# _
  2. #include "sys.h". x- ^% E3 ]0 O  X; u4 ?
  3. #include "usart1.h"% E# r3 i  E, V5 l* N  A
  4. #include "delay.h"6 L1 p' W/ a  O/ g& K0 l# P' I( M1 D
  5. #include "math.h": \7 w7 n! g1 f
  6. 3 d5 F' b+ P9 T2 y% x* O2 x5 {
  7. u16 t;  
    : t: w* A) {% ~7 {  `: [
  8. u16 len;                    //接收到的数据长度
    ; |$ ^. i! l% M1 f, t+ C
  9. u16 times=0;
    # n3 _2 m3 b+ ?8 P4 e2 W9 [
  10. char receive_data[60];        //接收到的字符
    ! P! z; q7 {. s; d, y) l3 S7 Z
  11. char state;                                //电机正反转标志位0正转,1反转9 n  }- Z9 {3 g
  12. int speed,angle;                //旋转速度,角度; y9 N: a2 K+ k) d) `  K% Q
  13. int a=0;                        //判断是否接收到数据6 Q- y2 f# x; _" e/ z. p6 |
  14. int r,data=0;                          //用于数据转换! J7 H2 o) R+ n) d( k; F
  15. int type;                                //转换后的数据    & r* l6 h" \3 ^7 z( l9 d$ d
  16. extern u16 USART_RX_STA;
    3 G4 r3 w% r. L8 Y
  17. 5 Y% F4 i! T/ r6 o' d8 W& G: a
  18. /**************************
    0 W6 k- Z7 Z# X, x
  19. * 函数名:delay
    . ^# y. r3 ?# k# Y0 h" }- E0 ?
  20. * 描述  :延时函数
    * v/ k% h9 @- J* R8 l2 Y
  21. * 输入  :无 1 |" a. l; C9 M, Y  j
  22. * 输出  :无
    . `$ Z; e+ e8 b: p/ ]
  23. * 返回值:无
    / I( d8 H* r5 n0 N) b# @
  24. ****************************/! n- X! D6 M1 D4 J* \8 ?" O
  25. void delay()//延时) T* y4 M8 r9 ]
  26. {
    3 q; z, E4 I8 `1 w. ^
  27.          int i,j;
    8 \) W6 ~9 C2 k. T8 D$ q# Q
  28.          for(i=0;i<2000;i++)6 b( v% W0 Q* N; J; W& q2 v
  29.          for(j=0;j<1000;j++);
    2 g& {4 s0 h2 d  L- C) I8 W
  30. }$ {) y& X  Q2 h. g" Z' w7 Z/ ]
  31. 9 X- }4 w9 |6 J; v
  32. /**************************. Q% C; L+ [5 g" \+ W5 ?5 }* N7 U8 G
  33. * 函数名:Waiting_receptio
    + X1 y: X  U6 W' k
  34. * 描述  :等待串口接收数据5 A' O* a: m) O6 C+ n
  35. * 输入  :无
      `( s+ [- S( x6 |5 _7 k
  36. * 输出  :无8 q# M! c# E3 M* V5 U* D% k
  37. * 返回值:无+ m3 x: s8 R3 A9 }/ c! H& w5 @
  38. ****************************/
    6 p7 ]% |" Y. q3 L/ G) U
  39. void Waiting_reception(void)" z7 T& I1 O8 m9 B; J
  40. {# O" w2 G5 O) _. J( c7 _( t
  41.         while(a==0)//等待数据发送完成2 R' [; |- k1 D( y5 a  q( T
  42.         {/ L2 w" @7 d4 l; {0 h
  43.                 delay_ms(100);9 O0 F+ T) C/ f7 C, `$ E2 G( J* m
  44.                 if(a==1)//接收到数据' ?5 O% c7 v6 b0 B) T% i4 L2 k
  45.                 {8 I/ l; R( ^1 p6 |% [) X
  46.                         if(USART_RX_STA&0x8000)//(串口接收用到了正点原子的例程)
    . N7 I- D' ~% q+ `
  47.                         {
    5 T; w/ O, Z5 n* v$ B# E& F! T/ W
  48.                                 len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度* q! `9 N% Q( c/ g
  49.                                 r=len;                               
    . f, ~+ o5 v1 s! s1 K  X
  50.                                 type=0;
    . D# }4 N0 A( [4 X
  51.                                 for(t=0;t<len;t++)//拷贝数据,将字符转换为十进制数
    ' J$ |9 x8 J: ~+ \" q5 F6 Q+ Q9 Q
  52.                                 {$ Y7 ^) r+ h# ?: j" ?/ p
  53.                                         receive_data[t]=USART_RX_BUF[t];7 M) T9 k) p/ R' i; @6 S$ f  E
  54.                                         data=(int)receive_data[t]-48;
    ( Z, z4 ^: p- s( s' j% _2 ^
  55.                                         r=r-1;
    7 G4 M: `0 Y" g! q& F
  56.                                         type=type+data*(pow(10,r));5 D  D. \" u% P. A( F
  57.                                 }
    ' f, B; l7 i( [3 Z
  58.                                 USART_RX_STA=0;
    7 R% x0 A( X1 w- M2 F4 w4 M
  59.                                 a=0;
    , W' I. M" d& Q3 D) j- j
  60.                                 delay_ms(500);: H, c; N8 y- g( H
  61.                                 break;' `* R$ H6 l" u+ Q, J( j/ }
  62.                         }4 h/ i0 ~# O  T, O% D- N
  63.                 }% u- W" F/ ]" L6 F; J! M
  64.         }
    9 z6 K8 v( R& g
  65. }
    4 m3 b% O1 _/ k' n. B
  66. /**************************& M6 h& v8 Z0 G5 S. Z
  67. * 函数名:KeyStates
    - `. i" E0 n+ k. A. v$ L
  68. * 描述  :监测按键状态
    2 d( m" U' p( e; X/ g% y; b6 f) n
  69. * 输入  :无
    3 H# `) u* x+ O
  70. * 输出  :无
    0 a4 [# Z0 _; E) U4 V* I
  71. * 返回值:0/1
    * r+ J1 @, M+ Z( Y% U; F. J
  72. ****************************/' Y( n2 @2 w- p
  73. u8 KeyStates()//按键状态+ n9 ]/ a7 @5 u: e% h2 W; B5 N- n
  74. {* |' U. J- t# S, o  Z
  75.         static u8 i = 0;
    / n# i" b9 f; O0 g- s
  76.         if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)==0)' N4 S1 S5 {. S" a
  77.         {
    # Y: ?  V7 G+ }- W$ `
  78.                 delay();& i* d: @2 \4 t( C0 H
  79.                 if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)==0)5 W1 H+ M. z( O- X" g$ P1 N8 A
  80.                         while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)==0);
      l  t+ T# H# `7 D3 e* Q
  81.                         i = ~i;
    1 b: p# s! G3 |0 n8 N  f" Z. ^
  82.         }' x# x( p, D  ^, x* h2 q
  83.         return i;+ N- c6 `! u4 s  j& F8 O9 D$ P- ?
  84. }  ]/ c& K3 ?! ?, Z, a# E
  85. /****************! e- n4 U5 V. ^$ ^" p: ^: |% L% C
  86. * 函数名:main! W+ H- s' b9 }' x+ ?1 v. ?
  87. * 描述  :主函数% x0 C' n0 x1 r
  88. * 输入  :无
    ! }+ ~8 ]0 @5 A1 p0 `9 d0 z
  89. * 输出  :无* |% o! p8 [0 O
  90. ******************/
    % G5 L8 [/ j. t2 r4 u  x
  91. int main(void)
    ; Q9 ?/ o0 \8 ^/ J, m5 i8 r" e
  92. {
    $ t. n0 c0 \$ B; m5 y/ ^. y1 i
  93.         NVIC_Configuration();                        //中断初始化) O/ V7 L' b4 e/ {8 n) t( H
  94.         GPIO_Config();                                        //IO口初始化
    8 u4 F$ @- q  P, [, p
  95.         USART1_Config();                                //串口初始化/ ?6 v) a. m' S* z( O5 [2 b! J
  96.     delay_init();                                   //延时函数初始化       
    & G' D0 K2 M( d8 j, N4 u
  97.         GPIO_ResetBits(GPIOA, GPIO_Pin_11);//A11置零  A11——EAN+
    - m! v2 i8 w+ S6 x8 C1 h0 H
  98.         GPIO_ResetBits(GPIOA, GPIO_Pin_12);//A12置零  A12——DIR+- d1 L$ W' x% m- ~* }6 V0 E6 ]4 ?
  99.         while(1)# ?* m- E; q- e5 J2 @+ P
  100.         {2 \& N2 C: ]$ ~4 |: z3 \
  101.                 delay_ms(100);
    # Q6 l' A3 Q* _* @0 F/ p1 u! t
  102.                 Initial_state:                printf("\r\n 请选择正反转,正转输入0,反转输入1 (以新行作为结束标志)\r\n");       
    7 `# p& Q3 D+ c/ R& O' P7 t
  103.                 Waiting_reception();
    , G5 W# Y& ~$ O+ n' H# g
  104.                 state=type;//将接收到的数据给type4 A0 z; C5 P$ g! [: }
  105.                 if(type==0)//电机正转" p7 t7 X  A8 V! W( C& l( L
  106.                 {
    $ o( d: b% I! @9 ^  ^, @- {! U" T
  107.                         GPIO_SetBits(GPIOA, GPIO_Pin_12);//电机正转
    $ h3 G4 |. u3 m1 G5 P3 J. M  ^, z
  108.                         printf("\r\n 电机为正转模式,请输入旋转速度(rad/s),输入0返回初始模式 \r\n");
    8 D. Y8 {) ~$ O; b5 s  c' h+ R' y
  109.                         ; m& l8 Z9 N  X, w; `; |* C7 ^( i$ z  ?
  110. /*********************************************此模块用于配置速度参数********************************************************/
    " i* Y  H. O  @

  111. 2 U, [5 i" }; v& L! e: v
  112.                         part1:Waiting_reception();% G. P$ |, ]& M" u
  113.                         speed =type;//将接收到的数据给speed
    2 i: i( j) u! Y' f+ b
  114.                         if(speed==0)goto Initial_state;//如果是0则返回初始模式& }) Y2 v1 `2 o- J5 c0 I7 W
  115.                                 else{$ }9 D! @. N) u/ W
  116.                                         if(speed>=15)
    + l# g" ]+ V- S& ^3 S# }
  117.                                         {
    9 d! P2 @) A* B- Z. F6 y% z4 {
  118.                                                 printf("\r\n 旋转速度>15rad/s,请重新选择旋转速度。\r\n");4 o) W. U% i/ ]1 w
  119.                                                 goto part1;
    ; s" j  @2 g# I8 [/ V
  120.                                         }
    ) J, k! J  |& z5 [" i6 P  l. D4 j
  121.                                                 else printf("\r\n 电机旋转速度为%d rad/s,请输入旋转角度,输入0返回初始模式 \r\n",speed);
    2 |: A8 R9 I( G7 a+ w7 H
  122.                                 }
    % }# I1 Q# r! C2 R. H3 ~  e& G' `
  123.        
    9 V( u" q  c6 f( t6 s
  124. /*********************************************此模块用于配置角度参数********************************************************/                0 Q* ^6 M$ u0 @: F7 H
  125. & M9 l5 e& \# E2 r8 v4 l+ D
  126.                         Waiting_reception();
    6 }8 ?9 C  y+ U( }
  127.                         angle =type;//将接收到的数据给type( W+ y, c7 E; D: }4 I
  128.                         for(;;)
    , O. B7 ?. P$ y
  129.                         {
    9 r, S; b) L! |; O3 i: F- `' W6 Z
  130.                                 if(angle>0)//接收到的数据不是09 F4 |4 [, p6 D, ]
  131.                                 {
    1 `- d$ u% |( \5 d2 g
  132.                                         TIM2_Master__TIM3_Slave_Configuration(speed,angle);        // 配置TIM2和TIM3的重装值 ,改变电机转动速度和角度3 o# [$ a, F9 s
  133.                                         delay_ms(20000);//电机保护
    0 a/ j7 E" v9 A3 F4 _
  134.                                         printf("\r\n 电机已旋转%d °,请输入下一次旋转角度,输入0返回初始模式; \r\n",angle);
    6 N$ K$ @! I7 d" V. P, g$ q
  135.                                         angle=0;
    + {. O- Q4 n$ f0 O9 @3 C0 F  U; z
  136.                                         Waiting_reception();                1 [; D* r0 m/ ~5 W6 p; l  l5 l
  137.                                         angle =type;                                       
    3 K9 v) r6 v0 `5 Q
  138.                                 }else{/ \9 r5 O9 }! N4 r9 S
  139.                                         if(angle==0)goto Initial_state;//返回初始状态       
    8 G" u: m$ ?: Q  M3 n3 w
  140.                                         else {
    3 _: o* a9 k* _" U# I
  141.                                                 printf("\r\n 角度错误,已返回初始模式 \r\n");                1 `0 |9 m8 C' }! `: q
  142.                                                 goto Initial_state;
    " O. K  d2 K5 |* C: f4 K" q
  143.                                         }                                                5 t$ P6 w- s4 }1 j! w
  144.                                 }$ O8 J; S  g1 }) Q0 M! I1 l" s  C3 o
  145.                         }/ h0 w) `( X% ~. m6 v8 m3 ]# O% q
  146.                 }                ( [& k( {) h2 W4 Y0 D
  147. /*********************************************反转模式********************************************************/               
    0 D- y( @  b3 A. [/ S. e
  148.                 else{3 l& F; P3 p) B4 D& P+ |/ I: i
  149.                         if(type==1)" q  P5 a: w5 @) a
  150.                         {& Q) M9 s; Z( m' ?+ x7 d
  151.                                 GPIO_ResetBits(GPIOA, GPIO_Pin_12);//电机反转$ W/ s& x& a% E) f8 Y0 a
  152.                                 printf("\r\n 电机为正转模式,请输入旋转速度(rad/s),输入0返回初始模式 \r\n");, o4 Z/ z( {7 v
  153.                                
    / B7 z+ h- C0 B0 `
  154. /*********************************************此模块用于配置速度参数********************************************************/
    : ~+ L+ H. D( k& [7 W
  155.                                 part2:                                Waiting_reception();
    " L4 p. u0 }; B* X: j1 c
  156.                                 speed =type;//将接收到的数据给speed, R  {& c6 S; S% v  w5 S
  157.                                 if(speed==0)goto Initial_state;//如果是0则返回初始模式" c7 i; ?0 k1 R0 Z) ?% {$ e' x
  158.                                         else{- `1 p1 m& ]/ {# [7 q2 _
  159.                                                 if(speed>=15)
    ; B  U7 p9 g+ ?* b
  160.                                                 {
    & N- [0 [: F1 w1 `3 ~6 ~/ j3 \
  161.                                                         printf("\r\n旋转速度>15rad/s,请重新选择旋转速度。\r\n");
    & L! p& z# f& r7 ^2 U/ D
  162.                                                         goto part2;
    # r; ^* @$ g4 |: v1 p/ i' ~
  163.                                                 }else printf("\r\n 电机旋转速度为%d rad/s,请输入旋转角度,输入0返回初始模式  \r\n",speed);3 d' ~0 z+ a6 A3 _( J
  164.                                         }        - R; q, n3 h& t9 _% n
  165. /*********************************************此模块用于配置角度参数********************************************************/               
    # B3 K9 W4 s0 b6 z7 T( B9 B; b
  166.                                 Waiting_reception();
    2 ^" ?7 R' |) @+ M9 ^' {
  167.                                 angle =type;//将接收到的数据给type4 Z* z( p; X- {" h, ~4 Y
  168.                                 for(;;)
    : O9 x  O' c3 N2 X7 C
  169.                                 {
    ; R4 q6 J8 A3 I' A# c7 \
  170.                                         if(angle>0)//接收到的数据不是00 e9 |( m9 u2 _! Y1 j
  171.                                         {' F, C# m. m$ t' p! O4 z. H, H( R2 c
  172.                                                 TIM2_Master__TIM3_Slave_Configuration(speed,angle);        // 配置TIM2和TIM3的重装值 ,改变电机转动速度和角度
    ' w4 u! e/ k) p2 g
  173.                                                 delay_ms(20000);//电机保护
    % o: ~* L) a- N; ^
  174.                                                 printf("\r\n 电机已旋转%d °,请输入下一次旋转角度,输入0返回初始模式;\r\n",angle);9 R% R% [* L; _; ~0 q) `0 X. M
  175.                                                 angle=0;9 N  V+ V, K' V* z6 h* G
  176.                                                 Waiting_reception();                9 C9 R9 v  k$ W7 T( D' I
  177.                                                 angle =type;                                        ; J+ j7 `1 ?) v, g- G# s; ^
  178.                                         }else{' O" D8 @. {7 E! s+ Y/ j9 S
  179.                                                 if(angle==0)goto Initial_state;//返回初始状态        ) U/ J0 I& P- I5 i3 c4 [
  180.                                                 else {
    7 _4 y" w+ p3 D& z' g. ]
  181.                                                         printf("\r\n 角度错误,已返回初始模式 \r\n");                " R- g0 W8 B0 _$ y( z
  182.                                                         goto Initial_state;( G! o/ E7 q3 ^9 ^" B7 w
  183.                                                 }                                                               
    , T5 F# b2 B" m$ k  B5 g5 j
  184.                                         }
    ) y% {" [8 @; m6 ^! y
  185.                                 }
    0 l4 q) x6 l# \0 c$ }0 D6 n/ S
  186. /****************************************************************************************************************************/                                       
    ; u* U( T2 H1 n4 W: {8 {
  187.                 }else{//if(a!=0)&(a!=1)
    + D* B* t& A1 A% P
  188.                         type=NULL;
    0 A6 `7 E8 Q+ X4 {; z6 `2 E
  189.                         printf("\r\n 输入无效 \r\n");" O$ r! `% h/ ]& j+ M
  190.                         goto Initial_state;//返回初始状态* k( s5 e$ o5 t" B% \9 Z  {9 p, a  l
  191.                         }! Z2 {8 a' L& ?% h4 x; X  n
  192.                 }' b; `7 b! W) R" k' r/ n3 R$ O% m
  193.         }
    9 O9 q; B) M: Z% H2 T
  194. }
    / X9 a) O. J# U& K) |6 Q) P
复制代码
2.main.h程序1 K: v& D4 F- i  e
  1. #ifndef _MAIN_H" e  P; N. S3 o- S" ^% X
  2. #define        _MAIN_H
    / N7 h" ^- b6 a
  3. #include <stm32f10x.h>
    : k, E: c, H" c0 j7 B  Q
  4. #include <usart1.h>) o* S, L5 R& C: e* m$ M
  5. #include <misc.h>/ V( L) m; Z) Q* @
  6. #include <nvic.h>+ j, V/ G+ x* B' b2 t* c2 E
  7. #include <stdio.h>9 ~  g9 r8 V; E% Q' M( Y* T
  8. #include "stm32f10x_tim.h"/ `- u" ~, X& q1 c5 _
  9. #include "timer.h"
    9 S9 y7 d, M, _1 J8 w1 y
  10. #endif- b- v. q- H1 T7 C
复制代码
3.time.c程序
% ~& |0 B% U1 e$ B: j& C/ l0 O- Q
  1. #include "timer.h"- D' X  q! _6 H7 e
  2. /**************************& }' u* L! _7 z1 _5 g9 c, n
  3. * 函数名:GPIO_Config
    & g( Q0 O7 N: o% h- U  \3 G6 w
  4. * 描述  :无8 M5 a' i% ~9 m; ~4 @
  5. * 输入  :无 . e" j: D1 \& K6 M1 l5 P! H, g
  6. * 输出  :无" O! a" b* I, t; P6 q9 t) {% z5 ]
  7. * 调用  :主函数3 ?, M. [# M6 ~# e$ ?
  8. * 返回值:无4 H8 L% {6 c8 h3 W6 w
  9. ****************************/
    7 ]# R) h0 e8 F  m( F4 M" U
  10. void GPIO_Config(void)
    . e+ \% h- ?) o; B. [
  11. { " Z6 ~# t  M7 a  E% k' u
  12.                 GPIO_InitTypeDef GPIO_InitStructure; 8 n- }  A& A0 X7 S  W
  13.                 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); //使能IOA
    5 R; N3 @" E8 P3 x+ Q
  14.                 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3, ENABLE); //使能TIM2,TIM3
    - z7 o- S- G' e; B5 D6 }" x( z
  15.                 $ r1 y5 p! `: G/ X
  16.             /* Timer2 Channel 1, PA0 */ . R4 ]  b- X/ B6 m& E! c; C
  17.             GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_0; ) A2 w8 y4 V1 a, k$ T
  18.             GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用输出
    5 o3 L- @: |- F
  19.             GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 3 M" b  X" V' _' v
  20.             GPIO_Init(GPIOA, &GPIO_InitStructure);
    . U! ^. `, I; y
  21.                  # t( f& V" ~' Q. n8 P  h" o
  22.                 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_11|GPIO_Pin_12;# I2 d# K8 s/ i3 c
  23.                 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         //通用推挽输出模式5 c. j6 N! Y6 {- ]
  24.                 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //指定GPIO引脚可输出的最高频率为50MHZ( f8 R$ A) P  g# N7 g
  25.                 GPIO_Init(GPIOA, &GPIO_InitStructure);                   //
    & G+ j- u# o; X& l- W1 L6 {3 c
  26.                 GPIO_ResetBits(GPIOA, GPIO_Pin_1);//指定引脚输出低电平,此时灯全灭,方向
    * k: R( C& O' c9 n1 X% w: W# J* a
  27.                 GPIO_ResetBits(GPIOA, GPIO_Pin_2);//指定引脚输出低电平,此时灯全灭        使能
    % S8 F! [+ {$ g* N
  28.                 GPIO_SetBits(GPIOA, GPIO_Pin_11);//指定引脚输出低电平,此时灯全灭,方向1 T: m. Q. |+ l/ C
  29.                 GPIO_SetBits(GPIOA, GPIO_Pin_12);//指定引脚输出低电平,此时灯全灭        使能
    / A' ^3 h9 C  q3 e
  30.        
    . A( h& R4 A0 h$ p/ X2 l( x
  31.          
    / S5 t: N& o) `. u5 Z/ k
  32.                 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    & h9 P, Q7 D2 j
  33.                 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;         //通用推挽输出模式( M( t8 M1 Q+ U& n# Z) X
  34.                 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //指定GPIO引脚可输出的最高频率为50MHZ7 Q* J* R2 u+ R- ]: b) _. h
  35.                 GPIO_Init(GPIOA, &GPIO_InitStructure);                   //
    5 B. T9 F4 ^  {! F+ @
  36.                
    5 e1 S" k/ G- j" G  O2 D% l8 \, P( u
  37.                 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    ) S( ^: n: u: H# M
  38.                 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;0 e' ^* j: |8 q/ B5 }
  39.                 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         //通用推挽输出模式
    & e1 Q6 X* d* \2 q8 ]
  40.                 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //指定GPIO引脚可输出的最高频率为50MHZ) y5 }& j9 Q( U* `% r' D
  41.                 GPIO_Init(GPIOB, &GPIO_InitStructure);                   //% e! T) f( d- H& b* s. Z) T
  42.                 GPIO_ResetBits(GPIOB, GPIO_Pin_12);//指定引脚输出低电平,此时灯全灭        使能/ o# K2 @4 t1 q
  43.                 2 ]2 f0 O+ R4 c& s0 u, m0 ^7 }6 x9 k$ i! ^
  44.                 //GPIO_ResetBits  GPIO_SetBits
    3 |) G" l8 u" `
  45. }
    8 h- B& t! Y8 z& c) L; U6 q
  46. : P+ ^: Q- F% H" _
  47. //================================================================================# f1 T8 ?) C7 T
  48. /**************************9 p1 W& y8 {% {0 H+ W
  49. * 函数名:TIM2_Master__TIM3_Slave_Configuration
    - K+ l& f6 P/ p
  50. * 描述  :主从定时器配置
    " ]) |* t. I8 n# c- `7 l: H4 O
  51. * 输入  :电机转速speed,转角angle
    1 a0 M" j0 ]+ X- E( ]8 O# ?
  52. * 输出  :无
    : p. s; [2 @5 u: L* J1 I3 K
  53. * 调用  :主函数+ k3 \' x5 X/ N+ [4 W9 P! L
  54. * 返回值:无' f7 r5 {& R$ C9 N/ L. T* f# W  ~
  55. ****************************/
    - S/ U6 M' F* H5 m0 W0 a
  56. void TIM2_Master__TIM3_Slave_Configuration(u32 PulseFrequency, u32 pulse)
    ! O* A! z/ q4 b9 E7 q8 c% q
  57. {% N' \0 ?6 P% g6 C/ v  f5 L( }
  58.         TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    % {/ |8 f/ |! `3 @
  59.         TIM_OCInitTypeDef TIM_OCInitStructure; 1 o2 q4 F; M+ s" B0 f
  60.        
    . q- Y! z5 {  ^" `0 c# t
  61.         u16 nPDTemp ;
    7 |# y) }% Z; n! k6 b, i5 A
  62.         u16 pulse_number;" r2 D3 Z+ {6 [2 r" F7 i6 |( E
  63.         float p=PulseFrequency;& X" k/ Q0 S$ n4 @, @
  64.         TIM_Cmd(TIM2, DISABLE); * f& g+ L9 X: n4 h  r  }# u. H. @, O
  65.         nPDTemp = (11.25/p);                            //TIM2重装值是11.25时1s转一圈(电机32细分下)
    % ?# P) Z* }/ k( z4 I3 }- J
  66.         pulse_number = (16.7778*pulse);//TIM3重装值是16.7778时转1°(电机32细分下)
    1 R; u& m; J3 q4 n) S( C
  67.        
    $ ]& x+ f1 v. ~$ t
  68.         // 时基配置:配置PWM输出定时器——TIM2 , ]5 }$ z1 i9 s
  69.         /* Time base configuration */ / r9 _8 m; A5 N
  70.         TIM_TimeBaseStructure.TIM_Period = nPDTemp; //定时周期为nPDTemp" S+ d, A  Q1 s- j- o
  71.         TIM_TimeBaseStructure.TIM_Prescaler = 999; //预分频值1000,即f=72khz
    & c3 w- m7 g: J8 F% @1 \) O* P( D5 R; w2 P
  72.         TIM_TimeBaseStructure.TIM_ClockDivision = 0; //时钟分频因子,会影响滤波器采样频率,与本实验无影响' f2 A& B) ~+ {
  73.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
    ; {5 K! p+ F' u7 F2 j
  74.         TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; //指定重复计数器值
    0 Z6 e9 l) z& q0 h7 h2 r
  75.         TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
    ) i- v' A: b+ p
  76.        
    1 g5 Q9 M4 D) f# |, M6 k( r7 ]
  77.         // 输出配置:配置PWM输出定时器——TIM2
    / D; D. p; Z" z1 U
  78.         /* PWM1 Mode configuration: Channel1 */    . I5 t% s6 P9 g0 @8 i$ v
  79.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //TIM 脉冲宽度调制模式 18 N/ a7 ~2 r+ T6 g; ^7 B
  80.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //高电平有效
    6 e4 ], Z$ \; s+ Y4 K* w' [* L
  81.         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //使能输出6 |8 ]- J' J; q1 ]+ H
  82.         TIM_OCInitStructure.TIM_Pulse = nPDTemp>>1;//50% //比较tim_ccr的值,输出脉冲发生跳变
    ; J  i( j! h: c8 x1 o
  83.         TIM_OC1Init(TIM2, &TIM_OCInitStructure); //初始化
    9 o8 \1 a& M; [3 B- Q/ @
  84.         TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); //使能 TIMx 在 CCR1 上的预装载寄存器
    0 H. U- f9 c0 i' y8 w" P# h
  85.         TIM_ARRPreloadConfig(TIM2, ENABLE); //使能或者失能 TIMx 在 ARR 上的预装载寄存器
    - U6 I# d$ H) c- Q6 f( G
  86.         / g: H2 }: z; J! U
  87.         // 时基配置:配置脉冲计数寄存器——TIM3
    ; e" _$ }! D. G! {. f  h1 m
  88.         TIM_TimeBaseStructure.TIM_Period = pulse_number;      //0x1900是360°;//改变给电机的脉冲个数                     
    . B. ?3 J) z* x; ^6 B! J5 o' _; Q- S+ \
  89.         TIM_TimeBaseStructure.TIM_Prescaler = 0;
    ) \, q1 v- L0 }' G" n: H
  90.         TIM_TimeBaseStructure.TIM_ClockDivision = 0; , @* p9 `; g0 i1 Q$ s
  91.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; , f3 @' a6 F2 \0 Z8 o# w2 \
  92.         TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
    & A- E8 k- J% q* g/ T: s! m9 Z- V
  93.         TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); # m* j2 O3 g. ^. `3 A7 s2 t. G
  94.         // 输出配置:配置输出比较非主动模式定时器——TIM3  l/ i  V' j  H; U% e" M( G5 t
  95.         // Output Compare Active Mode configuration: Channel1 9 r# l$ l, E! I2 w
  96.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Inactive; //输出比较非主动模式,(匹配时设置输出引脚为无效        电平,当计数值为比较/捕获寄存器值相同时,强制输出为低电平)      
    3 c% u* w% D. u7 X3 R# j
  97.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; 1 F+ @9 h$ A! @3 a: x- q) _
  98.         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; - {' k. l& u+ @6 o
  99.         TIM_OCInitStructure.TIM_Pulse = 0xFFFF; // 这里的配置值意义不大   
    7 i0 a! g, g1 y9 X4 S  P1 E
  100.         TIM_OC1Init(TIM3, &TIM_OCInitStructure);
    7 X* c) h2 y1 p- a/ t+ F

  101. 1 [. I3 A3 [, k) u: X" T/ R
  102.         // 配置TIM2为主定时器
    . D8 L' [5 A& j' L, g
  103.         // Select the Master Slave Mode ( n+ _6 @3 _6 |1 L4 N
  104.         TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable); //设置 TIM2 主/从模式并使能3 P2 H" }( m' d% u
  105.         // Master Mode selection  
    3 R* w6 ]* m* z& L0 h( A
  106.         TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update); //使用更新事件作为触发输出9 j' X4 n6 i+ Q7 n& q
  107.         ' F$ a4 x+ K7 p$ c+ u+ [% k
  108.         // 配置TIM3为从定时器 ) O+ S8 _& ~- R8 ], d1 E: G
  109.         // Slave Mode selection: TIM3
    5 c9 e+ h3 [$ M+ }
  110.         TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Gated); //选择 TIM3为从模式   TIM_SlaveMode_Gated-当触发信号(TRGI)为高电平时计数器时钟使能( z5 [9 r# [2 g6 c3 i1 n
  111.         TIM_SelectInputTrigger(TIM3, TIM_TS_ITR1); //选择 TIM3 输入触发源    TIM_TS_ITR1-TIM 内部触发 19 R8 G% A# A$ j4 A
  112.         TIM_ITRxExternalClockConfig(TIM3, TIM_TS_ITR1);//设置 TIM3 内部触发为外部时钟模式   TIM_TS_ITR1-TIM 内部触发 1+ `( b, K) I& b- e
  113.         TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE); //使能TIM3     TIM 捕获/比较 1 中断源            o& W( p0 G+ H$ {
  114.         . k3 @/ W% o5 \
  115.         TIM_Cmd(TIM2, ENABLE); # i6 @) f5 [% n5 G3 F) d: U  b- {6 F
  116.         TIM_Cmd(TIM3, ENABLE);
    ; D! Z) |; ^8 t# l7 ~. N
  117. } $ k  K3 A% z7 G0 j
  118. 3 p1 b: k' w0 D" c6 b! {2 j  ]: F7 X
  119. /****************************************************
    / W; w& B5 e' g9 a
  120. * 函数名:Output_Pulse
    9 i1 J) J8 |; a- j( C( F4 y) A
  121. * 描述  :无
    3 l0 |) v- I6 x7 s# d
  122. * 输入  :无
    ! _+ R% {8 N) y3 W- ^
  123. * 输出  :无) V4 c% ^, a6 X7 _* [
  124. * 返回值:无: T  e2 l+ H, H' x! _
  125. ******************************************************/
    2 M, w- f  V  B
  126. void Output_Pulse(u16 Num)8 T# v$ W9 e" {: D  S1 l
  127. {9 a4 B) Q( z  a
  128.                 GPIO_ResetBits(GPIOA, GPIO_Pin_2);//指定引脚输出低电平,此时灯全灭        使能
    ) [  \/ p: P5 I4 Q% s
  129.                 TIM3->CCR1 = Num;
    7 ?! v. m& e0 h. m# }
  130.                 TIM3->CNT = 0; 8 E+ }  m: }$ t' K3 A$ i3 |
  131.                 TIM_Cmd(TIM3, ENABLE);
    ! ^6 m5 o6 l+ M! U
  132.                 TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE);
    * g1 r, I# R, |3 T8 J
  133.                 TIM_Cmd(TIM2, ENABLE); 9 Y8 E1 J- f9 Z. P* W
  134. }
    7 u/ Y  P6 ]  [2 S- H( P

  135.   a3 w0 S0 t% c2 s- u: p
  136. /****************************************************
    9 ~2 ^6 {) g3 V6 e$ v
  137. * 函数名:angle_set
    ; @% K' J. ^6 A0 v
  138. * 描述  :无& t$ n- i- l' o, p0 \; w+ C0 I+ }# w
  139. * 输入  :无 6 d9 |& ~9 n* o% ]) f+ b" _
  140. * 输出  :无
    5 z% v8 a' a! x2 D
  141. * 返回值:无+ F/ i: E  M6 t1 B% G6 h
  142. ******************************************************/
    ( L) r: x8 h9 W& \( A
  143. void angle_set(u8 dir,u8 angle)
    & L+ g4 \6 `% l/ F( g' W
  144. {
    8 J6 n3 m, M6 i) M, p$ Q- H
  145.         if(dir==0)6 ^' z4 h* K+ ^* a
  146.                                 GPIO_ResetBits(GPIOA, GPIO_Pin_1);//指定引脚输出低电平,此时灯全灭,方向
    # F9 L9 M% E, w
  147.         else
    + h% T8 ~; \4 b. f) ]
  148.                                 GPIO_SetBits(GPIOA, GPIO_Pin_1);//指定引脚输出低电平,此时灯全灭,方向% L+ y2 z' l0 Q" M
  149.         1 i6 f$ s0 p  _& [( v; z
  150.         Output_Pulse(angle*6400);
    2 o) K; s7 [3 i
  151. }$ k' ^( F/ M: a0 L
复制代码
4.time.h程序( @" ?- E2 T8 w( j$ p1 p+ T* Z6 h
  1. #ifndef __TIMER_H* w/ f' Q( u; |# G) g2 P5 Q# z
  2. #define        __TIMER_H- f4 O. G) e3 u5 z, \) ~1 c# `
  3. #include "main.h"
    : P( u0 ?! L: M0 I/ ~0 ~# ^. Z
  4. extern unsigned char Flag;8 r7 I& o/ h7 m: |& |
  5. extern unsigned char TIM2_Pulse_TIM3_Counter_OK;
    5 U+ D: }4 \- l2 {/ h
  6. void GPIO_Config(void);
    8 n. `* C+ J  ]
  7. void TIM2_Master__TIM3_Slave_Configuration(u32 PulseFrequency,u32 pulse);, H) j. @" B4 l9 U! g
  8. void Frequence_Setting(u32 PulseFrequency);( q3 x/ D0 m+ ^" n, X' b5 z
  9. void Output_Pulse(u16 Num);" ]' k3 w# r9 X' \2 ^! A( F8 _
  10. void angle_set(u8 dir,u8 angle);- F3 y% Y- Q7 z9 q& p
  11. #endif9 `8 p& U' C8 v
复制代码
5.usart1.c程序* I+ n$ T4 n7 M% |4 W% a! V$ S. m& x
  1. #include <main.h>
    6 l6 U% y1 b" f3 G
  2. #include <usart1.h>) ]  C# O+ z2 N
  3. #include <string.h>
    $ X1 e; ^6 h- q9 @3 N6 Y8 @2 `
  4. #include <math.h>8 _" ]8 ~7 a7 D; G5 V

  5. 5 I8 A% |4 |2 p/ q* i7 E) N
  6. /******************************************************
    , A4 z. A; O$ H
  7. * 函数名:USART1_Config# i2 m: _+ k9 k7 r) t
  8. * 描述  :USART1 GPIO 配置,工作模式配置
    , W" O0 p3 u1 P2 D: v% Q! f% ^
  9. * 输入  :无' T  E: W% ?7 R6 C4 o
  10. * 输出  : 无& F5 |7 _; ]2 U0 H3 c, j- [! B
  11. * 调用  :外部调用
    & V! k7 b7 B. b( d- a* I2 Y
  12. ***************************************************** */& H! B0 o; r% M" |3 B
  13. void USART1_Config(void)
    + l2 z( t3 ~/ T1 V) O, `# D! W4 t
  14. {8 w( w/ A! K0 T, ]9 J1 R3 h6 O
  15.         GPIO_InitTypeDef GPIO_InitStructure;
    + D$ a  i2 A" _8 O# H% M4 }6 G7 f
  16.         USART_InitTypeDef USART_InitStructure;
    + l& M/ d: p+ e* y
  17.        
      t+ w  B6 |& r. N  k# `
  18.         /* config USART1 clock */
    % Z1 F' o; ?4 ~* I3 k5 S$ Z2 J8 W
  19.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    $ K& L0 C$ y9 O, u/ B/ [, C& P
  20.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);. K* L4 Q2 w$ W  _
  21. 2 }8 o4 Y# {8 ^$ h5 R, o
  22.         /* USART1 GPIO config */
    3 H: o1 N4 C5 q6 p/ r
  23.         /* Configure USART1 Tx (PA.09) as alternate function push-pull */" _! ]8 A1 p! K" ]
  24.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;2 e8 a4 q/ z. x7 i" H% x
  25.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    6 q: n( x7 P& c1 v- p4 ~  i% G* F
  26.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;$ a: R* a+ O: @) I
  27.         GPIO_Init(GPIOA, &GPIO_InitStructure);    : [! \. O) ?2 B* n$ ^
  28.         /* Configure USART1 Rx (PA.10) as input floating */
    - A! s$ ?0 ^3 M
  29.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;- i  U& H( S2 _* Y3 E8 k. |
  30.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;! ]5 B  F" M5 p* }& K4 u
  31.         GPIO_Init(GPIOA, &GPIO_InitStructure);
    . |$ Q3 o2 e) q. C+ P
  32.        
    + I2 G# Y, \3 }
  33.         /* USART1 mode config */1 f$ P2 Z8 o1 U  @3 k! r( w
  34.         USART_InitStructure.USART_BaudRate = 115200;
      s% A6 U$ J1 G# S
  35.         USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    % n8 _6 c* L* T+ V: ~- W" ?
  36.         USART_InitStructure.USART_StopBits = USART_StopBits_1;: l+ I* x( h; m$ o: H
  37.         USART_InitStructure.USART_Parity = USART_Parity_No ;
    + t! w' w  H! z" W5 D+ l4 a
  38.         USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    . g1 A+ _6 ?& j2 z: y
  39.         USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    ! B4 w$ l) Q1 ?- d: m' R2 \5 P
  40.         USART_Init(USART1, &USART_InitStructure);& W" E0 [* `, z1 \6 w" H! b
  41.         USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
    , U* c' ~* U' W; y' n
  42.        
    - v' W9 W; P- c- |. H9 n/ u
  43.         USART_Cmd(USART1, ENABLE);; x2 G7 S% P) y, O$ b
  44. }4 f' D+ D' `" U4 |" J8 i' Y) S

  45. , ~2 e$ X$ S: \0 m8 J; Q
  46. /******************************************************
    & N: N) z0 v, Q. _' t
  47. * 函数名:fputc
    7 y6 j; w' C1 g$ [" F( U) ^
  48. * 描述  :重定向c库函数printf到USART1
    " c1 _* b" l6 a7 N0 X2 w
  49. * 输入  :无
    4 R5 C, j6 Q, e4 `
  50. * 输出  :无
    4 N2 l3 B, [; \8 t3 G
  51. * 调用  :由printf调用  n: \/ g% s% m
  52. ***************************************************** */6 }, R1 |% c5 S2 R' q
  53. int fputc(int ch, FILE *f)
    1 V# I  u# `9 S7 p0 w0 A7 [
  54. {
    ; ?/ D5 c4 {  p
  55.         /* 将Printf内容发往串口 */2 s: p  h$ h" e" _6 o
  56.         USART_SendData(USART1, (unsigned char) ch);& E* G( O$ z0 m$ l# ^
  57.         while (!(USART1->SR & USART_FLAG_TXE));* b- W3 u% S& @" z' ~2 i
  58.        
    , l7 J& S3 h% r; H- A3 @+ p
  59.         return (ch);/ [5 B( A/ N7 G
  60. }
    2 g- _. O3 y) C
  61. + d) a" s7 d8 c" H- W. ~) C# M
  62. /*-------------------------------------------------------------------------------*/2 W! A, r- B: I3 O. q7 B# v
  63. /******************************************************8 ^. U, Q* r  [1 K1 W5 k
  64. * 函数名:USART1_IRQHandler
    1 p8 i3 n9 b, s" B2 m( {
  65. * 描述  :USART1中断服务函数
    ) [! m& e; w  y
  66. * 输入  :无
    - P* ^" p: Q3 L/ i8 b; U( }
  67. * 输出  :无
    " k' e% T. B6 t) S. u
  68. * 调用  :中断调用  b& S1 a$ w2 t0 u
  69. ***************************************************** */8 T7 \* j0 W7 E( F9 H. N
  70. u8 Res;
    & \+ n3 o: ^, N  ]$ C6 r- o
  71. extern int a;
    " u' X- U9 X  l1 u
  72. u16 USART_RX_STA=0;       //接收状态标记         
    9 x! C3 h7 l' h  }: a
  73. u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.6 ~3 D" w0 ^& j
  74. void USART1_IRQHandler(void)                        //串口1中断服务程序! ^- Y6 T4 j) Y
  75.         {
    & M  Q( V6 d( G" @" d# v
  76.                 . ?4 B" j# @5 r+ G* T
  77.                 Res =USART_ReceiveData(USART1);        //读取接收到的数据$ {4 T$ \6 Q- _* b" G
  78.                
    / v! {7 P/ |7 [% f2 \: Y
  79.                 if((USART_RX_STA&0x8000)==0)//接收未完成; x: _# o+ N( Q8 b4 ]- j7 g4 U
  80.                         {
    1 a; ^+ l2 Z' |  B3 P' @! v
  81.                         if(USART_RX_STA&0x4000)//接收到了0x0d
    9 P, j8 {. H/ S- @4 O
  82.                                 {: q* l3 T1 t1 O5 y0 X0 ~+ o
  83.                                 if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始4 G) ?) p( Z& p1 l
  84.                                 else USART_RX_STA|=0x8000;        //接收完成了 " {6 D2 T, @, \# W" Q. u' H; G
  85.                                 }, X5 R4 {1 X( H% o4 H' f1 |
  86.                         else //还没收到0X0D
    : k8 V( W7 r9 ~+ g/ b
  87.                                 {       
    $ [; T; ]: `7 N- T4 O; [' E; ^
  88.                                 if(Res==0x0d)USART_RX_STA|=0x4000;
    ( U) t* u  j6 o) z# {" ~
  89.                                 else8 F1 j6 [5 r5 Y) }- Q
  90.                                         {2 p+ Q9 C  {8 m. q: n: k7 S9 Y
  91.                                         USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
    & t5 I) @/ R! R- A5 d$ W( v) D# U6 x5 \
  92.                                         USART_RX_STA++;
    8 d" V% u) t# W& `2 v6 e
  93.                                         if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收          7 z$ ]. _- U0 ~/ i8 n
  94.                                         }                 . L& \1 V* X. Q) a6 K+ n
  95.                                 }* `: S+ Q9 d- }1 H9 T" v' a
  96.                         }                1 W& [$ }) ^& v0 b3 {
  97.                                 a=1;         . B, ^1 v  J7 e3 n  i% f
  98.         } : }& n* j3 C; N* X
  99. #if SYSTEM_SUPPORT_OS         //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.* N) N7 n: o( M* f3 _' L5 t9 r
  100.         OSIntExit();                                                                                           
    , X3 W( Q+ y( W
  101. #endif7 U- u' l& a9 h: b

  102. 2 C# M/ v! }; j/ r& d+ r( Q( U/ W
  103. /******************* (C) COPYRIGHT 2012 WildFire Team *****END OF FILE************/$ l, V' N4 q/ X
复制代码
6.usart1.h程序: t) ~' y' R5 |# f. i; c
  1. #ifndef __USART1_H
    ( K3 J9 t  C! a9 z* i* d
  2. #define        __USART1_H
    1 N4 ]) u6 [6 g  B. B  w5 K
  3. #include <main.h>
    0 w3 J0 d: G3 u
  4. #include <stdio.h>
    . ~! V9 R/ F- a8 [& o) _
  5. 1 v* k7 W- x* L7 D
  6. #define USART_REC_LEN                          200          //定义最大接收字节数 2008 c5 h; J( _1 f( ]/ j4 x$ h
  7. #define EN_USART1_RX                         1                //使能(1)/禁止(0)串口1接收
    , m; Y" _3 V& ^; P4 G4 t2 K2 x# s
  8. extern u8  USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 5 T$ b$ ~# J6 v. z( e* L6 w0 F
  9. extern u16 USART_RX_STA;                         //接收状态标记5 U2 d0 J: A! p
  10. int simple_atoi(char *source);
    ! `- ?. t9 ^5 D# o5 N
  11. void USART1_Config(void);
    7 [$ j+ P* V! _- N# |
  12. #endif /* __USART1_H */
      \  e3 A; T7 k: u% ~4 @+ r4 m% j( ~
复制代码
源码:' g4 s  T5 o2 E* |. [
步进电机程序—串口控制速度角度.zip (4.75 MB, 下载次数: 50)
收藏 1 评论0 发布时间:2021-6-25 13:30

举报

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