翻斗雨量计使用的是无源脉冲输出,每次翻一下就会触发干簧管产生一个脉冲,脉冲需要自己外部上拉。
电路如上图所示,C4非常重要,相当于硬件消抖,否则翻转一次可能会记录几次值,由于边沿毛刺导致的,DS1二极管相当于一个电平转换,为何此处要用12V上拉给雨量计,由于我的设备采集雨量需要低功耗,因此最好的做法是直接从电源上拉过去,只有翻转的瞬间才会耗电,除了3.3V其余电源平时都是关闭状态的,但是如果把3.3V传出去,线缆稍微长一点可能压降就很大了,并且3.3V给单片机供电,雨量计安装在外面,雷雨天气可能会有感应电损坏数字芯片。
采集单片机使用STM32,定时器2的脉冲输入模式,完全无需中断,无需外部干预,就算在sleep模式也一样能独立于CPU进行计数,因此非常方便,实际使用中使用1分钟或5分钟雨量,只要定时去读取time2的计数器值即可。
//雨量计分辨率定义 const u8 RAIN_RES_TYPE[RAIN_RES_TYPE_NUM] = {1, 2, 5, 10}; //扩大了10倍,分别对应0.1mm,0.2mm,0.5mm,1.0mm
//开启雨量计定时器 #define RAIN_TimeEnable() (TIM2->CR1 |= 0x01) //关闭雨量计定时器 #define RAIN_TimeDisable() (TIM2->CR1 &= ~0x01)
/************************************************************************************************************************* * 函数 : void RainGaugeInit(void) * 功能 : 脉冲雨量计初始化 * 参数 : 无 * 返回 : 无 * 依赖 : 底层读写函数 * 作者 : [email protected] * 时间 : 2017-08-18 * 最后修改时间 : 2017-08-18 * 说明 : 脉冲输入通道1,TIM2_CH2 / PA1,采用定时器外部时钟模式1 *************************************************************************************************************************/ void RainGaugeInit(void) { DeviceClockEnable(DEV_TIM2, ENABLE); //使能定时器2时钟 //配置定时器2 TIM2->PSC = 0xffff; //分频 TIM2->ARR = 0xffff; TIM2->CNT = 0; TIM2->CCMR1 = 1 << 8; //配置CC2通道为输入方向,IC2映射到IT2上 //TIM2->CCMR1 |= 0<<12; //输入滤波器 //TIM2->CCMR1 |= 0<<10; //预分频 //TIM2->CCER = 1 << 5; //IC2下降沿捕获 TIM2->CCER &= ~(1 << 5); //IC2上升沿捕获 TIM2->SR &= ~(1 << 6); //清除TIF标志 //外部时钟模式1设置 TIM2->SMCR = 7 << 0; //SMS:111 外部时钟模式1 TIM2->SMCR |= 6 << 4; //TS 110 滤波后的定时器输入2(TI2FP2) TIM2->SMCR |= 3 << 0; //从模式,选择为外部时钟模式1 TIM2->CR1 |= 0x01; //计时器使能 DeviceClockEnable(DEV_GPIOA, ENABLE); //使能时钟 GPIOx_Init(GPIOA, BIT1, IN_IPT, IN_IN); //初始化IO.下拉输入 //初始化初始计数器 g_LastCnt = 0; //上一秒的雨量计计数器值为0 SetRainGaugeCount(0); //设置雨量计计数器值为0 }
//获取雨量计计数器的值 __inline u16 GetRainGaugeCount(void) { return TIM2->CNT; //使用TIM2计数器 } //设置雨量计计数器的值 __inline void SetRainGaugeCount(u16 count) { TIM2->CNT = count; //使用TIM2计数器 }