请选择 进入手机版 | 继续访问电脑版

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

STM32 智能防酒驾装置

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

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

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


8 D9 ]# b) K7 [- J' |

二、硬件电路  P$ r" i" f  ?( o9 i4 O. M4 T" Q
9 v6 H0 a* w1 w5 v4 W/ }# v
1.主机

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

  \* m2 `) b$ d0 u6 G: P7 g0 [8 b7 q

20200911125526.19a5966287a6415602e11d615c611bde.png

20200911125551.8719143ed6a85976e3d5f2e14ccee351.png


. c0 ^. h: N8 n; m& [

2.从机3 M  F7 f) f2 ?8 d

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

20200911125610.670127be52c0fe9206aa1ff83431e1a8.png


+ ]# a' k/ \% T. M# f  d1 o

20200911125621.d6ee35ce3a04c0af9222fed41ba1f83c.png


0 h. h% L" p3 C+ |9 t

3.酒精传感器
: M1 _8 O0 `' }( A

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

3 m" q8 t4 n4 W+ N7 W$ _

5.png

20200911125654.3ba28eacb3f3ad543a45da431bb51eb5.png

6.png

6 e, o8 X. B5 ?- W% L5 B( _. h

9 z! t- p. K8 A2 V( H
三、程序设计
7.jpg
. d0 ~# l# u, P) F7 a7 u4 ?* u7 ]
" w/ P% S: \, s7 S* p. a
: D/ f! n9 e. Q7 p$ Y; J; j5 D
主机部分
# b* a2 W3 |0 T) u8 \% e

2 S1 c9 @9 X; w( O1.GPS

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

  1. <font size="3" color="#000000">//********************************************************************
    ' ?/ s3 l1 P2 }& p) l' _
  2. //得到GPS的经纬度) Y: [' p. L, X5 P. I" Y
  3. //数据为char型数组& z. h' i, }) [( R8 y- W
  4. //若没有得到数据则无返回结果  {4 ^- a/ ]+ Y! B
  5. //********************************************************************) F  W, w7 x& e0 s& ^+ K. p
  6. void GPS_GetData()
    ( V2 i% R# }+ X; t9 Q
  7. {
    . C: u1 @1 D# `
  8.         u8 i;: Y6 Z1 r( G6 K) k& d
  9.         if(USART3_RX_STA&0X8000)                //接收到一次数据了; f8 B! ^9 p2 w: u0 w$ ]. A1 T
  10.         {
    ; B' V; q! B9 {( ^* @9 A
  11.                 USART3_RX_STA=0;                                   //启动下一次接收" B9 K6 d2 N3 A  l
  12.                 . \$ [+ f+ k8 i7 X3 i" h# i
  13.                 GPS_Analysis(&gpsx,(u8*)USART3_RX_BUF);//分析字符串! g+ D9 g3 C. O! \$ F& D6 u. j
  14.                 5 c$ o" r  G. S" ~" v* I6 b
  15.                 if(gpsx.gpssta==1 ||gpsx.gpssta==2 )        //GPS定位成功
    - U! H3 `6 l  i) o
  16.                 {
    $ c5 h' B7 {% C5 P% L3 c
  17.                         u8 i;
    & J  v/ Y; U& T9 j/ n4 B
  18.                         3 I" p* K' o$ Y4 X# I. X( A' u
  19.                         GPS_positioning = 1;
    3 b5 G0 ~! d% [1 [2 ?8 \# m' P

  20. 7 S* O1 O- w2 i* C2 c
  21.                         Transform_double_to_char(((double)(gpsx.longitude)/10000000-0.003466), longitude_char, 6, 1);
    ! x$ J8 {1 V2 m- s4 z/ {# U1 D
  22.                         Transform_double_to_char(((double)(gpsx.latitude)/10000000+0.323707), latitude_char, 6, 1);        
    + _. p) b" |; I4 l7 I9 ^: M6 a
  23.                         & A3 Y5 L2 K: V" @
  24.                         i =strlen(longitude_char);7 s# E3 n: p  L# K) K/ ]* ~8 o
  25.                         longitude_char[i] =gpsx.ewhemi;
    8 \) w1 Y7 Q+ \" K( G! i+ @
  26.                         longitude_char[i+1] ='\0';
    . ~4 i4 A3 K- l" ^
  27.                         0 I+ S5 L4 c- d  C: J( p
  28.                         i =strlen(latitude_char);! P0 {: n$ Q; w. P. _
  29.                         latitude_char[i] =gpsx.nshemi;
    2 t7 O- l8 w% C- n$ a* v5 ^0 i' ?' y
  30.                         latitude_char[i+1] ='\0';
    5 i! \- A8 T# e& J2 x
  31.                         
    5 k; r; U( r2 t) P! G5 l
  32.                         printf("GPS定位成功\r\n");        
    " h  C, ^5 f/ g. |
  33.                 }- G/ N1 m  U! n# f5 N  W
  34.                 else if(gpsx.gpssta==0)% p1 v! T5 u  H% p( u/ d
  35.                 {        & D! P3 l6 W" U, w! ]7 M
  36.                         if(GPS_positioning == 1 )+ C# ?. p+ @8 c6 O( K
  37.                         {
    % X( s- w6 H$ w$ H! V; z
  38.                                 GPS_positioning = 2;
    ) X4 I6 G1 l) G) D3 z* p1 ~
  39.                                 printf("GPS信号弱\r\n");
    ; J+ h! X# @4 n* R
  40.                         }2 P# K' c( \/ F" P8 F/ ]
  41.                         else if(GPS_positioning == 0 )
    1 \6 ?: _; ^' }3 X- q& ?: b0 A
  42.                         {$ k. c3 \$ P9 z; ?
  43.                                 printf("GPS无信号\r\n");
    ( y* o. |( o/ B8 P2 V: }7 ]
  44.                         }2 v8 j1 U3 ~3 o
  45.                 }4 I' Q7 F  c' }8 ~5 `( o3 s
  46.                 gpsx.gpssta = 0;
    : L8 F: N$ z; I
  47.         }
    1 H' b  O+ ~2 {3 n+ M7 Z* R4 {% N
  48. }( {3 e9 \0 D# J3 h) ]
  49. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END/ a  W$ ?( c* \# v4 S; g
  50. ' C, S9 y" m  ]  R: b

  51. 8 V7 c9 q1 n# }, N; y/ t( [( L5 i* O

  52. ; [7 Q. e4 _& n3 n/ w
  53. //********************************************************************! M& P3 ]9 _: B6 |! D7 v1 K
  54. //浮点型/整型转字符型
    : l6 a8 `+ J  s- v
  55. //Decimal需转换小数
    ; I, c% I1 W6 F8 e+ B- a
  56. //Character字符型储存的地址,在主函数定义
    $ t; }7 p9 B8 d+ c" \
  57. //precision保留的精度3 P# v4 e: u1 r8 |+ T/ E
  58. //round是否四舍五入,1是,0否8 ?9 T+ q# D& D7 p* y9 p
  59. //注意可以转换的长度
    2 n& @& r# w" s. @3 L- T
  60. //********************************************************************
    ; F" i8 L# D/ ]+ Q& y7 D
  61. void Transform_double_to_char(double Decimal, char *Character, short int precision, char round)" l# ]6 a  m' _; K6 F9 x" D
  62. {; Z8 r) ^" _* _, R  @) Z
  63.         int i,x=1;' C' ?7 @0 U" \% y6 u2 V4 I- G
  64.         int integer ,integer_decimals;
    . K  C; l  n3 N+ o
  65.         char temporary_char[10];" n% u1 J3 |2 `& Z
  66.         for(i=0;i<precision;i++)* G3 g$ D- d0 b" T- h/ U6 O
  67.         {* J: D$ k; ]0 @/ z, W0 e6 J
  68.                 x *=10;
    $ E7 k+ Z3 I  ]/ b) M
  69.         }+ D! H/ [) r; g  I! h
  70.         integer = (int)Decimal;                                                                                                                        //整数部分  s$ a$ D8 S4 \
  71.         integer_decimals = (int)((Decimal - integer) * x + 0.5*round);2 b' A! H3 T! D
  72.         for(i=0 ;integer>0 ;i++)
    / e( d% O8 S6 ~5 |$ a7 `
  73.         {
    5 x2 ?6 z2 F* h; Q7 W2 ]
  74.                 temporary_char[i]= (integer % 10) + '0';
    6 P# h: T& `: w9 e/ k) [
  75.                 integer = (int)(integer/10);
    3 ^4 g- t& }' [% a. m. Q- E
  76.         }2 N  G5 F4 L+ E1 H
  77.         if( i==0)  {. ~! u; b& U6 X
  78.         {3 {. ^" O0 O% G% c  j
  79.                 temporary_char[i]= '0';' z( w! [+ i# V
  80.                 i++;  P  q+ v/ M$ G. M7 f8 s; A
  81.         }/ U3 b3 }6 K9 s$ s) p7 E; Y
  82.         for(x=0;x<i;x++)- D+ S) [  o! B* o) a
  83.         {# A1 o& Z# }/ C0 [3 r  p
  84.                 Character[x] =temporary_char[i-x-1];8 i0 K$ M# R( ^8 s! f
  85.         }
    $ _9 w2 I- ~6 R2 ?/ W
  86.         memset(temporary_char,NULL,sizeof(temporary_char));4 i7 d+ k) q6 v
  87.         if(precision!=0)9 r. T1 k# n4 `6 w) `* S2 b
  88.         {% E9 x( S) ?9 g( m+ D
  89.                 Character[x]= '.';! ?! B* V/ T1 H. f/ h2 Q
  90.                 x++;0 D* q# t* _8 j
  91.                 for(i=0 ;i<precision ;i++)
    6 H4 i( S+ a9 {# x$ f# o: w
  92.                 {' f$ R/ Q9 J9 ^3 ~7 v
  93.                         temporary_char[i]= (integer_decimals % 10) + '0';
    - H5 n& {- y" |# Z$ M6 s3 L. C
  94.                         integer_decimals = (int)(integer_decimals/10);) p% E+ p6 P7 X
  95.                 }
    $ P: M( S# f+ c2 q# J+ n' ]/ U
  96.                 for(i=0 ;i<precision ;x++,i++)+ W' S" |! I- O* D* C, x; D$ {
  97.                 {+ M) _1 b6 G% ?% D1 z
  98.                         Character[x] = temporary_char[precision-i-1];        
    1 j+ Y* u9 `0 }# I
  99.                 }1 {+ V, ?. o& q5 O  ^! w
  100.         }$ f2 A1 F' [0 b  F5 ?; b
  101.         Character[x] ='\0';
    $ |1 O9 z" o  f! j7 m! q
  102. }
    - I/ S: c/ \& L3 R
  103. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END</font>
复制代码
) Y3 D' S* A, W+ c! p2 i
2.GSM

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

  1. <font size="3" color="#000000">//********************************************************************9 F2 n9 w! |- E! D# F9 |5 m# H7 h5 u
  2. //SIM执行命令( D$ k" k/ w9 t3 K6 }- P: _1 e
  3. //0~3发送短信,0~3号联系人
    ! x! C' R4 S) n- Y9 U4 s( V1 R& U
  4. //********************************************************************4 [. P7 b. N( W% H& e' p; @
  5. char SIM900A_Executive_Command( char number ). s8 o& ?8 k3 n! {+ ~
  6. {        1 b$ H" k; z( U! ?' K
  7.         if( number == 0 ||number == 1 ||number == 2 ||number == 3 )
    $ y, g: @0 q* B( j. `/ O8 y/ o' n3 V% T
  8.         {1 C# x5 `0 P$ W4 }9 W2 {
  9.                 int i ,Length;
    . b! ?8 x4 K; E, e7 I5 Z7 r
  10.                 char Message_content[280];4 _: `* `% A$ j0 Y; g  q
  11.                 char AT_CMGS[4],Data_Length[4];4 \' ]! [! m+ M' _& r
  12.                 char PUD_latitude[50],PUD_longitude[50];
    ' q( X# [2 E8 q5 t( }3 }# ~; B
  13.                 char PUD_longitude_latitude[100];
    , K/ X0 l& ^* U
  14.                 char PUD_comma[5]={"002C"};( X; d2 L' W' H7 t* }; O
  15.                 2 {3 k- v3 d% ~- H! J7 U7 ?- D
  16.                 PDU_Transform__Phone_number(Phone_number[number]);
    / `9 p. l# B3 `" i5 K
  17.                         ; }9 a' o3 H! w6 d5 l+ ]
  18.                 if(GPS_positioning != 0)( ^  @$ j, m5 f) o0 Z
  19.                 {7 h  C7 g9 e1 E! H# _& w1 H) x; t) l
  20.                         PDU_Transform__Message_content(Message_content,Message_content_original_1);
    1 y; @# K" g. g0 H
  21.                         
    ' W! V0 S$ \7 v! a# S8 ~
  22.                         Char_to_Unicode(latitude_char, PUD_latitude );# e/ H$ f- K! N$ w2 N3 K6 A& t
  23.                         Char_to_Unicode(longitude_char, PUD_longitude );: P' q( k8 p) H$ [/ S$ L, S
  24.                         8 c8 u( n8 W9 v1 k
  25.                         memset(PUD_longitude_latitude,NULL,strlen(PUD_longitude_latitude));3 H( I, I) D& Q" \9 A
  26.                         String_addition(PUD_longitude_latitude ,PUD_latitude ,0);5 }# _2 [' ^' ^! J! I4 @& l6 p
  27.                         String_addition(PUD_longitude_latitude ,PUD_comma ,strlen(PUD_longitude_latitude));
    / o# |6 ~3 ^5 d
  28.                         String_addition(PUD_longitude_latitude ,PUD_longitude ,strlen(PUD_longitude_latitude));$ R! y" j9 M2 R" H
  29.                         ( k( W3 ~7 ^7 [: }
  30.                         String_addition(Message_content ,PUD_longitude_latitude ,15*4);
    & `6 O( ]) `* \# l
  31.                 }
    ( b. V6 I# N/ c2 r6 k/ K' W( {
  32.                 else  b$ v  s& K$ `, R( f2 T  E
  33.                 {
    : L7 U4 h9 c( L" w2 x/ i+ s! O% H
  34.                         PDU_Transform__Message_content(Message_content,Message_content_original_2);
    * K% I0 p% R! V$ M2 j, x& Z' A
  35.                 }9 W4 Y# d+ g  s* s/ b6 k
  36.                 Length = strlen(Message_content)/2;+ S8 I3 Z* q: y7 J
  37.                 Transform_int_to_hexadecimal(Length ,Data_Length ,2);/ s: r( H$ O' T: K
  38.                 Transform_double_to_char( Length+15, AT_CMGS, 0, 0);7 O2 v7 B* y0 c; b. ?
  39.                 . v' b5 R& p& V: b; o. {& }7 j
  40.                 printf("%s\r\n",PDU_Phone_number);) \" `9 G: c% y
  41.                 printf("%s\r\n",Data_Length);& I! u6 P7 d. E8 K. |
  42.                 printf("%s\r\n",Message_content);9 m' o1 C- g" r6 R
  43.                 % P/ h$ p  [, C. i1 @4 \
  44.                 for(i=0;i<Number_retries;i++)( U' m0 w, a& g2 U3 M4 `
  45.                 {
    " A; V+ Q0 x: L) _. m3 \% t
  46.                         SIM900A_Send_AT( "AT+CMGS=" ,0 );" ]$ V( ?6 B, G% ^% K7 e
  47.                         SIM900A_Send_AT( AT_CMGS ,1 );               
    ; u$ y8 ~& J  j2 O
  48.                         
    3 l% ^6 N2 T+ F  [
  49.                         if(USART2_Data_seek(USART2_Data ,">" ,500))
    7 m6 n5 @. N% }% q  J0 L( g4 y+ z
  50.                         {
    2 O2 W- A3 i3 M4 I- m2 j- T
  51.                                 SIM900A_Send_AT( PDU_Phone_number ,0 );
    . L. N) t6 n# w, y! E
  52.                                 SIM900A_Send_AT( Data_Length ,0 );
    9 w4 x! _3 q% n9 N, J. i+ I4 |
  53.                                 SIM900A_Send_AT( Message_content ,0 );- e+ s2 r& s! r) Y3 f3 \
  54. 3 Z8 ]  o/ q# c; q! D
  55.                                 USART_SendData( USART2, 0x1A );
    ! i: G3 t- I; L( u5 m& l% h
  56.                                 SIM900A_Send_AT( 0 ,1 );; p/ \0 `' k- D0 x
  57.                                 if(USART2_Data_seek(USART2_Data ,"ERROR" ,2000))
    4 D! G. K7 i0 F' d1 M8 t
  58.                                 {! z8 }/ Y; A( Y7 f9 [5 e) I
  59.                                         printf("发送失败\r\n");$ s/ q' |& i1 F& p7 X
  60.                                         return 0xFF;
    7 k0 [. ~' B( J
  61.                                 }5 i. m" C2 ~3 k! q- I- W$ A3 W
  62.                                 printf("发送成功\r\n");
    ) f/ x$ ^( t: G# C: S
  63.                                 return 0x00;
    ; j( J+ z; O: P" o" M% g
  64.                         }
    1 a! ^$ Q( W3 D! n+ X+ P
  65.                         else printf("AT+CMGS指令错误\r\n");8 }. U* _& M7 F! ^4 c& V( s
  66.                 }        : [9 E6 u7 ~) f5 t/ W7 J3 ~: F7 |
  67.         }
    ) y8 O' R" ?% X* G, c
  68.         printf("指令错误\r\n");5 V3 }; T2 k- i% D. _5 c; q
  69.         return 0xFF;& a8 n% ]2 h. ?
  70. }6 w5 j- m3 _& g+ t  V
  71. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END0 ~. p% t  o7 u4 b

  72. 0 }- C/ g% ~/ O! f3 p
  73. % G6 c$ @6 l/ K% U' K5 _1 O

  74. 5 J4 ~8 Z5 }, c1 o/ d6 M- ~: o3 S
  75. //********************************************************************( K6 P7 y+ s, \2 J
  76. //通过串口2发送AT指令
    : y! [( _% q& U6 {/ f
  77. //可以直接发字符串或发数组0 ^) Y9 S, s. C
  78. //********************************************************************' n' Z. ~& @5 b
  79. void SIM900A_Send_AT( char *AT_command ,char over )) s& O" t$ b* C% J  |
  80. {
    * B3 H* X& Z5 h$ j7 P. X2 G9 g
  81.         for(;*AT_command!='\0';AT_command++)# }; l. {; _! m; ~9 {6 A
  82.         {; V2 _# q0 S0 I3 v* L% v- V
  83.                 while( USART_GetFlagStatus( USART2 , USART_FLAG_TXE ) == 0 );# p" z: w% a0 V1 r8 F" @+ u
  84.                 USART_SendData( USART2, *AT_command );" W0 a! j  {5 [' g9 j! |5 h: s  }
  85.         }
    + x" V! m: |& Y5 q; P: }0 m: V! G
  86.         if( over )
    / J0 E/ P' `" E- w+ `, b9 E
  87.         {
    7 v  p4 T, ?& M" l9 N# V1 i8 P6 W& n
  88.                 while( USART_GetFlagStatus( USART2 , USART_FLAG_TXE ) == 0 );7 p; p6 x! f8 u; U! y+ Y1 J% b
  89.                 USART_SendData( USART2, 0x0d );//  /r,0x0d,回车的作用只是移动光标至该行的起始位置
    2 F; x& j, b( S0 f7 s" f  k
  90.                 while( USART_GetFlagStatus( USART2 , USART_FLAG_TXE ) == 0 );1 i" F1 @- x! _  M& G5 U( X
  91.                 USART_SendData( USART2, 0x0a );//  /n,0x0a,换行至下一行行首起始位置;- W4 C: I% Q7 \+ y" l5 m- D
  92.         }
    % r# O6 C% O0 K
  93.         while( USART_GetFlagStatus( USART2 , USART_FLAG_TXE ) == 0 );  E2 @. T- }9 k0 {3 t9 d- ]* h
  94. }
    - q$ x. Q. T& m
  95. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END
    ' E# R: W% e/ a' y( B, `

  96. ( U  S! [1 a3 ]
  97. % S( H& [$ L1 E# O: L

  98. 3 ^) e) ^/ A1 d+ G
  99. //*******************************************************************2 }; R2 A! t" g$ ]2 ^
  100. //将手机号码转换为PDU格式
    ; ~, G. @3 [* D6 T
  101. //*******************************************************************1 X+ d6 \1 @8 ?: Y# j- g2 C9 g
  102. void PDU_Transform__Phone_number(char *Phone_number_input)6 I" x" }$ T" b" n4 G; c5 W
  103. {
    . ?$ k2 }. \' U: Q: q) |7 O  ]! v
  104.         u8 i;
      p, o1 x, ^6 X9 l% g3 y$ \
  105.         Phone_number_input[11] = 'F';
    9 Q3 G5 {& @7 ]: I5 j6 z
  106.         for(i =0 ;i<12 ;i++)
    9 K- ^. D) W2 s% `2 X
  107.         {
    / D% U7 E0 O' M5 @4 [* B1 [4 L
  108.                 if( i%2 == 0)
    3 S. A; j' e$ Q* T3 B2 P, z
  109.                 {& Q* A- ]& {0 Y/ F  T$ P* z- ?" `
  110.                         PDU_Phone_number[i+12] = Phone_number_input[i+1];2 ], q/ A7 i4 B, D
  111.                 }" k1 }1 g! s$ f: D
  112.                 else
      G% o2 V( e5 S* l
  113.                 {. g# g1 T7 P6 T* n7 X. `/ ?
  114.                         PDU_Phone_number[i+12] = Phone_number_input[i-1];( J! U9 i$ E# p1 k$ b2 W5 J5 ?6 `
  115.                 }
    ; ~9 Y- \0 y( P8 ~1 ]
  116.         }: Q; S7 |2 k7 j: y/ a3 ?/ S' z) c
  117.         Phone_number_input[11] = '\0';- D$ e4 h2 _; r# n# |
  118. }9 T/ Q: P7 c9 L
  119. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END2 C5 X, C% G5 v2 O& A8 T2 c
  120.   U7 s$ ]' I8 M

  121. - F: k$ y% i% Z
  122. - j9 X, `0 R8 ]2 I7 P6 ]& P4 w
  123. //*******************************************************************
    6 o1 M2 {% L$ X5 G
  124. //字符串内添加字符串
    0 I/ A6 i& J5 ^2 V3 t$ ~1 C
  125. //原字符串String  [0 \+ I+ m! h4 c* ~! t# L
  126. //需要添加的字符串Add_String5 M$ m4 V1 e1 Z
  127. //第Add_location字之后添加4 o  Q/ |+ v% m; w, ]+ Z
  128. //*******************************************************************1 a+ r  Q! e+ c: Y
  129. void String_addition(char *String ,char *Add_String ,int Add_location)
      B" g6 z# N+ ?: u5 T% H
  130. {
    6 E  [2 G* m* `- x/ A! a
  131.         u8 i;6 J) L4 O: O9 ~' |
  132.         int length_String ,length_Add;
    / T. g# m( U3 c7 j
  133.         length_String = strlen(String);3 p, R1 t2 @; W' I
  134.         length_Add = strlen(Add_String);
    6 K% U0 y: H  [2 ]
  135.         
    4 b1 [2 y. {0 y! T; o: c
  136.         String[ length_String+length_Add ] ='\0';
    2 N7 z% {2 `1 W1 B7 j! r
  137.         
    , P! o3 F1 W4 S/ B
  138.         for( ;length_String> Add_location ; length_String--)' M' U+ c5 \, E) l( N: p
  139.         {7 H; d2 ]- w/ w" g
  140.                 String[ length_String-1+length_Add ] = String[ length_String-1 ];4 y% V, ~" j. |$ D! h) k5 _3 a  x# I: u
  141.         }4 [+ I+ i5 f- w9 t' Z- j
  142.         
    & ^9 b+ {% _3 W( }, J* Y
  143.         for( ;length_Add>0 ;length_Add--)
    : _+ z& g8 d! V. I5 T
  144.         {
    / m8 O2 }, i* @
  145.                 String[ Add_location-1+length_Add ] = Add_String[ length_Add-1 ];2 ~6 [% Z% a( F% n) O2 j' p4 {
  146.         }7 _5 Y' P. {& C! K. ^
  147. }
    # n& U. X' c! {3 s4 q
  148. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END</font>
复制代码
6 |+ X: L  F$ C/ }
3.NRF24L01

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

  1. <font size="3" color="#000000">**************************************6 w& M# x- T# [' C
  2. //NRF24L01数据解析
    % w8 [" o5 N. Q- ~9 W5 d! k
  3. //********************************************************************
    ( ]6 s4 x' F& ?8 Z$ b8 z+ f8 _+ @2 y
  4. void NRF24L01_Data_Parse(const char *data)) S8 a: ]/ |  S/ H" c/ Y+ S
  5. {& p4 X5 `+ a8 @. l4 @
  6.         u8 i,x;! h. v6 U5 u3 c# X
  7.         char cache[8],slave;; Q( Y+ _" E! x" `! y' J1 a
  8.         if( data[0]=='K' )
      C$ Y9 U: |2 O. P1 L" W; H
  9.         {
    5 }0 n6 c2 n9 V0 L$ i& d
  10.                 for(i=1,x=0; data[i]!='#'; i++)
    7 ^& s; U/ r/ X. }( E5 ^( G
  11.                 {
    5 C3 H/ c1 @7 Y  f
  12.                         switch(data[i])* n/ S  I5 b( p0 e) A' c
  13.                         {        
    2 s' K, H8 A; C9 e. o/ c+ O
  14.                                 case 'H' :                        for(i++,x=0 ;data[i]!='&' ;i++)        //没有结束% U6 b+ l9 b# Q% v3 h* l* l4 U
  15.                                                                         {
    , ~: T4 u/ y- n
  16.                                                                                 cache[x] = data[i];
    3 c1 B0 s6 \. o) t7 m1 C
  17.                                                                                 x++;
    % L; J  g1 e5 G7 o" N
  18.                                                                         };" K. z$ \% I. d( I
  19.                                                                         cache[x]='\0';
    8 h. C" t8 D  ~  }1 k: A( M8 Z: P# a& L
  20.                                                                         slave = Transform_char_to_double(cache);  [5 Y8 c* d  p* `7 R7 C
  21.                                                                         slave_disconnect[slave-1] = 0;, @* s) y) w6 z9 l' z
  22. //                                                                        printf("slave=%d\r\n",slave);
    2 y' p/ V% e2 M4 A5 p
  23.                                                                         break;; I6 A$ L4 A; D) ^/ N. B
  24.                                                                         & h: U  \% G$ o' _
  25.                                 case 'V' :               
    * x% t" b+ k" V+ {$ K; ?3 f
  26.                                                                         for(i++,x=0 ;data[i]!='&' ;i++)        //没有结束4 p: ?( a4 {$ h: K0 m4 Y
  27.                                                                         {6 H" Y  d+ `/ ?0 c) ^+ n, f
  28.                                                                                 cache[x] = data[i];0 J1 H& L) M7 a! [7 [
  29.                                                                                 x++;( X  Y" J/ e: \5 [8 J5 k1 ~3 o- q# T
  30.                                                                         };
    4 X, _  a9 }& y; X* l8 t" C8 b
  31.                                                                         cache[x]='\0';7 b7 x. s: a6 d
  32.                                                                         slave_unit_voltage[slave-1] = Transform_char_to_double(cache);
      \1 n/ C5 f; |6 o( A$ i* n: d
  33. //                                                                        printf("voltage=%lf\r\n",slave_unit_voltage[slave-1]);  h( R4 g% G! X( H; {+ }
  34.                                                                         break;3 S# _) f1 I- R2 ^
  35.                                 case 'A' :                        for(i++,x=0 ;data[i]!='&' ;i++)        //没有结束3 R4 Q0 L0 @6 y7 d3 S2 K
  36.                                                                         {
    & q7 Y# J) u" t4 m4 V
  37.                                                                                 cache[x] = data[i];( h' A/ |' q' P& b! R4 l. j
  38.                                                                                 x++;6 \, l1 i" o( B" m& }
  39.                                                                         };
    2 R' A- X( F. v4 L1 \5 t7 G
  40.                                                                         cache[x]='\0';( e) i0 O3 n1 H7 W5 W) r
  41.                                                                         slave_unit_alcohol_concentration[slave-1] = Transform_char_to_double(cache);
    / e9 ^6 |+ s6 d1 Z
  42. //                                                                        printf("alcohol_concentration=%d\r\n",slave_unit_alcohol_concentration[slave-1]);8 f4 a" j) U* K3 ^8 ^: c4 _5 F0 y' |
  43.                                                                         break;1 A4 a; a3 T1 O  U7 E" Y7 k
  44.                         }
    # _. L2 h0 e. e* h
  45.                                 memset(cache,NULL,strlen(cache));! `4 @4 S4 Q% v, K
  46.                 }        8 y! q# T" V+ t. \/ b+ K
  47.         }$ P0 O# |! S. m" f# [
  48. }, b/ j# A( A  s, x
  49. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END: J6 l+ D* k! L8 K2 C

  50. 8 L! H6 q% i% W9 O. Z/ X

  51. * N1 e) U7 H9 @; r
  52. / A( k3 ?+ r4 Q, H  m! D+ z
  53. //********************************************************************0 V! O, `8 M9 B9 M
  54. //接收到数据进入中断, t5 _( P) A7 {: V
  55. //分析接收到的数据
    + h) |. I  r( G
  56. //********************************************************************$ z+ s+ |- S$ ~/ Y! I; w
  57. void EXTI15_10_IRQHandler()
    4 i* U2 u' u* F& b/ {. y" x
  58. {4 \  z! _6 G% _' v
  59.         if(EXTI_GetITStatus(EXTI_Line12))  R: W9 k( j: F% e6 ^0 Q
  60.         {/ j8 ~+ M; p: {1 |9 k- U) I
  61.                 char NRF_RX_Data[32];
    # ^- h7 X6 G6 [
  62.                 NRF24L01_RxPacket(NRF_RX_Data);& _, @! L1 }* }3 K# ]  R0 j% a
  63. //                printf("%s\r\n",NRF_RX_Data);0 }: U1 g- C2 A5 L5 i+ {+ _' z- c" P
  64.                 NRF24L01_Data_Parse(NRF_RX_Data);2 h5 c, T, ]8 ~5 ~- }* x
  65.         }2 C) w8 b% [2 ?3 b
  66.         EXTI_ClearITPendingBit(EXTI_Line12);, J- @* a- F$ W* L
  67. }
    * P2 `$ _2 r# l$ a+ S. P& m& L9 o
  68. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END</font>
复制代码

7 x6 C1 C" ]9 b3 g; y9 \1 d, d4.OLED显示

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

  1. <font size="3" color="#000000">//********************************************************************' e% O# O. _8 j/ |  A9 |9 }- L
  2. //200ms进入一次中断
    # r7 ^( O- b3 W9 X
  3. //更新oled显示
    % l7 i/ ?8 E/ Z
  4. //********************************************************************
    8 @7 K. x# A7 M$ H+ i
  5. void TIM1_TRG_COM_TIM11_IRQHandler()
    2 ^0 k" s+ v3 y3 f0 e& N7 D/ |
  6. {' I7 H/ T; _4 G. O. _
  7.         if(TIM_GetITStatus(TIM11, TIM_IT_Update))5 Q0 T5 X# w% @9 `
  8.         {& \+ p! a) J+ {4 X6 j- q: v
  9.                 extern char PILOT;& I  T& F. ^- E( O% j- Z1 g
  10.                 static int Enter_number =0,Page =0 ,Canned_format=0,aaa=0;6 V9 h, `2 c1 Q; Y% e
  11.                 Page = Enter_number/20 ;//控制翻页时间200*20ms
    & M0 y- s* i( k
  12.                
    " u$ _1 Y) ?; t/ h
  13.                 //********************************************************************
    % ?: S& j* W# H( Q5 V) M
  14.                 //第一页信息
    : t: E9 S5 m  p
  15.                 //GPS状态- }2 [6 B. `9 ?9 ?
  16.                 //********************************************************************' }" Q* \8 D( P' ^% a
  17.                 if( Page ==0 )        
    ' N+ {9 d9 \" h! g0 Z
  18.                 {; j- b& e. c6 j; l
  19.                         extern char GPS_positioning;9 B! r: W- Q7 k/ I& W  K
  20.                         extern char longitude_char[15],latitude_char[15];; Z( {8 Y6 A6 H- P$ M& B8 A
  21. ( F+ {0 y, v  b# p, o
  22.                         if( Canned_format/10 != 1)3 r# o  ~3 M: H9 F4 y$ D
  23.                         {" U- B( j& E( H, ]1 f+ M3 Y4 K8 p. ?
  24.                                 OLED_CLS();: M9 Z% G8 m- \5 R8 l; o
  25.                                 OLED_P8x16Str(36,0,"GPS",F8x16);3 i; g, ~4 p9 x( H" K$ V0 Z2 F
  26.                                 OLED_P16x16Str(60,0,"状态",F16x16_Idx,F16x16);
    # V  \. b- @6 b, s; S0 ^% V
  27.                                 OLED_P6x8Str(122,0,"1",F6x8);- @9 n, @- F* y) x# t, R
  28.                                 6 B* y5 e. b* L0 s5 f
  29.                                 Canned_format = 10;
    " o1 A  f3 [" y- Q0 ^' g
  30.                         }7 Q' w6 j, ~( W2 a; ]" W4 ~

  31. 3 R6 f0 R" ?% t4 u) [- f( V
  32.                         if( GPS_positioning == 0)
    7 D$ z0 O; }2 c, W& z
  33.                         {2 e  K$ |) C1 t& W1 z' K! z
  34.                                 if(Canned_format%10 != 1 )- M% B4 N, ]8 r* `: Y4 ?
  35.                                 {: C9 I% C- ?, z: M  f
  36.                                         OLED_P8x16Str(0,24,"GPS",F8x16);( n1 S9 Z# D& X0 `+ q
  37.                                         OLED_P16x16Str(24,24,"定位失败",F16x16_Idx,F16x16);& T: C* r8 q0 R0 O  ]
  38.                                         Canned_format = 11;                                
    9 o) Y! |; X6 Y: e
  39.                                 }4 q) Z  o5 e$ H- J
  40.                         }
    - ^( L9 z( q! I' F, K# q. S4 U
  41.                         else if( GPS_positioning == 1)2 ?9 {8 P# `6 D1 J2 J
  42.                         {# _* @, Q- l+ w
  43.                                 if(Canned_format%10 != 2 ); H  z! K$ B& l3 e4 Z9 ~! `. }
  44.                                 {
    5 d. G  V6 j, ~, |
  45.                                         OLED_CLS_y(16);
      z$ g8 @) Z" x8 J% {! p( Q
  46.                                         OLED_CLS_y(24);
    ) U7 T$ m" G- l7 b% Z
  47.                                         OLED_CLS_y(32);5 {* ~0 w3 D6 @3 K4 d8 K; c
  48.                                         OLED_P8x16Str(0,16,"GPS",F8x16);2 |# m% \( N) Y' j* @+ }) ?
  49.                                         OLED_P16x16Str(24,16,"定位成功",F16x16_Idx,F16x16);        
    # J9 C: S0 Y7 f1 |
  50.                                         Canned_format = 12;
    - M9 l+ W& K. V) u0 j. _( k
  51.                                 }" T1 Z3 {, x* K4 n  F) a  t
  52.                                 OLED_P8x16Str(0,32,longitude_char,F8x16);
    # x0 ?* _5 R/ Z: ?  y  G8 Z
  53.                                 OLED_P8x16Str(0,48,latitude_char,F8x16);+ i( y; n  l( e1 H& r; V+ g6 h7 t
  54.                         }
    ' g" _' }2 _! U3 K' c. W3 O! a
  55.                         else if( GPS_positioning == 2): j/ {$ r* U! M3 t+ F& ~5 p% b$ ]
  56.                         {
    2 t6 |, m1 P. q) I, \
  57.                                 if(Canned_format%10 != 3 )& p8 v7 N& l7 r1 I1 b" D. E# O
  58.                                 {
    % H; A, Q5 r+ Q$ i: [7 `% B0 K
  59.                                         OLED_CLS_y(16);) c: i' X$ F/ w- G; H1 S( `
  60.                                         OLED_CLS_y(24);
    , e/ |# H2 E- u8 u
  61.                                         OLED_P8x16Str(0,16,"GPS",F8x16);
    1 L6 l: g+ m+ v( _! N: c9 ]) Y+ X. A
  62.                                         OLED_P16x16Str(24,16,"信号弱",F16x16_Idx,F16x16);
    * s( c& k% ?+ N9 U4 r0 ^8 u6 O
  63.                                         OLED_P8x16Str(0,32,longitude_char,F8x16);  m% J8 A: V; F/ c# E2 Y" j
  64.                                         OLED_P8x16Str(0,48,latitude_char,F8x16);; m: {1 W: L! b  ?7 q2 d
  65.                                         Canned_format = 13;
    + n5 J9 W, H* I- p1 G
  66.                                 }$ `% E8 h/ A3 `& a
  67.                         }  z& t; i0 X3 G& e2 {2 X
  68.                 }9 |8 ?0 q" \2 E% T5 q
  69.                 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END
    , x6 q3 @2 s' `9 b
  70.                
    3 V. R+ O9 X; J- z" b2 a% t5 U$ ^
  71.                
    " y& c7 s7 p# A, F
  72.                 1 Y+ i/ R/ z8 m* K7 e2 c
  73.                 //********************************************************************* X, A2 ~7 r4 w- Q' O- Q
  74.                 //第二页信息
    0 _) R0 u7 y) Z$ E: E; V' N% e" H. y
  75.                 //设备连接情况( U* v& l7 F$ z. E$ A, s( ]) x% R
  76.                 //********************************************************************
    # l5 G% Z8 u9 K* c2 Q, K6 l
  77.                 else if( Page ==1 )
    4 G' e& ?; R9 `' [  y5 M
  78.                 {
    . H8 `# f6 f: |; {9 {5 _( o$ v# h
  79.                         extern u8 slave_disconnect[3];+ \! K# @4 U" ~( ~+ v# Q: h
  80.                         # j6 T- ?' S9 M  H- ~# f/ l
  81.                         if( Canned_format/10 != 2)5 K4 w2 q  J; d+ F; _6 [! g
  82.                         {
    8 J& Q2 B& M# m
  83.                                 
    , g; k# D& _; s) D: v; z$ V
  84.                                 OLED_CLS();( c- e& F$ R- v/ Q
  85.                                 OLED_P16x16Str(16,0,"设备连接",F16x16_Idx,F16x16);
    4 Y3 _3 g7 o& L7 _" Q
  86.                                 OLED_P16x16Str(80,0,"状态",F16x16_Idx,F16x16);
    ) m) ]; x' U& K. q, [) s
  87.                                 OLED_P6x8Str(122,0,"2",F6x8);
    - N' X) l8 a" i8 A5 ]
  88. . D5 `" h8 M* {! H* [3 O
  89.                                 OLED_P16x16Str(0,16,"设备",F16x16_Idx,F16x16);/ i  ~- Y4 l* O! y) `
  90.                                 OLED_P8x16Str(32,16," 1 ",F8x16);( I* \6 y" E5 q5 K2 B3 u
  91.                                 OLED_P16x16Str(0,32,"设备",F16x16_Idx,F16x16);
    * _/ N- G' R  H, J
  92.                                 OLED_P8x16Str(32,32," 2 ",F8x16);
    " d9 |1 k& ]7 f6 a" C8 k. g* a& i
  93.                                 OLED_P16x16Str(0,48,"设备",F16x16_Idx,F16x16);9 g! H1 O5 w' V9 }
  94.                                 OLED_P8x16Str(32,48," 3 ",F8x16);# E% H/ G( h* P9 c0 J; _
  95.                                 / O! D4 G' }) L8 {! H% F; t( D& v
  96.                                 Canned_format = 20;/ |, E6 p7 `& `; p, I1 R
  97.                         }4 c0 p8 c+ k' k1 o8 }3 ?  @. J
  98.                         ( M3 t9 S  x. V, s
  99.                         if( slave_disconnect[0] == 100)
      f: @3 s1 x3 _
  100.                         {
    , r4 v, F. y0 D
  101.                                 if(Canned_format%10 != 1 )1 `; J0 V6 t! \8 O
  102.                                 {3 D. U0 u5 o2 n: D! z$ z% ?
  103.                                         OLED_P16x16Str(56,16,"断开连接",F16x16_Idx,F16x16);
    " ]  c) t' d: H
  104.                                         Canned_format = 21;                                
    : G; D( q" P+ Z2 i( D& I6 `: x
  105.                                 }
      f! \/ I. |7 f* k, Y- y
  106.                         }
    0 C3 |4 ?" Y0 R  |
  107.                         else/ l9 A, H- H( o6 j* ^+ m
  108.                         {
    $ i2 ]$ I/ Z* @7 v6 C& \2 c) y9 m# ]4 G
  109.                                 if(Canned_format%10 != 2 )
    0 L( w. {3 D" r8 n3 V
  110.                                 {
    ; g5 q! C& R1 w# \9 P
  111.                                         OLED_P16x16Str(56,16,"连接成功",F16x16_Idx,F16x16);7 E* N0 x8 H6 {$ Z2 S- t/ @, v2 E
  112.                                         Canned_format = 22;        
    7 n0 B1 @7 A: ]- |! x" `& \
  113.                                 }
    . k) z7 B# ^; F* h, v
  114.                         }
    / U7 z( o9 H# {. E9 {
  115.                         * S* }: O% c5 S  O# V1 ]& Z
  116.                         if( slave_disconnect[1] == 100)
    % T' c( a! k; r$ H, `
  117.                         {7 _4 }$ r- S" Y
  118.                                 if(Canned_format%10 != 3 )  B* ?, G: t5 M: [& d9 k
  119.                                 {- m$ q2 G! t9 a5 x
  120.                                         OLED_P16x16Str(56,32,"断开连接",F16x16_Idx,F16x16);: [0 z7 w  t; g- D; b
  121.                                         Canned_format = 23;                                , r) ^6 m- d- ?0 h3 U3 Q. c
  122.                                 }' o% u% s) o* a8 h& I+ @9 _
  123.                         }
    % V3 k8 z8 S+ T5 U; z7 {* e& K
  124.                         else- b) T# c6 m3 ~
  125.                         {
      q$ H4 L* ?3 `6 \9 R( }( R
  126.                                 if(Canned_format%10 != 4 )
    + a8 E* ?/ n7 g" B. }8 _
  127.                                 {
    0 a+ D2 ^% t1 j
  128.                                         OLED_P16x16Str(56,32,"连接成功",F16x16_Idx,F16x16);
    5 `$ v" E( u0 c0 k
  129.                                         Canned_format = 24;        
    7 e- z* k9 r$ Y- ^5 J+ L
  130.                                 }
    / @/ ^' {) n8 X7 R& y, }5 r" m
  131.                         }8 d8 T* ~0 L  L5 D9 u0 E3 `- B6 W
  132.                         + g+ X. H5 A. t$ j; Z
  133.                         if( slave_disconnect[2] == 100)
    2 }" H! ], S4 D( n# q. K0 U
  134.                         {8 {" j7 ?1 ^3 N5 V( g
  135.                                 if(Canned_format%10 != 5 ). c0 N, p7 L) i4 D
  136.                                 {9 g3 t! m  N" R4 P5 e
  137.                                         OLED_P16x16Str(56,48,"断开连接",F16x16_Idx,F16x16);' e, G) u& g1 ~9 \1 W) ]
  138.                                         Canned_format = 25;                                
    . l: R: `  c) [& \4 g! T/ l8 N
  139.                                 }, R5 h1 V' _" b. C" H  O* [: k
  140.                         }% w6 S: I" K2 F
  141.                         else
    5 V/ o4 W; G  Y6 ?% _2 I6 _
  142.                         {
    4 X" ~, s* ?$ f7 l$ d
  143.                                 if(Canned_format%10 != 6 )
    ) h! U8 _; {6 E- U: \; ?1 @+ c
  144.                                 {
    7 t/ v" H$ T1 m2 n4 A$ C# t( r" o+ @
  145.                                         OLED_P16x16Str(56,48,"连接成功",F16x16_Idx,F16x16);
    2 @1 D% O# b  Q8 \7 J0 w" i
  146.                                         Canned_format = 26;        + s/ Z( v! E) J
  147.                                 }
    9 K, y9 S; B; K, ~8 f% v" c8 \
  148.                         }        
    1 }7 T7 N# V. C# t; w  Q7 `
  149.                 }/ k6 L0 c" U) v- V1 y! g" s$ q2 `" \
  150.                 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END* {$ j5 x/ H$ \$ x! F& H
  151.                
    ( f9 D& W) [* \2 B' j' i
  152.                
    . v4 N  l- o+ A+ Y1 P4 J6 r0 N
  153.                
    7 p$ {) m$ x7 f0 u1 k8 V2 \5 K7 G
  154.                 //********************************************************************* j3 F2 K! e( x# X0 }* ^
  155.                 //第三页信息4 ~& A/ Y4 A+ Z# S6 D8 u5 F
  156.                 //电量+ e- e5 h% C* K- n) t
  157.                 //********************************************************************) `: X8 }& p) g5 B5 x2 r
  158.                 else if( Page ==2 )) ^9 ~% T( s2 I# N, E. W- n5 f
  159.                 {- W- D$ A0 y" d1 v
  160.                         extern double voltage;4 l5 J" @4 J# C# G
  161.                         extern double slave_unit_voltage[3];' \8 A  z0 V1 @' U% q
  162.                         
    - j6 ]& e& ]+ A
  163.                         char OLED_voltage[4][6];
    ' O0 u- i' H! Y, g+ d
  164.                         * B& T" Y7 W: q" m4 K* J7 t! @
  165.                         if( Canned_format/10 != 3)
    0 N& [& [; K4 ]. ~! s$ @" z7 K
  166.                         {' ^. ?1 l7 V4 s4 S3 N
  167.                                 OLED_CLS();  {1 E$ P% u0 }2 l* c( V
  168.                                 OLED_P16x16Str(48,0,"电量",F16x16_Idx,F16x16);
    . }& C4 j9 |* c# D1 O
  169.                                 OLED_P6x8Str(122,0,"3",F6x8);2 F1 u: v% J1 K  b; H7 P# t; r
  170. ' W" x- r1 M; W4 S* W1 v9 c
  171.                                 OLED_P8x16Str(0,24,        "M:    V",F8x16);                                " p+ p9 c7 e& J% r+ `
  172.                                 OLED_P8x16Str(72,24,"S1:   V",F8x16);
    ! x0 _, }  ]* G( }0 c
  173.                                 OLED_P8x16Str(0,48,        "S2:   V",F8x16);# A) h  Y/ ]: @# R' ]
  174.                                 OLED_P8x16Str(72,48,"S3:   V",F8x16);        3 c: O, p  ^! s  Q! n& D/ l
  175.                                 
    2 ^& m' i5 n9 T9 p5 R6 ]" q
  176.                                 Canned_format = 30;8 M1 b. I' Y3 p/ q1 X, h" Y1 b/ W
  177.                         }
    ; E. X1 X' P4 }5 B: l
  178.                         Transform_double_to_char( voltage , OLED_voltage[0], 1, 1);5 L6 l! X+ y/ Z: Z6 _6 Y, {8 ]$ D6 h
  179.                         Transform_double_to_char( slave_unit_voltage[0] , OLED_voltage[1], 1, 1);
    # X8 w: [: O$ @0 f+ a
  180.                         Transform_double_to_char( slave_unit_voltage[1] , OLED_voltage[2], 1, 1);% W3 ], w) {5 t$ x$ P% m6 ?8 k
  181.                         Transform_double_to_char( slave_unit_voltage[2] , OLED_voltage[3], 1, 1);  K5 ~" T3 Z3 V
  182.                         
    : ^4 O$ [8 Q# M) c( k. T3 m6 ^
  183.                         OLED_P8x16Str(16,24,OLED_voltage[0],F8x16);
    / R+ I; y8 p7 O+ s: u) X
  184.                         OLED_P8x16Str(94,24,OLED_voltage[1],F8x16);! S8 ]+ ^5 \- z6 H* d
  185.                         OLED_P8x16Str(24,48,OLED_voltage[2],F8x16);
    $ E" ]' F# H& S& @! v! O
  186.                         OLED_P8x16Str(94,48,OLED_voltage[3],F8x16);' O* o* p, W6 D7 u& v$ k
  187.                 }
    ) b1 P& B% }& Q: g& _
  188.                 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END) h0 O6 q5 l! `: u2 n
  189.                 ) v& t. r2 t: M: N$ m( X6 l
  190.                
    : o! _) i* z* _+ L" y# p9 ?5 O6 ~
  191.                
    5 J) _3 F/ l  m
  192.                 //********************************************************************; f, I, R& S" ~3 N
  193.                 //第四页信息+ r" W/ Z: Y$ L
  194.                 //酒精浓度
    2 y, p- h9 f% _, m
  195.                 //********************************************************************
      h3 w' X2 ]. v$ s' T2 h0 b9 W
  196.                 else if( Page ==3 )% @. B( J2 Q3 [, R7 X; l8 |; P( ]
  197.                 {% l* Q2 o7 ]* j) g; y& [
  198.                         extern short int alcohol_concentration;5 R/ X( t# k4 e$ Q2 S1 T
  199.                         extern short int slave_unit_alcohol_concentration[3];; r. L, N6 _$ Z4 Z+ b# i0 X  v- A* t* i
  200.                         % r* V' @0 ^/ J8 [
  201.                         char OLED_alcohol_concentration[4][6];
    + [0 @$ O% z: l1 [
  202.                         7 p# D4 Q7 c6 B  n$ i
  203.                         if( Canned_format/10 != 4)8 ~- d1 u# w/ Z4 A+ _
  204.                         {; }( @$ A5 _  A; ^9 y" x9 ]- b' H
  205.                                 OLED_CLS();6 c2 b5 k# T( o4 {$ H9 {; D6 G
  206.                                 OLED_P16x16Str(32,0,"酒精浓度",F16x16_Idx,F16x16);
    8 r: V1 z9 p% i7 I$ k% D+ O9 Q; g1 _
  207.                                 OLED_P6x8Str(122,0,"3",F6x8);# ]) f& }) V" Z' X& f
  208.                                 / ]. s2 A' z5 `0 y
  209.                                 OLED_P8x16Str(0,24,"A1:",F8x16);
    9 s9 p$ w% p4 r0 Q9 F% u& N
  210.                                 OLED_P8x16Str(64,24,"A2:",F8x16);' f' q* C( ~" ?" O& B
  211.                                 OLED_P8x16Str(0,48,"A3:",F8x16);6 \6 w7 G" c/ V! ^2 l
  212.                                 OLED_P8x16Str(64,48,"A4:",F8x16);0 {- G' q1 a5 O
  213.                                 
    9 _! b* a- @+ s& k4 u
  214.                                 Canned_format = 40;
    7 g, S; [) d% r& Z1 O
  215.                         }
    7 U/ U# i1 |# r7 B
  216.                         $ S. ]- |3 c3 t1 W/ J( _2 Z! Z! K
  217.                         Transform_double_to_char( alcohol_concentration , OLED_alcohol_concentration[0], 0, 1);
    ' r( }) Y$ X- r9 m. S- t% N, t
  218.                         Transform_double_to_char( slave_unit_alcohol_concentration[0] , OLED_alcohol_concentration[1], 0, 1);
    ! T5 H) ^8 H* y8 H/ l! w
  219.                         Transform_double_to_char( slave_unit_alcohol_concentration[1] , OLED_alcohol_concentration[2], 0, 1);$ R/ h8 @* R5 [: {+ ^5 _
  220.                         Transform_double_to_char( slave_unit_alcohol_concentration[2] , OLED_alcohol_concentration[3], 0, 1);
    # y! i6 J8 a4 l1 o
  221.                         
    5 D8 k4 u% [, k: m" X
  222.                         
    1 Q2 D- l6 E  n4 \. G$ r
  223.                         OLED_P8x16Str(48,24," ",F8x16);7 F% |- C1 t$ }1 j5 [: ]
  224.                         OLED_P8x16Str(112,24," ",F8x16);
    * Q: `8 I  g* p/ ~, _. w
  225.                         OLED_P8x16Str(48,48," ",F8x16);( c: f4 }) K& Z
  226.                         OLED_P8x16Str(112,48," ",F8x16);
    & Q6 _5 N* X; |
  227.                         
    ) t/ D. d# N/ A: I
  228.                         OLED_P8x16Str(24,24,OLED_alcohol_concentration[0],F8x16);
    5 ~1 l" ?8 T" \. G0 Q
  229.                         OLED_P8x16Str(88,24,OLED_alcohol_concentration[1],F8x16);) \4 R3 ]6 m# p' C* J3 x
  230.                         OLED_P8x16Str(24,48,OLED_alcohol_concentration[2],F8x16);: D) @) B6 D8 H+ W7 y5 S
  231.                         OLED_P8x16Str(88,48,OLED_alcohol_concentration[3],F8x16);
    / W" n( G# X) ^( w% E6 ^
  232.                         
    , {7 h0 q% s2 J$ D2 `) u$ F, F
  233.                 }
    5 T4 T; G/ I( J
  234.                 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END9 t8 f7 ~& u4 H, k% ]( F
  235.                 9 G& ^9 P4 v; \
  236.                
    * u- S! D" n8 B, r3 _% B5 D2 D
  237.                
    & Z; A% B( F. t5 s! a
  238.                 //********************************************************************
    4 L: {2 y9 G1 b3 D+ N' V2 ^
  239.                 //第五页信息
    8 H0 ], J! r  P- `* Y
  240.                 //) ~" u6 d+ A) H4 v- R3 t3 r8 U
  241.                 //********************************************************************                ( l' f" P. l( q  R
  242.                 else if( Page ==4 )! _* h% M1 I* c5 m& }/ y& X
  243.                 {! }9 i8 ^3 z+ [: U% |* _/ a" P, w$ Z
  244.                         extern char Phone_number[4][12];
    # ^1 c7 t) F7 n6 a
  245.                         if( Canned_format/10 != 5)* t9 [+ x/ ^' W; _/ a
  246.                         {
    2 l+ H, ?* z# W3 c7 a3 ~  b
  247.                                 OLED_CLS();$ P* Q4 _( j% L/ V1 J
  248.                                 OLED_P16x16Str(44,0,"联系人",F16x16_Idx,F16x16);        
    $ R1 U# N$ W& E9 [/ a( W/ s; }0 Y
  249.                                 OLED_P6x8Str(122,0,"5",F6x8);
    2 o# |9 z) F4 g- `8 s
  250.                                 
    : x+ s3 [: Z: O- a
  251.                                 OLED_P8x16Str(0,16,"C1:",F8x16);8 l8 u6 |3 `) q, D  }
  252.                                 OLED_P8x16Str(24,16,Phone_number[0],F8x16);
    ( r9 Q2 A6 R( Z( H6 h( M1 f
  253.                                 OLED_P8x16Str(0,32,"C2:",F8x16);2 [+ l2 f( k% F" b; y
  254.                                 OLED_P8x16Str(24,32,Phone_number[1],F8x16);$ s' b8 K" i/ X- ~- M* W3 W
  255.                                 OLED_P8x16Str(0,48,"C3:",F8x16);5 k+ ]) R9 E/ m* Q
  256.                                 OLED_P8x16Str(24,48,Phone_number[2],F8x16);1 q# ]( E! z, _& K9 a1 j6 p
  257.                                 
    . L" L, W: k9 @% r
  258.                                 Canned_format = 50;  a2 k2 a1 [& y  V# Y
  259.                         }5 L2 X# l( k! j
  260.                 }, m  Q2 Z2 f  ^0 P$ w) v
  261.                 //********************************************************************/ u* Z0 u! o  U5 k1 y$ T+ ?
  262.                 //第六页信息
    - e) \* E- Y1 g' B0 A
  263.                 //车辆状态
    ; }1 q" h2 _$ @3 E( \' q
  264.                 //********************************************************************, }: ^& V; m2 U) Y  R
  265.                 else if( Page ==5 )//第一页
    + [3 e) F7 `7 E. m4 n0 A
  266.                 {
      Z- P2 O2 ^- J& P/ N, Y, s% A7 \! y
  267.                         extern char DRUNK_DRIVING ;. h- s' H2 Z. I! j
  268.                         if( Canned_format/10 != 6): s# k: b/ I7 T- Q6 F7 P/ ~6 |
  269.                         {
    5 `* K5 e" m+ [# k* I1 ?
  270.                                 OLED_CLS();
    2 @8 M# c9 E$ q2 p
  271.                                 OLED_P16x16Str(32,0,"车辆状态",F16x16_Idx,F16x16);        
    + [1 D. F; Y/ K: L1 ^! ?) T
  272.                                 OLED_P6x8Str(122,0,"4",F6x8);4 c3 R& w7 b9 o4 L1 @
  273.                                 8 w2 ^1 b9 v6 }" M7 Y* y2 f
  274.                                 Canned_format = 60;        ! j  K8 w4 H0 t7 B
  275.                         }+ C$ C3 |  T6 f* Y& A8 |
  276.                         , r2 b" ]7 p' V* r6 d' B! Y
  277.                         if(DRUNK_DRIVING==0)2 A1 A% u  ?; Z0 i6 y
  278.                         {
    2 H% c/ R+ e0 |: I' O. ~
  279.                                 if( Canned_format%10 != 1)" m* H2 Y0 V: m0 U/ I3 r. a0 F
  280.                                 {% W1 y, [, x9 C8 f
  281.                                         OLED_CLS_y(16);
    4 Y% ?4 [+ a5 M. J! `! P
  282.                                         OLED_CLS_y(24);# O. c  q3 S# M! N8 R! Q) t- x- T
  283.                                         OLED_CLS_y(32);. r# p: R% C! C( M+ U! X
  284.                                         OLED_CLS_y(48);
    5 g2 F/ W0 S/ z& \# i) K
  285.                                         OLED_CLS_y(56);
    * K% c/ Z7 C0 q/ E0 ^2 x/ @* c
  286.                                         OLED_P16x16Str(16,32,"车辆正常行驶",F16x16_Idx,F16x16);        
    3 b8 N( e5 c1 S* h; U
  287.                                         Canned_format = 61;9 Y$ i  w$ E  \2 R, G  S  h
  288.                                 }. }8 E! e; P, T: P1 k5 G6 U# ]
  289.                         }
    ! ]+ P  {! U% e$ y
  290.                         else
    ) G! L# e( V! R, y2 K0 k6 A/ {
  291.                         {+ R, y; S2 n6 I/ p9 P) k
  292.                                 if( Canned_format%10 != 2)
    # H5 N, q, Q4 O9 o' @" E" p: w+ g
  293.                                 {
    / q: |# ]0 n3 }+ |5 [4 m
  294.                                         OLED_CLS_y(16);
    8 C' |( d6 N9 h2 V; ?- o7 ~
  295.                                         OLED_CLS_y(24);
    9 F# y  n* q+ {6 x' P" @
  296.                                         OLED_CLS_y(32);
    % w$ {4 D. ]# {5 E& x
  297.                                         OLED_CLS_y(48);% M( a2 P! I* a7 o
  298.                                         OLED_CLS_y(56);  e% z, H* \& E1 N: O
  299.                                         OLED_P16x16Str(8,24,"发现驾驶员酒驾",F16x16_Idx,F16x16);* B) v% D# I! X
  300.                                         OLED_P16x16Str(16,48,"车辆禁止行驶",F16x16_Idx,F16x16);        + a- q; g2 P1 y" K* a$ s# D0 J! @( F
  301.                                         Canned_format = 62;* n8 C) U6 ?" G: a1 Y' f  r5 `6 L2 Q
  302.                                 }
    / g4 l) T4 P* z7 ?/ o
  303.                         }        
    , g: G2 n  C$ _$ C5 J9 L3 o3 @
  304.                 }                6 ^; N3 T% D4 ~" x' J
  305.                   R- ?8 C! k2 }
  306.                 //********************************************************************# O8 Q; ~" h1 J' V
  307.                 //重新开始显示第一页- s: k8 R" L' _' T% t. s; v0 z
  308.                 //********************************************************************" H  T3 K0 O# M/ ]! y8 c
  309.                 else if(Page==6)
    ! `1 u9 q! }. @& N2 d0 P
  310.                 {
    1 C" R! I" O/ n; E9 f3 l
  311.                         Enter_number =0;. P# p* e/ j8 Y- z5 D2 S3 j4 V1 k) V8 E
  312.                         Canned_format=0;
    $ y6 A$ W& V( g- [& E
  313.                 }
    ; ~; z1 q" u; p8 P
  314.                 Enter_number++;
    " F" F( G5 A0 q: g0 B7 i
  315.         }
    2 n0 x+ {6 o* ]8 f% x, C% I+ l/ Z
  316.         TIM_ClearITPendingBit(TIM11, TIM_IT_Update);1 g3 I  ~5 S" M2 L% M" [( W
  317. }
    , c4 [4 g  a9 ]9 |
  318. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END</font>
复制代码
+ t  c3 F" Y" H5 Z( R1 I

; f) X- k: t/ |, N/ T5.酒精传感器

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

  1. <font size="3" color="#000000">//********************************************************************3 m6 j* k! H! k+ J
  2. //100ms进入一次中断
    9 o% o1 H: v: M% n& R
  3. //判断是否酒驾2 f+ y' }+ W5 r: H* d) |
  4. //********************************************************************
    ; k" U+ b" g+ z+ G: i9 `4 R
  5. void TIM1_BRK_TIM9_IRQHandler()
    / e$ ]& q% T6 T9 W  U
  6. {
    ; q9 R; v2 L: z" U+ @
  7.         extern short int alcohol_concentration;
    9 P3 T* w$ L/ e. |
  8.         extern short int slave_unit_alcohol_concentration[3];
    9 x4 d. _& U/ f; V, ]5 H! s
  9.         extern char DRUNK_DRIVING;
    9 q/ }8 C) Z& S  L$ F* m
  10.         extern u8 voice_prompt[15] ;6 k+ f8 m3 T* w7 B) r' f  I, S& t
  11.         static u8 Number_of_drunk_driving= 0;
    ! c# x' K+ w0 P7 u$ C7 f) w0 ^6 Y
  12.         if(TIM_GetITStatus(TIM9, TIM_IT_Update)), t: S; n0 C8 }' O: f- d# w1 b
  13.         {! l6 p5 \9 y& q. b
  14.                 double Weight_M=1 ,Weight_S1=1 ,Weight_S2=1 ,Weight_S3=1 ;
    0 l& {" e- l4 \: ^/ ~. e
  15.                 if(        alcohol_concentration > 2000 || DRUNK_DRIVING == 1)//当主传感器大于规定值开始判断
    ! ?$ C# t& p1 O% J3 ^
  16.                 {
    & l8 ~, w* H8 p8 L' L/ \6 Z
  17.                         //*****插入算法判断是否酒驾,之后需要修改* Z. v) I5 ^- d" ~* i0 A9 u& ]% |/ v
  18.                         if(Weight_M * alcohol_concentration > (Weight_S1*slave_unit_alcohol_concentration[0]+% g' s; J9 E$ W8 M7 {
  19.                                                                                                                                     Weight_S2*slave_unit_alcohol_concentration[1] +
    + J# M- J! c6 k) O% I% G
  20.                                                                                                                                    Weight_S3*slave_unit_alcohol_concentration[2] +500) /3;1 n; J' C2 t& ^- ^
  21.                           )
    * H+ n8 g  m4 R5 Y7 e) s
  22.                         {
    : X6 c" v8 C0 ^2 s5 B1 O# T
  23.                                 Number_of_drunk_driving++;4 L- h  G; w" O$ a. x: K, m
  24.                         }3 b7 |' n7 y' E$ Z3 n9 E
  25.                         else if(Number_of_drunk_driving!=0)
    8 g) @' }! x& n) B$ M! F9 G/ \
  26.                         {
    $ `) X1 u+ J! u6 E" y
  27.                                 Number_of_drunk_driving--;. {1 C' R/ n/ Q! m0 r. M; F( ]
  28.                         }
    6 Z+ y2 l2 ?8 r
  29.                         //>>>>>>>>>>>>>>>>>>>>>>>END" Z) f* ^: @* I* d7 _9 K3 b/ V' P( R- u
  30.                         
    ; F  _. k1 m8 }: B: Q" M2 c4 R: m
  31.                         //*****是否连续10次判定为酒驾
    ( u6 h3 }4 T8 B) X8 \& a
  32.                         if(Number_of_drunk_driving>10)
    . U) x% s$ {1 t1 s
  33.                         {
      ^- n3 i  _5 J& l* s: _
  34.                                 Number_of_drunk_driving = 10;
    " B) Y: H, m3 J  M4 g% G2 d+ B
  35.                                 DRUNK_DRIVING = 1;
    2 ?/ t! \3 }: q" Z- ?, O, p1 }
  36.                                 if( voice_prompt[3] == 0 )
    % u9 P: x0 k2 u
  37.                                 {
    3 F+ i& w3 K& {9 v% A" I0 i
  38.                                         JQ6500_play(4);- `8 i; `) X$ v8 j$ p$ y4 b5 x
  39.                                         voice_prompt[3] = 1;
    ; f" ^6 z; ?4 b% D
  40.                                         voice_prompt[4] = 0;
    + d" r6 p7 s; `/ g
  41.                                 }
    3 z4 A* W! ?. G9 |) w3 f1 E
  42.                         }
    / K8 @# P# I, a4 \1 g( X0 A4 V' @4 o' Y
  43.                         else if(DRUNK_DRIVING == 1 && Number_of_drunk_driving ==0)
    / b5 V+ Z: V+ {7 ?+ C3 D
  44.                         {4 v1 ?( I! \. K$ D6 \
  45.                                 DRUNK_DRIVING = 0;
    5 `0 Z# n2 T5 a+ n- d
  46.                                 if( voice_prompt[4] == 0 && voice_prompt[3] == 1)" t$ l* h6 n: K' G' n% g
  47.                                 {
    9 L7 `3 p, B$ [6 X" c* \
  48.                                         JQ6500_play(5);# Z9 O% o% D8 l8 Q3 U# C/ ^
  49.                                         voice_prompt[4] = 1;5 m5 j* n: j: L! u3 Q
  50.                                         voice_prompt[3] = 0;
    , R; c+ P1 i# v. n8 Y
  51.                                 }
    8 D( }: ^3 u$ P' q
  52.                         }
    - d, N" p( _3 _3 `9 \
  53.                         //>>>>>>>>>>>>>>>>>>>>>>>END. D% p% V/ W* D7 i: ^0 s8 ?7 r0 [
  54.                 }                + a, ^) N! X; T5 e
  55.         }
    1 Z) ~: l' z- @# e  X3 [0 [$ A
  56.         TIM_ClearITPendingBit(TIM9, TIM_IT_Update);  e2 A9 @8 R- C2 s- P
  57. }
    : R8 G& t- ^7 O7 L! N% q
  58. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END</font>
