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

stm32智能小车设计

[复制链接]
STMCU小助手 发布时间:2022-9-3 15:17
历时两周,总算把小车弄好了,总体上来说做的太慢了。自己在32的学习中还不够仔细深入,只是浅面的学习,当真正做一个项目时,暴露的问题就太多了。这次在小车的制作的过程中,遇到了各种各样的问题,软件,硬件,各式各样的问题迎面而来,真的好几次心态崩了。不过还好小车这个项目不只是我一个人在搞,组里的其他成员也在一直在考虑问题,想办法,不断地解决解决,总归小车终于做好了,下面是小车完成图:
微信图片_20220903151642.jpg 6 C7 |+ w* y6 M. R1 D) B
微信图片_20220903151646.jpg
0 }! d0 }+ @* `8 i- P5 B" }  x1 u1 a0 H
3 K/ q( C( }. @" q3 I" b3 {
是有点灵魂接线(·<·)。
! Q& O8 W" c1 F4 |! y! d$ X
# f5 x9 P* _' b$ y$ U+ B. p; P

. E1 v0 X, r5 }9 B

模块清单


$ }7 e; E$ U. g0 Z2 p
  • stm32f103C8T6开发板
    5 Y+ W! C9 M) Q7 B; \- C# X" {5 o$ I
  • HC-SR04超声波测距模块X3
  • TB6612FNG 电机驱动模块X2
  • HC-05主从一体无线蓝牙模块X1
  • 智能小车底盘 4WD小车循迹/避障小车 底盘X1
  • LM2596S DC-DC降压电源模块X1
  • 电源模块3.3V 5V 12V多路输出 电压转换模块DC-DC 12V转3.3V 5V X1
  • 12V电池X1
  • 杜邦线 Xn
  • 转串口模块X1
  • ST-linkX1
  • 面包板X1
    8 x7 [- {- r( S& d) y

' C6 n6 c. x  M7 Z0 j+ n% u" w/ O& R

! [  g5 x! Q3 m% }- h& H" s

完成功能

. H3 m& w  G% n8 V# D
  • 超声波避障
    / T. o+ A0 E" B: P4 p* _
  • 蓝牙控制
  • 走矩形

    ' N; d% k9 f4 z( B, E
' r4 E8 g3 k* k% p5 g& g

6 H3 k+ k' d: F3 e0 Y% A& @
各个模块就不再介绍了,具体介绍大家可以自行百度或者看一下我的前几篇Arduino智能小车博客,里面有简单的介绍。
* G, U" t% |  J( n0 e' }& w
5 _- o3 N' ?& g2 O: y/ R
那么,开始吧。

/ v- x% f9 b( s" Q9 W  F
6 w$ K2 v9 X- r; p+ Y9 s

准备工作

4 M6 t# a8 {5 w( C) Y4 p+ n- n
1.首先配置好keil5 c8t6模板(温馨提示:多看看模板的核心驱动,包括sys.h delay.h usart.h等,这些核心文件一定要保证准确无误!)
5 x! _) u0 j- W3 @& u$ j( G6 H
2.了解开发板和确保开发板无误
% i" y2 W  X: y6 J; r3.熟悉怎么用转串口模块和st-link将驱动下载到开发板上。

  C# E3 p+ j: J下图示为c8t6开发板的引脚图

6 Z( k8 I% a$ u8 x5 A6 Q 微信图片_20220903151652.jpg
0 G( [6 J9 @8 V: @- Y9 Z5 G1 D7 m2 a
1.超声波避障功能
$ W8 J1 S; B* f7 G  s
我们设计的思路如下,用三个超声波来避障。为什么用三个超声波呢?我们想的是如果用舵机的话,小车在行进过程中并不好判断,只能将车停下,舵机转动来检测哪个方向无障碍物,而用3个超声波不仅可以在行进中判断,也可以让小车没有停下的动作,显得整个过程比较流畅。这就是我们使用三个超声波的原因了。
0 s3 V( z, Y- a9 B( S# W9 i
我们使用的是定时器二的通道一,通道二,通道三来进行输入捕获的,那么,第一个问题就来了。

6 ~8 Z! o+ ^+ _, d* ~) n
我们在写超声波代码时,用一个超声波先测试,发现超声波测试的并没有问题 ,串口显示的数据也并没有问题。但是,但是,在用三个超声波同时测试是,却发现数据显示的总有问题,输出的数据总是毫无规律,且数字都非常大,我们就在想是什么问题。
4 i2 A2 J5 u" e# M
下面是三个超声波控制的代码:

$ j; i6 j& \: I% D) h% A& z
  1. //main.c$ [' X0 o' J& G& X% \
  2. #include "sys.h"
    0 u" f5 n( L, a# k
  3. #include "usart.h"   
    : _8 a  S, R) n# B5 \2 T3 ^
  4. #include "delay.h"  , e  ]3 S4 E% T# X+ D# ^$ g/ p" }: j3 K
  5. #include "led.h"  1 i2 [7 |6 u. w2 K
  6. #include "dianji.h"
    & Q4 F5 y$ T6 g. p8 ]! v* S/ \
  7. #include "hcsr.h"
    ) H! l) A% k# O8 L8 u2 h$ p
  8. u32 DIS_Init(u8 STA,u16 VAL)
    3 k0 F' I& i/ U7 O: a7 Y1 n
  9. {& |8 ]7 `0 k2 N8 L! L1 p" J
  10.     u32 temp;
    0 `: J1 O+ m5 @: q$ l( Z
  11.     u32 lenth;
    * S. y! o3 E2 U5 V
  12.     if((*STA)&0X80)//成功捕获到了一次高电平, c* s8 y5 Z! i" r: k
  13.     {; E: n! R3 C% m; ^& G0 D1 I
  14.         temp=STA&0X3F;
    6 d% E- M8 @. N# q& v2 s
  15.         temp*=65536;               //溢出时间总和
    " s/ |! p( H2 \9 W7 C  A- P
  16.         temp+=VAL; //得到总的高电平时间) _+ D  u( I0 ^6 i% J
  17.         lenth=temp*0.017;           //计算长度
    9 I7 ^% z4 J- z: M" |
  18.         STA=0;     //开启下一次捕获4 Z6 L( q2 u7 G; g
  19.     }4 u$ v1 p* ~1 v9 \6 t: {, i
  20.     return lenth;
    8 ?2 g. P2 Y6 h4 M2 c
  21. }+ b% V' Q, N# `

  22. : K9 Y& P* m8 ~6 a5 F% @. n4 k5 ^/ C
  23. extern u8 TIM2CH2_CAPTURE_STA; //输入捕获状态5 \: R) s' G1 h; J$ ?$ [4 w8 d# ?
  24. extern u16 TIM2CH2_CAPTURE_VAL;  //输入捕获值) q  `' G% g4 w9 j8 O

  25. 1 o- w( k  T" @7 k
  26. extern u8 TIM2CH3_CAPTURE_STA; //输入捕获状态* ^) K* R. n/ j+ b4 O
  27. extern u16 TIM2CH3_CAPTURE_VAL;  //输入捕获值
    - \4 {. ^( D6 e: r3 M. A; K. E! l

  28. ; A) v7 j% F$ ^( W, P, ?
  29. extern u8 TIM2CH4_CAPTURE_STA; //输入捕获状态2 T' m  c; z! V0 I
  30. extern u16 TIM2CH4_CAPTURE_VAL;  //输入捕获值
      |9 b  Y1 }& f5 y! y9 D7 M

  31. ' Z& H# E& m7 z- Y8 {- j
  32. int main(void)
    * k9 y, `; o! X8 \+ t# J
  33. {   
    % \3 t* R4 Y3 U1 W4 P
  34.   u32 temp=0;( v( c% X7 |) O( c) A+ \
  35.   u32 length1;! `2 _  `' ^( X, G; g
  36.   u32 length2;
    3 I4 F4 `' t+ H. f( H
  37.   u32 length3;   
    2 c" P+ k2 d" Y. ~' Q: C6 K/ B
  38.   Stm32_Clock_Init(9); //系统时钟设置! |, d, j$ x: ~) M4 c  s: X# n* u
  39.   delay_init(72);       //延时初始化
    4 ?% F! O. X% z! ]2 \9 z
  40.   uart_init(72,9600);  //串口初始化        //初始化与LED连接的硬件接口$ |7 ]$ F- M% J8 z5 X# A( j
  41.   TIM_PWM1_Init();//10000-1,36-1);//不分频。PWM频率=72M/(0.036M)=2Khz- T- I) h/ u8 M7 W
  42.   Echo1=0;
    8 F3 |# G# j9 i  @: S
  43.   Echo2=0;
    + E( I4 ]' k; p# O# u
  44.   Echo3=0;& m/ A  F* w% j& d: C# n
  45.   HCSR04_Init(0XFFFF,72-1);//以1Mhz的频率计数
    & [1 M' k0 B0 q- Z: Y6 ~) c  \
  46.   /*while(1)
    / c9 D/ R/ l6 Y5 H- y5 W
  47.   {
    / \( m9 G- P2 z# |- A
  48.     % B7 c5 m4 S) _0 x) G; l
  49.   }*/
    * _4 d  B. m, x* a
  50.   while(1)4 G3 U+ H; o0 H& s
  51.   {* P* }- s! Y& Z( N! V' G8 I7 D& K
  52.     Echo3=1;7 `& f; k' P0 B1 g
  53.     delay_us(20);' w- j% y1 R4 u
  54.     Echo3=0;
    ! d0 A" I5 O1 K) G
  55.     length1=DIS_Init(&TIM2CH4_CAPTURE_STA,TIM2CH4_CAPTURE_VAL);
    ; ~3 D0 B5 ]( I% U" z  f. e2 A
  56.     delay_ms(1000);
    3 T3 ]9 A! y8 ?$ A7 Y
  57.     Echo1=1;
    5 N' |9 N  j; t/ c4 N, P# u# s
  58.     delay_us(20);
    : p' a3 d/ C; a
  59.     Echo1=0;! h* i5 X3 l! g* H5 \0 O1 t
  60.     length2=DIS_Init(&TIM2CH2_CAPTURE_STA,TIM2CH2_CAPTURE_VAL);) K4 x+ l  {8 ^: F
  61.     delay_ms(1000);4 I) j- L, W5 X8 G
  62.     Echo2=1;
    : @- ]) z( O' b2 i5 o3 ?& `
  63.     delay_us(20);; K# B$ |( i; V1 `
  64.     Echo2=0;
    . u* S& T9 I# H
  65.     length3=DIS_Init(&TIM2CH3_CAPTURE_STA,TIM2CH3_CAPTURE_VAL);
    % m3 |8 W: {8 Y7 e0 m2 B  R
  66.     printf("%d %d %d\r\n",length1,length2,length3);
    # g/ r# f) m. w5 e- S
  67.   //  GO();
    5 C8 H. Q; n4 {# U( I, X
  68.     delay_ms(500);
    3 L% C  r& d& t  i5 p7 W. n
  69.   }
    ) ]: f" e7 t( e) @0 y$ }
  70. }8 [1 [4 i$ v0 w9 j& P
  71. 7 j% n+ Y4 i' q! }6 l5 i, M. i1 m, z7 e6 n
  72. hcsr.c
    % ]" X1 q3 W* i$ i: x0 v
  73. #include "sys.h"% ?/ d0 ?2 W5 z6 I$ f% D
  74. #include "delay.h"
    / R, L, ?, G; V0 F# _
  75. #include "usart.h"
    - O/ {& I6 j: n  v  }
  76. #include "hcsr.h"
    6 F2 A% t/ a8 X5 z' A  j
  77. void HCSR04_Init(u16 arr,u16 psc). f( x* T+ v0 C( K; @9 b" J
  78. {
    * b. k7 X$ S  P" Q! {
  79.     RCC->APB1ENR|=1<<0;    //TIM2时钟使能
    / b6 A$ M$ }6 K" r% W, S
  80.     RCC->APB2ENR|=1<<2;    //使能PORTA时钟
    - a6 k: ^1 a5 {# p5 F
  81.     RCC->APB2ENR|=1<<3;     //使能PORTB时钟
    0 p, u5 r1 T( ^& u. V) Z  [. @
  82.     GPIOA->CRL&=0XFFFF000F;//PA1 清除之前设置! q) d/ P, H3 d5 N& b( G- G* [6 w: j! q+ O
  83.     GPIOA->CRL|=0X00008880;//PA1输入
    4 I" x/ T' g" @# b
  84. //    GPIOA->ODR|=0<<0;
    / `5 h3 ~0 c" _# b( v6 [
  85.     GPIOA->ODR|=0<<1;      //PA1下拉
    , a7 K# r" `4 K6 ?! \; |7 E6 _$ g
  86.     GPIOA->ODR|=0<<2;/ Q5 `; l& P% j  M5 ^/ D
  87.     GPIOA->ODR|=0<<3;
    2 R0 i6 L5 ~/ @+ K( X* d1 }
  88.   
    : K! u, q* W' j$ h  f" I; L; T
  89.     GPIOB->CRL&=0X000FFFFF;//PB7清除之前设置# t  j" v! L) t
  90.     GPIOB->CRL|=0X33300000;//PB7推挽输出7 z* @% X8 ~% V3 H1 N4 |6 i$ K
  91.     GPIOB->ODR|=1<<7;      //PB7 输出高
    ' ~; }5 F( N) D
  92.     GPIOB->ODR|=1<<6;
    / @2 l* z7 k$ {4 s  g6 `
  93.     GPIOB->ODR|=1<<5;
    6 ^7 T' h* m* W" f! y
  94.   9 w8 c$ k" `% `2 Y
  95.     TIM2->ARR=arr;         //设定计数器自动重装值
    + I4 Z6 {- [: g( O  Y: ?' X% g
  96.     TIM2->PSC=psc;         //预分频器/ L- j0 n" b/ X6 ^- ?
  97.   
    6 L" }/ r0 T! E: {- `' W5 B$ _+ f
  98.     TIM2->CCMR1|=1<<8;     //CC2S=01 选择输入端IC1映射到TI1$ f" W" `1 u8 ~8 h
  99.     TIM2->CCMR1|=1<<12;     //IC2F=0001 配置滤波器 以Fck_int采样,两个事件后有效4 @% Z: }2 @' P& Q. f6 k
  100.     TIM2->CCMR1|=0<<10;    //IC2PS=00 配置输入分频,不分频
    . O+ O. s# V, t
  101.   
    * I) \: N! m! V7 }7 g
  102.     TIM2->CCER|=0<<5;      //CC2P=0 上升沿捕获
    . g& e! Y# _& }* c* }/ N) z$ B* j
  103.     TIM2->CCER|=1<<4;      //CC2E=1 允许捕获计数器的值到捕获寄存器中
    ; P& L, S" ]$ i, ~* r$ M9 j
  104.     ' j/ O. F- a$ t) {# ~& R" A
  105.     TIM2->CCMR2|=1<<0;     //CC2S=01 选择输入端IC1映射到TI17 U+ w$ Z$ k: Q7 t
  106.     TIM2->CCMR2|=1<<4;     //IC2F=0001 配置滤波器 以Fck_int采样,两个事件后有效
    6 l1 b! ?3 K. `; q4 v
  107.     TIM2->CCMR2|=0<<2;    //IC2PS=00 配置输入分频,不分频5 [! K7 R* @, _
  108.   
    " F' T" E7 c" g5 d4 K) k4 Q
  109.     TIM2->CCER|=0<<9;      //CC2P=0 上升沿捕获
    ; B& V6 r& I# ?: B2 a1 X: j
  110.     TIM2->CCER|=1<<8;      //CC2E=1 允许捕获计数器的值到捕获寄存器中
    ( S; K6 E9 u" p/ J/ D5 U6 @  p
  111.    
    5 Z) F" Q" G! P1 S6 n6 o
  112.     TIM2->CCMR2|=1<<8;     //CC2S=01 选择输入端IC1映射到TI1
    + i! t. F& e+ |6 k% I3 S  j, {
  113.     TIM2->CCMR2|=1<<12;     //IC2F=0001 配置滤波器 以Fck_int采样,两个事件后有效
    3 K. L, N* Q9 K! n- b
  114.     TIM2->CCMR2|=0<<10;    //IC2PS=00 配置输入分频,不分频
    ) f# y# f& W% r  Z* ~" j; O% `
  115.   
      l; B) i' |: Y9 n' [, A
  116.     TIM2->CCER|=0<<13;      //CC2P=0 上升沿捕获
    $ K1 r. D) n$ M
  117.     TIM2->CCER|=1<<12;      //CC2E=1 允许捕获计数器的值到捕获寄存器中
    7 f8 `) i1 j2 ]: S& Y: Z
  118.    
    5 y& e6 n8 ^& q. v3 ?0 r. a
  119.     TIM2->DIER|=1<<2;      //允许捕获中断
    3 w+ w" A" z0 k' C5 @& f4 d! @' ?9 z/ Q
  120.     TIM2->DIER|=1<<3;      //允许捕获中断/ @" V# l* G1 T% g# g( A
  121.     TIM2->DIER|=1<<4;      //允许捕获中断
    9 [$ E9 e+ y, v+ e7 h1 |) x
  122.     TIM2->DIER|=1<<0;      //允许更新中断
    1 J0 h0 L" f1 G! U/ M* `5 p
  123.     //TIM2->CR1|=0X01;       //使能定时器2
    4 _) z! j8 M3 M- }' z+ P
  124.     MY_NVIC_Init(2,0,TIM2_IRQn,2);//抢占2,子优先级0,组2
    * j* c1 ]9 Z" f! p  A7 F  j7 c
  125. }
    # T5 }4 v, |) ~; D5 q

  126. * M( o) F3 m3 _
  127. u8 TIM2CH1_CAPTURE_STA=0; //输入捕获状态' ^1 J3 G5 P5 t( O4 w9 d0 D
  128. u16 TIM2CH1_CAPTURE_VAL;  //输入捕获值
      N4 v4 H: z: y0 l+ Q) d
  129. . i2 g% s- T* P+ A# H* }
  130. u8 TIM2CH2_CAPTURE_STA=0; //输入捕获状态
    + b! j# g! Y6 r' J% a. E( ]
  131. u16 TIM2CH2_CAPTURE_VAL;  //输入捕获值
    " n5 F6 {2 a5 a- h# W
  132. " L( I0 B4 {) w- U% _4 U5 b
  133. u8 TIM2CH3_CAPTURE_STA=0; //输入捕获状态' D7 K4 i. f" k5 ?" u) ?( Q0 m, b
  134. u16 TIM2CH3_CAPTURE_VAL;  //输入捕获值
    4 _: }3 }1 [* ^8 @0 K

  135. 2 t! \% \( W% s: J9 I# h9 p8 b
  136. u8 TIM2CH4_CAPTURE_STA=0; //输入捕获状态
    ! W2 Q" {* j( k/ m: e2 L# |
  137. u16 TIM2CH4_CAPTURE_VAL;  //输入捕获值
    - L; V# |5 q* t8 D
  138. ) _1 ~# T$ L& I4 {/ i
  139. //定时器2中断服务程序
    ) t+ K  V4 K  l! R2 k! a# p% r
  140. void TIM2_IRQHandler(void)
    : V3 t. J- a6 Q, g3 E  ~3 C
  141. {
    / r' T& ?! E5 g: @9 s5 Q+ W$ H
  142.     u16 tsr;
    7 L1 z8 S: h' e; Q9 w3 Z
  143.     tsr=TIM2->SR;  t/ A! u" J" J. [* b0 ~
  144.   
    + a- |$ R  h7 v5 l3 o# S, H+ M
  145.     if((TIM2CH4_CAPTURE_STA&0X80)==0)//还未成功捕获
    6 F+ Z8 p. x6 Q
  146.     {
    9 S- O/ ^; E" ~+ V1 n
  147.         if(tsr&0X01)//溢出
    + O1 f4 @' V9 ~% n- N9 r& M/ g) F9 R
  148.         {3 ]0 D1 v+ C, }' m- \2 W) G( s
  149.             if(TIM2CH4_CAPTURE_STA&0X40)//已经捕获到高电平了+ v/ W# g, Y+ @7 D+ G
  150.             {( k/ N# _" s& D- b7 }5 b% m$ n
  151.                 if((TIM2CH4_CAPTURE_STA&0X3F)==0X3F)//高电平太长了  }, J: H: u3 c; k' O6 c1 N
  152.                 {& U; Z# ^* s0 Z
  153.                     TIM2CH4_CAPTURE_STA|=0X80;//标记成功捕获了一次4 ~# K# f6 Y$ K8 D1 |6 a
  154.                     TIM2CH4_CAPTURE_VAL=0XFFFF;( p/ y& u# k. h; H9 |6 [0 V# {
  155.                 }else TIM2CH4_CAPTURE_STA++;4 q1 O7 t, v6 U0 |
  156.             }
    6 s% H$ g- K! P  l! I& W
  157.         }
    " R3 d( v8 r6 Q  Q) M
  158.         if(tsr&0x10)//捕获1发生捕获事件
    7 h; T( ~) o/ n. |; G4 H3 O0 @
  159.         {/ N# B3 k" e# |: c0 R
  160.             if(TIM2CH4_CAPTURE_STA&0X40) //捕获到一个下降沿
    4 o6 z: P2 {) @
  161.             {
    1 z9 B8 i  |1 l; e
  162.                 TIM2CH4_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽5 q. }* U: c+ Z. ]+ x, r5 j
  163.                 TIM2CH4_CAPTURE_VAL=TIM2->CCR4;//获取当前的捕获值" M! f9 n5 n) x
  164.                 TIM2->CCER&=~(1<<13);    //CC1P=0 设置为上升沿捕获+ e5 f0 m; S3 s" V4 J$ N
  165.             }else                       //还未开始,第一次捕获上升沿6 a; V5 J& W/ V7 z% l3 B& `( {. u
  166.             {
    ; \* m7 ]4 d8 H" {6 `! F
  167.                 TIM2CH4_CAPTURE_VAL=0;
    2 q& A# v7 x4 Z- Y( `8 d6 V) H* v
  168.                 TIM2CH4_CAPTURE_STA=0X40; //标记捕获到了上升沿: f# y# T: k" K# X2 ~4 F4 p
  169.                 TIM2->CNT=0;             //计数器清空
    3 U. m2 ^" q- G0 S
  170.           //    TIM2CH4_CAPTURE_VAL=TIM2->CCR4;
    / S* }, E0 ?! a1 m( [  L$ a
  171.                 TIM2->CCER|=1<<13;        //CC1P=1 设置为下降沿捕获
    ! y9 ^9 f+ M- c& W5 E& w& |* e
  172.               TIM2->CR1|=0x01;
    ; S  M/ Z7 \: V2 W8 d- I
  173.             }
    " Z( r0 ~. V) T; n& ]# R
  174.         }. K* T9 C' U. n" _& v2 M- {+ h! T3 T
  175.     }, K+ T* p) a: s4 E
  176.     if((TIM2CH2_CAPTURE_STA&0X80)==0)//还未成功捕获
    ) A: P* w" V& E
  177.     {! D0 c  a2 D6 U; Y+ q1 d: k: Q
  178.         if(tsr&0X01)//溢出
    . U  t" A9 u& T# L1 Q3 P- a' e& v
  179.         {4 z- g! o" j# V6 S" T
  180.             if(TIM2CH2_CAPTURE_STA&0X40)//已经捕获到高电平了
    - C# Z+ _3 g2 y" L5 l5 Q
  181.             {& g4 N" M! G! j& J* ^! P* b9 n' C
  182.                 if((TIM2CH2_CAPTURE_STA&0X3F)==0X3F)//高电平太长了5 S( n( b4 c# _2 d6 F
  183.                 {) h- ?* ?+ }; k9 T+ q
  184.                     TIM2CH2_CAPTURE_STA|=0X80;//标记成功捕获了一次+ ^3 h! C  r5 f+ H& H; _
  185.                     TIM2CH2_CAPTURE_VAL=0XFFFF;, a; B8 b- h, t; m, S4 z. t
  186.                 }else TIM2CH2_CAPTURE_STA++;
    ' G- A4 s: m, U0 n7 ^- Q
  187.             }+ e8 F" C0 b, Y0 d6 B' a: E
  188.         }' b; M: U$ y8 V
  189.         if(tsr&0x04)//捕获1发生捕获事件
    4 _. C2 W! }4 A1 x
  190.         {
    # M- e8 S0 c. |. }3 r+ s% Y  }
  191.             if(TIM2CH2_CAPTURE_STA&0X40) //捕获到一个下降沿" Q4 e3 N: C+ A8 t0 m% S, B
  192.             {1 b0 S! B2 v$ v
  193.                 TIM2CH2_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽/ ?1 N1 T2 m7 {  t7 Q9 v1 g
  194.                 TIM2CH2_CAPTURE_VAL=TIM2->CCR2;//获取当前的捕获值# T) c+ d- Z- R, e6 J$ X" q# S! l9 T
  195.                 TIM2->CCER&=~(1<<5);    //CC1P=0 设置为上升沿捕获2 E- S) N* ^# A( j
  196.             }else                       //还未开始,第一次捕获上升沿0 g  Y! s  e/ t
  197.             {
    5 p" s5 w# Z% m8 j
  198.                 TIM2CH2_CAPTURE_VAL=0;
    1 T& a" N) L: X
  199.                 TIM2CH2_CAPTURE_STA=0X40; //标记捕获到了上升沿+ F/ S5 e1 j6 l5 p8 g4 y) S* \
  200.                 TIM2->CNT=0;             //计数器清空0 {0 r# y/ `7 j) ^1 b2 {
  201.                 TIM2->CCER|=1<<5;        //CC1P=1 设置为下降沿捕获
    . M' w0 ]9 A( C) Q; _( [
  202.               TIM2->CR1|=0x01;8 ^  c, x' h7 z" G) T
  203.             }% ?  W0 Y, O/ {6 L/ X3 k# G
  204.         }. N7 i7 R2 d% g3 [6 R+ |
  205.     }
    $ R. e8 f. D& z% P; o# ]
  206.     % E7 h' r, u; z' R: y& K
  207.     if((TIM2CH3_CAPTURE_STA&0X80)==0)//还未成功捕获4 z& k8 ^+ m2 F3 [/ \) l; L  n" O
  208.     {
    ! J% _; W0 d: W2 `/ n0 X
  209.         if(tsr&0X01)//溢出! M8 U9 a! A. t9 f2 F4 _+ q, N  c
  210.         {# `  [; P$ x. |8 a
  211.             if(TIM2CH3_CAPTURE_STA&0X40)//已经捕获到高电平了, L' g  y5 o* \' O# c  W
  212.             {
    6 M( y7 {. V3 s5 _
  213.                 if((TIM2CH3_CAPTURE_STA&0X3F)==0X3F)//高电平太长了; j& r$ l$ l) c) J5 A2 ?+ j$ k
  214.                 {0 r, ]$ n) K1 X" d' c& [
  215.                     TIM2CH3_CAPTURE_STA|=0X80;//标记成功捕获了一次
    4 P' |1 \' y* r1 i; f* F
  216.                     TIM2CH3_CAPTURE_VAL=0XFFFF;
    ; D  q+ j. L1 u. y5 Y
  217.                 }else TIM2CH3_CAPTURE_STA++;
    $ B+ d2 T3 l* V# R
  218.             }
    9 v; J' ?& F4 }7 ?
  219.         }
    5 R& @" E' N& q4 J9 `% f- C
  220.         if(tsr&0x08)//捕获1发生捕获事件3 i( }, ?6 b# w% l0 ^8 J, a" a' s
  221.         {. m! ~* s) m8 ?2 t4 @0 I
  222.             if(TIM2CH3_CAPTURE_STA&0X40) //捕获到一个下降沿
    6 n* r% R6 e1 y
  223.             {: I8 j! `# d  v2 Y6 r
  224.                 TIM2CH3_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽6 i, U1 W; }6 P' v5 e- x2 ]4 E' G5 M
  225.                 TIM2CH3_CAPTURE_VAL=TIM2->CCR3;//获取当前的捕获值
    1 x) ]% W2 _7 ?- u' _2 u
  226.                 TIM2->CCER&=~(1<<9);    //CC1P=0 设置为上升沿捕获, Y" H/ d: D. O0 @4 z' o6 `
  227.             }else                       //还未开始,第一次捕获上升沿
    8 g: L' i+ \+ \- j& T3 L
  228.             {
    6 O% ?( C7 X6 w' U+ b3 z
  229.                 TIM2CH3_CAPTURE_VAL=0;
    + k- e8 ~+ W9 B' p9 q, h
  230.                 TIM2CH3_CAPTURE_STA=0X40; //标记捕获到了上升沿: g9 @! F) G0 r0 H$ B
  231.                 TIM2->CNT=0;  $ ]& f2 ?1 e1 [1 [+ Y
  232.             //    TIM2CH3_CAPTURE_VAL=TIM2->CCR3;              //计数器清空
    $ H  v3 B7 j2 }2 O3 {
  233.                 TIM2->CCER|=1<<9;        //CC1P=1 设置为下降沿捕获* l4 [$ p# D1 O! A% z5 P
  234.               TIM2->CR1|=0x01;/ {7 V1 H3 Z1 C  l9 Q& @# l, [1 ~
  235.             }- O" V- ^0 O$ u
  236.         }
    : n7 f8 R  }2 a. l; m
  237.   }
    ' z1 I6 Q9 b% s5 E  Y
  238.    
    % k: |9 g$ ]2 M/ a$ O
  239.         
    ; n7 h  P% J  M0 ]
  240.     TIM2->SR=0;//清除中断标志位
    2 h3 @# L% f2 x$ J1 f, C# J& S5 w
  241.     2 }8 q. V! _9 y' F
  242. }
    ( f- R& O+ q5 L
  243. , c$ k) I0 O" q7 \6 C$ Z
  244. hcsr.h$ [7 i' B5 Y9 y. s/ E& @! C* j
  245. #ifndef __HSCR04_H5 Z, E' f; F. y- _2 H9 E
  246. #define __HSCR04_H
    + Y. R5 O$ s& k: D7 c
  247. #include "sys.h"& a/ r3 h+ w- O( M4 {9 V

  248. 4 \+ I/ V7 ~3 X  k+ P" f2 i
  249. #define Echo1 PBout(7) // PB74 ^+ u7 Y( w& S. X' R" F
  250. #define Echo2 PBout(6) // PB7
    ; Z% F5 w4 l8 N
  251. #define Echo3 PBout(5) // PB7& S- Q. W5 B) {0 Y# {! Q
  252. : ]/ u; r8 u" k% k! O* J& A
  253. void HCSR04_Init(u16 arr,u16 psc);4 _& S8 B# g" ]. H5 \
  254. ( k, o+ i$ ?0 g
  255. #endif
复制代码
/ ^% |; _5 T" t( X0 x3 }
最后发现,输入捕获代码中,中断服务函数中,TIM2->CNT不能清零,因为初始化中,用的是同一个定时器的通道2,3,4。如果每一次中断函数的某个通道函数将TIM2->CNT清0,那么其他通道的记录的TIM2->CNT的值就发生变化,从而导致了各种各样的情况。
( b- ~- b$ c" h- K' N! ^( g
问题二就是从串口读取数据,当时挺崩溃的。首先是keil5模板问题,当时串口怎么都显示不出来数据,我们当时都很疑惑。一直反复的看代码,考虑各种情况,但还是显示不出来数据。一开始我们以为是超声波接受的反馈的数据不满足某个条件,所以没有显示。到后面查来查去,又在想是开发板并没有给电压?超声波集体歇B?最终发现,usart.c文件写的串口不是我们接线串口所对应的。当时心态挺炸的,改了之后终于可以测试数据了。
3 W6 A- Z' H4 D
问题三是我们在没接电机驱动之前,超声波接收的数据无论准不准确,最起码能接收到,可是接了电机驱动却发现每次返回的值都是0。我们当时并没有找到原因,又在猜想是不是电机用到的定时器对超声波的定时器有影响?又在想是不是外部电子设备把信号影响了?又在想各种各样的问题?

$ p8 Z+ [  I; _) T. B% K* g- U
最终解决的方法是,串口模块给的电压不够。(我也不知道这样形容的对不对,但感觉就是),为什么这样说呢?

2 m& [5 Z, y& V4 u- A
当时一开始我想的是,超声波的模块在用转串口模块给其供电时,是不是超声波模块的VCC和GND引脚并没有电压,从而导致信号发射不出去。于是我用万用表测试两侧电压,发现是5V没错。又在想是不是发出信号并没有发去,于是我让TRIG引脚一直为1,测试TRIG电压发现为2.6v左右。在此之后,我又用12v的电池降压给开发板供电,发现TRIG电压为3.3V左右。我想验证,是不是电压问题而导致的接收数据为零。所以我想用电池给开发板供电,然后打开串口监视器看数据。但是要想启用串口监视器,必须要用串口给开发板供电。最后我们选用了蓝牙模块,从手机的接收器来观察数据。终于,果然是电压的问题,数据成功出现了!!!(哭了)
, d6 ~9 A+ J- N, d! z* a  O
2.用PWM调控电机速度
这一过程能稍微简单一些,就是一开始还是电压的问题,四个轮子根本带不起来。反复查看代码后并没有太多问题,可是轮子还是不转,但是发现电机嗡嗡响,去掉一个电机后,将速度调大,发现两个轮子缓缓的动了。验证时,我们将轮子速度调小,发现轮子不转,证明了代码并无问题。
9 W' t4 Y) K6 I- T
pwm控制部分代码:
  1. #include "dianji.h"8 ~9 V9 ?$ |) Y! a$ o
  2. #include "sys.h"2 b$ W  t5 s9 {  i: B
  3. #include "delay.h"2 Z) o9 k/ E, C( \( h& `0 }! H# T; w/ M
  4. 0 A, G" L9 Z& M  X
  5. void TIM_PWM1_Init(u16 arr,u16 psc)# A- [" d5 f. q9 Q5 n/ E
  6. {               
    ( }; r2 a9 y$ ]; j
  7.   //此部分需手动修改IO口设置" p8 T( u6 z3 s: |) q+ p, i7 f4 L
  8.   RCC->APB1ENR|=1<<1;   //TIM3时钟使能    6 C- j' [! }$ P' ^
  9.   RCC->APB2ENR|=1<<2;    //GPIOA使能" [: h1 Z# \3 h9 e
  10.   RCC->APB2ENR|=1<<3;   //GPIOB使能
    5 x# ?( {+ J; {7 {
  11.   RCC->APB2ENR|=1<<4;
    ; J5 y& [% F; ?6 X' @/ g& h% q( Q
  12.   GPIOA->CRL&=0X00FFFFFF;  //PA(7)PA(6)做复用,PA(3)是BIN1 PA(4)BIN2 PA(5)STBY
    * Y' a: r( \3 l) o; \  q
  13.   GPIOA->CRL|=0XBB000000;% R( E& M) p# Q
  14.   //GPIOA->ODR|=1<<7;
    % b: e4 ^  n. M- ^
  15.   //GPIOA->ODR|=1<<6;
    ' Z3 I+ [2 w8 v+ K
  16.   GPIOC->CRH&=0X000FFFFF;
    7 w9 p9 Q: ~  s# t5 N" G- h
  17.   GPIOC->CRH|=0X33300000;
      L1 ]0 m7 F1 ]/ g+ T
  18.   GPIOB->CRL&=0XFFFFF000; //PB(0)是AIN1 PB(1)是AIN2
    , s: e; j" \0 U. h3 ~" k/ u5 D  E1 V. Z
  19.   GPIOB->CRL|=0X00000333;
    - [+ ^! f8 O$ P6 B; X4 M/ n9 \
  20.   TIM3->ARR=arr;      //设定计数器3自动重装值
    8 g/ r5 G0 N5 l
  21.   TIM3->PSC=psc;      //预分频器设置
    2 @2 A( B3 N6 b, [8 a0 i3 k$ V
  22.   " O. G4 L5 r* P( {+ x; B
  23.   TIM3->CCMR1|=6<<4;    //CH1 PWM2模式     
    8 Z7 N7 k5 G1 _) L
  24.   TIM3->CCMR1|=1<<3;     //CH1预装载使能   
    ; U( {2 _: J1 r5 x* E
  25.   TIM3->CCMR1|=6<<12;    //CH2 PWM2模式     
    $ j; k% {6 o1 }, J: H0 `$ H4 w
  26.   TIM3->CCMR1|=1<<11;     //CH2预装载使能  
    / R( D0 {0 ]2 _
  27.   
    1 T0 \. r  c- x9 k! v3 w2 {- c
  28.    TIM3->CCER|=1<<0;     //OC1 输出使能' b" {& x$ G( n3 e" {# d2 t( E. |/ x
  29.   TIM3->CCER|=1<<4;     //OC1 输出使能  
    1 v" u0 U" a& S* o0 p
  30. //  TIM3->BDTR|=1<<15;     //MOE 主输出使能     
    - ^' O8 E1 n3 e  O

  31. 2 v# P" R) h5 {( Y( u
  32.   TIM3->CR1=0x0080;     //ARPE使能
    ' P. u. b# ^# j! A' W' _
  33.   TIM3->CR1|=0x01;      //使能定时器3
    % N! D, n  r# b; @/ O4 h$ ?
  34. . S# K; m$ w$ Y* O5 `9 X5 H, ~
  35.   RCC->APB2ENR|=1<<11; //TIM1定时器使能
    3 f- B8 O" n0 e
  36.   GPIOA->CRH&=0XFFFF0FF0;( t  T- K: z  `1 d# K8 B
  37.   GPIOA->CRH|=0X0000B00B;
    $ e6 M3 _: }% [) z6 A( f! i
  38.   //GPIOA->ODR|=1<<8;8 u2 M" @! Y  c
  39.   //GPIOA->ODR|=1<<11;
    $ I  B: |  B  `# c5 D6 A  b
  40.   
    8 }' n' e/ e) R6 q7 }
  41.   GPIOB->CRH&=0X0000FFFF;& \2 P0 i2 K) z/ \! L8 ~: a
  42.   GPIOB->CRH|=0X33330000;' a4 G, V* Y1 y# O9 p" d+ C
  43.   . ?4 v# L3 U+ i6 i0 b8 Y
  44.   TIM1->ARR=arr;      //设定计数器自动重装值
    ( b% p  Y" \. T1 v- ~
  45.   TIM1->PSC=psc;      //预分频器设置
    ' E6 x% }6 d5 J9 N3 \! T7 Q! m
  46.     c/ l' F: u' ~& ?- D
  47.   TIM1->CCMR1|=6<<4;    //CH1 PWM2模式     3 y. I- F- @3 z: i( S3 n4 C7 @! g: a2 d
  48.   TIM1->CCMR1|=1<<3;     //CH1预装载使能   
    1 q' E5 [( t% w& ?5 q
  49.   TIM1->CCMR2|=6<<12;    //CH4 PWM2模式     
    7 }9 Y0 z/ }/ z! r, ^1 B4 _
  50.   TIM1->CCMR2|=1<<11;     //CH4预装载使能  
    7 P$ g  D4 T$ ]' y. u1 |& @6 s
  51.   
    . w0 x, O' U$ |! W' R
  52.   TIM1->CCER|=1<<0;     //OC1 输出使能
    & k* w0 ~8 b& B1 N# T6 E# U
  53.   TIM1->CCER|=1<<12;     //OC4 输出使能  
    * V9 A; Y6 i9 U3 j7 t# Z
  54.   TIM1->BDTR|=1<<15;     //MOE 主输出使能     
    5 a% t( o1 K7 w  j7 `- p1 k7 T+ G

  55. 3 i# R4 _5 V) ~7 T0 W
  56.   TIM1->CR1=0x0080;     //ARPE使能 4 I0 [! a6 m2 n; @7 d9 n& r; h
  57.   TIM1->CR1|=0x01;      //使能定时器1 ) E0 I* G' ]0 E% _% Z
  58.   & f4 ^) |% K1 [+ Q8 [
  59.   STBY=1;3 M$ C7 j; G& y, e7 J
  60.   STBY1=1;
    8 o; E. |% {/ S0 K( I+ u
  61. }8 N  o' P2 d0 C$ F( k! ~) H4 K
  62. & l2 q7 t" p/ L* s. Q$ S( a+ w
  63. void GO(u16 a,u16 b)
    . @4 z1 c# L8 {
  64. {1 b, Y2 I- \+ H2 h
  65.   AIN1=0;     //AIN1,BIN1,AIN2,BIN2控制轮子方向
    ' a) e4 ]- N& U9 ^5 u
  66.   AIN2=1;6 ^7 p4 a! ]! o1 n: D9 j- Q! u
  67.   BIN1=0;9 O) \- H5 \( [$ S- s' f
  68.   BIN2=1;
    8 z! ~  H" H) M5 A2 j! e$ Y
  69.   AIN3=1;
    , V! f" d8 `' l- G+ o
  70.   AIN4=0;
    ' \* ]' a. u6 A
  71.   BIN3=1;
    # d1 A! @) A8 C. Q4 D, U6 B
  72.   BIN4=0;  
    5 |" U* ~1 s% \( Y
  73.   
    * A9 r! c6 g+ j$ D8 d. ~. X
  74.   TIM3->CCR1=a;//右上,控制速度$ s+ H2 Z5 I: G- j* k: @
  75.   TIM3->CCR2=b;//左上( ]0 c* i. M8 B
  76.   TIM1->CCR1=a;//右下
    ' {0 K9 ^$ a" n  s
  77.   TIM1->CCR4=b;//左下6 l& }1 ?- Q# I" o+ K
  78.   //delay_ms(2000);+ ?, l2 c: d3 R1 B  T& m$ I
  79. }
    - D* P# G  l$ Q* T! G' M! E  O0 W
  80. ! k9 a' K. J$ l/ {( I' t; q
  81. void STOP(void)  h) N9 Q1 P- K2 B- Z2 {- }+ ?7 K
  82. {
    - h: g$ ]- X- |" x8 B/ `9 E0 t0 B+ q
  83.   AIN1=0;
    9 x2 u- w8 s4 B3 D+ g
  84.   AIN2=0;
    . S3 x; a& C; A9 o$ W# T
  85.   BIN1=0;
    , ]2 ]! O8 M7 A
  86.   BIN2=0;
    9 h) ~' B* c, `1 t" C3 U
  87.   AIN3=0;
    2 n& J1 u) K7 A1 Y
  88.   AIN4=0;
    7 C- x7 s/ l3 {0 ^7 h$ L
  89.   BIN3=0;6 J* C& M! X' n! u, Q
  90.   BIN4=0;  . N# u9 P$ ~! r( Z
  91. }
    $ j* r: v3 f" T% R
  92. , |" V7 n, g+ h0 @1 ~6 [2 ]
  93. void BACK(u16 a,u16 b)) {  ^7 J. Z& ?  F& j0 u) d  ~. j
  94. {/ f! [) I. e1 n- w+ X: _6 u1 u4 O
  95.   AIN1=1;
    ; G& Y8 ]$ J' \7 f! j, {
  96.   AIN2=0;  ?  `; k* j, l0 @
  97.   BIN1=1;, `7 z. e' }0 E' V) _' c1 G- w1 y
  98.   BIN2=0;* ~# o. k6 N: c) ~5 [4 D
  99.   AIN3=0;
    2 k: `3 X# @1 k
  100.   AIN4=1;9 Y# p3 G) V& B5 I5 D
  101.   BIN3=0;1 _  I7 R& K  u
  102.   BIN4=1;  , Q& N+ D" s0 I4 D  Z
  103.   
    1 b( g( A% b! r4 c: n% T  m0 v/ b
  104.   TIM3->CCR1=a;//右上
    - l# @3 Z: f% ~3 w( T2 z0 n/ N
  105.   TIM3->CCR2=b;//左上& z5 A: |. Q: W( J% S5 q
  106.   TIM1->CCR1=a;//右下
    0 Z- x0 Q8 s$ ?/ G+ k
  107.   TIM1->CCR4=b;//左下
    4 ?# K* L; N. ~0 C' l6 L
  108. //  delay_ms(1000);
    2 b$ P/ r* c7 J! ]3 e9 g; \' Q
  109. }* d' p- J7 K8 z8 a

  110. 9 P1 i) b+ m+ J9 l' n
  111. void RIGHT(u16 a,u16 b): P9 J: X4 i' _6 Y1 n
  112. {$ O! C) A& t; f* d
  113.   AIN1=1;0 X; P+ M3 s% p3 L
  114.   AIN2=0;
    + ^5 y! G( ]+ F% B
  115.   BIN1=0;
    6 s  A+ ]4 [* e1 n; g" S+ _
  116.   BIN2=1;0 [6 @) d" W/ a, G$ k% C
  117.   AIN3=0;: f% h2 T/ C; z$ j4 u" p8 e
  118.   AIN4=1;
      E" v! C, x. P0 h  B- ^
  119.   BIN3=1;
    % ~5 Q6 }( n% G! H
  120.   BIN4=0;  
    3 a7 d7 d! B. h7 W$ x! \( U: k
  121.   & r2 C6 u. d0 n7 Y
  122.   TIM3->CCR1=a;//右上+ ^3 F! t0 m. D
  123.   TIM3->CCR2=b;//左上. ^$ _* {' O  [+ M* Z
  124.   TIM1->CCR1=a;//右下
    1 Y7 `; @; I0 W4 Y7 ?
  125.   TIM1->CCR4=b;//左下: b. Z. V2 X2 D: V. P. y: I
  126. //  delay_ms(1000);5 |6 ?) C* C3 B/ w: Z6 F
  127. }
    6 v2 E/ e6 D9 L( T* M8 Q

  128. , V5 f# o6 V1 m. d
  129. void LEFT(u16 a,u16 b)4 _: `2 ^+ Q: {- O
  130. {
    8 ]9 O# ~/ V0 }# e( c0 h
  131.   AIN1=0;
    + D$ y8 ^. }- L
  132.   AIN2=1;4 P1 j$ f5 \/ L9 O- F% |, x3 p
  133.   BIN1=1;
    8 W; E$ b( r' a5 \- V3 u
  134.   BIN2=0;8 x3 h  b0 }# A4 }6 v" L
  135.   AIN3=1;
    ; q; C) L5 @& t& e
  136.   AIN4=0;
    5 I1 G+ z. @6 B, M9 }) X* i2 H
  137.   BIN3=0;2 t# n, z: i6 m1 U7 o' U
  138.   BIN4=1;  
    ) g+ M3 D( `/ H, K2 g% j* I
  139.   
    3 ~) M. S/ f. c8 C6 Z' J
  140.   TIM3->CCR1=a;//右上
    4 ~' x" p# O- p6 \* e) U8 e$ g. U# N
  141.   TIM3->CCR2=b;//左上4 p- U) p$ Q; t8 {8 U/ a9 r
  142.   TIM1->CCR1=a;//右下1 B: j6 d( a; v- `
  143.   TIM1->CCR4=b;//左下
    & T$ S4 Y' g0 u  z0 M0 ]7 d" ?# t
  144. //  delay_ms(1000);8 m9 t: W0 a! J3 V3 o- c2 {! I$ f
  145. }
