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

STM32 智能防酒驾装置

[复制链接]
STMCU-管管 发布时间:2020-9-11 12:54
一、总体设计方案

  智能防酒驾装置由一个主机设备从和三个从机(酒精传感器)组成,主机采用STM32F407作为主控设备,从机采用STM32F030作为主控芯片,主机和从机之间通过NRF24L01进行无线通信。主机负责酒驾情况的判定、通过GPS进行定位、通过GSM向用户发送短信、控制车辆状态、显示设备当前状态并向驾驶员发出语音提示等工作。从机主要负责采集车辆内各处的酒精浓度、向主机报告车辆各处的酒精浓度。酒精传感器采用TGS2620高灵敏度乙醇气体传感器对气体信号进行检测,当空气中有乙醇气体存在时,该气体的浓度越高传感器的电导率也会越高。将电导率的变化转换成与该气体浓度相对应的电压信号输出,根据电压信号进行酒精含量的判断。

  该装置的工作流程为:驾驶司机进入车内后,会有一个装有气体传感器的装置强行检测司机的喝酒情况。当酒精浓度较低时,系统无反应并进行语音提示,车子可以正常行驶;但是当酒精浓度过高,超过安全驾驶的酒精浓度范围时,检测装置断开点火开关,使汽车无法发动,并发出语音提示驾驶员请勿酒驾。另外,系统会通过GPS对车辆进行定位,将司机醉酒驾驶的情况和当前位置以短信的形式发送给司机的家属、朋友,或向第三方发送位置,请求代驾。