复制代码
- m5 F4 ?0 C  l6 T1 d
6.语音模块

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

  1. <font size="3" color="#000000">*****************************************************4 ^/ ]5 d+ G. Y2 V: }5 `2 h
  2. //JQ6500发送控制指令
    $ V+ |# m& l2 N2 K! u$ V
  3. //********************************************************************! {  a3 p# X' o2 \
  4. void JQ6500_control_command(char command)- X7 P4 }6 [8 L+ e9 a2 o. A% {
  5. {& [6 ^2 ?% n2 \# H( a" K
  6.         ; B9 }( Q0 a' n- F. v) ~2 R* u: _
  7.         char JQ6500_instruct_1[5]={0x7E ,0x03 ,0x06 ,0x02 ,0xEF};                //音量00~1E3 x0 k) y6 J% {6 m3 ~
  8.         char JQ6500_instruct_2[5]={0x7E ,0x03 ,0x06 ,0x17 ,0xEF};                //音量00~1E5 P- f* P# `$ D$ D# s) J5 ^
  9.         char JQ6500_instruct_3[5]={0x7E ,0x03 ,0x06 ,0x1E ,0xEF};                //音量00~1E
    , N* e4 ^+ s: t" V4 @( M; t
  10.         
    : W; l* ^1 X+ {) R5 M  X
  11.         char JQ6500_instruct_4[5]={0x7E ,0x03 ,0x11 ,0x04 ,0xEF};         //播放模式:0 1 2 3 4(ALL FOL ONE RAM ONE_STOP)3 N5 V  X9 j4 P. I9 [* x0 Q
  12.         
    3 t5 m6 \  J$ [, v! |6 q
  13.         char JQ6500_instruct_5[4]={0x7E ,0x02 ,0x0A ,0xEF};                                //低功耗 + [' G  c3 a$ o( M& u
  14.         char JQ6500_instruct_6[4]={0x7E ,0x02 ,0x0C ,0xEF};                                //复位0 q- e: e' W! g; ^8 o& x( c
  15.         . y: [. H: b. g) X
  16. ( A' g4 j' K5 C: k; L3 u
  17.         switch (command)' \$ e5 b, ]1 Z/ t
  18.         {
    & s( a3 i; w7 e- F5 l3 S9 f2 \) R
  19.                 case 1:Send_hexadecimal_UART4(JQ6500_instruct_1);break;; ~$ U7 K( s+ t6 c6 m
  20.                 case 2:Send_hexadecimal_UART4(JQ6500_instruct_2);break;
    / u& a% `- j2 E: B# C  j7 c
  21.                 case 3:Send_hexadecimal_UART4(JQ6500_instruct_3);break;- B0 C' h6 `  e8 n* j3 g% X
  22.                 case 4:Send_hexadecimal_UART4(JQ6500_instruct_4);break;
    4 T+ h4 f' K' j; C. z% K
  23.                 case 5:Send_hexadecimal_UART4(JQ6500_instruct_5);break;0 X& ]8 n* I6 _3 L. z& b: ]
  24.                 case 6:Send_hexadecimal_UART4(JQ6500_instruct_6);break;
    1 [$ W/ Q7 m/ ]& w3 {7 Y
  25.                 1 `. ?$ U. _. }
  26.                 default: break;
    1 q5 {0 R5 |8 D/ O% J  p# c/ W, r
  27.         }2 o% c6 s: }, ]+ y5 p
  28.         delay_ms(50);5 \5 o, @* T9 M7 r' m% S5 R( l! @" f
  29. }! r9 R# j$ ]* s0 s
  30. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END
    * ^; T% g) q) V3 u3 H# q

  31. 4 k+ m3 K* ?. d; F. p9 z9 \
  32. ! }+ i. b' x8 o1 s' C/ s% r: G9 ?* P2 e

  33. ; q; h4 J& U5 \. ?: ]4 k
  34. //********************************************************************
    + m. L, F+ s6 U% S% C& f; Z  _
  35. //JQ6500语音模块播放指定曲目+ `6 _. r+ E& @* Q
  36. //********************************************************************
    , n- g0 w* y: r/ f& g
  37. void JQ6500_play(u16 number)/ X4 `% _8 v2 ^* z) E
  38. {
    0 U! X5 x$ ]" Z8 ^# r3 b- A
  39.         char JQ6500_play_number[6]={0x7E ,0x04 ,0x03 ,0x00 ,0x00 ,0xEF};                //音量00~1E
    , D# M' _8 v2 B( g/ C% l0 |
  40.         JQ6500_play_number[4] = (u8)number;* A1 M2 b: a. B& N. }& b
  41.         JQ6500_play_number[3] = (u8)(number>>8);$ A$ W7 K3 Q0 v" T. D4 c
  42.         
    / z' m8 a& n; _( E* \7 D
  43.         while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_12)==1);9 A; N" K: I( X4 H4 c2 s6 `
  44.         while((GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_12)==0))  c5 ]6 I1 n8 S" d. j
  45.         {
    / i, {8 P" K# t: e9 @
  46.                 Send_hexadecimal_UART4(JQ6500_play_number);delay_ms(100);
    / F- i! R+ `: b4 f, l6 y
  47.         }
    . I& ?/ y) g  T( p  l6 I3 a
  48.         while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_12)==1);
    4 Z% F5 H# w3 G6 G% S+ U- ^; i
  49. }
    8 r/ t3 ?$ T% _2 F
  50. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END) L9 p6 _5 u3 G8 a( ]+ \

  51. $ y6 Q! U1 |, U! e- n, Z
  52. 8 |( c4 Q0 R7 a% g

  53. * L# `$ V" I# C2 N, t2 H
  54. //********************************************************************+ T) h9 w+ ]) E, a) Z
  55. //UART4发送16进制数据
    9 P3 \9 R- \2 ~4 D$ `6 x7 K8 Q/ {
  56. //********************************************************************
    8 K3 T( g6 F7 o; L3 j
  57. void Send_hexadecimal_UART4( char *array )
    ' C! d# u3 \3 M" X( h; t* m" Y
  58. {
    0 U( C3 d: R' {1 P* S$ J. w$ i
  59.         for( ;*array!=0Xff ;array++)4 L- E! L/ d7 Q( u# ]
  60.         {
    0 r$ O0 p% V8 z$ P, i, _' X$ W" S; m
  61.                 while( USART_GetFlagStatus( UART4 , USART_FLAG_TXE ) == 0 );
    : k# t) R" W/ |3 [
  62.                 USART_SendData( UART4, *array );
    " t/ U  D3 u8 L4 t
  63.                 while( USART_GetFlagStatus( UART4 , USART_FLAG_TXE ) == 0 );
    # l$ S$ G/ K" s+ o" q
  64.         }# |6 s1 b2 l6 D+ H& g
  65. }; H* n8 A) P+ `. a: n
  66. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END
    4 c0 ]6 j' s$ W
  67. </font>
复制代码
3 G# J: {! O" J8 {$ ~

2 Z5 r, K$ m7 w+ q从机部分
. b( y' u; J7 h1 _: ~/ \, z6 b8 l

  从机采用HAL库进行编程


4 U# B4 f9 {* J5 X

1.NRF24L01

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

4 [( J4 @, l( o4 U" @# N. Y+ ~" K
  1. <font size="3" color="#000000">void DMA1_Channel1_IRQHandler(void); a0 w& ^$ _/ E9 K- U
  2. {
    " Z1 _$ D) Z# [4 G9 i( j
  3.         u8 i;  f+ x  G  X2 b9 E
  4.         double voltage;
    8 w) N# i4 L  T2 C) j7 B) Q
  5.         int alcohol_concentration;# }3 ~8 X& W! K" z0 @
  6.         char Transform[10],data_head[5]={"KH1&"};
    8 v! R3 Z' M4 i- e" u
  7.         u32 ADC_data1=0,ADC_data2=0;
    4 M3 _6 l" _6 l
  8.         for(i=0;i<20;i++), z+ m8 O* H! ^( S) o9 R4 x) Z
  9.         {9 g  x/ t6 S' {
  10.                 ADC_data1 += DMA_ADC_DATA[i][0];/ g; n" E2 F1 M2 ^( u
  11.                 ADC_data2 += DMA_ADC_DATA[i][1];5 E7 j1 K5 _* K) e
  12.         }" h6 {0 {  P- f6 T9 ]( R- z' w
  13.         alcohol_concentration = (double)(ADC_data1/20)+0.5;( m1 ^# Q/ O# p6 Y. B( h  z
  14.         voltage = (double)(ADC_data2/20)/4096*3.3*(3-0.025)+0.005;% u" H5 A# r8 Z  B; S. Q
  15.         - C% S) L" O$ h9 m9 z
  16.         if(NRF24l01_write_TXdata == 0)& b) ^  q/ P& o6 ]
  17.         {  |2 J, A  r* R5 ~4 Y
  18.                 memset(NRF_TX_Data,NULL,strlen(NRF_TX_Data));        //清空要发送的数据
    ) R* f/ x4 u- O2 N9 d
  19.                 strcat(NRF_TX_Data, data_head);                                        //发送数据加数据头
    : A. [5 N- ]# F' z1 L
  20. / Q5 `- s1 W7 h9 h: g
  21.                 NRF_TX_Data[strlen(NRF_TX_Data)] = 'V';                        //添加第一段数据
    & i7 u) w/ v3 y9 w% Z) H) l. ]
  22.                 Transform_double_to_char(voltage, Transform, 2, 1);
    7 o( `  S6 }1 N/ N- y, [% X/ M
  23.                 strcat(NRF_TX_Data, Transform);* t! m2 v( h( D; U
  24.                 NRF_TX_Data[strlen(NRF_TX_Data)] = '&';8 ~+ L. t4 r( U5 V( Y' h( X
  25.                
    + k; u2 i2 @' j- b: b
  26.                 NRF_TX_Data[strlen(NRF_TX_Data)] = 'A';                        //添加第二段数据, n! z* i5 y8 f
  27.                 Transform_double_to_char(alcohol_concentration, Transform, 0, 1);
    4 s% k: d# H" W0 c) s
  28.                 strcat(NRF_TX_Data, Transform);
    4 f  N+ J0 e$ H( D7 d# @
  29.                 NRF_TX_Data[strlen(NRF_TX_Data)] = '&';% w# y' @6 K2 t. W& ?: F
  30.                 . D! R0 M  O0 F
  31.                 NRF_TX_Data[strlen(NRF_TX_Data)] = '#';                        //添加结束符2 O( m- ^4 ^$ w
  32.         }  E8 r9 C. ^  G+ r! v% ~5 t
  33. //        printf("%s\r\n",NRF_TX_Data);
    6 e- p: \: x  `. V
  34.         
    ! O( m) F9 {% A* u4 `
  35.         HAL_DMA_IRQHandler(&hdma_adc);2 \) O8 u% K" j
  36. , |1 a- R" F. T, _0 d
  37.         HAL_ADC_Stop_DMA(&hadc);
    ; g8 x1 S5 C% r( ]( V
  38. }</font>
复制代码

2 g( b& O* R! h四、实物展示
20200907145407605.jpg
; N' q+ A* ~6 P4 O
20200907145419644.jpg

6 ~. x' s  ]9 @+ h# G9 f  r  y( p7 c8 z5 h8 [

+ M9 _5 |0 A0 ?3 U五、改进方向

. b' ]) U6 a$ P1.酒精传感器
5 m$ U/ d1 g8 M9 J+ }/ ^

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


1 m/ [- c, }6 \$ Q+ |* V; v

2.短信
: |# e4 e+ q- b/ p9 n: j

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

% [. w1 J) R$ Q; i: B* l4 b3 U

3.加入键盘! U* P" C0 F5 Y& f, m* x

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

: _; _. g) p& u3 u. F

4.加入人体检测
0 e! x! b/ y+ m

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

# k% H! X5 R, h( o  ]

. X) \7 c$ f' @" Q  B0 Y
: `5 |3 F1 M0 x5 e) d# q$ y3 H! N! h# w: h

. r0 k7 s: I+ C" x; s1 l( u/ \; f8 F/ K% P+ K6 q
收藏 1 评论1 发布时间:2020-9-11 12:54

举报

1个回答
goyhuan 回答时间:2020-9-11 13:40:49
有完整项目更佳

所属标签

相似分享

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