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

stm32智能小车设计

[复制链接]
STMCU小助手 发布时间:2022-9-3 15:17
历时两周,总算把小车弄好了,总体上来说做的太慢了。自己在32的学习中还不够仔细深入,只是浅面的学习,当真正做一个项目时,暴露的问题就太多了。这次在小车的制作的过程中,遇到了各种各样的问题,软件,硬件,各式各样的问题迎面而来,真的好几次心态崩了。不过还好小车这个项目不只是我一个人在搞,组里的其他成员也在一直在考虑问题,想办法,不断地解决解决,总归小车终于做好了,下面是小车完成图:
微信图片_20220903151642.jpg
# X' ?7 K; K3 \+ X% w 微信图片_20220903151646.jpg 0 o8 e' A$ ^" y) b
( N- E6 Q! k" u2 [! `' o/ ^* h( v
是有点灵魂接线(·<·)。

- m: P1 B, d. P
! _  `! E4 E* h# B
- \7 F2 A; d0 H- g3 G# g

模块清单


  ^9 @- A, N/ i! p
  • stm32f103C8T6开发板2 g. N% a5 E* ?  P2 r# K
  • 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
    5 \* V2 D$ i3 n$ @

7 n) r  {' e$ t4 T9 C: U! Z; \: n) J5 |6 t% k9 `/ O: P1 B
. q4 ~% P, B; k  V5 X5 P9 n3 l) y% u

完成功能


' I  @9 V6 w7 h  z/ T; T! _
  • 超声波避障
      I" ^* K( f6 ?, w$ v1 Z/ R- y& ~
  • 蓝牙控制
  • 走矩形

    6 O2 W/ @6 ]5 D8 h' k2 k4 _: {

. G3 v5 w1 ]0 Y& Z( c: r7 e: W; ^+ k! m2 i
各个模块就不再介绍了,具体介绍大家可以自行百度或者看一下我的前几篇Arduino智能小车博客,里面有简单的介绍。
$ A  i) y! |& S# T; x, o