+ e( S* {  L! [5 v1 M" |( t0 ^

二、硬件电路' x9 ^' K% z- |, J8 L

9 f3 {$ x& N4 }+ P6 r8 w' `1.主机

  主机由STM32F407VET6作为主控芯片,将GPS模块、GSM模块、语音模块、NRF24L01无线通信模块、OLED显示模块集成在一起,对外提供继电器、热释电红外模块、酒精传感器和矩阵键盘的接口。主设备采用12V电源进行供电,首先经过MP1584en稳压模块将电压降至5V,为GSM模块、语音模块、继电器进行供电(原定采用AMS1117-5.0进行5V稳压,但由于AMS1117的最大输出电流只有1A,无法满足设备的供电需求)。然后在经过AMS1117-3.3将电压稳压到3.3V,为GPS模块、OLED显示屏、NRF24L01无线通信模块、热释电红外模块进行供电。


$ _) }1 _6 j: ~

20200911125526.19a5966287a6415602e11d615c611bde.png

20200911125551.8719143ed6a85976e3d5f2e14ccee351.png


" W2 ?& U# V& L2 z' v0 E

2.从机1 E9 c6 j( u5 m0 f9 C7 Z

  从机由STM32F030F4P6作为主控芯片,主要负责对酒精传感器的信号进行采集,并通过NRF24L01将采集到的信号发送给主机做酒驾判断。为了减小从机的体积,从机部分没有采用外部的晶振提供时钟信号,只保留了稳压电路和滤波电路。

20200911125610.670127be52c0fe9206aa1ff83431e1a8.png


$ d* h( ^- \# j

20200911125621.d6ee35ce3a04c0af9222fed41ba1f83c.png

( F- M0 m4 b$ ~! U6 a3 _( |6 f2 O2 i

3.酒精传感器
. u5 c6 k; u9 a

  酒精传感器由TGS2620作为敏感元件,首先让TGS2620输出的电压信号经过惠斯通电桥,形成一组差分信号,然后经过由LM358组成的差分运算放大器,从而获得到空气中酒精浓度的相对变化值。


/ P+ ]+ z& O! Z7 M) J, @

5.png

20200911125654.3ba28eacb3f3ad543a45da431bb51eb5.png

6.png

8 ~! b/ A+ j! n% J) I


9 J) p3 o! G/ f( _三、程序设计
7.jpg

4 u) j* w  f9 a; @7 J/ l  n$ q( P6 {$ p& O2 y
) o7 t- m- _3 s8 b% x
主机部分
! N0 }  |# I- g/ O- s* B

- _6 {; P2 v. Y: ?" ?) T; {1.GPS

  GPS通过USART3与主机进行通信,波特率为9600。使用NMEA-0183协议进行通信,获取GPS返回的GPGGA数据,然后进行相关的数据解析。

  1. <font size="3" color="#000000">//********************************************************************
    # t# ^  |! `( F8 B& f6 x
  2. //得到GPS的经纬度9 }  p9 z$ v1 }$ _1 w& l! ?
  3. //数据为char型数组
    # S: w" [7 n% S  u* \: T, e
  4. //若没有得到数据则无返回结果/ i8 Z6 O8 a# `
  5. //********************************************************************
    ' \1 l" x1 i1 _
  6. void GPS_GetData()1 f* d& Y. Q4 K3 W" b7 M" m
  7. {
    1 d! A2 q- M; m3 }4 O$ ^
  8.         u8 i;
    ' p; U7 ~) d4 y9 b8 X8 c- ^
  9.         if(USART3_RX_STA&0X8000)                //接收到一次数据了  H2 H: h3 G- P
  10.         {3 k( _+ Q5 R1 C9 M# ]9 T5 M
  11.                 USART3_RX_STA=0;                                   //启动下一次接收. l, ]" W! E# ?& q) {
  12.                
    5 q6 |3 l  `  E
  13.                 GPS_Analysis(&gpsx,(u8*)USART3_RX_BUF);//分析字符串: R% ~9 o+ `/ @! q, a( b. v7 }
  14.                
    . J# a' ~* l- k. k- m. W
  15.                 if(gpsx.gpssta==1 ||gpsx.gpssta==2 )        //GPS定位成功 + j* o2 R1 g& B
  16.                 {
    # @2 a; K, I/ E, R& r* d) p
  17.                         u8 i;
    $ F; P, M  I; u% Y3 w
  18.                         ( Q+ Y( ^. W$ J  Q. @
  19.                         GPS_positioning = 1;6 ~0 I8 E7 \5 a
  20. 3 f2 k- P7 O) K/ b5 S
  21.                         Transform_double_to_char(((double)(gpsx.longitude)/10000000-0.003466), longitude_char, 6, 1);$ \* ^3 q, m' O! d
  22.                         Transform_double_to_char(((double)(gpsx.latitude)/10000000+0.323707), latitude_char, 6, 1);        
    3 M- `& }" ^' e
  23.                         ) y! |5 Z8 r0 H5 n; l
  24.                         i =strlen(longitude_char);1 l' x# g5 C3 u0 B
  25.                         longitude_char[i] =gpsx.ewhemi;8 w& V8 O7 y( N7 J# N. p4 j/ w
  26.                         longitude_char[i+1] ='\0';
    & S* ^) X& z/ ~! u
  27.                         
    . G6 M- i$ I( ?& c+ Y
  28.                         i =strlen(latitude_char);
    * _. a" p! }2 k4 K% o
  29.                         latitude_char[i] =gpsx.nshemi;- J& F8 g' S" ]# d+ I
  30.                         latitude_char[i+1] ='\0';
    & b3 h1 Q1 b& g, b# a- y0 c7 t
  31.                         . r# }, u" e9 X( m" d' {4 t7 [
  32.                         printf("GPS定位成功\r\n");        
    : O1 O5 s" a, U& |. }' k( t& X
  33.                 }
    - m  e7 R# w8 f
  34.                 else if(gpsx.gpssta==0)
    2 Z! r9 j3 h% q7 O( o, R  L9 b
  35.                 {        
    " j0 S" g. ?2 P* n  r
  36.                         if(GPS_positioning == 1 )
    ( D& }' ]* W3 @9 j
  37.                         {$ [- I, T, @3 ?4 G  r; C
  38.                                 GPS_positioning = 2;+ h, n( h7 @( @- @: z
  39.                                 printf("GPS信号弱\r\n");
    & ^6 s$ L8 H+ W0 i- I8 b& f
  40.                         }
    5 @2 @/ H! _6 ~7 P
  41.                         else if(GPS_positioning == 0 )6 l) V( C# L5 J  |' f
  42.                         {
    $ s* ^0 R; u; c5 [( G3 b. n
  43.                                 printf("GPS无信号\r\n");2 {* c4 A/ o( W& n; ]
  44.                         }
    6 S) \% h1 t, p/ ?# W
  45.                 }
    4 E5 {4 y) \5 }
  46.                 gpsx.gpssta = 0;
    ) o, ^' E+ P4 A4 g# Y$ [
  47.         }
    5 ~, U" c* V3 s- w9 K( |
  48. }+ ?( f  R/ ]( @5 v
  49. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END0 m# ?# T( z5 l- B0 C  P" ~
  50. 1 I6 @4 F, R  @8 W  Q
  51. " b4 O+ N- Z$ h1 g) J  R

  52. 8 U+ z; O  q* B1 J
  53. //********************************************************************
    9 ?  m0 b8 P1 a7 D: m8 j
  54. //浮点型/整型转字符型* J# p& z9 h6 Q: J1 I/ S
  55. //Decimal需转换小数& X7 x1 b5 s/ m0 r
  56. //Character字符型储存的地址,在主函数定义
    ! s$ m" c# D& l# ^" I/ Z
  57. //precision保留的精度
    & ~2 P1 N3 p" ]7 d
  58. //round是否四舍五入,1是,0否
    , |: Z2 s; Y/ p6 j! E" N
  59. //注意可以转换的长度+ I% a" L1 U0 @6 q( s; E
  60. //********************************************************************
    9 b0 Y$ E; O/ L) f0 N& Y
  61. void Transform_double_to_char(double Decimal, char *Character, short int precision, char round)
    * M/ f. ^9 R! Z2 N1 }
  62. {
    3 E, z  @" N8 v( W4 X4 }2 }
  63.         int i,x=1;3 e2 \* M" r, j" J
  64.         int integer ,integer_decimals;. _# n- g8 Q" i  o7 K
  65.         char temporary_char[10];
    # p: |5 z* [" W1 W
  66.         for(i=0;i<precision;i++)& W& C: |( |4 _" t$ E& Z
  67.         {
    $ U0 J# n# z3 r, X( H
  68.                 x *=10;
    4 f, D6 k; r. R1 v4 F
  69.         }4 S$ H# Z- `3 I2 m( C
  70.         integer = (int)Decimal;                                                                                                                        //整数部分5 Q* U2 d- i2 O3 h
  71.         integer_decimals = (int)((Decimal - integer) * x + 0.5*round);
    0 B7 y& S. f$ G1 O
  72.         for(i=0 ;integer>0 ;i++)
    6 f( C$ B2 @( [
  73.         {
    & r/ o3 F- O& W: m6 g  }2 P
  74.                 temporary_char[i]= (integer % 10) + '0';
    ; @! v$ ^' D" x( R  y% Q3 }
  75.                 integer = (int)(integer/10);
    + E! [/ G# o: |4 P! ?2 _8 Z! b
  76.         }
    3 ]/ E. p& C6 h0 p, ~
  77.         if( i==0); d" j- A( \, J
  78.         {# C2 W4 o5 i3 y/ ~/ j- G* G6 D
  79.                 temporary_char[i]= '0';+ w( a1 H7 \! n) [' K) Q9 ?' n/ ^
  80.                 i++;
    ( _2 b+ p  A& j; ~, E; U
  81.         }% P1 \' ~1 w9 ]# k5 r' Q
  82.         for(x=0;x<i;x++)
    3 C$ n$ @# {7 ]% d
  83.         {
    * R# g% ~5 c4 a7 W/ `) ^
  84.                 Character[x] =temporary_char[i-x-1];
    / T4 P+ `! n8 A# C
  85.         }
    0 @% z" Y4 o- I5 \; d# h9 X6 H5 L3 P
  86.         memset(temporary_char,NULL,sizeof(temporary_char));" E/ x. j0 ~) x+ B  d' @
  87.         if(precision!=0)/ m4 v& }/ I" N' g0 I. h
  88.         {
    2 _5 C4 F9 t# d% b$ U6 q
  89.                 Character[x]= '.';
    1 `+ L" e! |) E. a& m
  90.                 x++;
    6 U% S" U. t' B: r# ~
  91.                 for(i=0 ;i<precision ;i++)
    5 o9 `8 d* S  _0 b7 V
  92.                 {1 s, S" t1 [' K; t9 Y7 X
  93.                         temporary_char[i]= (integer_decimals % 10) + '0';. ~5 j) Y7 h1 d. x8 z
  94.                         integer_decimals = (int)(integer_decimals/10);; \' E9 r) r  i; H" A) ]& p3 P
  95.                 }
    5 L. [7 f* T0 z$ n$ L6 m
  96.                 for(i=0 ;i<precision ;x++,i++)0 O9 n% ~5 @6 W5 l
  97.                 {
    . Y4 {/ B3 f- f# L' p% w
  98.                         Character[x] = temporary_char[precision-i-1];        0 A* M, C- I5 Q: Y
  99.                 }
    9 X1 y+ \. [; O7 v
  100.         }
    4 L! k- Z( Y( [' I
  101.         Character[x] ='\0';
    8 C8 S- i0 `( t, V
  102. }
    " D6 J8 v! v8 V% n1 n
  103. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END</font>
复制代码
) C9 I$ R& \2 t9 Q1 w, [
2.GSM

  GSM采用USART2进行通信,向模块发送相应的AT指令既可完成对模块相应的操作。

  1. <font size="3" color="#000000">//********************************************************************
    3 a9 ]9 S9 ~0 B* O: E- ?7 Z0 ?* V
  2. //SIM执行命令) f2 ]0 c9 m8 X
  3. //0~3发送短信,0~3号联系人' U0 }3 D8 J6 B; p
  4. //********************************************************************
    0 t7 H2 C. |1 ?2 y; x' v
  5. char SIM900A_Executive_Command( char number )" a& A6 I5 }+ t$ @. p
  6. {          v6 z: u* s; D6 T# C8 F7 r0 m4 c
  7.         if( number == 0 ||number == 1 ||number == 2 ||number == 3 )# M: f3 a6 g* n4 ?
  8.         {
    ) a- K! s6 o! ]$ a. T
  9.                 int i ,Length;) N9 W; p- x' J9 [4 J- W
  10.                 char Message_content[280];, `9 A6 ]6 p" E4 K3 b
  11.                 char AT_CMGS[4],Data_Length[4];4 H0 a+ b8 O- c7 [% ~  \
  12.                 char PUD_latitude[50],PUD_longitude[50];6 V" p, O3 I' ?/ n! J# s( z
  13.                 char PUD_longitude_latitude[100];
    ! Y! X$ f  A3 q; n! d0 e+ j1 ]2 i
  14.                 char PUD_comma[5]={"002C"};$ ~4 S' ~" U* t! o- w( V! B
  15.                 # b  q2 v3 e; g% E7 b
  16.                 PDU_Transform__Phone_number(Phone_number[number]);5 j' G) K( ]( W# |% G2 Y+ ]1 T
  17.                         # t& c3 _- o; }  p
  18.                 if(GPS_positioning != 0)& n+ E, P0 K8 v/ ?! T: |+ S9 y
  19.                 {+ L. T& e% I5 t% O4 o% d7 E
  20.                         PDU_Transform__Message_content(Message_content,Message_content_original_1);
    ' l  }/ U1 ~3 e/ E$ d/ G
  21.                         6 S: h# u+ W$ M: u. a
  22.                         Char_to_Unicode(latitude_char, PUD_latitude );
    5 g! d7 N& k2 i: b( D
  23.                         Char_to_Unicode(longitude_char, PUD_longitude );  k. q# a" j% {6 P8 ~, g2 X( k( h  f
  24.                         ) L' C: p; a* l, s/ s# V
  25.                         memset(PUD_longitude_latitude,NULL,strlen(PUD_longitude_latitude));
    * O& N$ j) ~# y5 Y, o9 \1 `* ~
  26.                         String_addition(PUD_longitude_latitude ,PUD_latitude ,0);3 U1 w4 a/ {7 M* w
  27.                         String_addition(PUD_longitude_latitude ,PUD_comma ,strlen(PUD_longitude_latitude));6 X; g3 W/ E: v$ n
  28.                         String_addition(PUD_longitude_latitude ,PUD_longitude ,strlen(PUD_longitude_latitude));; [/ N/ K& i6 j: z8 c; p& S
  29.                           L  f+ M4 G- }" l
  30.                         String_addition(Message_content ,PUD_longitude_latitude ,15*4);
    ( f% i5 R* u! [" H- q9 X! K
  31.                 }' p$ S' M: \! K, I6 Q2 b$ h. r& P  l
  32.                 else
    , _# r6 N+ a* A
  33.                 {2 f9 N& |; S* v( O' G
  34.                         PDU_Transform__Message_content(Message_content,Message_content_original_2);* s; B; C* b: S$ W' g
  35.                 }, a- v! ~* z8 k- i
  36.                 Length = strlen(Message_content)/2;. \3 t4 J2 @3 F/ f$ l
  37.                 Transform_int_to_hexadecimal(Length ,Data_Length ,2);, o9 M& T* R; L
  38.                 Transform_double_to_char( Length+15, AT_CMGS, 0, 0);% w' S5 d$ K& ?% w+ ?2 F6 h4 W7 j0 |/ f
  39.                
    1 o) W( h- ?- ^  L( T: M, h
  40.                 printf("%s\r\n",PDU_Phone_number);- n* ?) r8 j; p5 K9 f; q% r
  41.                 printf("%s\r\n",Data_Length);
    4 r& M7 w! r+ b3 y% z" \0 m' ^, c
  42.                 printf("%s\r\n",Message_content);
    9 `4 e# u# l% U
  43.                 ; A' o/ W) ?( s+ w1 w7 I
  44.                 for(i=0;i<Number_retries;i++)8 P9 j% \3 {" O$ Z! i7 I
  45.                 {
    9 b2 ]! ~; Z; q6 R. x9 a, @3 ~& j
  46.                         SIM900A_Send_AT( "AT+CMGS=" ,0 );
    $ b! S% W" q( [# y% a
  47.                         SIM900A_Send_AT( AT_CMGS ,1 );                8 j7 F, t, }+ L* i) j, O- O3 @
  48.                         
    4 D4 U/ n" `* K4 p5 W
  49.                         if(USART2_Data_seek(USART2_Data ,">" ,500))
    - M' n2 ^0 r# R+ ~" R9 S
  50.                         {& r, X/ c6 F3 |: C/ k
  51.                                 SIM900A_Send_AT( PDU_Phone_number ,0 );# Q0 a& E9 t& r
  52.                                 SIM900A_Send_AT( Data_Length ,0 );  V4 C1 z, d+ f- D% X( p: S
  53.                                 SIM900A_Send_AT( Message_content ,0 );
    1 D5 H4 P/ ^: z' ?* C  T

  54. ( |: k: i+ |% B# ?: \5 E5 o
  55.                                 USART_SendData( USART2, 0x1A );: `7 F& Z( n- u; g8 r. b/ n
  56.                                 SIM900A_Send_AT( 0 ,1 );
    ! b+ p1 K: j: b
  57.                                 if(USART2_Data_seek(USART2_Data ,"ERROR" ,2000))
    , A' p6 H" g; }' k' Z( A/ E  k
  58.                                 {, C- Q. W3 U. o; y# m3 [2 ?
  59.                                         printf("发送失败\r\n");0 W, M2 r# u+ s0 D4 V4 {
  60.                                         return 0xFF;
    7 A" n4 l: V* \/ \
  61.                                 }
    6 H. ^( E0 t# M$ ]
  62.                                 printf("发送成功\r\n");
    1 n0 O+ t1 g, x) h
  63.                                 return 0x00;
    0 @' U5 F# S8 M' z  X5 p
  64.                         }5 G0 _/ A) t& J8 t- `+ V
  65.                         else printf("AT+CMGS指令错误\r\n");
    / s2 F; m+ z% p2 ~4 ^4 J
  66.                 }        
    1 {. O4 N7 f6 \/ ]* [/ z
  67.         }
    . k9 N% j3 `. y" `
  68.         printf("指令错误\r\n");' p! ^0 B0 ~; H/ b& S% ?
  69.         return 0xFF;
    + t7 r0 t  |5 k, Q9 l6 n  ^
  70. }
    * L- [9 M, y- f% M2 |& _% t
  71. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END" ?% O! N* B0 W" u

  72. 0 Q4 v: L2 G7 {
  73. ( C* h) y8 J8 A" q& O1 R
  74. ' O, W  f9 I1 N, N$ |
  75. //********************************************************************
    5 Y8 ~7 I" a1 @0 z( k# C5 V
  76. //通过串口2发送AT指令
    + D0 _! p; y2 C' C& N9 S9 D
  77. //可以直接发字符串或发数组
    9 G  ~" S- [. X9 M( j
  78. //********************************************************************! T' b- K* ~3 `+ X9 @) h6 `
  79. void SIM900A_Send_AT( char *AT_command ,char over )
    ; v- {* W+ M- V
  80. {
    ! `3 Z3 K8 J. ^% P
  81.         for(;*AT_command!='\0';AT_command++)5 Y# r) Y0 W3 v- Q7 l0 L9 v
  82.         {
    / G+ j7 Z7 C; J, ^2 o  c; e) |
  83.                 while( USART_GetFlagStatus( USART2 , USART_FLAG_TXE ) == 0 );
    $ x+ J$ @4 C* D7 S/ x
  84.                 USART_SendData( USART2, *AT_command );/ ?5 c) u6 L9 p0 w
  85.         }- [% D5 G% t: G+ H0 |+ V
  86.         if( over ). r/ C- D7 I! U5 |6 G5 ?; `% \
  87.         {5 g0 g. n2 {% q
  88.                 while( USART_GetFlagStatus( USART2 , USART_FLAG_TXE ) == 0 );
    * H# I  n: H7 b. [
  89.                 USART_SendData( USART2, 0x0d );//  /r,0x0d,回车的作用只是移动光标至该行的起始位置
    ' h% N" _& ?. l' j( K" h% L) n
  90.                 while( USART_GetFlagStatus( USART2 , USART_FLAG_TXE ) == 0 );
    , Q, S# t. \  I
  91.                 USART_SendData( USART2, 0x0a );//  /n,0x0a,换行至下一行行首起始位置;$ N7 x& p  ]9 r+ ]- j
  92.         }. `, Y: f* ^7 D
  93.         while( USART_GetFlagStatus( USART2 , USART_FLAG_TXE ) == 0 );
    & G- J3 `) Q/ d* J, L
  94. }% Q8 u) N" @9 O% c! d9 i7 h
  95. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END2 K. ^6 _: \: E1 g! ]
  96. , i, W' s2 a6 e& z3 y
  97. + B& v) i) w, a) b5 k- I' N. Q( t! `

  98. 4 Z- O/ Z, H3 J' f/ f6 @2 q5 w
  99. //*******************************************************************1 M# l( T" K( W  U' n/ m; k
  100. //将手机号码转换为PDU格式3 H- @: `4 |  I+ C
  101. //*******************************************************************2 J1 E3 i2 i& e+ R
  102. void PDU_Transform__Phone_number(char *Phone_number_input)
    ' P  L, e0 v* \$ N4 _6 T- K
  103. {
    . g6 g8 u( ?" O3 D* y2 ]6 f
  104.         u8 i;
    # j7 G% H" V$ d/ f8 [" J
  105.         Phone_number_input[11] = 'F';
    0 @: P/ x) [: ?
  106.         for(i =0 ;i<12 ;i++)
    : o& u" a6 r3 O9 [) R; B5 K
  107.         {
    # T: u2 O4 B, U1 n2 ?4 W/ Q
  108.                 if( i%2 == 0)4 {$ a$ `2 R5 k/ N% e% m' C
  109.                 {, x* \# `/ v+ Y& l: Q
  110.                         PDU_Phone_number[i+12] = Phone_number_input[i+1];2 \& `3 u8 q$ o
  111.                 }& |) U5 n$ M( T$ M, e' f
  112.                 else
    . h' S; }9 \+ f$ T
  113.                 {
    5 o6 F/ i% C2 k" |
  114.                         PDU_Phone_number[i+12] = Phone_number_input[i-1];1 B' b* B6 z* y& E  F
  115.                 }/ C" }' Y3 M; u3 y* n/ p0 i  G
  116.         }
    + w; l, i1 ?" u8 ^  V
  117.         Phone_number_input[11] = '\0';' |" M' a, D. V7 |  D) J
  118. }1 T- t/ }8 o0 h
  119. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END
    # M7 `& \  K1 H! z0 [

  120. 5 q+ v" H( O) F4 v& |

  121. 8 E/ Q! ]: `6 x5 K7 S7 Z) n7 k. [
  122. 8 G7 b- Y4 K% S, w  C9 {; q
  123. //*******************************************************************: J3 i2 k# K# D9 F2 Y0 i( ~
  124. //字符串内添加字符串
    2 ~1 S( j: k+ Y! A0 f" K
  125. //原字符串String
    % h( C( G5 G( J. P
  126. //需要添加的字符串Add_String+ g% [3 O4 Y- P( P# E; k$ Z
  127. //第Add_location字之后添加
    5 [- \0 d: r) e
  128. //*******************************************************************7 E: ^( q# I. o& t1 g# [: m; x" G
  129. void String_addition(char *String ,char *Add_String ,int Add_location)$ m- r* e% L3 l  H4 Z2 E  D8 @
  130. {" v4 e& S* y) U) K, I2 a- d
  131.         u8 i;) _% j1 |7 F8 {9 ]- P1 ]/ M
  132.         int length_String ,length_Add;4 ^9 [% p( g7 r$ l
  133.         length_String = strlen(String);
      a2 f$ ~, c( g8 F! j' U" x
  134.         length_Add = strlen(Add_String);- y9 t- @% A  O" Y, E0 U( S0 U
  135.         
    ) ]# \) r% B8 w1 x
  136.         String[ length_String+length_Add ] ='\0';8 {$ N0 T5 Y1 w1 H0 Z1 Z2 U% }9 Y
  137.         
    # @2 y' Q5 v6 R$ `6 Y9 M+ @3 ?
  138.         for( ;length_String> Add_location ; length_String--)
    * v# V6 U; f9 C: D* ]0 U
  139.         {( _  b, }$ m, E, n8 V/ f
  140.                 String[ length_String-1+length_Add ] = String[ length_String-1 ];9 V9 v, a. H0 m& b. q( ?8 I9 E
  141.         }
    ! U" P) M( @+ X, [9 m; J
  142.         
    % G% G3 i4 ]( k% _. H1 n6 V$ u
  143.         for( ;length_Add>0 ;length_Add--)1 e% {: o! b& N
  144.         {" @7 J9 I* ~8 J$ E# K4 f4 G( E
  145.                 String[ Add_location-1+length_Add ] = Add_String[ length_Add-1 ];
    $ T) V% i6 b5 A
  146.         }( C" R( m9 c  ~/ g' {
  147. }
    - a, p+ u# n; n! R. n% r0 C# T
  148. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END</font>
复制代码
6 q6 E* ?. m: h# M- u' z
3.NRF24L01

  NRF24L01采用SPI进行通信,由从机发送信息,主机只进行接收信息,并对信息进行解析。

  1. <font size="3" color="#000000">**************************************1 ~# {) ?% A1 z9 L& ~4 o
  2. //NRF24L01数据解析
    # q( S% I, ]  w$ j. P
  3. //********************************************************************' ~( r( o' C4 h. ?; _* D
  4. void NRF24L01_Data_Parse(const char *data), J$ S8 t, X* Z( r; h; R6 l4 n* j
  5. {
    ! s6 y, B& o1 w" {$ _# b( T$ ^
  6.         u8 i,x;6 ]$ f2 n6 j- ]: w
  7.         char cache[8],slave;
    7 d( z7 o6 V9 k2 i. \0 F3 D, B
  8.         if( data[0]=='K' )5 [5 }4 P  p) M) W8 f! ^. z
  9.         {1 t- y5 K$ U& a' D
  10.                 for(i=1,x=0; data[i]!='#'; i++)
    . r4 s! u  N" L9 b' T9 y
  11.                 {) v) G6 {& T- ?# R! i
  12.                         switch(data[i])
    & q4 n9 g; r0 G' C: p9 B) c
  13.                         {        
    ! a$ e) Z. O4 u; P8 i1 g
  14.                                 case 'H' :                        for(i++,x=0 ;data[i]!='&' ;i++)        //没有结束
    + u: ~% A, P3 H# ~
  15.                                                                         {
    * o8 h, f% W7 Z; h
  16.                                                                                 cache[x] = data[i];
    6 Q$ C$ s, ^1 D7 e3 U
  17.                                                                                 x++;
    % w6 Z8 X; E0 ^; ]" a" a( N
  18.                                                                         };2 A9 c" M4 z) q2 a% Y9 y
  19.                                                                         cache[x]='\0';6 h, J+ @& t; _( Y$ b
  20.                                                                         slave = Transform_char_to_double(cache);
    1 a! G% ]9 v& i
  21.                                                                         slave_disconnect[slave-1] = 0;3 p0 s4 m- w$ O/ u0 Z1 M3 _
  22. //                                                                        printf("slave=%d\r\n",slave);
    1 W! g: `/ B7 I9 M7 U2 y
  23.                                                                         break;
    ( B6 B% Z8 k& _- k- G* P
  24.                                                                         ; J- x( N: y% G: Y  D% r* [- p
  25.                                 case 'V' :                , ~6 T% j* g+ _. s: ^
  26.                                                                         for(i++,x=0 ;data[i]!='&' ;i++)        //没有结束
    4 h1 V3 ?8 b4 r
  27.                                                                         {+ i3 f2 T8 o! J5 k$ h8 r* l3 ?
  28.                                                                                 cache[x] = data[i];
    . N* e2 \' B& A  ]. C- W: x/ {( R
  29.                                                                                 x++;
    4 D+ S5 w3 P/ {+ n! H- V
  30.                                                                         };- t, T2 @# C" p8 ~5 u; I. q* e
  31.                                                                         cache[x]='\0';2 ^/ n$ c0 E7 v/ s
  32.                                                                         slave_unit_voltage[slave-1] = Transform_char_to_double(cache);
    : u+ H+ p( C: c; W
  33. //                                                                        printf("voltage=%lf\r\n",slave_unit_voltage[slave-1]);
    # ]- x. s0 _5 Z
  34.                                                                         break;
    6 F+ N" _) `% U
  35.                                 case 'A' :                        for(i++,x=0 ;data[i]!='&' ;i++)        //没有结束
    " E9 e8 N2 k$ D+ k' J
  36.                                                                         {
    # K2 `% i& n6 o0 K& W9 b) n" ^
  37.                                                                                 cache[x] = data[i];2 O. P0 a/ R% _) u- @' u# v
  38.                                                                                 x++;+ I3 N; b  m$ e9 A
  39.                                                                         };6 _5 A# ^: _: w
  40.                                                                         cache[x]='\0';
    : h4 k  Z/ Q5 R5 s+ I
  41.                                                                         slave_unit_alcohol_concentration[slave-1] = Transform_char_to_double(cache);0 y0 a1 R( O6 G2 O5 ~3 w3 F
  42. //                                                                        printf("alcohol_concentration=%d\r\n",slave_unit_alcohol_concentration[slave-1]);7 `2 Y* @* m  f
  43.                                                                         break;7 t3 p& R7 F/ O3 p7 T
  44.                         }
    - n% [8 S. @' e# i
  45.                                 memset(cache,NULL,strlen(cache));
    $ j: B% N% z5 c3 M" k& N. I6 X# v
  46.                 }        5 d& Q% k* V7 C  m( {* L" y8 R
  47.         }
    0 H' G) l6 y6 R; o. d* D: B
  48. }6 V& [/ B+ b( i& M5 D% \
  49. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END
    0 I/ t% u' W0 v) }* Y# ~2 C

  50. 4 T3 e6 `& D. l$ m* Z2 v; Z& d' s5 P
  51. 2 e/ O) J4 c& s1 [
  52. $ t2 V' Y1 Y# [) v6 o" _
  53. //********************************************************************
    ; A( t7 E- ^6 G3 j8 I5 ]1 E
  54. //接收到数据进入中断! ~# K! }- h1 L& d/ h' J, T% ~, H
  55. //分析接收到的数据
    & O# I* F' i4 X4 _! z+ D& u5 y
  56. //********************************************************************8 V1 B/ O: M6 }6 J6 w. W, ~$ Q
  57. void EXTI15_10_IRQHandler()' l, V& D& M, o# q7 r" L3 d6 C
  58. {
    - z* N8 \& Z2 O, W& M, s
  59.         if(EXTI_GetITStatus(EXTI_Line12))! }' ?, o! v+ u( Z( i
  60.         {# V' `% }, L- M; z' N/ f6 _
  61.                 char NRF_RX_Data[32];
    1 ^# C1 J2 i1 X; V: G1 T' w0 u
  62.                 NRF24L01_RxPacket(NRF_RX_Data);
    ; i& q( A' Q) T1 e5 S8 c9 l" c
  63. //                printf("%s\r\n",NRF_RX_Data);% E$ S4 w" M' ]; R
  64.                 NRF24L01_Data_Parse(NRF_RX_Data);( I' Y2 t$ c0 y* @; f
  65.         }. Q& m" H# Y# V6 n- e: t4 D* j$ k
  66.         EXTI_ClearITPendingBit(EXTI_Line12);! V* t1 _$ d% M
  67. }
    - e9 q4 y# V3 O% B
  68. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END</font>
复制代码
# }+ b: @8 ?0 @4 i- x  l
4.OLED显示

  OLED显示屏采用软件IIC进行数据通信,每200ms更新一次显示信息,每4s进行一次翻页,显示不同的设备状态信息。

  1. <font size="3" color="#000000">//********************************************************************6 n% x1 T7 ]0 d; w6 r
  2. //200ms进入一次中断7 Y1 X0 T' {  |* g: X  P0 t
  3. //更新oled显示
    - v! p" [) |6 T: s6 h
  4. //********************************************************************
    $ G6 D+ u$ j; Q; s
  5. void TIM1_TRG_COM_TIM11_IRQHandler()
    & P" ]4 y! ^. N' Q% ?( n$ p
  6. {
    2 W2 I; |5 n$ R# l/ }
  7.         if(TIM_GetITStatus(TIM11, TIM_IT_Update)), @0 ~; c0 b. ^" e+ ~# e0 d% X# J6 e- ]
  8.         {
    4 e% }5 G4 d7 A$ x
  9.                 extern char PILOT;
    $ x& q  E4 q" l. o
  10.                 static int Enter_number =0,Page =0 ,Canned_format=0,aaa=0;
    ' L) {: i! I6 W( ]0 [( r& s( ?7 [
  11.                 Page = Enter_number/20 ;//控制翻页时间200*20ms9 Q: v1 T2 p' J- ~6 o4 G
  12.                
    3 H3 a1 A/ }" K3 v' r( d& I
  13.                 //********************************************************************
    3 l4 c+ C% U4 T, _+ r( G
  14.                 //第一页信息( L: i" `! D3 Q, m9 l
  15.                 //GPS状态
    ( Y) N0 X$ s: H9 ]! r  {
  16.                 //********************************************************************% p+ a, u$ C' g$ k0 Q/ x: `1 K
  17.                 if( Page ==0 )        
    1 `, x. X) @* S) _$ {0 ~$ b
  18.                 {4 x5 H* A0 p" c% }7 r9 N. e# O
  19.                         extern char GPS_positioning;5 E7 D/ p2 B3 ~& L- g2 Y
  20.                         extern char longitude_char[15],latitude_char[15];
    & n" u+ m7 J7 o& R
  21. + n9 k8 z2 x2 w$ u
  22.                         if( Canned_format/10 != 1)
    9 E+ P( J9 {/ k9 `: W$ Q5 v" h* }
  23.                         {
    ' y# t2 I9 _( q, H' P" {& [& N0 ?
  24.                                 OLED_CLS();* _3 @5 l% ?$ `" x) u& N# [1 r/ D
  25.                                 OLED_P8x16Str(36,0,"GPS",F8x16);/ }% M9 |( \; K1 U
  26.                                 OLED_P16x16Str(60,0,"状态",F16x16_Idx,F16x16);
    $ U% N( ?. w$ B7 e
  27.                                 OLED_P6x8Str(122,0,"1",F6x8);
    / N& p: H5 e$ d; [
  28.                                 4 u$ }5 Z& @& ]
  29.                                 Canned_format = 10;
    ; ?& Y9 l# x+ ~% c# m. a
  30.                         }( q+ X; B- ]$ S% ^# I) O
  31. ( |7 f( {& N0 ]3 |5 H
  32.                         if( GPS_positioning == 0)) x8 B: y8 W8 Q+ _
  33.                         {
    8 V$ D. G" E7 v+ g7 j9 m1 m
  34.                                 if(Canned_format%10 != 1 )
    0 r2 O8 {0 d5 v  F- N3 V
  35.                                 {
    5 Z; \/ ?0 F2 u' @, O
  36.                                         OLED_P8x16Str(0,24,"GPS",F8x16);! i6 ?2 ~8 x7 X) y7 o0 E  Q
  37.                                         OLED_P16x16Str(24,24,"定位失败",F16x16_Idx,F16x16);
    5 B% }& h; a3 X/ p4 G+ F6 j
  38.                                         Canned_format = 11;                                : W' ^/ Z' t$ ^0 P) e
  39.                                 }
    % k, ^1 `' n) T% _- |
  40.                         }
    : b+ z2 V+ O% @) d" k7 z$ }
  41.                         else if( GPS_positioning == 1)/ A9 |  m1 y" d3 C) U
  42.                         {
    ' B2 D  a+ ?4 P. I( D
  43.                                 if(Canned_format%10 != 2 )! d- Z& b; @) n2 q, F( Q6 `
  44.                                 {
    " k+ E9 W6 Q( Z1 T  ^4 i! c# E
  45.                                         OLED_CLS_y(16);6 K7 k* e! p6 D3 p# m& d
  46.                                         OLED_CLS_y(24);' _1 \3 e! u$ l5 q
  47.                                         OLED_CLS_y(32);/ ]6 \+ U+ I! q9 X
  48.                                         OLED_P8x16Str(0,16,"GPS",F8x16);; x9 ]$ s. K6 R
  49.                                         OLED_P16x16Str(24,16,"定位成功",F16x16_Idx,F16x16);        - D1 t8 d+ y; F3 I; d
  50.                                         Canned_format = 12;
    ) `* e# X1 t2 `) C3 F
  51.                                 }; Y( H# G9 L4 ?) l/ ?5 q5 a
  52.                                 OLED_P8x16Str(0,32,longitude_char,F8x16);
    - A' ]: U6 B* t: \, U
  53.                                 OLED_P8x16Str(0,48,latitude_char,F8x16);
    # K3 J3 z: {7 c( m3 E$ p: _
  54.                         }* u9 F2 N5 f8 Z- ?
  55.                         else if( GPS_positioning == 2)
    2 ]0 {! o( T' G& d$ y
  56.                         {, A" K! J: |6 C5 [: ?. f' Z
  57.                                 if(Canned_format%10 != 3 )- g/ S) R2 l$ |
  58.                                 {: |' d- b$ }) U9 V: P5 o( w
  59.                                         OLED_CLS_y(16);
    9 ], p) o4 F7 K' Q# m
  60.                                         OLED_CLS_y(24);
    ( I  y5 |# Q! q9 f2 M0 D! G* r
  61.                                         OLED_P8x16Str(0,16,"GPS",F8x16);
    ! z. Q+ F( n. Y4 r" h- q7 w
  62.                                         OLED_P16x16Str(24,16,"信号弱",F16x16_Idx,F16x16);
    . z" a; P  i: \1 ]  k
  63.                                         OLED_P8x16Str(0,32,longitude_char,F8x16);$ A; ?8 a( Q- Y* B0 m& _
  64.                                         OLED_P8x16Str(0,48,latitude_char,F8x16);
    5 m, [9 x$ b* }& T
  65.                                         Canned_format = 13;
    & X7 z2 _1 s4 ^% ^
  66.                                 }: S# M: v- s7 }( b1 c* F
  67.                         }# W; ]$ e1 P1 G' w+ e! L6 C
  68.                 }
    4 z# f3 w1 k" @# v# X, Z5 S/ d
  69.                 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END9 O6 ^) T7 {* c, y% [  f7 C
  70.                 & K3 N. ~9 E: V# k
  71.                
    : m3 Y$ d# m4 ~6 o, q
  72.                
    2 n) k) m0 t6 \6 W2 y# H& s
  73.                 //********************************************************************& A( X  F1 m/ X6 r
  74.                 //第二页信息
    4 ^+ q1 ^1 o) y
  75.                 //设备连接情况
    ) M8 \0 `! D: d, Q; S, P6 H  V
  76.                 //********************************************************************% O7 T0 C, v; t6 @; Y* k' n
  77.                 else if( Page ==1 )6 X/ W3 q! ]# T/ _  Z" J0 D
  78.                 {
    . }2 q- V4 W( \0 B& Q2 g& `1 Y3 D/ ]
  79.                         extern u8 slave_disconnect[3];
    7 h0 M) p4 q+ X
  80.                         
    . [  v  {, U# D3 a) x
  81.                         if( Canned_format/10 != 2)
    . J8 g- Q3 t* Y5 j' O
  82.                         {1 j4 e/ B! E) r2 i( L/ n
  83.                                 9 S) t; H5 X6 w4 t9 D
  84.                                 OLED_CLS();4 Z& i% P# h8 t, o
  85.                                 OLED_P16x16Str(16,0,"设备连接",F16x16_Idx,F16x16);( p8 _3 G8 p( u! w) s7 Q8 L: p
  86.                                 OLED_P16x16Str(80,0,"状态",F16x16_Idx,F16x16);1 l5 j2 N  ~5 F. r5 x
  87.                                 OLED_P6x8Str(122,0,"2",F6x8);
    ' Q: t" k2 i* F; [% J3 W

  88. 9 M6 g+ w/ |- H! _5 h( p+ P/ `
  89.                                 OLED_P16x16Str(0,16,"设备",F16x16_Idx,F16x16);4 \- D2 n5 {0 k
  90.                                 OLED_P8x16Str(32,16," 1 ",F8x16);; Z7 s; N8 m- Y6 f* }! l
  91.                                 OLED_P16x16Str(0,32,"设备",F16x16_Idx,F16x16);, F: a! W! h; B. [4 J" C
  92.                                 OLED_P8x16Str(32,32," 2 ",F8x16);
    1 t$ d  x' U' J5 N, @
  93.                                 OLED_P16x16Str(0,48,"设备",F16x16_Idx,F16x16);
    . y9 u& w$ r! V
  94.                                 OLED_P8x16Str(32,48," 3 ",F8x16);
      Y; d5 a$ w  ?# t
  95.                                 
    " N+ B8 d/ y9 P, S, F3 }
  96.                                 Canned_format = 20;" Z0 }' P. I: T3 ~! ]+ `1 @
  97.                         }4 C( P: r) @! _8 n4 T. `/ Z
  98.                         5 K9 w* V+ \# p! O  n
  99.                         if( slave_disconnect[0] == 100)
    $ Q. D8 o9 j7 c5 [$ w, G
  100.                         {
    * y! s; i4 n/ b! i: [  j7 e
  101.                                 if(Canned_format%10 != 1 ), D% E3 {# f! M3 O8 ^9 t% X9 o0 k6 L
  102.                                 {+ m9 w3 n& Y2 G. A
  103.                                         OLED_P16x16Str(56,16,"断开连接",F16x16_Idx,F16x16);
    6 P  {$ k, `* G1 ^0 C& Z. K
  104.                                         Canned_format = 21;                                
    & n" h  j/ Q; A# Q
  105.                                 }& V4 }, u' z9 O" Z
  106.                         }$ V. z" V) t+ ~/ J, j* J" x/ Q
  107.                         else
    , b5 i2 o% t! D2 Z+ t
  108.                         {
    ; R* A, Y/ a" ]+ N' ]8 h
  109.                                 if(Canned_format%10 != 2 )
    4 P( h' v; F6 C- j1 w* T
  110.                                 {% f" Z! F9 {1 I% X
  111.                                         OLED_P16x16Str(56,16,"连接成功",F16x16_Idx,F16x16);* G3 b# t2 t- v. ?
  112.                                         Canned_format = 22;        
    " @% Y$ H. l, X- q' x
  113.                                 }
    8 C# P7 E* U* E* _& _$ K& q% |
  114.                         }; y5 Z( c, r  l5 Y7 k
  115.                         
    $ B, A  Z" _: g
  116.                         if( slave_disconnect[1] == 100)7 Z8 q% z; t3 A8 s4 a6 I( m% ~( P+ \( ^
  117.                         {
      {3 D, E4 m9 W! ]. R
  118.                                 if(Canned_format%10 != 3 )0 u3 I0 A$ e9 B0 r" Q- ?6 P0 t  V
  119.                                 {6 c: V0 ?6 @% C# r0 K* M9 L
  120.                                         OLED_P16x16Str(56,32,"断开连接",F16x16_Idx,F16x16);: x. N/ l5 E- U" g! F7 t) `0 ]
  121.                                         Canned_format = 23;                                $ x- |2 l- B! b, j
  122.                                 }' }$ W, F# [* x; D3 i; h0 a
  123.                         }
    8 G5 K6 b' x+ s
  124.                         else2 U# [& A5 d1 t
  125.                         {
      W8 I6 L1 C9 N7 w' {* F+ Y# _
  126.                                 if(Canned_format%10 != 4 )
    5 M% g  I% I2 V8 _
  127.                                 {
    ' _- T3 P- x* j
  128.                                         OLED_P16x16Str(56,32,"连接成功",F16x16_Idx,F16x16);
    / X( j2 ~+ L/ R0 v$ @3 M( I
  129.                                         Canned_format = 24;        ; o/ }# o4 c0 F7 L) o! u: V- r: |  ^
  130.                                 }
    * N5 D8 D- E8 U  m: U/ E0 g
  131.                         }
    ; f5 u. `0 d4 R' H+ ?0 Y( J
  132.                         
    $ i6 F, c1 O  G+ f, X. R
  133.                         if( slave_disconnect[2] == 100)4 T1 n. R$ Q3 N+ H) X$ X6 j
  134.                         {
    6 f7 Y! }* h; G6 X* F; P: m
  135.                                 if(Canned_format%10 != 5 ), |6 s1 m: I% \
  136.                                 {1 ]- M+ o% X! G1 A2 A, }9 C
  137.                                         OLED_P16x16Str(56,48,"断开连接",F16x16_Idx,F16x16);
    ) N% l8 Q9 W' T( k) j1 E% d/ @4 [
  138.                                         Canned_format = 25;                                
    8 x9 r% I( w3 _2 ]6 o" H9 f
  139.                                 }3 q! d; o( h+ I$ m6 t
  140.                         }
    4 j8 e1 S. D+ b, E. C
  141.                         else- P) d: v1 K& T4 I2 `: ^- I
  142.                         {
    4 f) _- W7 ]% }. X" F* x( M* m
  143.                                 if(Canned_format%10 != 6 )8 U1 \3 }5 J+ Q5 _% F0 X, A4 A
  144.                                 {' X6 _; i/ w- F5 \8 T! C! |) _9 ?
  145.                                         OLED_P16x16Str(56,48,"连接成功",F16x16_Idx,F16x16);
    4 W% m  {# U. m" m7 u* u/ a, }# o
  146.                                         Canned_format = 26;        : e1 N- ?8 Z% j0 E! T4 Y
  147.                                 }
    " ]4 g# G3 B  y# I' ]
  148.                         }        7 H/ l6 z% V# J# T$ L$ q6 S
  149.                 }" j6 h& \5 G' r( u* L* S0 _& F
  150.                 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END
    5 t: d9 x8 p2 M) h6 d) H5 l. Q
  151.                
    ' A2 ]  n, [6 O) a% n; C* _
  152.                
    4 p$ {. C; |$ \/ i
  153.                 ! _2 C5 j2 G1 M- T
  154.                 //********************************************************************
    ' d9 j# C% x/ _% H8 d/ ^
  155.                 //第三页信息
    8 w. Y! r: [! z; B
  156.                 //电量
    2 h) I7 W5 z$ T. {: _
  157.                 //********************************************************************
    , [) Q9 b) k5 m. ~; e" J2 X# D
  158.                 else if( Page ==2 )* K7 k' @' O! c/ p
  159.                 {$ i5 g( [( `5 U9 F& _9 W. @- g: _9 O# L
  160.                         extern double voltage;# w; r9 y- h7 u% a, d! |2 \  g
  161.                         extern double slave_unit_voltage[3];5 @2 b+ R  {  c& ]* i( [
  162.                         & l$ }! y: R" P- F( n" ^# D& f
  163.                         char OLED_voltage[4][6];
    * g1 ?  b- {' ?- f7 A2 |
  164.                         $ r' @4 o4 d' b4 Q* p
  165.                         if( Canned_format/10 != 3); L! s# t7 y2 Y0 q6 u/ g7 G$ A
  166.                         {+ A' t$ _+ [7 J) q& B8 B1 @
  167.                                 OLED_CLS();
    ! }" d8 U, }7 E% P
  168.                                 OLED_P16x16Str(48,0,"电量",F16x16_Idx,F16x16);3 g/ p4 H$ [! B! k) m1 O3 M
  169.                                 OLED_P6x8Str(122,0,"3",F6x8);3 w$ |/ X: A; w/ u

  170. $ ]" S& ?; _) F. N0 h* A
  171.                                 OLED_P8x16Str(0,24,        "M:    V",F8x16);                                ! t+ A, ~9 x, R& l. p$ A& @7 j
  172.                                 OLED_P8x16Str(72,24,"S1:   V",F8x16);! O. G6 u: f, I  f+ J
  173.                                 OLED_P8x16Str(0,48,        "S2:   V",F8x16);
    " V. p8 m4 Q8 y( e& c* G: y' W
  174.                                 OLED_P8x16Str(72,48,"S3:   V",F8x16);        
    : D. ~& \$ p9 J# A; Y  T4 `$ f/ U6 t
  175.                                 
    $ C2 [8 J9 X% \4 |5 p3 q  j6 d
  176.                                 Canned_format = 30;
    0 P. f/ `/ E' `6 t& T
  177.                         }
    * Q/ o+ N$ ~, _! u$ T
  178.                         Transform_double_to_char( voltage , OLED_voltage[0], 1, 1);
    9 ?8 Z5 N& Q7 m/ ?
  179.                         Transform_double_to_char( slave_unit_voltage[0] , OLED_voltage[1], 1, 1);
    ' h6 f1 f1 m" X  \" Z
  180.                         Transform_double_to_char( slave_unit_voltage[1] , OLED_voltage[2], 1, 1);
    ! E  y4 ?# I8 p* H7 \
  181.                         Transform_double_to_char( slave_unit_voltage[2] , OLED_voltage[3], 1, 1);! L$ z1 d. G, z
  182.                         
    % M" h7 ~7 z' _- ^( F
  183.                         OLED_P8x16Str(16,24,OLED_voltage[0],F8x16);; v! S3 O/ [- o; g. N
  184.                         OLED_P8x16Str(94,24,OLED_voltage[1],F8x16);
    3 G3 p/ `1 ]/ ?0 u, ]6 q0 a
  185.                         OLED_P8x16Str(24,48,OLED_voltage[2],F8x16);& c7 F) E0 T# K/ ?9 d
  186.                         OLED_P8x16Str(94,48,OLED_voltage[3],F8x16);( `( T- X: g/ b
  187.                 }
    % y7 O6 ^3 e" z' r, Q
  188.                 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END
    0 D2 K  M" j3 ^' l& Y, K, ^, w( D$ a1 _; G1 R
  189.                 . u2 [) S9 W: x! U+ c9 D
  190.                
    ) J- u1 V: t( o# g( l
  191.                 ' _" q5 X) I6 L- R/ K
  192.                 //********************************************************************
    " K7 c! }6 J6 O1 ?
  193.                 //第四页信息- e) t  I' ~$ Q0 R/ s. b; |( Q5 ~* V
  194.                 //酒精浓度
    ; {" @+ Z, ]; E0 H! k) ~. o  X
  195.                 //********************************************************************( g4 w* J9 l$ r$ S
  196.                 else if( Page ==3 )
      j$ u8 ~3 }8 L; ^8 \
  197.                 {
    1 j% c- }4 `. t& S
  198.                         extern short int alcohol_concentration;
    & s9 i4 a6 _: {4 S+ K2 `1 y% f" r& ]
  199.                         extern short int slave_unit_alcohol_concentration[3];. k: F! J) j; O+ M% ^$ ]
  200.                         ( j% m  C( o. `& d4 {; R
  201.                         char OLED_alcohol_concentration[4][6];
    + ^7 ~7 J4 |9 L5 Y* w, a- I* u
  202.                         3 F! R8 a3 E% z+ T5 a  H
  203.                         if( Canned_format/10 != 4)' U% O% M0 s1 T: A9 c
  204.                         {
    ; v9 T# }- v5 \1 a& ^6 Z" o. Y
  205.                                 OLED_CLS();
    8 _' |$ F0 c% F3 p
  206.                                 OLED_P16x16Str(32,0,"酒精浓度",F16x16_Idx,F16x16);$ ]5 {: Y; J" q- k% ?( Q
  207.                                 OLED_P6x8Str(122,0,"3",F6x8);
    / R8 s2 t1 i! J# G2 E% h5 |
  208.                                 7 g4 W6 x: k  y9 j4 l  P+ X
  209.                                 OLED_P8x16Str(0,24,"A1:",F8x16);& i5 [/ V1 s/ {1 I
  210.                                 OLED_P8x16Str(64,24,"A2:",F8x16);
    7 R) D: h0 ^- B5 o! k$ Y( d: l
  211.                                 OLED_P8x16Str(0,48,"A3:",F8x16);
    3 [, Y4 w1 _+ e  e- e
  212.                                 OLED_P8x16Str(64,48,"A4:",F8x16);& J3 [4 w# ^" }, O6 K
  213.                                 
    6 w4 {) y, B1 F7 c
  214.                                 Canned_format = 40;
    5 I" c& D- |: Y! k( x  G
  215.                         }: p9 F  D8 I# j) ?. \
  216.                         
    % J* }' A/ C  B  _" m* {% N. T
  217.                         Transform_double_to_char( alcohol_concentration , OLED_alcohol_concentration[0], 0, 1);
    # l! T0 j  Z* H8 j  R
  218.                         Transform_double_to_char( slave_unit_alcohol_concentration[0] , OLED_alcohol_concentration[1], 0, 1);
    2 w( }, I! D! n( }# m
  219.                         Transform_double_to_char( slave_unit_alcohol_concentration[1] , OLED_alcohol_concentration[2], 0, 1);
    & o3 j) d( u5 q& w' S
  220.                         Transform_double_to_char( slave_unit_alcohol_concentration[2] , OLED_alcohol_concentration[3], 0, 1);5 `; L/ c! s, k* U0 U
  221.                         ' t0 Y0 T& n/ D5 y- I
  222.                         
    ( ]4 T! ~+ `# F1 m2 Q4 o' T/ Q1 `
  223.                         OLED_P8x16Str(48,24," ",F8x16);. Y8 O( i1 |/ V/ B$ P" q3 J( |
  224.                         OLED_P8x16Str(112,24," ",F8x16);, R! h7 `' ]1 L! ^
  225.                         OLED_P8x16Str(48,48," ",F8x16);
    . }5 C, |  ?1 F# j+ b  }
  226.                         OLED_P8x16Str(112,48," ",F8x16);
    3 D5 d6 x0 O8 O/ e; T6 a7 D( `+ W
  227.                         6 z- B, c5 v5 o( N; e& P/ T) r8 u, S( P
  228.                         OLED_P8x16Str(24,24,OLED_alcohol_concentration[0],F8x16);6 J0 d3 U) a/ Y" x- h/ }' e
  229.                         OLED_P8x16Str(88,24,OLED_alcohol_concentration[1],F8x16);' h: T3 g* \8 Z8 n. a
  230.                         OLED_P8x16Str(24,48,OLED_alcohol_concentration[2],F8x16);* v) i" x. ~0 F3 a" \+ \# y8 T5 \
  231.                         OLED_P8x16Str(88,48,OLED_alcohol_concentration[3],F8x16);
    , v$ a0 Y( Y( ^6 N) m' _
  232.                         
    1 ]1 S4 r: c/ Z: E( f
  233.                 }
    9 P- K8 s+ T! X  [5 |  V
  234.                 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END. p0 _- M1 M1 x0 u
  235.                 - j# s+ i. v) l1 v8 M
  236.                
    ' W8 o# ?* n* z$ u6 Z) T
  237.                 ( b8 F6 p$ ^0 P+ I- [
  238.                 //********************************************************************
    3 @$ Y# y& T, G, e8 a
  239.                 //第五页信息, a( T; F9 U' _
  240.                 //
    ( D+ P# L% Q, p$ ]! l- c* X( U
  241.                 //********************************************************************               
    $ u8 b, p) O9 \7 q
  242.                 else if( Page ==4 ). M2 M6 p4 c  t/ c0 J# D4 T
  243.                 {
    9 V& n- G9 B0 k5 \9 T' z+ T9 B) ]  l
  244.                         extern char Phone_number[4][12];
    " F! z# @+ g8 O2 m" o
  245.                         if( Canned_format/10 != 5)6 C3 h, h" c; l0 x+ t1 M" z# l8 ]
  246.                         {
    ; V5 ^" P+ P' l, m) e7 E6 {
  247.                                 OLED_CLS();
    - Y% K' l6 r& O; n% Q) f
  248.                                 OLED_P16x16Str(44,0,"联系人",F16x16_Idx,F16x16);        
    $ ?  i6 ^$ X: {" E1 x# A/ g
  249.                                 OLED_P6x8Str(122,0,"5",F6x8);0 N4 N8 b! d9 L# g, i
  250.                                   t0 h: k3 _7 o) t
  251.                                 OLED_P8x16Str(0,16,"C1:",F8x16);
    : U% X. P. q6 B2 a8 k/ c1 [- P
  252.                                 OLED_P8x16Str(24,16,Phone_number[0],F8x16);
    5 E; X2 O  i# J% V, p
  253.                                 OLED_P8x16Str(0,32,"C2:",F8x16);  Y  u6 Q& W# I- D& d' H6 Y% X
  254.                                 OLED_P8x16Str(24,32,Phone_number[1],F8x16);
    7 O. l( ]6 z. R( C# u
  255.                                 OLED_P8x16Str(0,48,"C3:",F8x16);
    ; ]1 a) O: K  `" u6 x: _9 N) G
  256.                                 OLED_P8x16Str(24,48,Phone_number[2],F8x16);
    " `' V' [8 z  `. f* i
  257.                                 
    5 u3 B; R" N% ~4 M  |* q7 U) x1 N6 ^
  258.                                 Canned_format = 50;7 I1 \% }3 f" @' A& i& E
  259.                         }2 G3 x  X* M3 a& j
  260.                 }) e9 ~0 q' w2 V" k, Q+ x$ {: i
  261.                 //********************************************************************
    2 U$ S4 d; a$ C; p2 z* J; L8 ~
  262.                 //第六页信息& }3 w# C: C$ }( i: |8 r
  263.                 //车辆状态
    1 j2 ]; |* d% ^8 a7 j: Z
  264.                 //********************************************************************$ G% D# E8 x/ z. e6 S
  265.                 else if( Page ==5 )//第一页
    : G1 i+ y9 s! N+ `" {2 ~7 ?. n
  266.                 {1 C. b& H7 A8 ~
  267.                         extern char DRUNK_DRIVING ;
    . d* M6 M' E& L/ x. ~* a8 d
  268.                         if( Canned_format/10 != 6)
    5 y6 d% j: M$ M6 p
  269.                         {8 z3 M) l- L3 T1 T
  270.                                 OLED_CLS();# k8 T$ b- ^  A* ~  ?
  271.                                 OLED_P16x16Str(32,0,"车辆状态",F16x16_Idx,F16x16);        
    5 j, `4 f- s3 }6 C
  272.                                 OLED_P6x8Str(122,0,"4",F6x8);
    - D, I5 B! N+ j% X0 w6 \
  273.                                 8 s8 k: {7 Q; F. w. K2 ?
  274.                                 Canned_format = 60;        
      M: C, A; f8 U: W, X# `
  275.                         }' ]3 P: D' P- M! P/ X# m5 \
  276.                         1 m! n/ b; p* Q- K, R, t
  277.                         if(DRUNK_DRIVING==0)$ |* I5 g4 x5 c% I
  278.                         {$ O  J4 s6 @2 }/ x
  279.                                 if( Canned_format%10 != 1)
    . c. a; `/ j" ?8 y+ L! h" d
  280.                                 {' i8 _; T  g. {( u' W* F# I: b
  281.                                         OLED_CLS_y(16);- p) P: z' L7 {6 t) F9 p
  282.                                         OLED_CLS_y(24);1 V: o0 H) ?( G0 a; \2 k# C8 @
  283.                                         OLED_CLS_y(32);
    $ {3 o8 y. s* K) T6 T8 Y2 Q8 a, |
  284.                                         OLED_CLS_y(48);/ G# B$ s) J# j3 j6 X
  285.                                         OLED_CLS_y(56);; q7 ^# r+ g& y/ n, j
  286.                                         OLED_P16x16Str(16,32,"车辆正常行驶",F16x16_Idx,F16x16);        
    9 R  u' `3 b, {& f
  287.                                         Canned_format = 61;
    8 G' n2 B. \; @5 `* M
  288.                                 }
    . Q) A% Z* b( t
  289.                         }- t# O4 S8 H6 P3 @7 ]9 ~
  290.                         else9 B  {# x7 m, o6 ]
  291.                         {
    ( N# H& T& Q2 L- |4 }! _+ B) z
  292.                                 if( Canned_format%10 != 2)
    8 i: Y! d9 H2 n! t- \
  293.                                 {8 `. ~& x, P' z3 R
  294.                                         OLED_CLS_y(16);
    8 Y' w) J4 O+ I/ W' O: \9 _
  295.                                         OLED_CLS_y(24);" `2 B) {5 w8 J% H( i: p) K( T
  296.                                         OLED_CLS_y(32);8 V7 r# u+ ^  E
  297.                                         OLED_CLS_y(48);) j- g4 y3 A; U# S- R
  298.                                         OLED_CLS_y(56);. g" I) W; y2 `+ K1 l$ ~" j% E7 u
  299.                                         OLED_P16x16Str(8,24,"发现驾驶员酒驾",F16x16_Idx,F16x16);
    # o: c4 Z3 [/ l4 L5 k. j+ L
  300.                                         OLED_P16x16Str(16,48,"车辆禁止行驶",F16x16_Idx,F16x16);        
    - ~; d5 F: Y- D+ h
  301.                                         Canned_format = 62;
    9 T+ u4 \, D. y
  302.                                 }* l$ j6 k! A3 F, v* ^
  303.                         }        ; c, j" q0 F/ d! D) J4 e
  304.                 }               
    % @5 P' L$ X8 C
  305.                
      A; b& J" v" T4 Q
  306.                 //********************************************************************" d# b" z3 v2 S
  307.                 //重新开始显示第一页
    6 N! b( M4 e$ ?$ T. P, U) K
  308.                 //********************************************************************; V& d: {& c( [" f% u3 j
  309.                 else if(Page==6)7 [$ P+ u' v" e/ ?
  310.                 {1 ^8 y& q7 p/ O2 q) V7 h
  311.                         Enter_number =0;
    + ~# |, `7 B1 c/ M4 d$ A
  312.                         Canned_format=0;% q- ]% e4 a4 n
  313.                 }" W/ K/ q1 J7 `  t: {" C8 B( T
  314.                 Enter_number++;# x' T: e6 E# i1 o$ Z) P  V: y: [
  315.         }
    - f4 f& Q( L& v% P3 U- K, }* \. c
  316.         TIM_ClearITPendingBit(TIM11, TIM_IT_Update);7 k' F' N1 T: R/ ^# I: V& m
  317. }0 ^& l3 R; o) R6 v
  318. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END</font>
复制代码

! U" g3 Y# u( @, e) ^$ ^! ]. J% B/ k8 D) D
5.酒精传感器

  酒精传感器使用ADC+DMA进行数据采集,每50ms进行一次ADC采集,每次采集20个数据,对这20个数据取平均值,获得一次酒精传感器的测量值。每100ms进入一次定时器中断,将主机采集的酒精传感器测量值与其余从机采集的酒精传感器测量值进行比较,从而判断驾驶员是否酒驾。

  1. <font size="3" color="#000000">//********************************************************************
    / d. \: d. U6 E# Y
  2. //100ms进入一次中断3 m2 M; Z- V) o" n
  3. //判断是否酒驾/ e; Q/ I  f% a
  4. //********************************************************************% ~- n2 L' y2 [" E" s  m4 w7 j
  5. void TIM1_BRK_TIM9_IRQHandler()3 J% T# x8 _$ H% j6 E2 y# G3 ^8 h
  6. {
    ; J5 e  b5 l* `" h, l/ I4 [8 A# P
  7.         extern short int alcohol_concentration;
    , H2 r& s3 H9 @3 D: H/ c
  8.         extern short int slave_unit_alcohol_concentration[3];1 i1 i3 B9 _; ~( Y- ~
  9.         extern char DRUNK_DRIVING;
    + j% Y* v$ w9 f8 S8 p
  10.         extern u8 voice_prompt[15] ;
    2 P1 @' K- Y4 ^; v2 `
  11.         static u8 Number_of_drunk_driving= 0;
      p- ^& C7 D9 q/ B+ v
  12.         if(TIM_GetITStatus(TIM9, TIM_IT_Update))9 ~- k$ b9 |8 [" u! A* h- P8 b
  13.         {
    . |- f; a* s. `4 b/ h  ^' h( Y3 O
  14.                 double Weight_M=1 ,Weight_S1=1 ,Weight_S2=1 ,Weight_S3=1 ;
    0 V/ u$ `2 L8 O- e( P& f
  15.                 if(        alcohol_concentration > 2000 || DRUNK_DRIVING == 1)//当主传感器大于规定值开始判断4 z9 s- A/ z& k$ ]+ Z3 }
  16.                 {
      d  }- x! j2 P# |# h# w/ B
  17.                         //*****插入算法判断是否酒驾,之后需要修改
    7 t8 t$ c  M% B) u. b( y& O
  18.                         if(Weight_M * alcohol_concentration > (Weight_S1*slave_unit_alcohol_concentration[0]+1 K/ P5 z- O' [" ^% o0 X4 |" D/ e) N
  19.                                                                                                                                     Weight_S2*slave_unit_alcohol_concentration[1] +5 G! o$ f* ?$ @8 W; ]* J' _
  20.                                                                                                                                    Weight_S3*slave_unit_alcohol_concentration[2] +500) /3;: \0 W$ v5 b6 p
  21.                           )
    , y( M2 X6 P1 a, }$ \, H3 A( q
  22.                         {8 X5 z1 M; N2 B$ O: c
  23.                                 Number_of_drunk_driving++;
    - t9 @( S: n8 [1 n. V
  24.                         }+ d0 v; f3 ^' L7 y) O( T/ w! K
  25.                         else if(Number_of_drunk_driving!=0)
    0 ?% b( K& [5 L, ^- l) G3 u: L) T7 i+ a7 e
  26.                         {
    ! B6 {, e. V$ C/ M8 `) A
  27.                                 Number_of_drunk_driving--;
    : V& [0 K) m( C/ ~# T0 Q: v2 X+ m
  28.                         }
    % E8 N3 w8 x( q+ H, o. {  o
  29.                         //>>>>>>>>>>>>>>>>>>>>>>>END* _5 n) G) ?% H; i* K6 F- a! y
  30.                         
    9 g/ x, k7 L) O& O; F
  31.                         //*****是否连续10次判定为酒驾9 g4 L3 }  c1 R' r5 g$ v
  32.                         if(Number_of_drunk_driving>10)
    ( x6 }0 b& Z$ }; R) s
  33.                         {! n! g' b( r0 J, ^( P
  34.                                 Number_of_drunk_driving = 10;6 G5 V5 ]7 [3 u" @+ r- C
  35.                                 DRUNK_DRIVING = 1;
    : y8 ^' c! g5 K# R. E4 [
  36.                                 if( voice_prompt[3] == 0 )
    * w* s; e7 }4 \% N
  37.                                 {! |; ?( h7 }, D! f
  38.                                         JQ6500_play(4);
    ! A# l1 `6 V5 I# w" I0 A  B
  39.                                         voice_prompt[3] = 1;$ e' ~( |( S" ]
  40.                                         voice_prompt[4] = 0;
    8 Q# H. E) w2 X
  41.                                 }
    + Z& ]2 P/ q* `8 S+ _2 E8 X
  42.                         }
    / e5 y1 b: m8 m5 J: k# t+ I
  43.                         else if(DRUNK_DRIVING == 1 && Number_of_drunk_driving ==0)" T& [$ }0 f4 _" x4 I; H3 U
  44.                         {' o7 [/ n0 C% j' J/ M+ x, H
  45.                                 DRUNK_DRIVING = 0;5 t$ r$ i) G) m# l5 |
  46.                                 if( voice_prompt[4] == 0 && voice_prompt[3] == 1)
    $ L4 _# g8 f+ E2 p
  47.                                 {
    ' X; }2 g0 J2 K0 n
  48.                                         JQ6500_play(5);; ?% L- V1 n5 c5 h  e* f& {9 R
  49.                                         voice_prompt[4] = 1;
    ' _3 ^& o7 O" A. X
  50.                                         voice_prompt[3] = 0;
    0 @0 U' b: T( o* \+ t
  51.                                 }8 @9 C. i7 K( c( R+ \- j
  52.                         }
    - b, P. H: ], x
  53.                         //>>>>>>>>>>>>>>>>>>>>>>>END/ T! `# |: I( u( \
  54.                 }               
    % }' u7 O1 A% y1 b
  55.         }( t* l) C7 M9 c) A
  56.         TIM_ClearITPendingBit(TIM9, TIM_IT_Update);
    ) e; `7 i% K; B! [/ b6 |6 s: `
  57. }9 ]' h- c) X/ q3 M* L3 N5 ]& [
  58. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END</font>
复制代码

7 A4 f" h2 R0 N" G7 I3 u; v- x6.语音模块

  语音模块采用UART4进行通信,波特率为9600.通过UART4发送16进制指令对JQ6500语音模块进行控制。

  1. <font size="3" color="#000000">*****************************************************+ m9 M; g) c2 I3 W- ?6 T6 x
  2. //JQ6500发送控制指令0 P# Z2 p2 y  K$ b  r6 G* E
  3. //********************************************************************, F! m& q! w' R
  4. void JQ6500_control_command(char command)
    6 Y! I' p1 _. e" T8 E9 z( t
  5. {
    ; t7 m, L2 q8 g- _; u3 p) x
  6.         
    3 D3 s. n2 i9 H) y4 W0 B3 ~$ q1 J: V
  7.         char JQ6500_instruct_1[5]={0x7E ,0x03 ,0x06 ,0x02 ,0xEF};                //音量00~1E  I4 z/ |1 |* t  Y# G) ^- z
  8.         char JQ6500_instruct_2[5]={0x7E ,0x03 ,0x06 ,0x17 ,0xEF};                //音量00~1E/ r0 \+ G  N7 Y+ G8 z4 g: @8 Z
  9.         char JQ6500_instruct_3[5]={0x7E ,0x03 ,0x06 ,0x1E ,0xEF};                //音量00~1E
    / D5 S4 t" b7 @! c
  10.         
    ; a5 n6 e* a+ U# p, N
  11.         char JQ6500_instruct_4[5]={0x7E ,0x03 ,0x11 ,0x04 ,0xEF};         //播放模式:0 1 2 3 4(ALL FOL ONE RAM ONE_STOP)2 ?) s0 _! s0 z( B: ~1 t
  12.         
    : Q: H% i0 U% Y  x
  13.         char JQ6500_instruct_5[4]={0x7E ,0x02 ,0x0A ,0xEF};                                //低功耗 8 O" L$ K/ m% B$ ~- G
  14.         char JQ6500_instruct_6[4]={0x7E ,0x02 ,0x0C ,0xEF};                                //复位
    / F  L! s% E5 P# P( @5 E
  15.         
    ( ^5 o2 f8 F$ _( I( E' f7 o

  16. # o. m3 {, G5 j9 n8 r% [' R' M
  17.         switch (command)5 L2 h2 g7 j3 C8 H" p  z
  18.         {& P0 l% L- u5 l3 d+ |
  19.                 case 1:Send_hexadecimal_UART4(JQ6500_instruct_1);break;8 [9 r6 o$ ]: ~+ y) F1 Z7 @& ]
  20.                 case 2:Send_hexadecimal_UART4(JQ6500_instruct_2);break;/ U! x- A# ?" `" S2 O  g
  21.                 case 3:Send_hexadecimal_UART4(JQ6500_instruct_3);break;
    2 o. i7 b# e$ L3 Q( q" A
  22.                 case 4:Send_hexadecimal_UART4(JQ6500_instruct_4);break;
    2 V; V7 s) U3 Q/ k3 S
  23.                 case 5:Send_hexadecimal_UART4(JQ6500_instruct_5);break;' V# Q& g8 Z( O' A0 a; q( u6 O7 X
  24.                 case 6:Send_hexadecimal_UART4(JQ6500_instruct_6);break;
    3 w3 p) ~* i. t6 O1 r
  25.                
    ! ?) Y  A: I2 \% d/ F2 ]
  26.                 default: break;- r, @. P% ]& M, d' n$ k; m
  27.         }  V% h  X; G; I: ^% x
  28.         delay_ms(50);
    , @! ]- j. R! |
  29. }3 k/ j( a- }/ O+ A! V( B8 h
  30. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END
    1 d2 `, M+ g' e+ T/ m
  31. 1 j2 x( L. S! p5 ~: }9 ~. ^2 R
  32. 0 m# I* s8 _! F9 \2 a% M3 Z4 B
  33. % p4 K; s  n& u7 w
  34. //********************************************************************
    - Y) J. k5 k% w4 U8 n3 |8 S  m
  35. //JQ6500语音模块播放指定曲目% T3 F9 B1 e+ _! Y; Q
  36. //********************************************************************
    3 n/ V8 o+ Y0 b! k) [9 s5 ~6 M
  37. void JQ6500_play(u16 number)
    9 q5 i1 u9 ]3 f7 M
  38. {
    7 l; D# R0 z/ y7 X1 z; X
  39.         char JQ6500_play_number[6]={0x7E ,0x04 ,0x03 ,0x00 ,0x00 ,0xEF};                //音量00~1E; b6 O# r5 V# _$ I9 Q- {* b( S9 x1 c
  40.         JQ6500_play_number[4] = (u8)number;7 x. T) x5 k% Q7 g
  41.         JQ6500_play_number[3] = (u8)(number>>8);
    8 Y5 P9 y) F( N  t) Z
  42.         " M+ ^; ?3 T2 z+ \0 v+ m2 Y
  43.         while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_12)==1);* @3 h4 H( Z1 V9 o
  44.         while((GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_12)==0))
    ' U" L- v  L1 L* {( F
  45.         {# Z' b! n$ a( s! ~" B( P
  46.                 Send_hexadecimal_UART4(JQ6500_play_number);delay_ms(100);, ~9 C7 }7 e& j8 C  B
  47.         }- f7 y4 x, e  P, t9 u# @8 ^
  48.         while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_12)==1);& U7 W5 k. ^$ F9 D! f4 j2 q
  49. }
    6 u( f; K6 C8 |6 {
  50. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END* \4 ]7 G" g  c
  51. $ b3 X! a+ B" k  |) i& }
  52. 8 d( Z0 Q' d+ E2 D2 L
  53. + Z3 Q/ F4 G' d. a
  54. //********************************************************************# ?. y! N8 |0 \8 w. t7 [
  55. //UART4发送16进制数据
    % {* p. V" o, r, n! n
  56. //********************************************************************
    $ t3 a- w# y  t8 J1 z
  57. void Send_hexadecimal_UART4( char *array )( l) E$ X0 w/ g/ P" z* h
  58. {
    ) `. }7 B6 N, {; _2 ?
  59.         for( ;*array!=0Xff ;array++)
    - i3 Y3 j/ ]) m; I* O
  60.         {
    / n  S  p0 k6 k$ l) Y
  61.                 while( USART_GetFlagStatus( UART4 , USART_FLAG_TXE ) == 0 );
    - @8 ~0 {# d& h& O$ n& u# W4 D5 Z) k
  62.                 USART_SendData( UART4, *array );- R; o3 i1 a( q2 Z9 M0 z6 M
  63.                 while( USART_GetFlagStatus( UART4 , USART_FLAG_TXE ) == 0 );
    . K/ Y( L+ a# l* S) T1 {' @; m
  64.         }
    / ]' G: _' \0 Y: r
  65. }; A; i" e7 D) S4 W7 A7 t& R7 A
  66. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END
    6 `. }, c* h) T- j
  67. </font>
复制代码

) z0 F( X. b+ b- Y1 d1 n; v/ z% m2 z' ]& n
从机部分

' W) ~2 ~! c( S: [! Z1 C

  从机采用HAL库进行编程

2 N' v3 W* l' n) @8 e

1.NRF24L01

  每次完成一次DMA传输后进行一次数据打包,在主函数中进行检测,如果数据准备好了,就启动一次数据的传输。

* ]5 s) W# ]5 \5 ?/ }3 H
  1. <font size="3" color="#000000">void DMA1_Channel1_IRQHandler(void)
    9 Y0 r5 h) p% b; |! C' m# l
  2. {
    5 X& B' q8 T( J( ]0 t
  3.         u8 i;; ?5 Z. a/ S$ Q/ E% O: o
  4.         double voltage;
    2 B) K1 ]2 o6 k
  5.         int alcohol_concentration;
    . O; ^) w/ B3 R) N" K" O
  6.         char Transform[10],data_head[5]={"KH1&"};) w- a: b, ~2 q. Z3 ?9 a3 ]# r# j
  7.         u32 ADC_data1=0,ADC_data2=0;
    6 c; E! L, [4 V( G) c, T) f! y
  8.         for(i=0;i<20;i++)
    . T7 g4 }; \5 Z% C
  9.         {7 j" M. F# n( S+ J
  10.                 ADC_data1 += DMA_ADC_DATA[i][0];
    ' }- i3 c: s0 Q4 ?
  11.                 ADC_data2 += DMA_ADC_DATA[i][1];
    . Z: S8 @1 t# A/ b& {! h1 g) u. d
  12.         }: h) f' e: _! `' |
  13.         alcohol_concentration = (double)(ADC_data1/20)+0.5;* a6 I% Y( B7 C5 C
  14.         voltage = (double)(ADC_data2/20)/4096*3.3*(3-0.025)+0.005;
    & P6 F6 v% G# X1 ?7 r! U- u
  15.         
    7 ]0 t- V: w( w- X% a
  16.         if(NRF24l01_write_TXdata == 0)( V; H4 M7 M& n# {9 @
  17.         {
    * v, {8 S" v$ t( o) M( O: F
  18.                 memset(NRF_TX_Data,NULL,strlen(NRF_TX_Data));        //清空要发送的数据
    , c& i0 r( Z! ~2 u5 }7 R* K
  19.                 strcat(NRF_TX_Data, data_head);                                        //发送数据加数据头
    ! _  U1 u, [, H7 F3 ~( S2 R, m+ T
  20. 1 P3 I- u) q& W9 ^; R* p6 V3 c( ^( ]
  21.                 NRF_TX_Data[strlen(NRF_TX_Data)] = 'V';                        //添加第一段数据3 R3 u: {- q& j, }0 U3 T
  22.                 Transform_double_to_char(voltage, Transform, 2, 1);
    0 m* d1 I9 u* K/ L; L
  23.                 strcat(NRF_TX_Data, Transform);
    ' {2 C) l0 U' ~) K) w8 B9 T+ j; Z
  24.                 NRF_TX_Data[strlen(NRF_TX_Data)] = '&';
    $ `$ p2 o+ r7 y
  25.                
    4 r4 x' P* k/ j) Q1 h( ?2 \
  26.                 NRF_TX_Data[strlen(NRF_TX_Data)] = 'A';                        //添加第二段数据
    / |+ s0 g- T7 x1 ?/ E* G, F
  27.                 Transform_double_to_char(alcohol_concentration, Transform, 0, 1);. `0 y  x/ d0 T) ?0 m
  28.                 strcat(NRF_TX_Data, Transform);& U4 E2 k5 W9 }7 G
  29.                 NRF_TX_Data[strlen(NRF_TX_Data)] = '&';5 M, L& j; u0 M! @$ m
  30.                
    1 b: I, I# r( g
  31.                 NRF_TX_Data[strlen(NRF_TX_Data)] = '#';                        //添加结束符+ |+ K. D8 H4 j9 L' A1 S
  32.         }
    0 Q8 H# Z& f4 |. C# N
  33. //        printf("%s\r\n",NRF_TX_Data);3 ]/ Y9 B! s8 C6 A( u2 v8 d
  34.         ' I1 A  f  t+ z* {$ @% G# [/ Q
  35.         HAL_DMA_IRQHandler(&hdma_adc);9 k/ w' l; o# e3 e7 a- f5 M1 [

  36. 1 _$ ]+ G6 l3 _/ ~' }
  37.         HAL_ADC_Stop_DMA(&hadc);
    3 w8 k5 i  \1 v& H1 ~8 s
  38. }</font>
复制代码
; A4 f6 P4 h+ A
四、实物展示
20200907145407605.jpg

) [6 q9 E2 j7 b  X& q3 ^7 d3 O
20200907145419644.jpg
9 \7 a; k, N1 q9 m- u# ?+ Y
6 j% Z3 l5 |3 ]; d1 D3 y9 ]6 o! ^

4 L" a6 k, T9 e& E, K+ ]. E' p五、改进方向

" {% V# o+ [9 ^* @0 `4 K1.酒精传感器  H& ~/ q% G8 A$ z8 ~7 I. f

  刚开始使用MQ-3作为酒精传感器,测量灵敏度不足,所以采用电桥电路,并使用运放将信号进行放大。但之后更换TGS2620作为敏感元件,灵敏度大大增加,只使用简单的电阻分压电路就可以得到较为准确的测量值。目前的电桥电路设计也有一些问题,由于调零电阻的关系,导致同样酒精浓度变化下传感器测量值的变化灵敏度不一致,如果想使用电桥电路获得更精准的测量数据,需要改进电桥电路的调零部分。


; `7 t  j) ~2 B9 S

2.短信5 N, o( P& @9 t9 R% k$ `) Y7 U8 ]8 l) H

  当前的GSM模块只可以发送经纬度数据,需要用户自己使用谷歌地球进行位置查询。今后可以使用GPRS数据传输与阿里云等平台进行网络连接,通过一些高德地图提供的API进行对经纬度进行逆地理编码,从而获得当前具体的所在位置。也可以使用微信小程序,直接查看当前所在位置的地图。


6 w7 R9 J0 t3 Q+ {; l

3.加入键盘  L0 m( D3 H) s

  主机的PCB电路板已经预留了矩阵键盘的接口,加入键盘后可对联系人进行设置,OLED显示信息进行翻页等操作。如果使用了微信小程序,可在小程序上完成对联系人进行设置的功能,省略键盘。


) F8 |1 e$ T* j% R4 t3 U' |4 x

4.加入人体检测
' x/ J9 ^$ b: @' a

  开始计划使用红外热释电传感器检测是否车内有人,当有人驾驶时,系统开始检测酒驾行为。无人驾驶时进入低功耗模式。但由于红外热释电只能检测运动的物体,无法精准检测人体活动,容易造成误检测。之后可以通过判断是否有启动车辆行为来决定系统是否进入工作模式,或采用其他模块检测人体活动。

; w- @4 M" \" U7 `% L0 r% M+ u

! `3 h) \+ J+ c) `2 |+ {
  S' c7 s. o/ m8 ?! H7 r8 |9 A+ ?' U
3 |3 p8 f' ^% O" N. E8 R; K/ O7 m

1 j: H( @$ \& U
赞 收藏 1 评论1 发布时间:2020-9-11 12:54

举报

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