复制代码

* g. m" G" l2 ~: N6 w9 e3.蓝牙控制
蓝牙控制这一内容是小伙伴写的,大概内容和串口一章内容相似,就是多做出了判断,即没通过蓝牙输入数据来改变小车此时的模式,在蓝牙控制模式下,也可以相对应用蓝牙控制小车的方向。我们用的仍是串口一来控制蓝牙,为什么这样做?一是方便,二是就如前面所说,电机和超声波的分压严重,在电脑上上的串口监视器得出的数据并不准确,所以还不如用蓝牙来看数据,于是我们直接用了串口一来和蓝牙连接。初始化问题并不需要要修改,直接调用uart()函数即可,在中断控制代码下加入接收数据而触发的各种就好了。

: }. m* w6 w7 P( u+ A
蓝牙控制部分代码:
  1. void USART1_IRQHandler(void)
    ( M. E% s4 G7 {6 Y
  2. {# R! y  q+ d7 {0 a$ S; J8 K' S
  3.   char res;  
    2 D; D# ^6 t/ {: E  g7 f" h
  4.   if(USART1->SR&(1<<5))
    8 z% C8 U' U! ]' t; n: A* z" R
  5.   {   
    ! j  h3 @/ m- P) {, @* t
  6.     res=USART1->DR;/ v: H8 e8 R0 l' ]
  7.     printf("\r\n%d",res);    & j9 I+ r) s" _1 @6 `3 q) _
  8.     if(res==50)                                              //输入2为前进
    7 ]. `9 F/ i0 D8 j) X% S
  9.     {  
    $ x* K$ n  v  `" H8 M. }5 p5 D1 a
  10.       GO(300,300);2 F0 E# G4 H: N1 E( O* w( H
  11.       printf("\r\nGo Stright");: r' p; _* @' L. ?: [& |7 b2 {
  12.     }
    : _2 E! u- X# |& y- X$ c
  13.     else if(res==56)                       //输入8为后退
    8 ?/ }, S8 j* S) G$ _1 |# |$ {5 y
  14.     {9 o; R' U4 j& C* r0 d2 x1 J( s
  15.       BACK(300,300);
    6 q+ n( t1 l% e, U' C& M
  16.       printf("\r\nGo Back");! ^' S/ Z: [7 j9 A8 l5 r8 b  N
  17.     }. i4 D% y6 ~" `2 L) l! O5 R
  18.     else if(res== 52)                //输入4为左转, m; q! W: W% v2 h$ y" C' S: K
  19.     {4 p, I/ U* V! L% y& N
  20.       LEFT(300,300);. [* P! P- u) D, _. W
  21.       printf("\r\nTurn Left");      
    - E9 x5 k, L0 u9 K) H
  22.     }
    - @: G: c6 x2 p9 {9 x
  23.     else if(res==54)                //输入6为右转
    ( l$ n) F8 {. W; @# X
  24.     {
    - v" K8 B* R  J4 k5 F
  25.       RIGHT(300,300);
    5 ?- K2 H  R' a. ]* `
  26.       printf("\r\nTurn Right");& c# N- v6 ]; f  D
  27.     }0 ?+ U4 E$ ?, h1 h' s
  28.     else if(res==53)                //输入5为停止  h6 s0 R1 C1 k7 @/ u# B9 G, Q& T
  29.     {
    & O$ j& S: p1 Y2 l
  30.       STOP();
    $ V5 R: X" E- X" i. j& q6 b
  31.       printf("\r\nStop");
    5 M; X/ R. s5 x" D3 g) c
  32.     }* T; f; S2 ~, u' e6 \' k( u. p7 \6 X, O
  33.     else if(res=='9')                //进入超声波避障模式& D" G" ~6 E; x8 V! k
  34.     {& @7 h& T% R, F; p& F& d+ e; i0 ^
  35.       opq=0;: A# u" g% X4 V# c2 `9 k) D8 e
  36.     }8 [* }' X2 n8 k& a
  37.   }7 Q3 s! e9 P2 f1 K* B
  38. }
复制代码

* K! N; H5 o. b9 n5 z- M9 a
总的来说蓝牙控制这块并没有踩多少坑(大概这不是我写的吧^ _ ^,感谢小伙伴)

" u% f1 j! p- w$ m& W: D4.走矩形
# n- B; M! H3 d$ t; y9 p) ?$ F* t8 s; t. o- ^
走矩形功能也是小伙伴写的,设计思路大致是通过蓝牙输入长和宽,小车通过接受的数据进行矩形运动。在这唯一遇到的问题就是小车的速度问题和转向时间。这个是他们弄得,自我感觉还是很不好调的,因为要考虑电池可供电压,小车行驶的惯性,不同地面的摩擦程度等等。考虑的方面比较多,根据不同的情况可能还要修改小车的速度和转向时间。我们就是在光滑地砖上测得,摩擦力应该是比较小的。- d1 c) u( S; k! f5 Y. H
走矩形代码:
  1. void Juxing()//小车的矩形运动函数0 P9 v- \3 y4 ~7 e0 [
  2. {8 B, y+ @" k" {! h5 |- i
  3.   u8 chang,kuan,x,y;//chang、kuan分别是小车要走矩形的长和宽的值% I0 w' n3 A* N3 Z- n. z/ i5 u% L; t
  4.   delay_ms(200);
    * b3 G( o0 k/ W5 P" Y! J
  5.   printf("Chang:\r\n");! l/ C/ j. X, a
  6.   while(1)% {$ i) T+ @' m
  7.   {9 M6 I; P( V) L1 E. w' u1 B$ T
  8.     printf("Input Chang:\r\n");8 l" ^0 M4 w" k& P6 K/ n
  9.     delay_ms(200);
    * r* a. R2 o) k% \7 B* ~
  10.     if(USART1->SR&(1<<5))//当串口接收到消息后跳出循环
      f2 x& Q& g7 f4 f, Z
  11.     {) a& G8 _( K; D
  12.       chang=USART1->DR-'0';//将字符型的数据转换为整型数据- @; q* g: x4 z. I1 z/ ?# ?+ w1 s
  13.       break;
    : S) e9 f2 D+ F6 p
  14.     }
    $ I% p. H0 n  H6 B
  15.   }
    ; J+ y& J9 s! t( [- F
  16.   printf("长:%d\r\n",chang);//打印串口接收到的数据
    + h! ?/ \4 w+ t  h  ~
  17.   USART1->SR=0;//串口的接收标志位清零,为下一次接收宽度数据做准备
    ' b& y7 J) V5 o' l
  18.   while(1)
    2 b" [/ t" E4 l2 |; o5 _
  19.   {
    2 N" N3 p6 b7 l- v2 \3 ?1 ?
  20.     printf("Input Kuan:\r\n");
    : m: _4 y, ?& P& n9 ]6 u
  21.     delay_ms(200);
    : B% K9 [/ M. n4 [- `1 ]* p$ z$ @
  22.     if(USART1->SR&(1<<5))
    0 i. x5 a% m1 h! T  o
  23.     {. o  n9 [+ Q5 K7 U
  24.       kuan=USART1->DR-'0';//当串口接收到数据后跳出循环( v, L/ [4 d: N) Z  A1 ^+ ]
  25.       break;) s! H" B! f' d$ s  m. g" Q, M
  26.     }
    + o8 }$ a7 Q1 h" K% J. R
  27.   }
    # `$ Z8 r, W. n+ C
  28.   printf("宽:%d\r\n",kuan);//打印宽度数据
    . a; \* M/ Y1 j3 Q
  29.   //当前小车速度为0.25米每秒则小车每走1cm要用40ms所以以1cm为单位每走1cm耗时40ms用for函数驱动小车运动
    + [( P: S( D" [0 H
  30.   for(x=0;x<chang*10;x++)//直走长, h* o5 B# f/ t8 J9 ?! n. N
  31.   {- J% ]: J" j1 z# I6 i' v
  32.     GO(300,300);3 s3 {/ ~0 C1 I! }! p
  33.     delay_ms(40);
    ) v# d* T2 N" l6 t1 S4 J6 M
  34.   }
    ) v; {' H. M" V1 }7 C3 h
  35.   RIGHT(300,300);//右拐7 W0 N* I0 U8 X; a3 Q5 }/ V5 e
  36.   delay_ms(785);# m$ ?, A  }0 Z& Z2 B
  37.   for(y=0;y<kuan*10;y++)//直走宽
    2 C' I  @% J! C0 t6 X! e
  38.   {0 M2 `! c) w: S" U, j+ s3 p
  39.     GO(300,300);8 x7 L& r4 Y; S4 _6 L" o; f! W
  40.     delay_ms(40);
    - Q$ S% J, n% v, F4 P- |2 x: K
  41.   }0 Z7 J' K' ?4 G$ b$ {5 O, L" M
  42.   RIGHT(300,300);//右拐
    : B# r3 q% R# f( o, r5 A1 I
  43.   delay_ms(785);
    + \, l% `/ s: Z) w' C
  44.   for(x=0;x<chang*10;x++)//直走长
    ; S% M% @8 W- n
  45.   {
    , R7 o7 Z7 Z& h* N8 `( i; P. `# W
  46.     GO(300,300);
    2 c" Y" Y$ Y! p* H' b5 V3 |) U) S
  47.     delay_ms(40);6 K; y6 p$ ~5 p% G4 T$ W
  48.   }
    : y4 ]. O8 V" D5 |% E3 }
  49.   RIGHT(300,300);//右拐* t' y" ^" f' C! v  J4 C
  50.   delay_ms(785);
    $ G8 [' j  c( W5 O4 ]0 O$ @$ A
  51.   for(y=0;y<kuan*10;y++)//直走宽
    7 ^0 `8 |- k3 F# @- i( _
  52.   {$ t3 a0 Y1 K' R3 K8 N
  53.     GO(300,300);
    / A4 X) w. f3 I
  54.     delay_ms(40);* A0 r9 O# Q" t2 V. M& H& [1 A  Q9 I
  55.   }+ e9 f" l- b3 S6 H
  56.   RIGHT(300,300);//右拐
    & M' F8 O& ?* R- x2 A7 @
  57.   delay_ms(785);" @' |; R. @4 |. b2 r" h  I
  58.   STOP();5 Z7 K4 E3 k& _0 H! ?' T0 j, z% G/ S
  59.   
复制代码

0 C( [$ t; k6 |) o- Q; q6 ?8 f5 n% y$ b& [: I2 i1 ^* t+ H" M4 p
转载自: 古月居0 i9 k! U  l' @* `/ L  d6 k
赞 收藏 评论0 发布时间:2022-9-3 15:17

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版