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

STM32 智能防酒驾装置

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

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

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


- r% P& u) p. [* w3 @9 ^

二、硬件电路
, f+ r  m, H5 t" P5 f! A; b
* s  I3 {/ C& S% k. L% z. s  S5 {# r1.主机

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


  ~0 T2 A- `) V4 c6 \

20200911125526.19a5966287a6415602e11d615c611bde.png

20200911125551.8719143ed6a85976e3d5f2e14ccee351.png


2 E+ g% w$ o# N2 ^: M: L8 @5 p1 x% }

2.从机! ]; R8 ?, f, |) {

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

20200911125610.670127be52c0fe9206aa1ff83431e1a8.png


+ R7 E' ~0 G/ v* Z9 o8 x

20200911125621.d6ee35ce3a04c0af9222fed41ba1f83c.png


- e7 ]! {# G5 ?7 N1 s" w+ L

3.酒精传感器" v: _! m" d3 P) A0 V; ~6 v, y3 o

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


  p: \. Y" c# t; q+ a1 p: F) \

5.png

20200911125654.3ba28eacb3f3ad543a45da431bb51eb5.png

6.png


% n5 b+ y  @; Y# @

- L( \. S$ s$ Y3 q# y
三、程序设计
7.jpg
& q) a, N$ o/ r
( U9 }8 y6 c4 R3 N+ T9 E

5 |2 W5 y3 D* f) M7 F主机部分

( }! f5 I7 K; {% ]$ ]/ k( W1 v
' Z/ M0 _- g1 ^1.GPS

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

  1. <font size="3" color="#000000">//********************************************************************6 O5 ^. p1 q$ g2 W. m3 O# `
  2. //得到GPS的经纬度" E+ N8 o: _/ r/ N
  3. //数据为char型数组9 U/ p, M. Z+ c$ g
  4. //若没有得到数据则无返回结果! t# Q0 V! j/ _6 S) L
  5. //********************************************************************) ~, L" d% a( g4 ]0 u- F
  6. void GPS_GetData()
    2 U( D& \2 @6 ~2 l4 o
  7. {
    - B" P- T# a8 q0 t
  8.         u8 i;4 Y2 _( p* |/ t  G& \* w
  9.         if(USART3_RX_STA&0X8000)                //接收到一次数据了
    . {* v/ ]7 t3 w- G. |# N" N& r& z2 j
  10.         {
    4 S9 g1 H0 O6 ^
  11.                 USART3_RX_STA=0;                                   //启动下一次接收" R8 G; T5 q2 E( u! n
  12.                
    , X) N! z2 i' f" i+ ]
  13.                 GPS_Analysis(&gpsx,(u8*)USART3_RX_BUF);//分析字符串2 p" }% j" G. {
  14.                
    # L1 W5 w- b/ q* B8 x+ s: e
  15.                 if(gpsx.gpssta==1 ||gpsx.gpssta==2 )        //GPS定位成功
    " q0 k$ ?& c; P( \2 y
  16.                 {0 c! b/ A' i# l) V5 R0 e; t* \
  17.                         u8 i;' H. M- G4 s% @9 b/ A& F3 c7 W) P
  18.                           @! D2 m0 e3 z, [. y+ Q/ h
  19.                         GPS_positioning = 1;
    " Y5 _# w3 a& }6 U4 o
  20. ) y) i  \: G8 Z* b% B. Q( ~
  21.                         Transform_double_to_char(((double)(gpsx.longitude)/10000000-0.003466), longitude_char, 6, 1);
    1 q" ]; _. U8 X* |6 Z
  22.                         Transform_double_to_char(((double)(gpsx.latitude)/10000000+0.323707), latitude_char, 6, 1);        0 z$ H4 m5 E7 ^: B
  23.                         
    1 W( H0 T2 ~% c+ d- L' B
  24.                         i =strlen(longitude_char);- ]: J9 n4 @" r. K$ l
  25.                         longitude_char[i] =gpsx.ewhemi;
    & u- R: P- `5 m% S  S' T
  26.                         longitude_char[i+1] ='\0';
    8 J2 n6 D) W7 \' Q
  27.                         2 w7 |, k2 s; N+ {& Q
  28.                         i =strlen(latitude_char);# p: m! h. {$ E3 C/ ]
  29.                         latitude_char[i] =gpsx.nshemi;
    : f6 e% |* i) m2 F
  30.                         latitude_char[i+1] ='\0';2 A' C! E' n- i3 L! r0 S6 l
  31.                         
    5 c, V4 n9 s; L% \9 R9 u) }2 c/ H
  32.                         printf("GPS定位成功\r\n");        " h" c& y6 r' {. p1 }8 P
  33.                 }" `8 k* d0 y* k9 x0 E/ u
  34.                 else if(gpsx.gpssta==0)+ ]7 [1 r+ K0 H) n
  35.                 {        
    ( G% O. `5 J! X- e1 Z
  36.                         if(GPS_positioning == 1 )
    / N- A* X& ]+ p% b
  37.                         {! g3 [! ^& h) |3 A4 [6 H, }
  38.                                 GPS_positioning = 2;
    . t7 B* ?% w2 Y3 d% c: ^- Y
  39.                                 printf("GPS信号弱\r\n");
    ; M' G6 N# W; V% Y
  40.                         }1 T0 f9 ]' u2 a
  41.                         else if(GPS_positioning == 0 )
    * O3 I2 h" F6 ~9 r& R0 X/ r  q
  42.                         {
    8 I) P( L+ H2 j7 ^& x1 [) f4 M
  43.                                 printf("GPS无信号\r\n");
    & U/ S1 r& D, K) }1 ~
  44.                         }
    ) Z5 j; m; x; M! f( c: c
  45.                 }& `1 N5 _) m5 C. p
  46.                 gpsx.gpssta = 0;
    " V, L& z" Z7 _% f+ f! v1 G0 E
  47.         }
    4 d, p" \; O6 q6 B) e0 x/ ~9 U
  48. }
    : G. e" O+ p/ m- R* d
  49. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END  N3 ^7 V- Z& ~
  50. 2 ?0 C7 i/ z" h: [2 d

  51. ) H. c0 V2 K7 ]4 Z

  52. 3 I5 [  t) N/ \
  53. //********************************************************************. d% l: j6 i2 g
  54. //浮点型/整型转字符型
    - ?" j. t1 k6 ^6 V6 S. D3 z
  55. //Decimal需转换小数& }5 v  q% R% d1 w; n; o" V
  56. //Character字符型储存的地址,在主函数定义
    & N8 i/ ?! n7 r' m4 U) d1 B
  57. //precision保留的精度
    2 {6 j# k* q5 h' P7 a4 V
  58. //round是否四舍五入,1是,0否4 x5 `& f! w+ Q: _) ]
  59. //注意可以转换的长度
    ( a" R( _. q0 L" B% Z% t5 z: _% y
  60. //********************************************************************% Z9 \$ [  Y* G* A; J( f8 j2 F% _
  61. void Transform_double_to_char(double Decimal, char *Character, short int precision, char round)
    7 T8 ?8 J8 Q- a1 H! b( [
  62. {, a& h# H* w& u4 I  o3 [
  63.         int i,x=1;
    " ~3 |7 f4 K2 E1 K
  64.         int integer ,integer_decimals;0 o9 g. Y6 Q. \  u
  65.         char temporary_char[10];
    $ I4 Q# n3 b4 `7 H# Z
  66.         for(i=0;i<precision;i++)4 @5 ^; H& P( a5 ^9 _: ?
  67.         {( w) @, L7 y  }
  68.                 x *=10;
    * j) q+ H5 z+ \/ ^* u$ D
  69.         }7 ~- X. q/ t0 H/ P. P5 T, }
  70.         integer = (int)Decimal;                                                                                                                        //整数部分
    4 |+ x: x8 _% [3 u- g0 {
  71.         integer_decimals = (int)((Decimal - integer) * x + 0.5*round);
    9 [  l: Y$ M8 L# P8 k( d# M
  72.         for(i=0 ;integer>0 ;i++)
    $ T" ^5 J& b; `" `4 j
  73.         {
    6 V( ~3 A  b, P) j5 m: b
  74.                 temporary_char[i]= (integer % 10) + '0';
    4 q1 L" R# P, o7 E1 S- U* H
  75.                 integer = (int)(integer/10);2 S6 c% y2 b% ]5 q8 N' w
  76.         }
    4 Z# {) q5 h3 k' w  t" \5 ]
  77.         if( i==0)
    ) g  P. \, o( h8 y9 f5 E! H( x/ I2 \
  78.         {
    6 Q) K8 R' d$ D( X3 Q& v: s  z6 Z
  79.                 temporary_char[i]= '0';' }6 R: |0 J9 L5 _; _
  80.                 i++;" z' p: d' Y  S3 g$ U5 ^
  81.         }0 e" K' \$ e; {
  82.         for(x=0;x<i;x++)
    - G* ^# h9 X; ]% t! t: I) D+ E, O
  83.         {, Y0 `% @' r! R4 A( s9 {" L. n" v
  84.                 Character[x] =temporary_char[i-x-1];
    : i7 D8 N, w. p# R
  85.         }
    % X# q2 |+ c' i0 D6 E2 y0 H6 O
  86.         memset(temporary_char,NULL,sizeof(temporary_char));
    ( L8 Z! e3 v6 ]( z  @2 s$ i" H
  87.         if(precision!=0)
    $ _8 w' f/ B- W2 E5 `
  88.         {, v/ r/ f- k6 M4 M7 w
  89.                 Character[x]= '.';( H. c) w& x3 ?8 N4 r) }
  90.                 x++;8 b/ I/ Q( W8 I9 W
  91.                 for(i=0 ;i<precision ;i++). V$ n$ t3 S5 Q9 E
  92.                 {5 i9 \& T9 P0 g$ Y( C% [
  93.                         temporary_char[i]= (integer_decimals % 10) + '0';: P  `- e4 J. w* b( y
  94.                         integer_decimals = (int)(integer_decimals/10);
    , O0 L% U8 P: h
  95.                 }
    ; u5 e. O2 Z: f. s/ x6 o, n
  96.                 for(i=0 ;i<precision ;x++,i++)! t: j: R* c. G& V  [, B$ F
  97.                 {% O( F+ o/ q: ~  \5 r2 K3 Q' Z- h
  98.                         Character[x] = temporary_char[precision-i-1];        
    / v0 N. T( n+ |3 S
  99.                 }7 c! v- ]' }7 c' x; d3 f
  100.         }' a4 c, ~$ P3 X3 `2 K* T3 s, |
  101.         Character[x] ='\0';0 j, x: [4 ]4 s/ D: ~; k" {! G
  102. }
    , i4 F, s7 N* C! N+ I; w; Z# P
  103. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END</font>
复制代码

) Q% R$ n* s. e3 I  b  b4 A3 a5 b2.GSM

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

  1. <font size="3" color="#000000">//********************************************************************* f' T; U! W6 d0 R8 j
  2. //SIM执行命令
    7 i% B" f! M4 }+ c* ?& ~
  3. //0~3发送短信,0~3号联系人/ m' ]. g. X2 h. T9 G% M
  4. //********************************************************************
    " a( v7 Z1 D: k
  5. char SIM900A_Executive_Command( char number )0 }7 H7 J" z- v. Q
  6. {        
    ' o3 Q/ N. Z3 ]4 @& g  D" h
  7.         if( number == 0 ||number == 1 ||number == 2 ||number == 3 )2 K2 F- D  N' J. o  q+ }
  8.         {4 y/ s, p* W' Z& ?2 h4 c  H7 x
  9.                 int i ,Length;4 x4 V8 \: f% M6 V2 e  {9 K
  10.                 char Message_content[280];8 Z# D' |5 Q  n3 s/ R" x, A
  11.                 char AT_CMGS[4],Data_Length[4];" D* m+ f7 B* \: j( w, G' D
  12.                 char PUD_latitude[50],PUD_longitude[50];
    $ @7 E4 N7 x& D% H" |4 Y5 @" a
  13.                 char PUD_longitude_latitude[100];
    1 L6 M4 A5 @3 q+ ~, D! W( J( j
  14.                 char PUD_comma[5]={"002C"};* u% C3 l, X" b" \, J
  15.                 2 E- {6 K  `8 R, E; k1 Q
  16.                 PDU_Transform__Phone_number(Phone_number[number]);
    " p  C4 U9 U5 w5 E. n% A
  17.                         
    8 n, e; z) o4 @
  18.                 if(GPS_positioning != 0); M4 Y9 a4 x; k0 n( w
  19.                 {- d8 c% k$ L* C% g, {
  20.                         PDU_Transform__Message_content(Message_content,Message_content_original_1);0 B7 f( A/ \# h" N  q
  21.                         
    " w; j# T: @+ Q2 X
  22.                         Char_to_Unicode(latitude_char, PUD_latitude );
    6 Z! Z# U% |3 {5 p7 q
  23.                         Char_to_Unicode(longitude_char, PUD_longitude );# ?: p" ^, H. c1 T# ~$ V+ b
  24.                         " J, N! _, }5 m& h* W8 |# W: E  p2 l
  25.                         memset(PUD_longitude_latitude,NULL,strlen(PUD_longitude_latitude));
    2 w; m2 f4 g& {/ e9 \
  26.                         String_addition(PUD_longitude_latitude ,PUD_latitude ,0);" o' w$ a% D% Y
  27.                         String_addition(PUD_longitude_latitude ,PUD_comma ,strlen(PUD_longitude_latitude));
    - p* m: A7 r( G# J2 d5 M' [
  28.                         String_addition(PUD_longitude_latitude ,PUD_longitude ,strlen(PUD_longitude_latitude));& J7 P3 A2 M; h; I! ^) ^- Y: H
  29.                         
    , Q. w: @& R  a
  30.                         String_addition(Message_content ,PUD_longitude_latitude ,15*4);; d  {2 b1 z+ G+ t' s
  31.                 }: P% Y5 N# [/ a  H) F7 ^; O
  32.                 else
    6 C1 d$ E* o4 y& U0 j3 p
  33.                 {
    2 x6 j; I, i( C. i
  34.                         PDU_Transform__Message_content(Message_content,Message_content_original_2);% U: u8 T( E8 m* Y0 D9 _
  35.                 }; u  ?- a6 J" \2 D% t, h
  36.                 Length = strlen(Message_content)/2;
    # a$ d2 t7 I1 B% j/ ]$ h6 h
  37.                 Transform_int_to_hexadecimal(Length ,Data_Length ,2);
    4 ^6 ]  L+ J8 w( T- O. b8 I. d: |
  38.                 Transform_double_to_char( Length+15, AT_CMGS, 0, 0);
    9 J; y& p0 m1 u# l* i
  39.                 & \8 e- u+ l6 h% g
  40.                 printf("%s\r\n",PDU_Phone_number);8 l  W$ l$ z  I( ], U
  41.                 printf("%s\r\n",Data_Length);
    + z9 R' |# d! \" j" H6 ~% O
  42.                 printf("%s\r\n",Message_content);0 k$ G% _! S0 z" r- G0 [& O+ N1 V
  43.                
    6 y* `1 W6 G. R3 }
  44.                 for(i=0;i<Number_retries;i++)
    ' b& J3 A, s( w# p/ N9 |& W- q
  45.                 {
    # J. ~% g. q5 Y. M. h
  46.                         SIM900A_Send_AT( "AT+CMGS=" ,0 );$ c( f  I3 q  @
  47.                         SIM900A_Send_AT( AT_CMGS ,1 );               
    - A2 F% m* B* @  y' b4 }
  48.                         3 p( k$ b6 r* K" x. y
  49.                         if(USART2_Data_seek(USART2_Data ,">" ,500))* {! Q% ~5 j. w/ I# s" g
  50.                         {9 k. l( n' Z7 Z" E3 r2 n% t0 I
  51.                                 SIM900A_Send_AT( PDU_Phone_number ,0 );9 [/ n9 L- J6 Z1 `! j  N8 m' x- {
  52.                                 SIM900A_Send_AT( Data_Length ,0 );# C' g8 R1 t7 U% M# [
  53.                                 SIM900A_Send_AT( Message_content ,0 );9 I$ B, u4 H& w0 M' \. W
  54. 6 a2 ^/ ]$ E+ w
  55.                                 USART_SendData( USART2, 0x1A );+ }' y: \+ @, x
  56.                                 SIM900A_Send_AT( 0 ,1 );6 v+ T1 a) k2 K! S4 r. Z- H2 u7 x& U
  57.                                 if(USART2_Data_seek(USART2_Data ,"ERROR" ,2000))
    4 l6 R6 e5 F2 F$ b: Q% g% d6 v
  58.                                 {' }! R0 W- X) m. \8 S8 z$ U; g
  59.                                         printf("发送失败\r\n");
    " ]* w  t; I3 O
  60.                                         return 0xFF;
    - z2 O8 a8 x, u5 b- w
  61.                                 }- q# T8 m: n. A! e/ Q8 S
  62.                                 printf("发送成功\r\n");, G, O, @5 {' u  H/ F$ O
  63.                                 return 0x00;
      a- V" F, ?- y/ a
  64.                         }
    7 k2 |9 J. |4 `: m
  65.                         else printf("AT+CMGS指令错误\r\n");# E0 V* D; A  c; @, `' @
  66.                 }        , v0 T/ F4 T8 ?" e
  67.         }
    - Y* @0 F2 Q/ [$ ~1 H9 |
  68.         printf("指令错误\r\n");
    * r, i7 B) d8 G$ R% E/ @- ?
  69.         return 0xFF;+ h, S; d4 W; p1 T7 B6 Y
  70. }
    # ]6 I* L* a4 D4 R3 P
  71. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END
    $ n" v$ }1 Z, W5 A" l
  72. " P; l* b% i% N7 O+ X# X& j9 a
  73. 4 C* h5 f, W6 ^" X' W9 ~  e

  74. : y5 {7 G/ K3 U) E! i3 W
  75. //********************************************************************7 u9 [5 {3 J* ~9 K0 ?2 K$ n: s
  76. //通过串口2发送AT指令) S  |  |8 H* H5 g6 R- \7 r/ p
  77. //可以直接发字符串或发数组) V0 P; {& Z. }
  78. //********************************************************************7 _( G! e! H* k7 `( _
  79. void SIM900A_Send_AT( char *AT_command ,char over )# v, S$ ]2 L) Q1 _- ?) [
  80. {
    - ^" I4 r" L  ]' a
  81.         for(;*AT_command!='\0';AT_command++)7 o0 Q1 U& J/ }, Y% |# y
  82.         {% r% t8 F& p: N6 y' _; c
  83.                 while( USART_GetFlagStatus( USART2 , USART_FLAG_TXE ) == 0 );
    6 d7 g. U! m" u8 R; ]
  84.                 USART_SendData( USART2, *AT_command );
    / |# D8 C) B& \* p" ], ?  ]2 b
  85.         }
    + ~5 E, R1 [+ M6 F
  86.         if( over ); F8 Y: l; E2 l" u8 K+ R
  87.         {; d5 J, r+ x6 \% @% q0 O& S
  88.                 while( USART_GetFlagStatus( USART2 , USART_FLAG_TXE ) == 0 );
      g0 @' h1 z) B7 ~- }3 M
  89.                 USART_SendData( USART2, 0x0d );//  /r,0x0d,回车的作用只是移动光标至该行的起始位置
    / Z* N: H& H( I9 k
  90.                 while( USART_GetFlagStatus( USART2 , USART_FLAG_TXE ) == 0 );
    , M; S; x; f+ R3 I$ {5 V6 M& T
  91.                 USART_SendData( USART2, 0x0a );//  /n,0x0a,换行至下一行行首起始位置;" _& m/ O4 `. e7 s; D
  92.         }% F. W2 Q' Q( {/ s7 F7 a  {
  93.         while( USART_GetFlagStatus( USART2 , USART_FLAG_TXE ) == 0 );" ?" Q; F+ h/ k" H, G/ i0 L
  94. }4 U( k" t, t) [# [* H
  95. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END
    ) h% \9 b4 v8 q: j

  96.   t# n5 K% r$ k# Z

  97. + {3 R1 i  U0 G7 \; p% d) V

  98. % w2 {9 q# r% R" l8 [. i* e
  99. //*******************************************************************6 m* n1 [! {6 h# l' t" ?$ a# V
  100. //将手机号码转换为PDU格式/ _' E, Y: T* q# b
  101. //*******************************************************************1 b* m0 g- \" B$ O* D
  102. void PDU_Transform__Phone_number(char *Phone_number_input)
    / |; h' C7 \8 f; I) O2 _, W- r1 V0 v
  103. {
      d+ X3 V2 |* n" k; O9 \& A
  104.         u8 i;
    9 W! b: R. ^. m4 D9 @
  105.         Phone_number_input[11] = 'F';1 P, I) z4 Y- H  f) `
  106.         for(i =0 ;i<12 ;i++)" J; q9 k0 ?) R) `5 g4 C
  107.         {
    + D6 r0 a: i/ \$ n% F1 r( _
  108.                 if( i%2 == 0)9 E3 K; l# h6 a  I9 G
  109.                 {
    8 b7 c( H# E' ?* P8 b3 z
  110.                         PDU_Phone_number[i+12] = Phone_number_input[i+1];2 m* b% `( S& h: X
  111.                 }
    $ B# _8 q3 t/ N4 i/ w; y
  112.                 else2 l! H4 ]: c0 [, L( ?1 N
  113.                 {
    8 V4 G$ e3 n% a( C
  114.                         PDU_Phone_number[i+12] = Phone_number_input[i-1];  ^1 y/ I; V6 m
  115.                 }
    0 M7 }6 P$ M$ e1 b5 Z! B
  116.         }+ z% A9 A: t) j- s
  117.         Phone_number_input[11] = '\0';
    . f) F% s) R. ~2 P; A) z, F+ q
  118. }4 L5 P2 l; y! F) f* p3 l
  119. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END6 ?0 e+ [5 R2 O1 O7 W  K

  120. * m0 j6 N* r+ _+ W

  121. - q) A$ a3 Z6 q

  122. , D8 H' m9 O. o4 ]7 z9 i
  123. //*******************************************************************3 t+ A# K8 t: `# U7 Z  u
  124. //字符串内添加字符串
    7 X4 H6 O9 v4 A: ^; D, l9 }+ N
  125. //原字符串String
    & K  C) y) Q# e( t" Z; X% A
  126. //需要添加的字符串Add_String; a+ ]( j% h- p/ q* V+ I
  127. //第Add_location字之后添加' a$ [( W6 T/ P5 _, D3 w; B0 n$ H" O
  128. //*******************************************************************
    . {; C1 S' V9 w+ f0 N
  129. void String_addition(char *String ,char *Add_String ,int Add_location)
    $ ~. \) C3 Q$ E
  130. {: K$ x/ ^& k  ?
  131.         u8 i;
    7 D3 Y8 L' L" T7 ]6 ^
  132.         int length_String ,length_Add;$ v, a9 T( v) J' Q+ L
  133.         length_String = strlen(String);
    - i# q. K# [; [1 l+ q: C- Y$ h0 T# f
  134.         length_Add = strlen(Add_String);) F/ p2 u6 i1 ~
  135.         / Q; j& u% `, d7 c, K
  136.         String[ length_String+length_Add ] ='\0';
      R+ _( S& d! F1 i+ E7 q
  137.         
    ! I" f. P9 g- ^, G9 `
  138.         for( ;length_String> Add_location ; length_String--)
    8 M1 K, @+ V6 U- ]8 c( W! j3 Z2 `
  139.         {) N% A# @6 m) s3 p
  140.                 String[ length_String-1+length_Add ] = String[ length_String-1 ];
    # h7 J, [7 h9 M) }
  141.         }
    7 G3 M" W- t/ C
  142.         6 t, K5 ^% z/ Z
  143.         for( ;length_Add>0 ;length_Add--)# z5 x4 S* N$ @9 P
  144.         {! G5 P; ~- \4 @9 v
  145.                 String[ Add_location-1+length_Add ] = Add_String[ length_Add-1 ];
    0 c3 W8 e* w3 Q8 ?% g% E
  146.         }- u9 a/ s0 `$ o7 b: L# Q
  147. }( o. c7 B8 {! B9 h2 b' T7 ~# W% u
  148. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END</font>
复制代码

3 M" G" G9 i4 ~, A0 b: O' M* L3.NRF24L01

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

  1. <font size="3" color="#000000">**************************************( U% N: w  k6 b5 L2 q
  2. //NRF24L01数据解析8 S) b5 G. v; P- c- ^6 Z* c. S# S
  3. //********************************************************************
    $ y0 z- b. G$ N% _4 X
  4. void NRF24L01_Data_Parse(const char *data)
    6 ?5 c! g+ T0 ]4 }
  5. {+ S* L$ g0 l9 ]7 V' w
  6.         u8 i,x;
      Q4 J/ e! C' S
  7.         char cache[8],slave;) s& Y( W/ ~" c  ?% f0 q
  8.         if( data[0]=='K' )
    ( i( ^4 b5 r# _. L  N/ ^5 u8 P
  9.         {/ j3 @$ R$ l3 D% v% L9 u. U
  10.                 for(i=1,x=0; data[i]!='#'; i++)
    ; S! q2 h+ c  x% e. Q
  11.                 {
    7 H. ]. I* ]( P- M# |1 u8 c
  12.                         switch(data[i])5 O& r7 V; z3 j
  13.                         {        
    $ N, S9 [+ |7 L  Y4 @# C
  14.                                 case 'H' :                        for(i++,x=0 ;data[i]!='&' ;i++)        //没有结束( n, V, [5 _& s* H9 K: N4 S
  15.                                                                         {2 {3 B) V6 S" |$ l7 n! N9 w
  16.                                                                                 cache[x] = data[i];. }! R$ g' v& i  U4 T- ^# _
  17.                                                                                 x++;
    9 K0 y" X& ^% G. p. [2 n9 X3 Y. S. x
  18.                                                                         };
    2 m4 q" A- y. m
  19.                                                                         cache[x]='\0';( ]/ h# Q' g5 s* w: _  F
  20.                                                                         slave = Transform_char_to_double(cache);) Z- f' C( R9 b; D  H1 H
  21.                                                                         slave_disconnect[slave-1] = 0;
    5 {. N; K8 ^* y1 `6 n+ T( C
  22. //                                                                        printf("slave=%d\r\n",slave);
    2 d) T7 a& x# q" S) g0 [( N* j  R3 s
  23.                                                                         break;* ~$ ~5 M# |2 C  Q
  24.                                                                         
    ' q5 U2 i" ]5 ^
  25.                                 case 'V' :                # ]% z, ^: v3 r
  26.                                                                         for(i++,x=0 ;data[i]!='&' ;i++)        //没有结束8 J' k9 {& |% F) O
  27.                                                                         {% i- M9 ]0 _" e; m2 I, x1 o
  28.                                                                                 cache[x] = data[i];
    & {0 Y- A: M) m. \( X1 W; J
  29.                                                                                 x++;
      ]+ \, \& t+ N0 f
  30.                                                                         };
    0 E- ?2 e% d' p* G0 X4 O+ l
  31.                                                                         cache[x]='\0';+ C4 d2 |6 m" }1 J# J! A
  32.                                                                         slave_unit_voltage[slave-1] = Transform_char_to_double(cache);
    5 b! @8 A$ j& X( n! G* B
  33. //                                                                        printf("voltage=%lf\r\n",slave_unit_voltage[slave-1]);
    5 ^) [6 h, |: I
  34.                                                                         break;6 [. g9 L3 O( B2 I
  35.                                 case 'A' :                        for(i++,x=0 ;data[i]!='&' ;i++)        //没有结束
    7 a3 Y8 d! s; o- L# M* F
  36.                                                                         {
    + _8 s5 ]4 p7 n4 `5 A" B
  37.                                                                                 cache[x] = data[i];7 C* O' O+ B6 v- i7 ^
  38.                                                                                 x++;
    * K2 f0 g3 R) ~2 k" s8 Q
  39.                                                                         };5 O- o  d6 T, o% z9 W
  40.                                                                         cache[x]='\0';
    3 X; V( T, R2 ^! B7 u* \4 c
  41.                                                                         slave_unit_alcohol_concentration[slave-1] = Transform_char_to_double(cache);2 Y* w" X, ^. J, k; ~2 j7 T
  42. //                                                                        printf("alcohol_concentration=%d\r\n",slave_unit_alcohol_concentration[slave-1]);7 v: J& Q, i. ~, d1 b# A* t9 H
  43.                                                                         break;' N9 x6 }; _! F% _* r0 \) `/ q
  44.                         }
    % b$ x* x+ W' O2 }+ }0 C+ m% B
  45.                                 memset(cache,NULL,strlen(cache));9 T% I( C* Q3 }6 x" v: S$ G
  46.                 }        
    2 V! x1 Y1 C, U$ N+ Q
  47.         }% _/ L5 W4 T- z- ]5 U8 }. N
  48. }5 q) M; v+ T$ w4 A+ \. p: C% J
  49. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END! C+ p$ D5 W1 d# i

  50. & A* u3 f; w! P: i

  51. * A# j1 |" S) {8 h6 a

  52. 4 G+ x, r& [/ C  w( L
  53. //********************************************************************, _( C- }) h" J8 j! ^0 v9 |7 P
  54. //接收到数据进入中断
      v( l! _8 S# {. c5 M3 H6 o
  55. //分析接收到的数据2 E4 c+ C' p% x' v6 ^( `
  56. //********************************************************************) S% i! l2 C! h; w/ R
  57. void EXTI15_10_IRQHandler()
    ! n9 p" K2 t) J/ d& v! ~
  58. {# ?5 v, w  e% [& B
  59.         if(EXTI_GetITStatus(EXTI_Line12))
    - [7 @! M. }' V; y1 O
  60.         {
    4 j; v1 K# A% v% z
  61.                 char NRF_RX_Data[32];/ }" L" @( L4 G& c
  62.                 NRF24L01_RxPacket(NRF_RX_Data);
    " o; T' s& v: M# A6 n# {
  63. //                printf("%s\r\n",NRF_RX_Data);# }% F6 A, C0 }7 k
  64.                 NRF24L01_Data_Parse(NRF_RX_Data);3 X# h$ ?+ O2 W7 E* |
  65.         }
    1 }* F/ f8 B# q- ~
  66.         EXTI_ClearITPendingBit(EXTI_Line12);
    ' J6 d) U0 t* m* {/ j3 I; c+ n
  67. }
    ; g' T) N. W9 v9 E7 Q: M
  68. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END</font>
复制代码
- Z- H2 n$ O1 n0 N" @
4.OLED显示

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

  1. <font size="3" color="#000000">//********************************************************************# ]1 w& ~8 [8 A& X1 C' H
  2. //200ms进入一次中断
    2 [' [1 t" S- E* G2 Y: w: Y
  3. //更新oled显示/ V, D4 G* T( n. {7 \7 P( @- Z7 p1 \
  4. //********************************************************************
    4 W- f! \. m/ n  ]! w4 ^) e8 m9 v- F3 G0 R
  5. void TIM1_TRG_COM_TIM11_IRQHandler()# a* l! s* e5 k+ q1 p+ N' y
  6. {" X- o. P+ j# |
  7.         if(TIM_GetITStatus(TIM11, TIM_IT_Update))6 t* p  w) j8 @7 B
  8.         {4 Z5 J5 J: m( e
  9.                 extern char PILOT;
    1 W  T. Z: E* c4 u
  10.                 static int Enter_number =0,Page =0 ,Canned_format=0,aaa=0;# b) F4 Q6 w. W
  11.                 Page = Enter_number/20 ;//控制翻页时间200*20ms
    # b5 l9 |9 K, g! p) i) a
  12.                
    ' ]2 K6 |; M3 r
  13.                 //********************************************************************
    6 c" n# M4 G+ t+ s, T0 L
  14.                 //第一页信息: {3 @6 C) h4 w
  15.                 //GPS状态
    ; I4 A( `7 R+ x$ L# p2 @
  16.                 //********************************************************************3 X0 V4 {$ j% x5 p8 q" w9 J8 z
  17.                 if( Page ==0 )        
    4 I1 s: U, F* k2 O, h; ?
  18.                 {9 E7 Z0 S; J. v" b3 ~7 ]1 }* A
  19.                         extern char GPS_positioning;$ \! R0 H0 I/ O' @: s
  20.                         extern char longitude_char[15],latitude_char[15];% O- S+ ]$ ^; f  X/ A, e1 \8 S' C

  21. 2 a7 I, K; m" |- \4 h4 c. b
  22.                         if( Canned_format/10 != 1)0 x9 N7 C+ g! ~; `9 [2 X' G
  23.                         {, u4 k6 d4 a/ }
  24.                                 OLED_CLS();. c2 \' H* D  ^8 r* }( M9 I
  25.                                 OLED_P8x16Str(36,0,"GPS",F8x16);
    1 G" V5 C4 X+ m8 }5 Q$ |: W
  26.                                 OLED_P16x16Str(60,0,"状态",F16x16_Idx,F16x16);+ H) h7 [% e' Y" S7 {$ l
  27.                                 OLED_P6x8Str(122,0,"1",F6x8);- R0 Q$ i+ ~- u' L
  28.                                 , |; E, @& z6 `# y+ q" |
  29.                                 Canned_format = 10;; \( G' O* l6 }7 t
  30.                         }
    $ n: }$ \1 U2 ~' c3 O
  31. 4 P$ M$ O4 U; x- C: F, k3 j& h( E
  32.                         if( GPS_positioning == 0)% n* e* L* P& S- `* M! Y: s
  33.                         {& L8 d. z  L  U# t4 b, n
  34.                                 if(Canned_format%10 != 1 )
    8 E! k  N  I. ]5 a- d- b+ L
  35.                                 {
    5 N& ]/ J3 @9 r1 j" S* b7 W2 w. o
  36.                                         OLED_P8x16Str(0,24,"GPS",F8x16);: O' Y: d% z3 l( Z: v
  37.                                         OLED_P16x16Str(24,24,"定位失败",F16x16_Idx,F16x16);
    7 W; R* F  v+ E* y# P" @
  38.                                         Canned_format = 11;                                ( I( r' B, s& \& j# T! H
  39.                                 }3 [8 ~! l1 c$ ^8 d1 m
  40.                         }
    - t1 V; A; ?* t. c6 A# Y
  41.                         else if( GPS_positioning == 1)' k) `& w* E+ R6 @+ f
  42.                         {1 n+ u" R# Y  b: Z0 M" n+ i
  43.                                 if(Canned_format%10 != 2 )
    & P4 i" ]4 q! q" c  j3 T
  44.                                 {
    $ V7 K( `) H: ]' G$ z0 Q; Y% \
  45.                                         OLED_CLS_y(16);- P, }. Z' G( e9 a' ?/ q
  46.                                         OLED_CLS_y(24);
    , I- D3 h* K. G1 i7 `& n$ H  f
  47.                                         OLED_CLS_y(32);  ^' _( M: a, h; S* b  C( {' `( b4 }
  48.                                         OLED_P8x16Str(0,16,"GPS",F8x16);
    3 P/ b4 e0 M; j( a
  49.                                         OLED_P16x16Str(24,16,"定位成功",F16x16_Idx,F16x16);        
    0 X6 X( G% Z! f8 G9 U2 v# Z
  50.                                         Canned_format = 12;
    $ n# p$ r8 F* M  O$ N  p4 [
  51.                                 }0 ^+ u0 d& c6 x) U) A. [
  52.                                 OLED_P8x16Str(0,32,longitude_char,F8x16);
    2 M/ \3 K$ P/ a8 n$ x+ u6 h
  53.                                 OLED_P8x16Str(0,48,latitude_char,F8x16);4 E, v* ?3 D4 r5 `1 l
  54.                         }
    : Y& D5 f( G; ]8 Q
  55.                         else if( GPS_positioning == 2)
    - R1 S2 p1 G6 U( U
  56.                         {
    * J5 P' _9 T4 G7 x+ }) F8 N
  57.                                 if(Canned_format%10 != 3 )* m# @. U7 S- U9 x( j
  58.                                 {
    2 s' F( x$ n5 a0 \( V
  59.                                         OLED_CLS_y(16);. n- N" T$ H  E5 z
  60.                                         OLED_CLS_y(24);% A& j  e# v  y8 y
  61.                                         OLED_P8x16Str(0,16,"GPS",F8x16);0 b, s" G+ W5 s- V* O* K! ?+ K! A$ P2 ~: I
  62.                                         OLED_P16x16Str(24,16,"信号弱",F16x16_Idx,F16x16);
    + p) s4 X. p6 j/ o" W! p9 k  V
  63.                                         OLED_P8x16Str(0,32,longitude_char,F8x16);
    * f( E1 E# s: f2 q( m  p0 J3 o+ O( B
  64.                                         OLED_P8x16Str(0,48,latitude_char,F8x16);( }- [7 j, v6 A. u
  65.                                         Canned_format = 13;5 a& M) x$ q! A" ]
  66.                                 }+ @# t" q  M* Y3 M  Y# x2 Z
  67.                         }
    ! d- i7 U4 ^4 f$ _
  68.                 }
    + y9 W4 l3 I/ I( ~
  69.                 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END, m" t5 y" c+ x. B2 A
  70.                 . u/ f* O# q" J0 V
  71.                
    2 A- Q" F0 b) z; ^, w. w$ d
  72.                
    7 Q4 M7 [( ~7 p& R* o% H7 K
  73.                 //********************************************************************$ Z8 T+ b: T7 f$ X
  74.                 //第二页信息# V8 X- b7 H0 ?
  75.                 //设备连接情况
    9 ]* h9 [  Z- N. n1 h
  76.                 //********************************************************************
    . x" w; K+ \! m( w7 s
  77.                 else if( Page ==1 )
    4 |: e! a9 g: K
  78.                 {& Y  U7 }7 F) u' A" V5 U# t' ?% O5 \
  79.                         extern u8 slave_disconnect[3];
    * v3 h; }) R) P( }: d. a" q
  80.                         ) D9 q$ D, k. z" ^: G
  81.                         if( Canned_format/10 != 2)" H, \! x( i. b8 U
  82.                         {! U4 S/ ^% H' d# X3 \* Z
  83.                                 : B- ^" z0 Q* n/ c  x: a
  84.                                 OLED_CLS();: c% r" n7 n+ @
  85.                                 OLED_P16x16Str(16,0,"设备连接",F16x16_Idx,F16x16);
    . V3 d, J6 V5 s/ g; c
  86.                                 OLED_P16x16Str(80,0,"状态",F16x16_Idx,F16x16);
    , P+ R% e  c  U6 T
  87.                                 OLED_P6x8Str(122,0,"2",F6x8);
    5 X  |3 _' E/ T
  88. / j- x$ E/ d0 x  a
  89.                                 OLED_P16x16Str(0,16,"设备",F16x16_Idx,F16x16);! K& |) `& W3 J& U9 h+ {* K: B
  90.                                 OLED_P8x16Str(32,16," 1 ",F8x16);
    " e1 W- G+ C( R) p
  91.                                 OLED_P16x16Str(0,32,"设备",F16x16_Idx,F16x16);3 T$ y* x' g5 R6 i4 B
  92.                                 OLED_P8x16Str(32,32," 2 ",F8x16);$ I: j. Z2 ]% T5 i  \
  93.                                 OLED_P16x16Str(0,48,"设备",F16x16_Idx,F16x16);4 f& M. e1 S9 |) c1 n& v
  94.                                 OLED_P8x16Str(32,48," 3 ",F8x16);
    4 a9 n" H# S. n) j7 M' a) d) t: |1 g
  95.                                 
    . I/ B) h6 u& Q$ m
  96.                                 Canned_format = 20;. C/ z/ @3 l6 ]! ~. w
  97.                         }) w; Z6 m  ]% s- e0 J, t& ^  i
  98.                         
    1 |# T: i6 @4 ]
  99.                         if( slave_disconnect[0] == 100)) T- C+ ]; R" v' i) K
  100.                         {
    - D' N: d- \- ]. D
  101.                                 if(Canned_format%10 != 1 )# c7 @( Z" i3 i
  102.                                 {
    : V: Q; j% x& m% s5 N# U! _
  103.                                         OLED_P16x16Str(56,16,"断开连接",F16x16_Idx,F16x16);. \: f+ i6 `* m# e1 R
  104.                                         Canned_format = 21;                                
    6 `  Q9 y5 k% d8 ]
  105.                                 }
    8 \: O; M9 e% Q. G7 F5 y
  106.                         }
    ; |+ N9 q' t, e/ X+ G% j! T! F& g
  107.                         else9 R/ N2 i0 z% s2 Z- d; D
  108.                         {
    * Y( s) ?6 c& ~! }) n
  109.                                 if(Canned_format%10 != 2 )8 f9 e' P4 ]' O' `  |% T% z
  110.                                 {) P$ A  O$ s5 M5 w
  111.                                         OLED_P16x16Str(56,16,"连接成功",F16x16_Idx,F16x16);* E5 Y( b" [% |
  112.                                         Canned_format = 22;        ( y* G7 ~8 x% F) C/ [$ ?
  113.                                 }, V: Q2 t! q3 X5 y
  114.                         }" L: e/ J) X3 h3 |2 z6 O
  115.                         
    ! ~& a/ {. a3 O9 V4 F( b' o
  116.                         if( slave_disconnect[1] == 100)
    & e9 M6 J5 I7 g
  117.                         {
    ' q7 B% S* e+ ^+ o& h/ A
  118.                                 if(Canned_format%10 != 3 )$ _; X. a+ F2 ]# U2 N* _1 n
  119.                                 {
    $ p. I: \( k6 C% Z- j( V0 @
  120.                                         OLED_P16x16Str(56,32,"断开连接",F16x16_Idx,F16x16);6 m* [6 R$ r+ z; }- ^) m
  121.                                         Canned_format = 23;                                * x& G% o* v- X" \8 y
  122.                                 }8 P- F$ y. p2 Q; Y* m% n) r; m
  123.                         }% i0 @% g8 p1 [, V( s4 R6 S, t
  124.                         else
    , H! \* S# ]* K
  125.                         {" @$ S* g' e: C! v. n$ ^
  126.                                 if(Canned_format%10 != 4 )
    5 ~* F* Z' F9 J" z3 m1 M! n
  127.                                 {
    ) I, N7 l! C3 [' u( \, Q& ?5 I, V7 _
  128.                                         OLED_P16x16Str(56,32,"连接成功",F16x16_Idx,F16x16);0 `* g& n. t0 [; ]& C' G' m8 s0 s
  129.                                         Canned_format = 24;        " \4 c0 `0 F1 _2 r7 N# r) C$ M
  130.                                 }, |9 r9 }7 {3 d5 [+ v' _4 F6 J6 y
  131.                         }
    ; V& K9 w. n: v' V( ^7 z! N0 r
  132.                         7 a. P# s; T( }
  133.                         if( slave_disconnect[2] == 100)- ^2 N; |  @8 B
  134.                         {2 u) }1 B1 ^# w% M! ~7 z& g
  135.                                 if(Canned_format%10 != 5 )
    0 l# }$ \; h3 {
  136.                                 {- y0 r% K8 m1 P! J0 L/ H9 a
  137.                                         OLED_P16x16Str(56,48,"断开连接",F16x16_Idx,F16x16);% ?* t! F2 a3 a& {
  138.                                         Canned_format = 25;                                9 t; q3 C9 v" R# R1 y* L- a
  139.                                 }
    ( v9 v# D. V8 z- E* J2 S
  140.                         }
    ' D# i$ C% G3 j9 p
  141.                         else1 |0 W# p8 n/ U! t/ p; h" |7 u
  142.                         {0 i* q& F/ X7 E3 `
  143.                                 if(Canned_format%10 != 6 )
    0 I7 u: w% {6 n& O* }% m& M0 I
  144.                                 {0 j. g) c, f" G; V
  145.                                         OLED_P16x16Str(56,48,"连接成功",F16x16_Idx,F16x16);3 o, m8 e9 Y# U8 N8 i" v
  146.                                         Canned_format = 26;        
    5 i6 ]% O* m8 v9 ?8 ?( Z" T) i
  147.                                 }& R9 x) S6 V) L5 t
  148.                         }        
      ?& P" r# M  |/ @$ C0 F
  149.                 }6 Z9 @4 m1 Y) i& |
  150.                 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END
    4 R9 {8 \; }& r/ v& F
  151.                
    ! P( o- }7 J. B$ j) [: e2 b4 l/ ?9 M
  152.                
    3 G+ y+ [- H' l' t  K: m
  153.                 : }8 m* u5 O" e$ h  E+ ?( ?
  154.                 //********************************************************************
    1 `9 a) O, f8 D, n* J) r
  155.                 //第三页信息
    1 N& }" D, }: X6 M# U* M
  156.                 //电量, t6 B: o/ T* S- E$ y
  157.                 //********************************************************************
    9 v" D$ j" _& k! g4 T1 t: R/ [3 w
  158.                 else if( Page ==2 )
    * _0 J' Q+ k! Q3 U
  159.                 {
    ' ?6 X/ s6 A5 ]
  160.                         extern double voltage;2 |- B3 R2 b9 G' A. ?( q' d
  161.                         extern double slave_unit_voltage[3];7 D0 N' f! Z/ [) L! v5 m
  162.                         . a8 @3 Y: S3 P* z! h
  163.                         char OLED_voltage[4][6];9 \2 x- n4 _( c/ \1 ^; J% v
  164.                         
    & K; ?# X. B5 V0 d' e/ Z) p0 x
  165.                         if( Canned_format/10 != 3)
    : O0 p' y; s2 j  q: E4 E
  166.                         {
    ! p( m0 e! t. P* {0 ?3 j+ E! i
  167.                                 OLED_CLS();1 M2 z0 p# a+ a5 f
  168.                                 OLED_P16x16Str(48,0,"电量",F16x16_Idx,F16x16);
    * T8 H+ ?# C1 {8 `
  169.                                 OLED_P6x8Str(122,0,"3",F6x8);9 ?) W, y* ?: y3 r

  170. * Y; m6 f) i: ~  H' T' b+ ^
  171.                                 OLED_P8x16Str(0,24,        "M:    V",F8x16);                                " r! t0 c) ~) l8 `
  172.                                 OLED_P8x16Str(72,24,"S1:   V",F8x16);
    + i, u7 J7 W& X% o
  173.                                 OLED_P8x16Str(0,48,        "S2:   V",F8x16);7 g6 Y0 Z9 A6 J- v8 G/ N5 @8 {
  174.                                 OLED_P8x16Str(72,48,"S3:   V",F8x16);        
    7 n% Y5 g- i, p
  175.                                 
    ! j: R7 s8 S) D
  176.                                 Canned_format = 30;7 W7 W0 u% m, W- e  v. H0 E+ ?
  177.                         }- \( T( @$ x/ f# \% H! J, U  m
  178.                         Transform_double_to_char( voltage , OLED_voltage[0], 1, 1);
    $ y3 h4 Z. D. M1 _$ a% R
  179.                         Transform_double_to_char( slave_unit_voltage[0] , OLED_voltage[1], 1, 1);! m$ {  ]; t$ K
  180.                         Transform_double_to_char( slave_unit_voltage[1] , OLED_voltage[2], 1, 1);" B) w6 l. j! J) G9 D6 {
  181.                         Transform_double_to_char( slave_unit_voltage[2] , OLED_voltage[3], 1, 1);
    ( s, z. g& X7 e2 G! P! Q5 i
  182.                         $ a' Z5 v6 b. j4 L; _  I
  183.                         OLED_P8x16Str(16,24,OLED_voltage[0],F8x16);8 b2 f- t5 _- |) u3 w- @
  184.                         OLED_P8x16Str(94,24,OLED_voltage[1],F8x16);
    ! N: o; Q& b5 w4 U
  185.                         OLED_P8x16Str(24,48,OLED_voltage[2],F8x16);
      P9 K0 T/ a( Y  t
  186.                         OLED_P8x16Str(94,48,OLED_voltage[3],F8x16);
    6 `: R8 Q9 u6 @* O  M: C2 M  Z* N. G+ |
  187.                 }
    0 G8 V( s6 w" l+ Y- n: e
  188.                 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END& U1 p! d- |6 A, J" l; d8 |
  189.                 & @0 y" P+ q3 v4 o$ b% K
  190.                 : C) C( [5 x0 H1 G% B; r
  191.                
    . W! R" s; Q6 ^
  192.                 //********************************************************************
    0 R4 @0 D5 e8 I: F4 e1 [( t/ H
  193.                 //第四页信息
    + G; t5 P: o7 w" {2 @
  194.                 //酒精浓度* y, U  Q: V/ H( L) z/ V5 y% [# x
  195.                 //********************************************************************& a2 [: `  }% b( b4 g6 Z: L
  196.                 else if( Page ==3 )
    3 H7 a$ r! A; @6 h6 f" }. o
  197.                 {
    " P) k0 G1 y: ]7 I; r
  198.                         extern short int alcohol_concentration;
    ( Q3 p. A  E2 l: d: Y! u7 n" }, k- K
  199.                         extern short int slave_unit_alcohol_concentration[3];
    - l% d7 F: m' `6 @6 {
  200.                         0 ~! B* J+ D1 w& v/ X
  201.                         char OLED_alcohol_concentration[4][6];9 L( z  ~6 d& j6 R- }: F
  202.                         
    - W" i; B( J5 M7 L! d. Y( |) P
  203.                         if( Canned_format/10 != 4)5 P' r7 |# @* I. w8 f9 C  v
  204.                         {
    % Y6 F; V- `7 ~$ R# _
  205.                                 OLED_CLS();
    0 O0 z, @! P, x3 q( H( [( C0 I, Y
  206.                                 OLED_P16x16Str(32,0,"酒精浓度",F16x16_Idx,F16x16);# q( G/ d, v" t
  207.                                 OLED_P6x8Str(122,0,"3",F6x8);
    ! K. t4 L$ }2 g2 r3 ^$ G0 [
  208.                                 
    ' C6 u9 O7 Y0 d4 E$ V
  209.                                 OLED_P8x16Str(0,24,"A1:",F8x16);# P! `# b, T2 @; @  V
  210.                                 OLED_P8x16Str(64,24,"A2:",F8x16);
    - X5 w8 b9 s9 j, x
  211.                                 OLED_P8x16Str(0,48,"A3:",F8x16);
    + d8 `  w+ i/ u6 e3 s# ?; _! r
  212.                                 OLED_P8x16Str(64,48,"A4:",F8x16);
    0 V4 }; ]2 i4 g
  213.                                 
    , @9 q+ X0 K) E2 ^
  214.                                 Canned_format = 40;  {+ W4 P% K. W4 r
  215.                         }
    # C7 F+ s% N  n$ o
  216.                         $ J# c* o& Y2 B1 @. h
  217.                         Transform_double_to_char( alcohol_concentration , OLED_alcohol_concentration[0], 0, 1);
    . ^; G0 S  n4 I" O; Y( V3 t. `
  218.                         Transform_double_to_char( slave_unit_alcohol_concentration[0] , OLED_alcohol_concentration[1], 0, 1);
    / z  O( \! A% l: ]! p6 ~
  219.                         Transform_double_to_char( slave_unit_alcohol_concentration[1] , OLED_alcohol_concentration[2], 0, 1);- M/ {, X* n7 b% G( ]# Z! w( i" {
  220.                         Transform_double_to_char( slave_unit_alcohol_concentration[2] , OLED_alcohol_concentration[3], 0, 1);
    9 _5 e) J7 I1 b& ]. ~# }+ W
  221.                           `7 T* ]- T, v& {, a1 t5 c$ b& c
  222.                         
    $ h; T( L( O" j& k, R
  223.                         OLED_P8x16Str(48,24," ",F8x16);# a8 W3 j* A  O- ~* Y% x
  224.                         OLED_P8x16Str(112,24," ",F8x16);: X3 X/ i7 j/ p% J, p) @8 ]# {
  225.                         OLED_P8x16Str(48,48," ",F8x16);
    . h  d9 q# J8 x' A
  226.                         OLED_P8x16Str(112,48," ",F8x16);
    " R8 [: w4 d/ Y! n9 s9 S1 D/ X8 R$ P
  227.                         ! j( W5 \8 `7 S. H* E7 E0 @
  228.                         OLED_P8x16Str(24,24,OLED_alcohol_concentration[0],F8x16);* R" {% V* a. f2 b* T# J* G
  229.                         OLED_P8x16Str(88,24,OLED_alcohol_concentration[1],F8x16);, ]# J5 m/ I" d4 L& W1 z! d7 t
  230.                         OLED_P8x16Str(24,48,OLED_alcohol_concentration[2],F8x16);: {* Z/ c3 t% ]  W$ g
  231.                         OLED_P8x16Str(88,48,OLED_alcohol_concentration[3],F8x16);$ v; p% U0 ?: N4 o2 ~1 ]: Y2 B, M
  232.                         4 z! r. x- i" Y6 ~7 E+ J& D! ^
  233.                 }, W, m6 o1 w  X1 u3 N4 O# d7 d% c
  234.                 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END# q! D" ?4 u$ X' S3 l
  235.                
    ' U: C3 K' T2 c1 M6 F3 T( m. M
  236.                 ' g$ c5 _5 h2 S! _: ~; Y
  237.                 3 c+ e9 |, a% n8 V: i, c1 K
  238.                 //********************************************************************) ^! X; g& `' G# c8 P! w
  239.                 //第五页信息
    $ Q! e! O0 F/ W- O
  240.                 //# p# q# O# F, c
  241.                 //********************************************************************               
    6 R; N4 Z4 w% u5 A! d
  242.                 else if( Page ==4 )5 ?8 o7 C$ N- e. [- J: A$ m
  243.                 {
    % D0 |5 {4 Z  Y& o) ?
  244.                         extern char Phone_number[4][12];5 w8 X9 e9 D+ W5 {
  245.                         if( Canned_format/10 != 5)# v/ n- y0 r" i- o( I! j
  246.                         {, X/ D/ b; u$ n' z) m+ ~
  247.                                 OLED_CLS();: J% U5 K! F4 G! s
  248.                                 OLED_P16x16Str(44,0,"联系人",F16x16_Idx,F16x16);        , L: S7 {6 Z5 ?' F( d( o3 W) r
  249.                                 OLED_P6x8Str(122,0,"5",F6x8);
    ! Q# q% K- l* W" g5 p
  250.                                 
    + y2 O' R% t; b( J- @1 ^% p
  251.                                 OLED_P8x16Str(0,16,"C1:",F8x16);
    , X! o6 V7 J8 V+ K5 o# b, @
  252.                                 OLED_P8x16Str(24,16,Phone_number[0],F8x16);' V! m" n( q5 Z8 B8 p. }
  253.                                 OLED_P8x16Str(0,32,"C2:",F8x16);
    8 v" U5 a  L" b9 o0 }$ j  F* _
  254.                                 OLED_P8x16Str(24,32,Phone_number[1],F8x16);
    0 Z0 N4 P- ?; X9 i3 }
  255.                                 OLED_P8x16Str(0,48,"C3:",F8x16);6 N6 I& C7 L: W% m: n5 i3 b
  256.                                 OLED_P8x16Str(24,48,Phone_number[2],F8x16);
    . g! J5 J) l* _
  257.                                 
    5 F9 u+ Z4 E/ Q) i
  258.                                 Canned_format = 50;
    + f9 w! u# y3 n- O4 @, W! C
  259.                         }" c5 ]* ]: _8 V+ d
  260.                 }
    * G& C: O& s# K3 ^
  261.                 //********************************************************************$ }- W1 o1 |; @4 ?
  262.                 //第六页信息
    6 o; p3 _$ D" W: N7 r. @
  263.                 //车辆状态# {" C- X. v; F+ ~5 T
  264.                 //********************************************************************: K7 A3 C) e4 t+ |3 {
  265.                 else if( Page ==5 )//第一页( I. J' a: n' D; o7 Q; \
  266.                 {9 u- j( c( Y2 g# x. }: i5 T
  267.                         extern char DRUNK_DRIVING ;
    - }8 Q7 e9 Y+ K
  268.                         if( Canned_format/10 != 6)
    8 k) b& k+ d2 N5 a$ P( R+ I( B8 j
  269.                         {+ @0 U! [8 L1 l$ P
  270.                                 OLED_CLS();
    # l- l6 I* r4 s2 S
  271.                                 OLED_P16x16Str(32,0,"车辆状态",F16x16_Idx,F16x16);        ) i5 b$ p6 ?2 e8 i$ a( j; L7 _+ w% b* j
  272.                                 OLED_P6x8Str(122,0,"4",F6x8);
    8 Z' l% W* q$ E' `
  273.                                 3 b! I" n- `! a6 _6 j6 D/ a" b& W) G
  274.                                 Canned_format = 60;        
    % a! N5 t* H& g# Z% g5 i) R7 s
  275.                         }
    8 T! i& r+ J" T- C# i8 D
  276.                         " P. |9 _% `# {
  277.                         if(DRUNK_DRIVING==0)
    - {1 j) N, c: B+ Q! D0 `1 P
  278.                         {
    6 B* G- W4 m5 m* A* X# y! e0 R
  279.                                 if( Canned_format%10 != 1): `* D  g' d2 H& w$ I' C+ n( [& n
  280.                                 {( O/ s& [% ]4 `9 q8 M, A
  281.                                         OLED_CLS_y(16);
    - d2 L/ j% o+ A/ J$ c, ~
  282.                                         OLED_CLS_y(24);2 ?7 S' M* _0 a! R$ S. A% [% B
  283.                                         OLED_CLS_y(32);2 m" a8 H. r( F; t
  284.                                         OLED_CLS_y(48);! C: t2 v6 u. v
  285.                                         OLED_CLS_y(56);
      e1 y0 r& F' Z. \
  286.                                         OLED_P16x16Str(16,32,"车辆正常行驶",F16x16_Idx,F16x16);        
    & @$ p+ E% A9 X
  287.                                         Canned_format = 61;2 `2 W" o* R4 L; i6 h
  288.                                 }& p3 N8 s' ]* o
  289.                         }8 D6 u, d7 N) _; X# T
  290.                         else
    ) J" w; j' _  E2 d
  291.                         {' U$ P! p# `! G" l
  292.                                 if( Canned_format%10 != 2)+ U4 o2 O( H: R' ]) j$ r7 }
  293.                                 {
    7 p4 Q9 q/ ]4 D, G
  294.                                         OLED_CLS_y(16);
    5 m% R, P1 T% S
  295.                                         OLED_CLS_y(24);
      n; E" S/ `. j2 x9 d: e: x3 K
  296.                                         OLED_CLS_y(32);
    8 ^2 L2 }$ `- I! ~* e; N3 ~  t
  297.                                         OLED_CLS_y(48);
    2 Z0 l# C' q4 Y+ C& ]
  298.                                         OLED_CLS_y(56);6 X$ I6 g# o1 M. ?) A) ]
  299.                                         OLED_P16x16Str(8,24,"发现驾驶员酒驾",F16x16_Idx,F16x16);
    0 s8 G& g5 H0 c. p* ~
  300.                                         OLED_P16x16Str(16,48,"车辆禁止行驶",F16x16_Idx,F16x16);        8 `4 ^9 ]5 Z+ B$ P4 v
  301.                                         Canned_format = 62;' q8 p3 W7 ~9 O' d/ S3 M* ~
  302.                                 }; U( `: _8 i9 g& q4 K9 x1 c
  303.                         }        
    5 \  U5 J, n# b) U
  304.                 }                ; J; u/ J, L, A% N! L/ g; F
  305.                
    3 \: ]* y( H& p+ H* q7 k: r* M+ B
  306.                 //********************************************************************
    / X- Z5 F5 |5 K! z8 Q6 T* `
  307.                 //重新开始显示第一页
    0 D9 q4 W5 F. L2 U+ C( }0 B
  308.                 //********************************************************************5 P/ j$ ^2 {, V. X3 G& g
  309.                 else if(Page==6)
    8 D' G- E' k8 |6 V
  310.                 {
    , d) y# i* f# Y6 @) E1 R& d: E# ~6 Z
  311.                         Enter_number =0;
    - b% X5 f/ x& k- f7 G1 j
  312.                         Canned_format=0;+ Y2 L( {0 W$ Q7 A2 K/ x3 ~2 j
  313.                 }8 p/ c8 `: t8 \$ l
  314.                 Enter_number++;
    ; y) H. M6 s7 B. R8 w$ J+ e
  315.         }5 ^. ~' d5 l" e7 [/ t
  316.         TIM_ClearITPendingBit(TIM11, TIM_IT_Update);* {* |& h4 E6 A! M% |3 L/ U
  317. }
    ! s& D9 S5 ?' o4 A
  318. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END</font>
复制代码

. w" ?! p8 x6 _4 _/ \7 \* b6 o( s) M2 W4 \1 [
5.酒精传感器

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

  1. <font size="3" color="#000000">//********************************************************************
    " X! }  S  `% x7 [6 r
  2. //100ms进入一次中断5 X5 ]. g& \1 [# w$ E/ p
  3. //判断是否酒驾
    2 t+ I! v5 Z1 S3 E. S5 ?$ P
  4. //********************************************************************
    5 D) m+ g7 f6 T! f
  5. void TIM1_BRK_TIM9_IRQHandler()0 W. e7 N9 T  T
  6. {& c) A0 m" e8 X% e
  7.         extern short int alcohol_concentration;
    , Q: K3 f2 j% i2 f1 H' E/ R
  8.         extern short int slave_unit_alcohol_concentration[3];4 r0 ?# v: L: @; d5 J
  9.         extern char DRUNK_DRIVING;
      O) ]: B6 N1 h, T
  10.         extern u8 voice_prompt[15] ;
    $ h1 y# [; o% B; t9 r8 N1 x
  11.         static u8 Number_of_drunk_driving= 0;
    0 V! W+ @" R4 Q
  12.         if(TIM_GetITStatus(TIM9, TIM_IT_Update))4 \5 @7 z9 v  R' a* i, c
  13.         {
    . E8 S0 {0 c  j- l1 l/ j
  14.                 double Weight_M=1 ,Weight_S1=1 ,Weight_S2=1 ,Weight_S3=1 ;" b8 y6 P4 C* h& r! p$ F1 t
  15.                 if(        alcohol_concentration > 2000 || DRUNK_DRIVING == 1)//当主传感器大于规定值开始判断! I! R" [; @) C& I5 ^$ C1 K4 @
  16.                 {
    ' p$ ]' s7 t0 m$ o
  17.                         //*****插入算法判断是否酒驾,之后需要修改
    # v& r9 b- @6 c% I2 g5 g
  18.                         if(Weight_M * alcohol_concentration > (Weight_S1*slave_unit_alcohol_concentration[0]+/ x* u( Z/ _7 h3 B9 c4 m( }+ c
  19.                                                                                                                                     Weight_S2*slave_unit_alcohol_concentration[1] +; ~2 k' j+ P4 a9 R9 |7 W
  20.                                                                                                                                    Weight_S3*slave_unit_alcohol_concentration[2] +500) /3;
    6 g0 p1 R5 k: B  ?& o' B; I+ d. f
  21.                           )
    9 {$ l2 A0 d% g
  22.                         {
    * {( l: C/ K) A6 @
  23.                                 Number_of_drunk_driving++;
    ; m0 a$ }: A3 B/ N/ [
  24.                         }9 U- g' J% R  Q
  25.                         else if(Number_of_drunk_driving!=0)
      T% n, |  _( y6 R
  26.                         {4 v5 c9 }. t/ s, \# E
  27.                                 Number_of_drunk_driving--;; a- a) Z3 W" Y& p$ Z
  28.                         }
    2 p+ o# y# c, ]% Y4 B8 j/ E
  29.                         //>>>>>>>>>>>>>>>>>>>>>>>END0 r) P" d+ ~( m  r, O; [/ ?
  30.                         
    * s! C: S0 p3 Q0 E3 \. F
  31.                         //*****是否连续10次判定为酒驾# u8 J* A- \) L; |( U
  32.                         if(Number_of_drunk_driving>10)
    $ k. j) o5 z2 f) [5 T7 B
  33.                         {
    % u4 ~0 m$ S; X* f5 s2 h
  34.                                 Number_of_drunk_driving = 10;
    % V- F3 @5 R' u" R; ~
  35.                                 DRUNK_DRIVING = 1;
    7 N0 k% E( F" y+ P4 J6 U' U
  36.                                 if( voice_prompt[3] == 0 )' E1 f, Z0 M1 L7 q
  37.                                 {5 f2 `* }" ^5 t% n8 [# U
  38.                                         JQ6500_play(4);) o5 ~4 A. }& P1 _, H  c% Y
  39.                                         voice_prompt[3] = 1;
    - B8 |) F% @: g' h! a8 v6 T' s
  40.                                         voice_prompt[4] = 0;: `$ Z. [6 M! H* ~2 T
  41.                                 }
    , U- m, W9 i* P8 E' u& Y
  42.                         }
    1 r& g" t6 b# ?
  43.                         else if(DRUNK_DRIVING == 1 && Number_of_drunk_driving ==0)
    ; o& Z# t1 s* m- m0 q
  44.                         {$ V  K/ q& z4 u+ L: W! z
  45.                                 DRUNK_DRIVING = 0;$ B2 C; G% s$ @: K, s6 Q9 I0 u
  46.                                 if( voice_prompt[4] == 0 && voice_prompt[3] == 1)% d  `+ q) |, Q# C4 j
  47.                                 {7 j' f! ]- k8 n0 X4 k: c; I
  48.                                         JQ6500_play(5);
    4 i2 n( f0 H2 ~9 N4 E
  49.                                         voice_prompt[4] = 1;
    , ^3 E4 T. ^7 o; p. {0 \# |1 d
  50.                                         voice_prompt[3] = 0;
    ) F0 G; y5 n$ C" A, F  D
  51.                                 }
    ) a' d! b9 \& N% ]- B, h7 f+ f
  52.                         }
    5 ~4 d& {8 F) j% o9 y8 O. w
  53.                         //>>>>>>>>>>>>>>>>>>>>>>>END* ^; \6 |" p7 F2 b9 ~3 \
  54.                 }                2 Z) Z7 T; J" G. y1 _$ G
  55.         }5 Z( q* q+ [( @& d
  56.         TIM_ClearITPendingBit(TIM9, TIM_IT_Update);# U1 z$ \% o) C& j9 D" m6 J
  57. }
    $ \- L& K: t& C3 B5 t
  58. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END</font>
复制代码

2 `$ D# k' ~% f+ g6 @6.语音模块

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

  1. <font size="3" color="#000000">*****************************************************$ \0 p  L1 W* Z+ W% z3 v% y) J" Q
  2. //JQ6500发送控制指令
    6 i7 I- B& ~8 V- S9 G
  3. //********************************************************************
    0 n. m. W: x/ {7 `( S" ~* Q
  4. void JQ6500_control_command(char command)
      O# s2 @$ P+ z! c6 d5 N% W; Q3 F+ d
  5. {4 Y1 d" F2 A) ?
  6.         
    5 U7 H" r$ B2 y* ?. x# E: H  g; h% P
  7.         char JQ6500_instruct_1[5]={0x7E ,0x03 ,0x06 ,0x02 ,0xEF};                //音量00~1E+ Z6 X# n. \0 l& P+ f7 t
  8.         char JQ6500_instruct_2[5]={0x7E ,0x03 ,0x06 ,0x17 ,0xEF};                //音量00~1E+ I1 Y8 @" b0 T
  9.         char JQ6500_instruct_3[5]={0x7E ,0x03 ,0x06 ,0x1E ,0xEF};                //音量00~1E
    & e7 V6 g4 d. @# O
  10.         ! Y5 d$ @; F& g# f- E
  11.         char JQ6500_instruct_4[5]={0x7E ,0x03 ,0x11 ,0x04 ,0xEF};         //播放模式:0 1 2 3 4(ALL FOL ONE RAM ONE_STOP)
    % C; S2 E5 ?. a, O9 m1 @
  12.           `2 T* e" F3 Z9 v# c6 U
  13.         char JQ6500_instruct_5[4]={0x7E ,0x02 ,0x0A ,0xEF};                                //低功耗
    ( G$ W2 m3 T$ ^( ^4 U
  14.         char JQ6500_instruct_6[4]={0x7E ,0x02 ,0x0C ,0xEF};                                //复位' ^/ Z; G7 u+ ?/ Y5 J  p0 R0 O
  15.         2 s9 F* B8 ]0 |& p9 \6 o0 q1 }
  16. & l' @& \7 [/ t6 o$ z! |
  17.         switch (command)2 q$ T+ Y; q- m% n
  18.         {
    - ~/ n' X" ]9 o  Z) C
  19.                 case 1:Send_hexadecimal_UART4(JQ6500_instruct_1);break;' @" u" {: Y! @, C
  20.                 case 2:Send_hexadecimal_UART4(JQ6500_instruct_2);break;! U5 b; m, ?1 P( E' l# P" M
  21.                 case 3:Send_hexadecimal_UART4(JQ6500_instruct_3);break;! K* ]; V6 Z6 g& j; U
  22.                 case 4:Send_hexadecimal_UART4(JQ6500_instruct_4);break;
    ; I8 O3 ]5 Q! r7 j0 N* I5 B
  23.                 case 5:Send_hexadecimal_UART4(JQ6500_instruct_5);break;1 i% u0 |9 s* I  w) K
  24.                 case 6:Send_hexadecimal_UART4(JQ6500_instruct_6);break;. a* y$ x6 S3 H" O+ U( H) k- [5 Z3 z
  25.                 - a9 }' Z5 h" p5 s0 ~: L
  26.                 default: break;0 _& G- x4 w8 r' T5 z6 C
  27.         }
    ; A+ h& {8 g3 L  a7 Q# J
  28.         delay_ms(50);
    ) d6 N7 B9 m. A4 a) z4 g
  29. }1 Z' C' T, f* ]8 f! b
  30. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END
    , L3 _9 a4 S- {  y) ]. i
  31. & ~4 \& _3 j* o2 h' q+ Q3 D
  32. ) h3 I& o) X% K+ D  x

  33. - B4 ~) m3 A& T  Z
  34. //********************************************************************
    . ]: {- u  ]! u* D5 d# _- b
  35. //JQ6500语音模块播放指定曲目5 ^& D( I1 I. e1 n
  36. //********************************************************************5 j; T+ c' D& i. q; E( k3 Z7 R
  37. void JQ6500_play(u16 number), K4 K! c9 B3 x0 o9 r1 j. d
  38. {' ^( B& u  Q' n
  39.         char JQ6500_play_number[6]={0x7E ,0x04 ,0x03 ,0x00 ,0x00 ,0xEF};                //音量00~1E/ d* q6 T# F8 [9 `' N  G+ l4 W/ u" h6 N
  40.         JQ6500_play_number[4] = (u8)number;( k. ~; P; Z& n$ A
  41.         JQ6500_play_number[3] = (u8)(number>>8);- g: w- D7 [- x# o) @4 a
  42.         
    2 ~7 S0 D( s6 L" ]
  43.         while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_12)==1);
    0 l, s6 }& q( {3 f& S: d% e6 f
  44.         while((GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_12)==0))
    5 ^$ \) l3 B2 l4 Q0 r: W9 [* u" ~5 c
  45.         {& }' a3 f3 i1 k; T  z  q
  46.                 Send_hexadecimal_UART4(JQ6500_play_number);delay_ms(100);% z1 _4 E7 J5 k8 I, i1 F0 @" l' _
  47.         }
    * k+ U2 F2 J+ n
  48.         while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_12)==1);
    & U' s! a2 w6 b0 o3 c$ P% S
  49. }
    2 P0 L% Q7 W8 |
  50. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END
    5 P& Y2 z& e$ s

  51. + A2 M6 A/ a- U, ~
  52. ' y$ J% I: Q2 w2 s! P, e

  53. 0 b- e6 @" @# c0 D
  54. //********************************************************************# ^. x9 T. o' {8 O
  55. //UART4发送16进制数据
    5 B" G: i/ v* ^; }
  56. //********************************************************************" W+ h3 Z; e/ p. S
  57. void Send_hexadecimal_UART4( char *array )
      Z- t3 j) Y( T* @0 T2 T
  58. {" L8 H/ G: N0 a$ q& g
  59.         for( ;*array!=0Xff ;array++)6 f% z1 Y: A# I3 D$ Y: S4 `
  60.         {6 U. k' ?$ ?3 f3 m- j
  61.                 while( USART_GetFlagStatus( UART4 , USART_FLAG_TXE ) == 0 );! ^) l$ u! {8 A! g
  62.                 USART_SendData( UART4, *array );
    6 k: J% ~: B! @4 [' j
  63.                 while( USART_GetFlagStatus( UART4 , USART_FLAG_TXE ) == 0 );3 @4 ~! |2 _& j5 h
  64.         }
    8 w7 Q* E2 l/ s4 h
  65. }
    ; R  a, g( f& s( d
  66. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>END/ C6 A% B( |, N* D) a
  67. </font>
复制代码
3 K) F( `9 s% b( E$ v* P

" \1 Q/ k% @' A( w) v. {; t从机部分

; l/ c1 W4 d. E+ ?2 g+ |# j

  从机采用HAL库进行编程


$ K8 u& O% b9 o  N. N, x

1.NRF24L01

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

( O  J2 z8 Q7 J# k( q, Y- c0 @
  1. <font size="3" color="#000000">void DMA1_Channel1_IRQHandler(void)# n; _6 @9 ~7 ^/ ^
  2. {
    % J3 s# {7 v; m
  3.         u8 i;
    ( L4 ]  t8 ^2 L" c  p& @! e9 I
  4.         double voltage;
    1 b6 X  }( x7 ^3 \
  5.         int alcohol_concentration;
    + i. r9 J. a5 I: a( e
  6.         char Transform[10],data_head[5]={"KH1&"};
    ' y2 y) E& t4 h6 X  {: Z6 P
  7.         u32 ADC_data1=0,ADC_data2=0;
    $ \2 j) i# `. W. {! S5 B% j
  8.         for(i=0;i<20;i++)
      j2 h) k: M/ C  j! O/ O
  9.         {7 G4 P" @  u7 k" a5 h# w  Y
  10.                 ADC_data1 += DMA_ADC_DATA[i][0];, j5 U( [0 u' V/ w3 G' f5 P
  11.                 ADC_data2 += DMA_ADC_DATA[i][1];+ }/ B" ?" j  w" R$ w4 Y! X! b( l+ G
  12.         }
    " e& I- x( b0 g) U5 M6 l
  13.         alcohol_concentration = (double)(ADC_data1/20)+0.5;
    ; G2 k# K8 h& ^7 u9 Q8 U
  14.         voltage = (double)(ADC_data2/20)/4096*3.3*(3-0.025)+0.005;
    3 e4 r  O. Z$ ]+ H5 M  }7 q3 \
  15.         : |+ f& ^4 o! o9 R3 W& h8 Y
  16.         if(NRF24l01_write_TXdata == 0)! d1 \- M! i6 I" t' H) p
  17.         {% A$ k% w+ T: X$ _! v9 d* I
  18.                 memset(NRF_TX_Data,NULL,strlen(NRF_TX_Data));        //清空要发送的数据
    ! }2 \5 F; t3 J
  19.                 strcat(NRF_TX_Data, data_head);                                        //发送数据加数据头5 n! y1 v3 i) I, f2 L; `

  20. . e+ F& @; I) W- e9 V
  21.                 NRF_TX_Data[strlen(NRF_TX_Data)] = 'V';                        //添加第一段数据
    : n" d7 z1 y) C) h) O3 t
  22.                 Transform_double_to_char(voltage, Transform, 2, 1);
    9 s& r" K+ V8 s9 w& g) @
  23.                 strcat(NRF_TX_Data, Transform);2 J# P6 x4 N# P) C; {, y
  24.                 NRF_TX_Data[strlen(NRF_TX_Data)] = '&';
    ! `/ l( Y% A- @1 a. M
  25.                
    - b8 e6 V/ {: Z* w7 ~0 `4 L
  26.                 NRF_TX_Data[strlen(NRF_TX_Data)] = 'A';                        //添加第二段数据
    - R  F# F+ q) v
  27.                 Transform_double_to_char(alcohol_concentration, Transform, 0, 1);
    " w" N! G2 r8 q7 i! W
  28.                 strcat(NRF_TX_Data, Transform);. V  B5 k+ |+ G6 L  G6 W
  29.                 NRF_TX_Data[strlen(NRF_TX_Data)] = '&';
    + B& g0 ?5 N" O+ r/ }/ q1 Z& w% ~
  30.                 ; o9 @( S$ @: y$ B0 Q4 z
  31.                 NRF_TX_Data[strlen(NRF_TX_Data)] = '#';                        //添加结束符: \0 e9 m( O+ Z2 ^5 N, R
  32.         }
    1 T  A2 L  ^. T, w$ |
  33. //        printf("%s\r\n",NRF_TX_Data);
    5 r; L# J% I; }
  34.         7 g: ]; Y8 n: |; b, Y: C) b0 t
  35.         HAL_DMA_IRQHandler(&hdma_adc);( I9 K$ ]' e5 {2 u

  36. # ~- R* `. t8 l% O) F
  37.         HAL_ADC_Stop_DMA(&hadc);+ I) U7 [$ |4 g" f5 u* w
  38. }</font>
复制代码
0 M5 I2 s8 q) ~; o' _2 X
四、实物展示
20200907145407605.jpg

0 I" L* |3 \% e( v/ O& v( S% @
20200907145419644.jpg

  ^1 D! }  l  ~2 F# i% V( g  r, s3 b7 {  \- P5 I0 `
( `9 y' e$ F7 w& j2 w7 ^
五、改进方向

$ E& ^" u  ^6 l2 \: h1.酒精传感器4 ]2 K% l0 l6 c# t: u

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

5 N/ W: L  C0 g' |

2.短信
! C9 ^1 b! s6 x( R* c$ I% g

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

% ^0 ^' _! V- q5 T+ b/ [/ x) s4 @

3.加入键盘" a- H. c( t6 b- \

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

8 e8 _' S4 S  G, i# Y

4.加入人体检测
9 r9 t$ Z0 c4 x

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


* u! v3 b  z' Z4 `% ^6 `5 y
9 i. W  |* Y6 C* o
3 ^3 _% s0 v; [- M* h* x2 e) A) `' ]* W7 ]/ @" \/ X' H1 {
% `, j8 ^7 g% ~( c

, v" k2 C  }$ {7 O4 ~
收藏 1 评论1 发布时间:2020-9-11 12:54

举报

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

所属标签

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