资讯详情

[网友问答4]基于NPN型脉冲风速变送器获取实时风速

问题原由

粉丝提问,NPN型脉冲风速变送器怎么求得风速,平时支持小哈哥工作的小伙伴有需求,小哈哥一定要安排,这次发文总结一下,希望对大家有所帮助。

开发环境和工具

  • Keil 5
  • 芯片为STM32F103RET6
  • 下载工具为JLINK
  • PC为Win10
  • 风速变送器型号为:

展示视频

NPN脉冲风速变送器的使用见以下视频教程:

程序源码

在上面显示的视频中获取测试工程源码的方法。

,请期待更多精彩。

主要参数

  • 直流供电:5V DC
  • 脉冲输出:脉冲输出
  • 分辨率:0.0875 m/s
  • 精度:±(0.2 0.03V) m/s V表示风速
  • 测量范围:0~70 m/s
  • 动态响应时间: ≤0.5s
  • 启动风速:≤0.2 m/s

产品选型

产品型号命名规则如下:

根据上述风速变送器上的标签,该风速变送器的型号为:,与命名规则相比,我们可以知道这是一个没有内部上拉电阻的人NPN风速变送器的输出。

换算关系

脉冲输出风速变送器风速与脉冲数量的转换关系如下:

从上面我们可以得出结论,我们只需要在一秒钟内计算脉冲N。通过脉冲N和上述截图中的已知信息,我们可以得到风速的转换关系如下:

风速=(1.75 / 20) * N

因此,本模块应用的难点在于如何准确计算单位时间内的脉冲数。

引脚定义

因为这个模块是NPN所以我们只需要用棕色( 5V)、黑色(GND)、蓝色(和一个GPIO连接)三条线即可。

等效电路 输出电路图

在编写代码之前,我们必须首先确定风速变送器的脉冲输出,以及输出的脉冲波形的特性,所以我们需要使用示波器来查看输出的脉冲信号。

将棕色线与 5V电源连接,黑线接地,蓝线进入示波器。

查询手册,NPN类型输出的等效电路如下:

必须在图中进行测试位置添加一个上拉电阻才能输出正常的方波!!!

蓝线输出的方波信号如下:

从上面可以看出,风速变送器输出的脉冲为0~5V脉冲信号,所以为了系统的稳定性,我们需要选择一个标识的引脚。

FT:five volt tolerant 意思的兼容5V信号电压。因为一般STM32 的引脚是3.3V,后面带有FT标识可容忍5V。

我们选择这个例子为例。

接线

棕色线 5V 电源正
黑色线 GND 电源负
蓝色线 PB12 NPN-OUT

代码实现

1. 初始化外部中断

为了计算脉冲的数量,我们使用外部中断来计算脉冲,每个脉冲,外部中断执行一次。

void NPNInit() {     EXTI_InitTypeDef EXTI_InitStructure;         NVIC_InitTypeDef NVIC_InitStructure;     GPIO_InitTypeDef GPIO_InitStructure;           ///使用外部中断需要打开RCC_APB2Periph_AFIO时钟     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);     //初始化IO口为输入          GPIO_InitStructure.GPIO_Pin =   NPN_Pin;          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;     GPIO_Init(NPN_PORT, &GPIO_InitStructure);                //GPIOB.12中断线     EXTI_ClearITPendingBit(EXTI_Line12);     GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource12);      EXTI_InitStructure.EXTI_Line=EXTI_Line12;     EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;     EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising;    ///上升沿中断     EXTI_InitStructure.EXTI_LineCmd=ENABLE;     EXTI_Init(&EXTI_InitStructure);       //中断初始配置     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);      NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;       NVIC_Init(&NVIC_InitStructure);     } 

2. 外部中断函数

在外部中断函数中,自定义全局变量加1,该值记录了收到的脉冲数。

void EXTI15_10_IRQHandler(void) {     if(EXTI_GetITStatus(EXTI_Line12)==SET)     {         msNPNCount  ;          EXTI_ClearITPendingBit(EXTI_Line12);  // 清除中断标志     }     } 

3. 定时器初始化

因为我们需要记录单位时间内收到的脉冲数量,所以我们需要占用一个定时器来计时。我们可以随意选择一个定时器我们选择,下面代码对TIM四是初始化:

//// //arr:自动重装值。 //psc:时钟预分频率    void TIM4_Init(u16 arr,u16 psc) {      NVIC_InitTypeDef NVIC_InitStructure;     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;      RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////TIM4时钟使能           //定时器TIM初始化
    TIM_TimeBaseStructure.TIM_Period = arr; 						//设置自动重装载值	
    TIM_TimeBaseStructure.TIM_Prescaler =psc; 						//设置TIMx时钟频率的预分频值,16位
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; 		//设置时钟分割:TDTS = Tck_tim
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  	//TIM向上计数模式
    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); 				//根据指定的参数初始化TIMx的时间基数单位
 
    TIM_ClearFlag(TIM4, TIM_FLAG_Update);  
    TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE ); 						//使能指定的TIM4中断,允许更新中断
	 	  
    NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;	
    NVIC_Init(&NVIC_InitStructure);									//根据指定的参数初始化NVIC寄存器
	
    TIM_Cmd(TIM4,DISABLE); 
}

main函数中调用定时器4的初始化函数如下:

    TIM4_Init(1000-1,7200-1);       //7200分频,10KHz,计数1K耗时100ms
    TIM4_Set(1);        //开启定时器

TIM4每100ms执行一次中断。

4. 定时器中断

我们定义了两个全局变量,一个数组用于记录每100ms内收到的脉冲数,一个用于记录当前数组的索引:

u32 CounterArr[10];
u8 CounterIndex = 0;

在TIM4的定时器中断函数中,每次中断发生时,将脉冲计数保存在数组中,然后脉冲计数清零。

//定时器4中断
void TIM4_IRQHandler(void)  
{
   if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)  
   {
        TIM_ClearITPendingBit(TIM4, TIM_IT_Update  ); 
       
        //保存NPN脉冲计数
        CounterArr[CounterIndex] = msNPNCount;
        msNPNCount = 0;
        CounterIndex++;
        if(CounterIndex>=10)
            CounterIndex=0;
   }
}

5. 脉冲数与风速转换

函数中,周期计算风速值,数组中存的十个脉冲数,即1秒中内的脉冲总数,然后将,所得的结果即为风速值。

if(times%200==0)
{
    //计算风速值
    nTotalNPNCounter = 0;
    for(i=0;i<9;i++)
    {
        nTotalNPNCounter += CounterArr[i];
    }

    printf("风速为 %.2f m/s\r\n",nTotalNPNCounter*0.0875);
} 

相关常识

参考阅读

红外遥控功能的实现

485型风速和风向变送器数据包解析

欢迎关注

程序员小哈带你玩转嵌入式,微信搜索:,更多干货等着你。

标签: hc319变送器d风速变送器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台