水浊度传感器
Posted 丿轩雪灬
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了水浊度传感器相关的知识,希望对你有一定的参考价值。
水浊度传感器
文章目录
硬件使用
- STM32F103 RCT6 (32芯片)
- TSW-30 (水浊度传感器)
软件使用
- keil5 MDK
- 串口调试助手
实现说明
1. 水浊度传感器原理
这款浊度传感器利用光学原理,通过溶液中的透光率和 散射率来综合判断浊度情况。传感器内部是一个红外线对管,当光线穿过一定量 的水时,光线的透过量取决于该水的污浊程度,水越污浊,透过的光就越少。光接收端把透过的光强度转换为对应的电流大小,透过的光多,电流大,反之透过的光少,电流小。 根据上面的原理可知,了解到 只要获取到电压就可以获取水浊度,所以采取 ADC 模拟/数字转换来实现获取到水浊度。
2. 具体操作代码说明
(1)首先先定义 TSW30(水浊度传感器)上所对应的 LED 引脚,方便后续校验
GPIO_InitTypeDef GPIO_InitStrue;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
GPIO_InitStrue.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStrue.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStrue.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStrue);
(2)再定义 STM32 上对应的 模拟 引脚和 ADC 引脚,这个需要根据下面的图来进行定义
博主这边采取的是 通道1 PA1 口 的 ADC1
大概实现步骤为:
- 开启 PA 口时钟和 ADC1 时钟,设置 PA1 为模拟输入
- 复位 ADC1, 同时设置 ADC1 分频因子
- 初始化 ADC1 参数
- 使能 ADC 并校准
所以可得出的代码为:
GPIO_InitTypeDef GPIO_InitStruct;
ADC_InitTypeDef ADC_InitStruct;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div4);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOA, &GPIO_InitStruct);
ADC_DeInit(ADC1);
ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;
ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;
ADC_InitStruct.ADC_NbrOfChannel = 1;
ADC_InitStruct.ADC_ScanConvMode = DISABLE;
ADC_Init(ADC1,&ADC_InitStruct);
ADC_Cmd(ADC1,ENABLE); //使能 ADC
ADC_ResetCalibration( ADC1); //使能复位校准
while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
ADC_StartCalibration( ADC1);
while(ADC_GetCalibrationStatus(ADC1));
注意: 需要额外注意的是 RCC_ADCCLKConfig(RCC_PCLK2_Div4); //需要对 ADC时钟进行分频
3. 配置通道规则
ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_1Cycles5);
参数1: ADCx 选择 ADC 外设
参数2: 设置 ADC 通道 (更多参阅 STM32 库函数 中的 ADC_Channel)
参数3: 规则组采样顺序 --这里我们只使用一种,所以直接定义为 Rank = 1 即可
参数四: 指定 ADC 通道的采样时间值
4. 开启软件转换
ADC_SoftwareStartConvCmd( ADC1, ENABLE);
5. 判断转换完成,读取 ADC 值
while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)); //判断是否转换结束
return ADC_GetConversionValue(ADC1); //返回最近一次 ADC 采取的数值
**再写个函数 取平均值,大概每 10 次取平均值即可**
6.计算水浊度
根据商家提供的计算公式或例程可以计算出 所对应的 水浊度信息 (获取电流)
adcx=Get_Adc_Average(ADC_Channel_1,10); //获取到 电压平均值
temp=(float)adcx*(3.3/4096);
temp = temp*100/3.3;
if(temp > 100) temp = 100;
7.通过串口发送到串口调试助手
(1)初始化串口
GPIO_InitTypeDef GPIO_InitStrue;
USART_InitTypeDef USART_InitStrue;
NVIC_InitTypeDef NVIC_InitStrue;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); //使能 USART1
GPIO_InitStrue.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 //USART1_Tx USB Rx STM32中为 Tx,需要接到 USB转TTL串口中的 Rx
GPIO_InitStrue.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStrue.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOA,&GPIO_InitStrue);
//USART1_Rx USB Tx
GPIO_InitStrue.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_InitStrue.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStrue.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOA,&GPIO_InitStrue);
USART_InitStrue.USART_BaudRate = 115200;
USART_InitStrue.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStrue.USART_Mode = USART_Mode_Tx|USART_Mode_Rx;
USART_InitStrue.USART_Parity = USART_Parity_No;
USART_InitStrue.USART_StopBits = USART_StopBits_1;
USART_InitStrue.USART_WordLength = USART_WordLength_8b;
USART_Init(USART1,&USART_InitStrue);
USART_Cmd(USART1,ENABLE);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
NVIC_InitStrue.NVIC_IRQChannel = USART1_IRQn;//设置中断
NVIC_InitStrue.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级1
NVIC_InitStrue.NVIC_IRQChannelSubPriority = 1; //子优先级1
NVIC_Init(&NVIC_InitStrue);
(2)中断发送数据
void USART1_IRQHandler(void)
{
u8 s;
while(*s!='\\0')
{
while(USART_GetFlagStatus(USART1,USART_FLAG_TC )==RESET);
USART_SendData(USART1,*s);
s++;
}
}
最后
第一次尝试编写博客,若是有什么建议,欢迎批评指出。
后续会逐步分块更新,并会在最后一篇文章上传源代码。
若是该文章对你有作用或是觉得文章写得还行,帮忙点点赞,三连!
以上是关于水浊度传感器的主要内容,如果未能解决你的问题,请参考以下文章