一、设备说明
/ o2 D+ W* \* y( c' s. R- b' f单片机:STM32f103zet6- b) h+ g. X0 p8 o: O
雨滴模块
6 D3 @, i7 x7 v1 }% b( {
. ^7 m' P3 `2 a; x5 }2 n
; o6 g5 S$ v: O% x% v
7 n( _( c- ]" c2 x
, r8 K- A0 z' P7 b$ w" a9 A" f ?3 _
+ I; K! h" t! ^
二、部分关键代码9 s, j( q; Z1 n) `
1.初始化ADC采集
/ {; {7 ?$ `/ d- T8 ? N代码如下(示例):
4 u. T4 o0 G; J$ X8 J3 ^- <font face="微软雅黑" size="3">void Adc_Init(void)& G, J% z6 s8 j
- { $ C [# |* }5 O
- ADC_InitTypeDef ADC_InitStructure; 3 f! r( U0 Q6 A5 m/ w0 g. H
- GPIO_InitTypeDef GPIO_InitStructure;
: C; r9 |5 n5 C1 |+ D - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1 , ENABLE ); //使能ADC1通道时钟2 v5 k3 F+ o% u. B( ?* M H4 {2 }
- RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M+ q) o" `; b6 U. h% g0 P0 G" i; J, r
- //PA1 作为模拟通道输入引脚
! z/ g9 w/ M( A0 T* V+ E v& P# s - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;: t, [; y6 D. k; d6 ]" J
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚8 A6 z4 [: U( b: y1 M0 @( L
- GPIO_Init(GPIOA, &GPIO_InitStructure); . a" ?8 _9 n4 | W
- //**All notes can be deleted and modified**//. l7 j- `- ~, I" V3 V3 U
- ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式
* ~4 C% P+ J6 x$ e' P) W4 S$ r - ADC_InitStructure.ADC_ScanConvMode = DISABLE; //模数转换工作在单通道模式
$ ^, Q' ] U) N& U- c# a1 } - ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //模数转换工作在单次转换模式
( N& ], Q+ V. v# K: p& c: K+ v& d, b - ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动2 t+ p( d" Q. P9 d3 A9 ?1 m
- ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐
% @/ C/ t/ `0 i; d) d! J6 Q1 R9 [ - ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目
/ o2 W" | z. e+ U' b/ r. \: | - ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器 $ J" T# v1 {& ~- |4 x
- ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1 ) }; p+ c6 V7 {& \ r
- ADC_ResetCalibration(ADC1); //使能复位校准 $ m; p" _& _; m7 f% U
- while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束 2 T3 t& @3 M( u/ C$ y
- ADC_StartCalibration(ADC1); //开启AD校准) u; E! ^* j% I
- while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束7 G" s- a1 v! {+ O1 @. v: w" D# X. G
- </font>
复制代码 2.读入数据
7 B, V% W5 v8 w" W# v: S- U! F代码如下(示例):
+ A0 S- m; g6 g$ ~- <font face="微软雅黑" size="3"> adcx=Get_Adc_Average(ADC_Channel_0,5);//读取ad转换值 5次求平均
- i5 ~* `4 q7 h5 m2 b) r - printf(" adcx %d\r\n",adcx); ( _ X1 `, L8 D1 ~/ @
- + A3 k, h/ t: m) {" p8 s2 G4 P
- sensorVal =99-((float)adcx*3.3/4096)*2*99.0/5.0;// 采集值 *2表示电阻分压 输出最大5v 但是要转化为最大3.3v
8 z6 y% K: T/ d0 D* j* o - sensorVal =99-((float)adcx*3.3/4096)*99.0/5.0;5 I9 z- l+ `% F6 ^, D7 a% _3 u8 P2 B% h
- 3 Z3 t. J+ J6 K
- printf(" sensorVal %d\r\n",sensorVal);# w/ c% {# M% i5 a3 b
- if(sensorVal<BASICS_VAL)sensorVal = 0;//过滤传感器本身自带电压
8 ^0 C4 l7 |' w9 e3 _3 ? - else
4 j: i; |4 m- y( R7 X+ J$ s - {0 H. j @9 g! O
- sensorVal = (sensorVal-BASICS_VAL)*99/(99-BASICS_VAL);//将30-99值转化为0-99的值8 _6 |! w% Y6 d: V% j
- }
5 Q7 N0 m2 V0 `. x - $ Z( G! x+ Y( g# W, I& z. [; W
- printf(dis0,"nowValue:%d ",sensorVal); //打印 5 f3 R3 o" {9 |/ h& ]: [
- $ a6 E/ K5 r! Y4 R
- if(setMode){4 [: Y8 a$ h4 s: O
- printf(dis1,"setValue:%02d< ",setNum); //打印 * Z3 Y4 f( {+ I& |
- }
x4 E* B1 [4 q1 T - else{0 e: y6 I x& z% E4 d" a5 T
- printf(dis1,"setValue:%02d ",setNum);
% Q# E% j' O7 c: {# C3 Y& | - }
, T5 c u+ B! \1 | - </font>
复制代码
/ ?: f* `& @( ^3 D1 s. ~7 z2 r- f1 W& z& P
总结! S0 c( r6 t4 J6 U4 _8 d0 _8 C
最后输出的结果:0 f) c) F" U: `4 f( Z6 F# |
根据测试,雨滴模块浸入水的深度不同,返回的电压值转化成的adc值不同:
" W5 L6 v/ v% u) y2 ~, p完全无水的情况返回的adc值为4096;" e. f$ c7 u* ^9 y# G9 a
完全浸入水中返回值接近400(是因为有模块供电的电压)。4 R1 l' N8 @) v9 I
根据400~4096的区间,按百分比输出,无水情况输出0,完全浸没输出99;$ i# z7 K- b" n( G
$ k. C: ` p1 ` |