3 S: |' a  f! j& b+ A
那么,开始吧。
: u$ [3 q9 d! R3 F# V$ {1 q& W9 n
; V$ X: ~7 M( B4 m9 ^- ?. j0 ~

准备工作


  K' j, F, y: p% R; M0 _2 E. n: l2 `! c
1.首先配置好keil5 c8t6模板(温馨提示:多看看模板的核心驱动,包括sys.h delay.h usart.h等,这些核心文件一定要保证准确无误!)5 }  V# S5 H$ c' z: K% L
2.了解开发板和确保开发板无误
  ]( N6 ?+ ~- ?3.熟悉怎么用转串口模块和st-link将驱动下载到开发板上。

( C4 ?) z+ P- R  p/ Y) w" @9 Z下图示为c8t6开发板的引脚图
3 e) t7 N  Q7 x, T/ P, P$ J
微信图片_20220903151652.jpg 8 I/ G+ f1 t$ n4 Z( X( S0 [

) K, y2 Z9 R3 v9 ]6 Z$ Q! W1.超声波避障功能
: X. T: G. s& r5 k
我们设计的思路如下,用三个超声波来避障。为什么用三个超声波呢?我们想的是如果用舵机的话,小车在行进过程中并不好判断,只能将车停下,舵机转动来检测哪个方向无障碍物,而用3个超声波不仅可以在行进中判断,也可以让小车没有停下的动作,显得整个过程比较流畅。这就是我们使用三个超声波的原因了。
: d; F6 X4 W4 [) o. P! M% ~9 x
我们使用的是定时器二的通道一,通道二,通道三来进行输入捕获的,那么,第一个问题就来了。
8 u/ v8 G! w% h$ e6 ~/ k  \- j
我们在写超声波代码时,用一个超声波先测试,发现超声波测试的并没有问题 ,串口显示的数据也并没有问题。但是,但是,在用三个超声波同时测试是,却发现数据显示的总有问题,输出的数据总是毫无规律,且数字都非常大,我们就在想是什么问题。

" G! V- F2 K6 R( g$ B下面是三个超声波控制的代码:
2 L- \  o, c* z7 d# k* t
  1. //main.c+ o- _* g- {, Y) j
  2. #include "sys.h"+ d; C1 c$ ^- ?# o  e1 _
  3. #include "usart.h"    , M8 k% L0 U3 G5 d; z9 {
  4. #include "delay.h"  
    2 P9 y5 p: K* K& d! b* O
  5. #include "led.h"  
    6 R  T& G7 Y- z' c
  6. #include "dianji.h") l1 Q" ~6 u; n) a( {
  7. #include "hcsr.h"
    + T1 H4 g; T' g
  8. u32 DIS_Init(u8 STA,u16 VAL)
    2 u5 D; H1 L: C' a0 W, z
  9. {( E, U) U# U2 f
  10.     u32 temp;
    , ^0 ~- v1 C7 `! l. d
  11.     u32 lenth;
    # A" [, I# W, f' D; Z
  12.     if((*STA)&0X80)//成功捕获到了一次高电平7 N  i: h: b2 [8 I
  13.     {
    7 j& t0 Z& L8 m# V/ W2 o2 ^6 v
  14.         temp=STA&0X3F;/ y3 v" \9 Z' W( s( C+ s& b
  15.         temp*=65536;               //溢出时间总和9 P* n1 K& z, ~* G( F3 v
  16.         temp+=VAL; //得到总的高电平时间
    6 d: o6 |1 z+ f& W
  17.         lenth=temp*0.017;           //计算长度
    5 A9 V! Y. P7 a# T. p( J: T8 p7 ?
  18.         STA=0;     //开启下一次捕获/ Z9 j0 D  S+ [* R9 T1 f
  19.     }  A$ T+ I6 x9 a; r. v
  20.     return lenth;
    2 q% I# a3 F. O% c+ m# `9 @; B/ a4 o
  21. }
    / S. n; c8 M% O* m8 C
  22. 7 w0 O2 r6 S2 a( C* T
  23. extern u8 TIM2CH2_CAPTURE_STA; //输入捕获状态! O& Z5 N. i; I# r7 z
  24. extern u16 TIM2CH2_CAPTURE_VAL;  //输入捕获值
    * Y$ K5 d5 Y/ j# E6 `. u3 o$ J
  25. & U" v2 Z% G/ G! G0 D7 ?
  26. extern u8 TIM2CH3_CAPTURE_STA; //输入捕获状态
    + a1 `' e2 u  {9 C- q
  27. extern u16 TIM2CH3_CAPTURE_VAL;  //输入捕获值9 D1 i, r/ n9 }/ v% r+ r, V# ?7 T6 T3 z
  28. 0 u9 _  U# N1 z. w* n9 Y
  29. extern u8 TIM2CH4_CAPTURE_STA; //输入捕获状态- w* U4 \7 _- t9 o: H9 J% a
  30. extern u16 TIM2CH4_CAPTURE_VAL;  //输入捕获值6 Z1 w) b4 I$ a0 q& i

  31. + e" V* ~$ }9 d" }8 L. ~
  32. int main(void)3 ]7 T0 Y7 \. \5 p4 _, ?
  33. {    4 I& b% K4 X: j# w# h; O3 x
  34.   u32 temp=0;. H. w9 S0 d4 p3 v  B
  35.   u32 length1;
    - C0 D2 U( v3 k- r7 |% M; r
  36.   u32 length2;+ R1 y+ L. w+ X. Q! ?( q. }) M
  37.   u32 length3;   
    * j, q( [8 A$ Y8 r, B
  38.   Stm32_Clock_Init(9); //系统时钟设置
    ( A, m" e/ \+ _# S
  39.   delay_init(72);       //延时初始化
    9 {1 n  ]0 F) V6 P* k- T) _
  40.   uart_init(72,9600);  //串口初始化        //初始化与LED连接的硬件接口
    ' T7 ?9 j/ ~9 B& H: N! z" V+ R
  41.   TIM_PWM1_Init();//10000-1,36-1);//不分频。PWM频率=72M/(0.036M)=2Khz3 ~/ B/ ]4 O( n0 R
  42.   Echo1=0;
    / |( p; k" |; \& c' I1 h6 h/ [
  43.   Echo2=0;
    0 I  H* ]* T1 V) n( P+ `6 O- r
  44.   Echo3=0;" d8 K2 Q2 D/ I5 G, O0 K2 i
  45.   HCSR04_Init(0XFFFF,72-1);//以1Mhz的频率计数* E$ Z* \$ G' M$ i9 Z6 k& f3 ]
  46.   /*while(1)1 O! b3 a% {; E& X/ f0 ~! E; O
  47.   {4 r; k8 E5 K* ~% L6 M! z3 E, }1 M
  48.    
    * L8 s/ L+ u0 S7 i; k2 q
  49.   }*/, b& {- f2 {2 w8 k5 X
  50.   while(1)
    3 B4 d0 G. x& q+ S$ L- d9 e
  51.   {
    : Y# w4 y5 r) u  Y$ F
  52.     Echo3=1;
    / X1 Z$ O0 I; K" A: ~$ v
  53.     delay_us(20);3 T/ V& u9 `' x# K
  54.     Echo3=0;( C, [- r6 Q6 o) X- J# z% j
  55.     length1=DIS_Init(&TIM2CH4_CAPTURE_STA,TIM2CH4_CAPTURE_VAL);
    4 H) C1 {1 b8 ^
  56.     delay_ms(1000);& D# u9 P+ l% G
  57.     Echo1=1;
    # U/ E5 h7 A( l( z$ Y7 |
  58.     delay_us(20);
    ' I6 P. }0 N1 d8 H
  59.     Echo1=0;$ u3 P+ ]% p+ c! d& W
  60.     length2=DIS_Init(&TIM2CH2_CAPTURE_STA,TIM2CH2_CAPTURE_VAL);8 e3 h7 s* E3 r% P$ l
  61.     delay_ms(1000);
    ' |3 b% n1 H6 ?9 `# @
  62.     Echo2=1;! \- L# d: h, P; L$ O! U
  63.     delay_us(20);5 Q* ~- w5 x3 f, Q9 P$ E1 j* v
  64.     Echo2=0;  ?6 a5 H3 U3 H3 X6 o  E/ u
  65.     length3=DIS_Init(&TIM2CH3_CAPTURE_STA,TIM2CH3_CAPTURE_VAL);% X, t/ r. D5 \9 U
  66.     printf("%d %d %d\r\n",length1,length2,length3);
    ( R2 g5 ~3 y5 f5 G/ m: u/ W) I
  67.   //  GO();
    ) D: R7 o$ n. w6 ^
  68.     delay_ms(500);
    / Q! e7 r7 o* `: f( S
  69.   }6 m4 Y& n& W7 Z) a6 m# u  U
  70. }
    ! [$ _8 _/ H' a- z/ ]. ^" f  k

  71. : P/ H. M; v9 l9 T- y( p
  72. hcsr.c* P% V, Q% @% d: a
  73. #include "sys.h"0 [" b8 n+ k3 X+ {
  74. #include "delay.h", W/ H5 C4 T3 N8 `8 M
  75. #include "usart.h"
    5 W. Y. f) S1 ?% ~
  76. #include "hcsr.h"
    7 i  p# {. R: d- f
  77. void HCSR04_Init(u16 arr,u16 psc)' W- K$ `* P% M) {: _, M8 \
  78. {: h. j4 P6 Z  r3 C2 `
  79.     RCC->APB1ENR|=1<<0;    //TIM2时钟使能0 C8 F- B$ s! d2 }  |& U
  80.     RCC->APB2ENR|=1<<2;    //使能PORTA时钟6 j9 y/ K2 {6 z+ k
  81.     RCC->APB2ENR|=1<<3;     //使能PORTB时钟/ ^- k/ X9 b) Q: `4 G; E) o: i
  82.     GPIOA->CRL&=0XFFFF000F;//PA1 清除之前设置/ ]8 [) q9 o. x" i
  83.     GPIOA->CRL|=0X00008880;//PA1输入# i; }* p: F* z
  84. //    GPIOA->ODR|=0<<0;/ e- d1 a( u( v# x6 o# R% v0 R7 \0 {! S- j
  85.     GPIOA->ODR|=0<<1;      //PA1下拉, ?' q' O9 u$ [3 c, V8 _8 ~5 g) t
  86.     GPIOA->ODR|=0<<2;( P! t8 @0 V( \) v# K( G4 r% ]
  87.     GPIOA->ODR|=0<<3;& J, z$ P0 X- c5 D
  88.   5 ?" u) u+ Y% n3 X/ b7 }
  89.     GPIOB->CRL&=0X000FFFFF;//PB7清除之前设置7 A; D& _! ~4 P) H1 o) U
  90.     GPIOB->CRL|=0X33300000;//PB7推挽输出
    $ A  X* i$ Y$ v& C4 F" h# J  ?8 r% W& N
  91.     GPIOB->ODR|=1<<7;      //PB7 输出高
    ( T+ {) D" X, {2 h: B1 I8 ~
  92.     GPIOB->ODR|=1<<6;" M* r. p) Y* H5 J/ p
  93.     GPIOB->ODR|=1<<5;
    % W& ~7 f7 l) }' V
  94.   
    , Z# h' m2 y0 o5 w
  95.     TIM2->ARR=arr;         //设定计数器自动重装值
    2 o+ e2 `$ R9 ~- l
  96.     TIM2->PSC=psc;         //预分频器
    ! P9 L" v7 j1 y- r, G
  97.   : Y- P6 J& _! V3 B$ }. j9 J) {
  98.     TIM2->CCMR1|=1<<8;     //CC2S=01 选择输入端IC1映射到TI1
    9 ?, i6 R3 E3 k0 Z% z) u: j
  99.     TIM2->CCMR1|=1<<12;     //IC2F=0001 配置滤波器 以Fck_int采样,两个事件后有效
    + S/ f6 y) W! u, G$ ?7 L7 i6 m6 H
  100.     TIM2->CCMR1|=0<<10;    //IC2PS=00 配置输入分频,不分频/ B# p+ E3 m! v+ B& j
  101.   
    : y3 E# u" g! l  e
  102.     TIM2->CCER|=0<<5;      //CC2P=0 上升沿捕获
    * ~2 ~" W" R4 {& W
  103.     TIM2->CCER|=1<<4;      //CC2E=1 允许捕获计数器的值到捕获寄存器中
    ' b3 M* _/ B2 u9 E- c, V/ g0 i
  104.     # v  e  n/ B2 g) \; D2 {; T
  105.     TIM2->CCMR2|=1<<0;     //CC2S=01 选择输入端IC1映射到TI1
      X' Q& A0 s1 c' v
  106.     TIM2->CCMR2|=1<<4;     //IC2F=0001 配置滤波器 以Fck_int采样,两个事件后有效, j( _- i  j& N3 D, t5 b
  107.     TIM2->CCMR2|=0<<2;    //IC2PS=00 配置输入分频,不分频
    + t+ h1 ~3 R# n% W
  108.   ) ?  A. F5 m4 o% Q
  109.     TIM2->CCER|=0<<9;      //CC2P=0 上升沿捕获
    & v& n1 o  L8 Q5 x. c
  110.     TIM2->CCER|=1<<8;      //CC2E=1 允许捕获计数器的值到捕获寄存器中
    ! d3 Z4 C7 r1 f8 g" D
  111.     & s, j8 y- V( i' a5 q. h6 A4 D
  112.     TIM2->CCMR2|=1<<8;     //CC2S=01 选择输入端IC1映射到TI1
    8 d: m9 P' Q, E4 a) b) @; N" Z& l0 o2 f3 X
  113.     TIM2->CCMR2|=1<<12;     //IC2F=0001 配置滤波器 以Fck_int采样,两个事件后有效/ o8 e7 N2 _* f1 m
  114.     TIM2->CCMR2|=0<<10;    //IC2PS=00 配置输入分频,不分频
    , l8 b! `+ T0 |/ J
  115.   + B" m: u8 Y6 j% k
  116.     TIM2->CCER|=0<<13;      //CC2P=0 上升沿捕获
    . J" M5 f% K6 X- ]* d; ~" E
  117.     TIM2->CCER|=1<<12;      //CC2E=1 允许捕获计数器的值到捕获寄存器中0 M$ b" T& p& k$ H, x5 C2 c
  118.     / C% y& T0 w& |1 N9 s; `7 A
  119.     TIM2->DIER|=1<<2;      //允许捕获中断& ]0 R' |: P6 L+ v- Q! }; O
  120.     TIM2->DIER|=1<<3;      //允许捕获中断8 k( N3 g, H. {$ z. C
  121.     TIM2->DIER|=1<<4;      //允许捕获中断$ }: Z9 t- N# V% O. q! q, M
  122.     TIM2->DIER|=1<<0;      //允许更新中断6 i+ `: Y1 @( P7 Q
  123.     //TIM2->CR1|=0X01;       //使能定时器27 {1 H+ b9 K- G( _5 K3 S
  124.     MY_NVIC_Init(2,0,TIM2_IRQn,2);//抢占2,子优先级0,组2$ E- z! [- B4 s+ N) `. K5 a
  125. }
    0 s! M. W' o+ W8 X3 y) X8 W
  126. ; l( f- a1 G9 w. j
  127. u8 TIM2CH1_CAPTURE_STA=0; //输入捕获状态+ W: y7 y3 d9 {9 [/ E7 K$ q+ d
  128. u16 TIM2CH1_CAPTURE_VAL;  //输入捕获值
    7 d+ D$ o( X' h1 N5 e

  129. & R& n+ F% {2 S5 g% i/ J$ Y
  130. u8 TIM2CH2_CAPTURE_STA=0; //输入捕获状态6 ^' j, c- B$ o( J4 @8 z
  131. u16 TIM2CH2_CAPTURE_VAL;  //输入捕获值0 a$ h: c! r! Y5 [5 h) o+ N% v
  132. ! ~7 ]4 b/ m* M% W& E8 N
  133. u8 TIM2CH3_CAPTURE_STA=0; //输入捕获状态
    , p$ `2 O/ v0 u# h
  134. u16 TIM2CH3_CAPTURE_VAL;  //输入捕获值
    # m2 Y6 o. U& b& u, @

  135. % P7 m/ B* u, f
  136. u8 TIM2CH4_CAPTURE_STA=0; //输入捕获状态4 ?! ^: c% _+ ]+ w- L, L  l
  137. u16 TIM2CH4_CAPTURE_VAL;  //输入捕获值, x4 w; ?2 V, `' v* O- T/ D0 M1 B

  138. $ T0 [1 z# k, i5 E( |) n! Q% m
  139. //定时器2中断服务程序: ?9 u7 g9 Z7 B# _
  140. void TIM2_IRQHandler(void)0 ~4 ^$ E; g9 P. q& T+ L% |
  141. {
    . W7 r; o1 R9 G8 L
  142.     u16 tsr;3 @  a2 Z+ t5 ~  Q  w7 a
  143.     tsr=TIM2->SR;, z: U6 k) Y3 `* y9 I" C
  144.   
    / `* e: l3 k- s& r$ X. b
  145.     if((TIM2CH4_CAPTURE_STA&0X80)==0)//还未成功捕获
    4 r  a! F" [- O7 k
  146.     {: ]4 A4 ~) k; B( W8 z  c
  147.         if(tsr&0X01)//溢出0 j% P  B. o5 R  w- X
  148.         {8 A- p* N% x5 G
  149.             if(TIM2CH4_CAPTURE_STA&0X40)//已经捕获到高电平了
    5 s* e2 v" a& ^
  150.             {( Z% o, W7 P8 T# f5 j9 L
  151.                 if((TIM2CH4_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
    6 S" K. v" |% u% z" M
  152.                 {
    8 {8 _, d$ v( y! q7 i+ i, Z
  153.                     TIM2CH4_CAPTURE_STA|=0X80;//标记成功捕获了一次1 y8 ~9 N) c8 |- J- [/ G) [0 n9 F
  154.                     TIM2CH4_CAPTURE_VAL=0XFFFF;! W! Y$ V% r. L
  155.                 }else TIM2CH4_CAPTURE_STA++;
    8 p, w+ }) M! a9 [" e, o
  156.             }* ~3 }1 J1 l% P( g0 [% N5 ?, [
  157.         }
    % Q7 F' A. h9 b/ A2 k9 p1 j  ~
  158.         if(tsr&0x10)//捕获1发生捕获事件
    3 _% S! u  ~5 i+ v) a
  159.         {
    . Q; S, C; Q! O8 d8 N* U  j
  160.             if(TIM2CH4_CAPTURE_STA&0X40) //捕获到一个下降沿
    9 w9 H: c- s+ \  _& H2 B, p1 P# f/ ?# T
  161.             {& r" g0 V1 J4 ?8 ]2 S
  162.                 TIM2CH4_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽
    $ s; O0 O* `4 u& Y# `' t
  163.                 TIM2CH4_CAPTURE_VAL=TIM2->CCR4;//获取当前的捕获值
    ' P% ~" i8 ?# w
  164.                 TIM2->CCER&=~(1<<13);    //CC1P=0 设置为上升沿捕获
    , o3 J$ V8 ~% h  n/ e4 P
  165.             }else                       //还未开始,第一次捕获上升沿
    7 A$ p5 Y$ n! |; O
  166.             {
    : ]- a( x7 p8 f2 w
  167.                 TIM2CH4_CAPTURE_VAL=0;
    , d) m3 ~- j7 g2 n
  168.                 TIM2CH4_CAPTURE_STA=0X40; //标记捕获到了上升沿
    - I/ n! K8 C9 [5 I
  169.                 TIM2->CNT=0;             //计数器清空' Z  X6 d7 a% c7 j
  170.           //    TIM2CH4_CAPTURE_VAL=TIM2->CCR4;% ~. k# T3 W/ \$ P3 {! H/ a5 a0 A
  171.                 TIM2->CCER|=1<<13;        //CC1P=1 设置为下降沿捕获
    . t* |  E3 E: m& A6 h8 q3 v
  172.               TIM2->CR1|=0x01;$ d* V3 q1 s! E. m2 J* ?; c3 h% }
  173.             }0 M/ l6 S7 v4 Q% h
  174.         }9 a, M" q) E- U2 ]9 J. x3 H
  175.     }, |$ ^/ w( g6 [1 Y  Y6 X$ y( K* t! R
  176.     if((TIM2CH2_CAPTURE_STA&0X80)==0)//还未成功捕获
    3 \1 y9 G4 p& n2 k( J
  177.     {/ v  \$ e/ A. L: c' D
  178.         if(tsr&0X01)//溢出1 b, s2 \* \( g
  179.         {* z4 t* J6 g: t8 d$ K* `1 n& D' K
  180.             if(TIM2CH2_CAPTURE_STA&0X40)//已经捕获到高电平了4 a- @3 n- g. X1 W' H. E' r" ~
  181.             {; p2 o5 |& I& k* G3 _+ P8 ]9 S3 f( p
  182.                 if((TIM2CH2_CAPTURE_STA&0X3F)==0X3F)//高电平太长了/ X% |& `& D4 `, S
  183.                 {
    # y0 R4 {. ]6 {. e
  184.                     TIM2CH2_CAPTURE_STA|=0X80;//标记成功捕获了一次
    2 J; V8 N" A; z, V
  185.                     TIM2CH2_CAPTURE_VAL=0XFFFF;
    & W8 `2 s+ X" d5 z- I
  186.                 }else TIM2CH2_CAPTURE_STA++;
    ( |5 T5 \3 z8 r2 B# f9 P
  187.             }
    " D' v! f9 `# Y/ G. r. Z
  188.         }
    3 A5 x2 I% x$ e
  189.         if(tsr&0x04)//捕获1发生捕获事件
    ; V2 I7 E' x8 t) S. p) A: b: m
  190.         {
    - \6 P. H3 [# }
  191.             if(TIM2CH2_CAPTURE_STA&0X40) //捕获到一个下降沿  @+ p# G  R9 T
  192.             {
    7 `* t. g! _3 d1 N
  193.                 TIM2CH2_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽
    % s0 j6 V1 h3 w8 W0 r: d+ e4 ?( b" ~: U
  194.                 TIM2CH2_CAPTURE_VAL=TIM2->CCR2;//获取当前的捕获值# \8 Z8 d* p7 x: }; A# Y' s+ u- L
  195.                 TIM2->CCER&=~(1<<5);    //CC1P=0 设置为上升沿捕获
    $ b. F0 u$ O( ^2 Q# i2 |& y8 ?1 k
  196.             }else                       //还未开始,第一次捕获上升沿
    / O- j  l; x. j" e; B% G) c* S+ _
  197.             {
    : Z- V/ v5 U, l! g. Q. p# p* T
  198.                 TIM2CH2_CAPTURE_VAL=0;
    $ Q1 ~+ j; p: e" U( d
  199.                 TIM2CH2_CAPTURE_STA=0X40; //标记捕获到了上升沿* H( h1 F+ q7 k
  200.                 TIM2->CNT=0;             //计数器清空
    6 ^& C5 i2 q$ ~! B* s5 J9 ?7 k. N6 V
  201.                 TIM2->CCER|=1<<5;        //CC1P=1 设置为下降沿捕获8 U3 B; t) O* G5 a* ^
  202.               TIM2->CR1|=0x01;
    $ N7 e8 N1 F: x! r
  203.             }$ w1 k2 s$ m8 \# d: m& L
  204.         }- K: ?0 [8 v  [. B5 u
  205.     }
    + |4 F, n, i' {7 |+ z
  206.     . E) L7 a. \5 ]! V- w
  207.     if((TIM2CH3_CAPTURE_STA&0X80)==0)//还未成功捕获
    , A3 b) b8 ~) K0 g1 t
  208.     {2 L5 g% c/ ~; D/ @
  209.         if(tsr&0X01)//溢出2 ?8 X0 o: ?6 ?' a
  210.         {
    & y. s/ Z8 _" F0 W* ~( I* z
  211.             if(TIM2CH3_CAPTURE_STA&0X40)//已经捕获到高电平了
      }: {; c) }( s6 r7 l" j- p
  212.             {
    9 o) M) c. q2 h* [7 F
  213.                 if((TIM2CH3_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
    " v' F0 }" V, N: `+ Z
  214.                 {" W9 r7 z; i; U0 u
  215.                     TIM2CH3_CAPTURE_STA|=0X80;//标记成功捕获了一次3 q9 }& W1 s# b# W( l
  216.                     TIM2CH3_CAPTURE_VAL=0XFFFF;
    ' d, Q! J+ v! B0 J/ }6 O
  217.                 }else TIM2CH3_CAPTURE_STA++;
    % G0 Y( J4 z6 C  p1 |$ ]5 h
  218.             }" M' g" j( i9 G
  219.         }
    8 I2 f7 W7 T- \8 Q' \, C  W5 B) [
  220.         if(tsr&0x08)//捕获1发生捕获事件
    " B# w5 ]- l. h, [! `( T2 b
  221.         {
    ; `  E8 g5 n4 s4 v7 s2 J, j
  222.             if(TIM2CH3_CAPTURE_STA&0X40) //捕获到一个下降沿* p+ c4 O  Y: u. F+ h
  223.             {
    $ ^) B; R/ F3 Q' k
  224.                 TIM2CH3_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽2 ]" s5 C" m% A+ j$ G3 _& I
  225.                 TIM2CH3_CAPTURE_VAL=TIM2->CCR3;//获取当前的捕获值  |( m. X2 e! C2 \" a
  226.                 TIM2->CCER&=~(1<<9);    //CC1P=0 设置为上升沿捕获. w) V! ^+ x( P5 x* p/ f
  227.             }else                       //还未开始,第一次捕获上升沿8 w9 v$ o  X1 D( h* O
  228.             {1 C& z* e) b* E& W1 U% z
  229.                 TIM2CH3_CAPTURE_VAL=0;4 k: D$ ~7 s1 z
  230.                 TIM2CH3_CAPTURE_STA=0X40; //标记捕获到了上升沿" p2 J; u; L' P
  231.                 TIM2->CNT=0;  $ ?, _2 }& b, u  h( ?$ v( H
  232.             //    TIM2CH3_CAPTURE_VAL=TIM2->CCR3;              //计数器清空/ e' J, Q2 |8 D4 b' H
  233.                 TIM2->CCER|=1<<9;        //CC1P=1 设置为下降沿捕获% h. p0 k: [6 m, I2 S% e
  234.               TIM2->CR1|=0x01;/ Y% _' l# P! [
  235.             }
    - [7 H. s" Q6 k2 \+ q
  236.         }
    8 ^0 v; m+ P) H7 @" y4 x- \9 X
  237.   }+ t4 F/ N6 o9 L0 t+ G
  238.     & W, p- f( ^! e
  239.         
    $ U& T9 }+ ]% F! ]: w0 j
  240.     TIM2->SR=0;//清除中断标志位
    * g; s& O" e0 w
  241.    
    0 ^( ^0 w' u$ z1 K: H
  242. }/ A& }$ {( f/ A9 d- e' |

  243. - T' b  z& i7 w0 v! r- |
  244. hcsr.h7 u8 T1 N- K& v- v  y8 a5 B$ |
  245. #ifndef __HSCR04_H, o7 n, K4 |+ e! N5 g; P
  246. #define __HSCR04_H: ~" I: f+ w( g! [2 H4 v
  247. #include "sys.h"
    0 h& l! a, H% a

  248. 0 C6 _6 ^- A( V, T& V, U
  249. #define Echo1 PBout(7) // PB7! [$ C3 C" A! E9 V. y5 n' H
  250. #define Echo2 PBout(6) // PB7
    & F- v* N. W! R! T! {9 }. q
  251. #define Echo3 PBout(5) // PB7& c2 I# p7 y4 e6 n4 x5 L3 d

  252. 6 y4 U3 l  @) D& B$ c
  253. void HCSR04_Init(u16 arr,u16 psc);4 _4 k- h9 ?6 m; ~5 x2 i
  254. 6 C. K8 `& j/ F& _  E0 J
  255. #endif
复制代码

- C  p; u( U8 R4 _* \
最后发现,输入捕获代码中,中断服务函数中,TIM2->CNT不能清零,因为初始化中,用的是同一个定时器的通道2,3,4。如果每一次中断函数的某个通道函数将TIM2->CNT清0,那么其他通道的记录的TIM2->CNT的值就发生变化,从而导致了各种各样的情况。
' ^" B% W& E0 J6 C' ?4 j0 N) _
问题二就是从串口读取数据,当时挺崩溃的。首先是keil5模板问题,当时串口怎么都显示不出来数据,我们当时都很疑惑。一直反复的看代码,考虑各种情况,但还是显示不出来数据。一开始我们以为是超声波接受的反馈的数据不满足某个条件,所以没有显示。到后面查来查去,又在想是开发板并没有给电压?超声波集体歇B?最终发现,usart.c文件写的串口不是我们接线串口所对应的。当时心态挺炸的,改了之后终于可以测试数据了。
8 d' h' U- y7 C/ U; u6 \
问题三是我们在没接电机驱动之前,超声波接收的数据无论准不准确,最起码能接收到,可是接了电机驱动却发现每次返回的值都是0。我们当时并没有找到原因,又在猜想是不是电机用到的定时器对超声波的定时器有影响?又在想是不是外部电子设备把信号影响了?又在想各种各样的问题?
' u/ i4 Q. b; n/ P/ |
最终解决的方法是,串口模块给的电压不够。(我也不知道这样形容的对不对,但感觉就是),为什么这样说呢?

, Z" S9 p* V1 E
当时一开始我想的是,超声波的模块在用转串口模块给其供电时,是不是超声波模块的VCC和GND引脚并没有电压,从而导致信号发射不出去。于是我用万用表测试两侧电压,发现是5V没错。又在想是不是发出信号并没有发去,于是我让TRIG引脚一直为1,测试TRIG电压发现为2.6v左右。在此之后,我又用12v的电池降压给开发板供电,发现TRIG电压为3.3V左右。我想验证,是不是电压问题而导致的接收数据为零。所以我想用电池给开发板供电,然后打开串口监视器看数据。但是要想启用串口监视器,必须要用串口给开发板供电。最后我们选用了蓝牙模块,从手机的接收器来观察数据。终于,果然是电压的问题,数据成功出现了!!!(哭了)

" I' L' K9 K- N* j2.用PWM调控电机速度
这一过程能稍微简单一些,就是一开始还是电压的问题,四个轮子根本带不起来。反复查看代码后并没有太多问题,可是轮子还是不转,但是发现电机嗡嗡响,去掉一个电机后,将速度调大,发现两个轮子缓缓的动了。验证时,我们将轮子速度调小,发现轮子不转,证明了代码并无问题。
* x/ o9 S$ e! o: ?+ o5 }: x
pwm控制部分代码:
  1. #include "dianji.h"
    ; h' n. d7 w1 l% j
  2. #include "sys.h"- d$ x/ q) Z6 B' o  d" J" U# X9 e
  3. #include "delay.h"
    . T- y) r$ X8 \4 H( B: h

  4. & P. U5 k: x2 D; G, [* U3 J# `7 q
  5. void TIM_PWM1_Init(u16 arr,u16 psc), q0 l/ z; [2 ^" M, P
  6. {               
    ; `" [5 L+ d$ K+ h7 U9 s
  7.   //此部分需手动修改IO口设置5 G) @6 ~6 y( ^: Q/ f6 n
  8.   RCC->APB1ENR|=1<<1;   //TIM3时钟使能    ) R$ Y' U+ r% g! ^$ ^
  9.   RCC->APB2ENR|=1<<2;    //GPIOA使能* ^2 b( l! }1 G. V9 F0 X" i
  10.   RCC->APB2ENR|=1<<3;   //GPIOB使能' e. J- N5 _$ N8 f1 M( d
  11.   RCC->APB2ENR|=1<<4;
    ! z5 \: f6 R0 E' z& L% J$ a
  12.   GPIOA->CRL&=0X00FFFFFF;  //PA(7)PA(6)做复用,PA(3)是BIN1 PA(4)BIN2 PA(5)STBY
    ! N3 Z+ y4 U& N9 p
  13.   GPIOA->CRL|=0XBB000000;
    / w! \8 {5 x) p$ w4 _- I4 Y
  14.   //GPIOA->ODR|=1<<7;* D& x3 i) j/ R8 ?" _
  15.   //GPIOA->ODR|=1<<6;0 A; c/ d) |% f% O1 z
  16.   GPIOC->CRH&=0X000FFFFF;
    $ q3 z0 E6 t5 X
  17.   GPIOC->CRH|=0X33300000;
    * a2 h* `% I; v+ r3 o( L3 H8 F
  18.   GPIOB->CRL&=0XFFFFF000; //PB(0)是AIN1 PB(1)是AIN20 g2 }6 L4 Z7 j. l8 K# g
  19.   GPIOB->CRL|=0X00000333;
    # S0 d- }% z, m* H. y
  20.   TIM3->ARR=arr;      //设定计数器3自动重装值
    , ^: G% t2 A# D8 i0 a% A
  21.   TIM3->PSC=psc;      //预分频器设置$ f% Z) h# h' {' I/ M
  22.   " P( r3 U9 d1 @4 `+ \( H
  23.   TIM3->CCMR1|=6<<4;    //CH1 PWM2模式     % f. c2 z* H$ n6 \
  24.   TIM3->CCMR1|=1<<3;     //CH1预装载使能   8 Q2 Z7 ~* R" S, K
  25.   TIM3->CCMR1|=6<<12;    //CH2 PWM2模式     
    0 `/ `7 K+ P0 K) }
  26.   TIM3->CCMR1|=1<<11;     //CH2预装载使能  ( }  t( L0 s% A+ [( |, c
  27.   
    4 R" ^3 C  C+ w* u# l# K
  28.    TIM3->CCER|=1<<0;     //OC1 输出使能2 n" q. T6 P/ W9 _2 T7 b. r+ m) B$ g
  29.   TIM3->CCER|=1<<4;     //OC1 输出使能  
    3 ~7 o- H+ i' w( ^$ G2 C- Y+ L
  30. //  TIM3->BDTR|=1<<15;     //MOE 主输出使能       ^  f- O7 B4 f1 u  G6 A

  31. 3 Z1 q2 J! q# o" C% X3 s* e# z
  32.   TIM3->CR1=0x0080;     //ARPE使能 , h7 y! c* l3 h) _6 v
  33.   TIM3->CR1|=0x01;      //使能定时器3 0 l. K: o9 \6 W7 d: j( l2 z

  34. ) N& l6 I6 h" A$ _* z8 V, ]
  35.   RCC->APB2ENR|=1<<11; //TIM1定时器使能
    ! H* k$ W/ l9 p, V# C
  36.   GPIOA->CRH&=0XFFFF0FF0;+ [  Y( Y; e6 c! x, m
  37.   GPIOA->CRH|=0X0000B00B;
    ; H2 u; D/ c" |4 D9 Z* y8 f/ s
  38.   //GPIOA->ODR|=1<<8;3 X: I( z- S& M- P9 s1 \& ^
  39.   //GPIOA->ODR|=1<<11;
    ) @# P2 A% r) g# e1 k' L, z
  40.   
    " q; c/ k1 O5 u) ^. y: Y0 S
  41.   GPIOB->CRH&=0X0000FFFF;
    % z7 i6 I' N  @- F) h, u: X& e
  42.   GPIOB->CRH|=0X33330000;
    ( L6 h6 {0 V2 t2 r) B0 n
  43.   
    " O1 U6 E) b% B1 p( q
  44.   TIM1->ARR=arr;      //设定计数器自动重装值 2 }5 C9 q- I' r7 Y5 U- x
  45.   TIM1->PSC=psc;      //预分频器设置% t, r4 {# A, C# G+ J
  46.   ) F! Y* \; q1 M! N3 E
  47.   TIM1->CCMR1|=6<<4;    //CH1 PWM2模式     ; _, X) |% G6 V) t' _* N" V
  48.   TIM1->CCMR1|=1<<3;     //CH1预装载使能   , }- l$ T6 V' i2 e1 H  `/ i
  49.   TIM1->CCMR2|=6<<12;    //CH4 PWM2模式     
    ' }' f2 I7 l& L+ i8 Y0 {0 A, X1 l
  50.   TIM1->CCMR2|=1<<11;     //CH4预装载使能  ! f; X3 e) Y5 o' i0 }1 f% k" `
  51.   
    4 y! v' i* m* a; c* q& n
  52.   TIM1->CCER|=1<<0;     //OC1 输出使能
    2 _. L- i9 g8 p2 H1 j
  53.   TIM1->CCER|=1<<12;     //OC4 输出使能  0 Z: D, f3 h" F
  54.   TIM1->BDTR|=1<<15;     //MOE 主输出使能     
    ; u* c* h8 J: {  w6 `

  55. 3 }1 b/ d  f' \: a; _5 ~# \3 z" Y3 t
  56.   TIM1->CR1=0x0080;     //ARPE使能 : n2 k$ [) ]/ }- U/ e
  57.   TIM1->CR1|=0x01;      //使能定时器1 % b0 ]& D7 |+ U
  58.   ' r7 I* Q6 j% O
  59.   STBY=1;
    0 u( V5 W5 S) P0 p" u
  60.   STBY1=1;) [* ?! h/ a) M( [" ]4 d. _
  61. }
    ( Q% T+ B# `* _
  62. " O4 p1 _8 B6 Z) ^. F3 z. T
  63. void GO(u16 a,u16 b)
    + v/ h3 q+ C8 ]' K( \; U
  64. {* G2 a- K  H7 }
  65.   AIN1=0;     //AIN1,BIN1,AIN2,BIN2控制轮子方向
    ; u4 \- a- `) p! U$ s6 t
  66.   AIN2=1;0 m1 }( H) y  r# c
  67.   BIN1=0;6 S# z7 ]' H* l9 ^% w
  68.   BIN2=1;
    ) ~. r9 k* E2 C* ?% s
  69.   AIN3=1;
    6 p0 T7 M/ z0 A, l
  70.   AIN4=0;( M3 m2 `5 Z0 y
  71.   BIN3=1;9 V- F: l8 m* V5 _
  72.   BIN4=0;  
    8 |' z) k0 _( H: `8 [9 R
  73.   
    2 A; k. W0 F& M! P" B) [/ }
  74.   TIM3->CCR1=a;//右上,控制速度
    / X4 b! `8 ~  U: Q" l
  75.   TIM3->CCR2=b;//左上
      e$ l( h& G* k6 N( k1 C* |
  76.   TIM1->CCR1=a;//右下4 g0 s# e! U: ~
  77.   TIM1->CCR4=b;//左下# b3 Z8 x  R# g/ S1 V- l
  78.   //delay_ms(2000);5 V  X' t& a- G5 C0 H% O4 a
  79. }0 D. X( b! V4 ~

  80. * d* T% K! f2 u1 O
  81. void STOP(void)
    " X9 k; v5 y1 v4 N
  82. {
    ' q9 ^" H0 g. Z( T+ E: z( E
  83.   AIN1=0;9 j' n: S' L: N  ~, _5 h# J
  84.   AIN2=0;+ g6 t% G+ R7 f2 Z  c' _
  85.   BIN1=0;8 _" u- ~% M) u" ^) U0 g, ]
  86.   BIN2=0;! t2 T5 L8 C1 \( u- Z, O5 @
  87.   AIN3=0;
    * d- N7 d  J, Y. l& ^9 |  p
  88.   AIN4=0;
    & N# G0 m; S, g( h4 |
  89.   BIN3=0;7 @( M, T* D; l# c- H1 d* Z, R# z* Z
  90.   BIN4=0;  ; K( T2 j  j: E. q
  91. }( W" x8 }1 c2 u: E# J7 b
  92.   M& [/ |4 u, S* A* m7 Q: m+ j3 y1 N9 f
  93. void BACK(u16 a,u16 b)
    * V" L" ?4 |6 v# Y: C6 A6 I4 d1 V
  94. {+ l. f" {0 g' f. I# Y0 y
  95.   AIN1=1;0 b5 G, H5 l5 ^
  96.   AIN2=0;+ u. q" k% p+ i" T& d
  97.   BIN1=1;- V$ @, H/ {/ ^7 P
  98.   BIN2=0;
    . H9 L- h/ q5 _' z: W
  99.   AIN3=0;
    8 X. m! k6 u# S* I. h3 x" [
  100.   AIN4=1;3 B- a. {2 s! K
  101.   BIN3=0;0 o. C& l$ B. x0 L1 O6 ~+ K% @
  102.   BIN4=1;  ' R$ h# ?0 g2 i5 R$ r5 T2 R
  103.   2 U# n' e" {1 T- X) \# u
  104.   TIM3->CCR1=a;//右上
    ; n& b  k3 G6 u! N, H
  105.   TIM3->CCR2=b;//左上1 ^) t8 K- @# I3 d+ Q$ q$ O! k+ O5 ~
  106.   TIM1->CCR1=a;//右下; R+ B$ i& b3 U' T
  107.   TIM1->CCR4=b;//左下9 V, l: {0 q# {% k) D' B
  108. //  delay_ms(1000);& ?" n& R2 C. e" w; O9 R9 ^# R) A
  109. }% C; ~/ y: y+ ^  V, f% S6 M
  110. ' X. x2 x( U. K$ [6 |9 C% Y
  111. void RIGHT(u16 a,u16 b)
    & [3 a0 h6 w. G5 r
  112. {
    6 A; m; F5 d; d" W- L9 G
  113.   AIN1=1;. q" Q' X, b/ o7 ]; t, W
  114.   AIN2=0;
    ( Y" G  U# b: B; g
  115.   BIN1=0;7 _- S' P8 e" {
  116.   BIN2=1;
    8 [$ o6 a4 i: h1 M
  117.   AIN3=0;
    6 N/ q* J  S0 {2 `& ~
  118.   AIN4=1;9 q( D8 v2 |$ A' L/ f- g0 C
  119.   BIN3=1;. h4 V: L% L2 }; z3 a5 T- x
  120.   BIN4=0;  6 {% d5 [6 b4 U! Z' ~
  121.   & h! H& z. T$ ^& t0 i! a2 p! Z* X
  122.   TIM3->CCR1=a;//右上% [+ Q8 ?: S. S5 p, A- M
  123.   TIM3->CCR2=b;//左上1 ~6 G8 m7 f, I0 u4 t: p
  124.   TIM1->CCR1=a;//右下
    3 t$ f, {2 v% ^# n& t
  125.   TIM1->CCR4=b;//左下/ q# X( G% o& O' m) N' |
  126. //  delay_ms(1000);
    % b4 @+ c! s' c" l7 f) d( Q4 N
  127. }9 I6 o! L9 z. M/ ?/ K& h4 ~
  128. ( C0 A8 C; \7 @2 M' ~
  129. void LEFT(u16 a,u16 b)4 @; l- q! ~& q/ l. n
  130. {
    3 M# S! i* ]  V3 E  v7 B1 A
  131.   AIN1=0;
    . D% i* V; V2 d5 E+ K2 r
  132.   AIN2=1;
    , {; ?* _! }2 h& U) [. J+ V$ W
  133.   BIN1=1;
    % h1 _' k1 o' L* r$ R* C/ |5 E8 H
  134.   BIN2=0;
    1 L, Y6 O! h+ J5 S+ G% C; u
  135.   AIN3=1;
    , ?6 }( S' [! o& \* u
  136.   AIN4=0;3 N5 A+ t3 e' p5 X& x  e" c8 Z1 H: K% q
  137.   BIN3=0;0 G# W. U/ T( I7 i* h) J) ~
  138.   BIN4=1;  : a. Y: \$ h* F- S
  139.   0 b2 A# u6 K! A3 c: L
  140.   TIM3->CCR1=a;//右上
    * q0 Q* M; T/ m. V2 O  `8 p+ h3 U
  141.   TIM3->CCR2=b;//左上9 K% v7 s, w  f3 r+ B/ N. _
  142.   TIM1->CCR1=a;//右下% T8 W  K& J- i8 m8 t5 n
  143.   TIM1->CCR4=b;//左下
    0 c1 h8 \4 @  w2 q
  144. //  delay_ms(1000);( [$ \" m3 p3 W
  145. }
复制代码
1 M# B+ U9 k2 n! x5 K2 ^
3.蓝牙控制
蓝牙控制这一内容是小伙伴写的,大概内容和串口一章内容相似,就是多做出了判断,即没通过蓝牙输入数据来改变小车此时的模式,在蓝牙控制模式下,也可以相对应用蓝牙控制小车的方向。我们用的仍是串口一来控制蓝牙,为什么这样做?一是方便,二是就如前面所说,电机和超声波的分压严重,在电脑上上的串口监视器得出的数据并不准确,所以还不如用蓝牙来看数据,于是我们直接用了串口一来和蓝牙连接。初始化问题并不需要要修改,直接调用uart()函数即可,在中断控制代码下加入接收数据而触发的各种就好了。

. @. l* h9 z3 S" @( t
蓝牙控制部分代码:
  1. void USART1_IRQHandler(void)( F, D# n* ~3 r+ U# [- W! |
  2. {
    ' O7 j2 i: A5 e( F* W% w0 j. n+ E
  3.   char res;  * b" o+ n6 e" V; V4 P* b
  4.   if(USART1->SR&(1<<5)). O: s. `4 [0 p2 ]) }* n: F
  5.   {    3 }+ X; g% m! v4 w
  6.     res=USART1->DR;
    * j4 F1 A* N! F; A7 @
  7.     printf("\r\n%d",res);   
    & q+ v4 p, c3 M0 W! `" `% |
  8.     if(res==50)                                              //输入2为前进+ ]' Y6 K" I" s1 n, H
  9.     {  
    ) G& F. A# r5 x7 Y2 a
  10.       GO(300,300);' L7 h6 {  M) x- ~- h. I
  11.       printf("\r\nGo Stright");
    * t2 W9 |  d/ b9 u: z3 Z1 [
  12.     }7 h7 M% a; `% H" A, V/ `
  13.     else if(res==56)                       //输入8为后退2 X. D1 S+ V& h: N
  14.     {
    & u; M2 `/ [6 G3 ]
  15.       BACK(300,300);6 ]4 n" v% U1 W6 S: b6 l' m% a0 K
  16.       printf("\r\nGo Back");
    6 \# s1 L' i! P7 \& g( D
  17.     }
    - S% T# y/ U5 P) G
  18.     else if(res== 52)                //输入4为左转
    # _; v  v, k$ _) r$ Y
  19.     {
    # l# }) ]' r) O, d5 F! ]
  20.       LEFT(300,300);3 s, \0 v1 o0 f! e2 P
  21.       printf("\r\nTurn Left");      
    , U) y9 }% W0 n5 T' [9 A
  22.     }
    8 [. S" l' J2 S
  23.     else if(res==54)                //输入6为右转
    ) k/ D6 A  x" W( |- t1 }
  24.     {
    9 F; |' @+ V" U" ?
  25.       RIGHT(300,300);
    ' @5 W0 w( O. t6 d
  26.       printf("\r\nTurn Right");
    * u9 _* m  p% j6 y
  27.     }1 i+ x! q. D; X9 V4 {
  28.     else if(res==53)                //输入5为停止
      i7 k$ f" G8 g
  29.     {
    ( C( D0 u( j) C$ s* X* v* Q
  30.       STOP();8 h2 N/ j2 p" R8 R4 |1 T
  31.       printf("\r\nStop");
    ! L) Y: [" g! T1 N* W# r
  32.     }
    " p4 Z9 \) k8 H, Z
  33.     else if(res=='9')                //进入超声波避障模式. x2 l2 v. x- F* N& {/ N% m5 g. ]
  34.     {
    1 X# o# {  n$ g  [' b  d
  35.       opq=0;
    0 K2 r8 K9 Z5 [7 a/ z* \; u: ]
  36.     }. I( v& Q* s2 {
  37.   }
    * [# O( G) m5 G
  38. }
复制代码
' `. l% I% l0 [9 x& V4 v% i, C
总的来说蓝牙控制这块并没有踩多少坑(大概这不是我写的吧^ _ ^,感谢小伙伴)

7 ^& [  ?) ]3 h/ j; x2 B4.走矩形% R: P3 I; x, p& P' x
1 I- b; f1 ^% ~$ _& q9 e: \& c% ^
走矩形功能也是小伙伴写的,设计思路大致是通过蓝牙输入长和宽,小车通过接受的数据进行矩形运动。在这唯一遇到的问题就是小车的速度问题和转向时间。这个是他们弄得,自我感觉还是很不好调的,因为要考虑电池可供电压,小车行驶的惯性,不同地面的摩擦程度等等。考虑的方面比较多,根据不同的情况可能还要修改小车的速度和转向时间。我们就是在光滑地砖上测得,摩擦力应该是比较小的。
# N3 H6 J, F; ?
走矩形代码:
  1. void Juxing()//小车的矩形运动函数
    * a5 m0 b- E* x, e" r
  2. {
    3 R$ [2 z. T$ F$ }3 a
  3.   u8 chang,kuan,x,y;//chang、kuan分别是小车要走矩形的长和宽的值
    ! n) g" H3 @* z7 _1 o
  4.   delay_ms(200);, y2 f7 d4 U# x/ n* S
  5.   printf("Chang:\r\n");
    / g* S' h2 ~8 y, N" ]) i8 Z% `3 i: X
  6.   while(1)
    - w/ H1 n& d  Z6 {5 X" e  n
  7.   {  C4 J7 O  H: [2 @
  8.     printf("Input Chang:\r\n");) k3 {* A3 ~% Q2 g% M" J; H2 o
  9.     delay_ms(200);
    % K) S" _5 o" E/ T/ a
  10.     if(USART1->SR&(1<<5))//当串口接收到消息后跳出循环( T/ |6 ^% J1 C$ }. f+ v* o7 v
  11.     {
    ) [  b! t+ |& w
  12.       chang=USART1->DR-'0';//将字符型的数据转换为整型数据; c( H+ x: O% \3 _6 c8 J8 y) e
  13.       break;8 W1 n7 d/ V/ ?' G& z2 M
  14.     }
    2 ]" Q+ B3 D& a' H
  15.   }
    ( ^2 }( |6 z6 x8 f; ?+ w8 M( @
  16.   printf("长:%d\r\n",chang);//打印串口接收到的数据) y3 h8 z: X# x8 _
  17.   USART1->SR=0;//串口的接收标志位清零,为下一次接收宽度数据做准备! X% j- u& [: E. z2 k9 W9 `: _
  18.   while(1)3 `  D0 Y# |  v, H5 I8 _5 W" J
  19.   {6 J) Y: G: q. Y# z2 R4 |6 w4 @
  20.     printf("Input Kuan:\r\n");
    2 A4 w5 e  }# A4 D
  21.     delay_ms(200);
    - y; N9 n1 C4 ~7 P6 ?) E
  22.     if(USART1->SR&(1<<5))8 u% {$ ^7 N% _9 D9 |4 ?
  23.     {8 w2 V8 ~& r' e7 q" S, e
  24.       kuan=USART1->DR-'0';//当串口接收到数据后跳出循环
    ; N6 W! l  Z" B4 w1 z$ q- z
  25.       break;
    3 E, S, F9 \% |
  26.     }
    0 d5 C2 e4 J) Z3 G$ C7 u
  27.   }
    ; ~, t9 {+ {- H# h- h1 b* E8 v
  28.   printf("宽:%d\r\n",kuan);//打印宽度数据& o4 ~0 x9 h/ N
  29.   //当前小车速度为0.25米每秒则小车每走1cm要用40ms所以以1cm为单位每走1cm耗时40ms用for函数驱动小车运动  F8 u2 Q' F5 c
  30.   for(x=0;x<chang*10;x++)//直走长
    - F; B: T$ Q" ^! h0 |
  31.   {5 d6 w& F, ?% X! S$ e( y
  32.     GO(300,300);
    # t# a. r6 A6 o( M+ h3 P
  33.     delay_ms(40);
    1 S. x+ q' k0 M7 G0 b
  34.   }% ?/ b7 o0 z# T. l. m9 p' l2 z
  35.   RIGHT(300,300);//右拐2 {4 `  g+ w* A6 o* t
  36.   delay_ms(785);
    + D- a- B, c5 _/ n* i& p
  37.   for(y=0;y<kuan*10;y++)//直走宽2 `+ }; W& e" u, ^
  38.   {
    2 v$ @# i) n3 p+ t$ m6 U% t# ~9 U* o/ E( X
  39.     GO(300,300);- N9 {2 j8 B6 `1 O7 Y2 w
  40.     delay_ms(40);
    8 {% Y  H, q& [
  41.   }! H) m. C' u1 a! X0 s1 I/ Y
  42.   RIGHT(300,300);//右拐3 h$ t8 J) f8 b- u' ~
  43.   delay_ms(785);7 m3 ]: s  ~( Z( c5 L
  44.   for(x=0;x<chang*10;x++)//直走长
    7 S  C+ y0 `6 g7 N6 E, O! n
  45.   {
    - p5 N; T+ v5 V" b: Q. X* x  C' y/ S
  46.     GO(300,300);! A" n  V8 p% s5 k/ w
  47.     delay_ms(40);
    ( N& @' ^) @: w' w, `- j
  48.   }6 g5 ^4 J% J- v+ c: u+ I( P9 F
  49.   RIGHT(300,300);//右拐
    0 S5 k, @) ^5 S& y3 k+ ?. ^0 T3 Q
  50.   delay_ms(785);
    8 U6 n9 h  ^4 \
  51.   for(y=0;y<kuan*10;y++)//直走宽
    ( P; R5 w+ f# j4 ^+ i" F8 \) g: [
  52.   {
    ' u6 o$ T6 I: p8 I" ?: U2 ]
  53.     GO(300,300);+ z( {- e+ Y% }, l( m( b0 }& h
  54.     delay_ms(40);
    9 y: C( Z% |5 }# h
  55.   }
    - N0 `- m( w2 @3 M7 f; J
  56.   RIGHT(300,300);//右拐
    # _2 T/ R! m: U
  57.   delay_ms(785);
    9 H) m' a" w" \0 H0 k, _9 s% M4 t
  58.   STOP();
    1 s0 u) M3 s* ~$ R
  59.   
复制代码
8 t& W% Y/ e( M0 Q; ]+ J# G
, V7 N) l7 }" _1 D6 f: g3 Y* n/ T  K
转载自: 古月居
6 q' V/ `$ a- @+ J7 o1 b8 E
收藏 评论0 发布时间:2022-9-3 15:17

举报

0个回答

所属标签

相似分享

官网相关资源

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