在上一个开箱帖中简单介绍了本次活动的开发板和各个模块,在本贴中,将对各个模块进行简单的测试及驱动。
首先是开发板的驱动:当拿到一个开发板的时候,第一个烧录的程序通常是点灯操作。keil的操作相信大家都非常熟悉,本次使用的keil模板是单片机是STM32F103C8T6,我们只需在Device中将单片机型号换成STM32F103RB即可使用。

查阅原理图,发现开发板上共有3个灯,最上面的是st-link指示灯,LD3是电源指示灯,需要我们点亮的是LD2。

在原理图上LD2绿灯与PA5和PB13都进行了连接,那么如何判断它连接的是PA5还是PB13呢?开发板背面有我们需要的答案!

可以看到SB42焊接了0Ω的电阻,而SB29没有。由此可以判断,LD2绿灯与PA5相连。那么下面的操作就非常简单了。
首先是创建.h和.c文件
led.h
#ifndef __LED_H__ #define __LED_H__ #include "stm32f10x.h" #define RCC_GPIO RCC_APB2Periph_GPIOA #define RCC_GPIO_LED RCC_APB2Periph_GPIOA #define LED_GPIO GPIOA #define LED_GPIO_Pin GPIO_Pin_5 void led_init(void); void led_on(void); void led_off(void); #endif
led.c
#include "LED.h"
void led_init(void)
{
GPIO_InitTypeDef GPIOA_Initstruct;
RCC_APB2PeriphClockCmd(RCC_GPIO, ENABLE);
GPIOA_Initstruct.GPIO_Pin = LED_GPIO_Pin;
GPIOA_Initstruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIOA_Initstruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(LED_GPIO, &GPIOA_Initstruct);
}
void led_on(void)
{
GPIO_SetBits(LED_GPIO, LED_GPIO_Pin);
}
void led_off(void)
{
GPIO_ResetBits(LED_GPIO, LED_GPIO_Pin);
}在main.c中添加头文件并初始化,即可点亮LD2。效果如下:

继电器的驱动与LED的驱动类型,都是通过给引脚高低电平开实现功能,只是最终实现的功能不同。继电器的实现效果如下:

给下面的信号线高电平时,继电器模块上的红灯会亮,COM与NO连通。下面是LCD显示模块的驱动,因为LCD模块的显示驱动比较复杂,我们可以将别人写好的模块移植到我我们这块开发板上面。在本次实验中,使用的时软件模拟IIC,所以可以任意选择SDA和SCL,因此选择PC2位SDA,PC3为SCL。使用LCD取模软件获得”瞬间流量“和”累计流量“的数组,将其存入到oledfront.h中。
在main.c中初始化及驱动后,效果如下

最后是比较复杂的流量传感器,它是一种叶轮式水流量传感器,工作原理是当水通过传感器时,会推动叶轮旋转,叶轮上装有磁铁,每旋转一圈时,磁场的变化会被霍尔传感器检测到,霍尔传感器将磁场变化转换为电脉冲信号,脉冲的频率与水流速度成正比。由公式Q=k⋅f即可计算出水流速。在本次实验中,使用中断来接收脉冲信号。
YF_S401.h
#ifndef __YF_S401_H__
#define __YF_S401_H__
#include "sys.h"
#include "stdlib.h"
#include "stm32f10x.h"
//定义流量相关参数
typedef struct
{
float instant; // 瞬时流量
float acculat; // 累计流量
float cnt; // 脉冲数
} GOLBAL_FLOW;
// 定义流量模型的枚举类型
typedef enum
{
MODE_4_PIPE = 0, // 四分管
MODE_6_PIPE = 1, // 六分管
MODE_6MM_PIPE = 2 // 6mm管
} FlowModel;
//引脚定义
#define YF_S401_RCC RCC_APB2Periph_GPIOA
#define YF_S401_GPIO GPIOA
#define YF_S401_GPIO_PIN GPIO_Pin_1
#define YF_S401_EXTI_Line EXTI_Line1
//函数定义
void bsp_YF_S401_Init(void);
void Flow_Read(void);
#endif // ! __YF_S401_H__YF_S401.c
#include "YF_S401.h"
GOLBAL_FLOW golbal_flow;
// 定义流量参数
float flowK[3] = {5.0f, 5.5f, 40.0f}; // 流量系数 K
float pulseCntPerLiter[3] = {300.0f, 330.0f, 4800.0f}; // 每升水脉冲数
// 定义 Flow_Model
FlowModel flowModel = MODE_6MM_PIPE; // 默认使用6mm管
u32 pluse1L; // 测试1L水的脉冲数
void bsp_YF_S401_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB2PeriphClockCmd(YF_S401_RCC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStruct.GPIO_Pin = YF_S401_GPIO_PIN;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(YF_S401_GPIO, &GPIO_InitStruct);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1);
EXTI_InitStruct.EXTI_Line = YF_S401_EXTI_Line;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStruct);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStruct.NVIC_IRQChannel = EXTI1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
/**
* @brief 读取YF-S40流量传感器流量
*
*/
void Flow_Read(void)
{
// 根据 Flow_Model 选择不同的流量参数
float flowKValue = flowK[flowModel];
float pulseCntValue = pulseCntPerLiter[flowModel];
if (golbal_flow.cnt > 0)
{
golbal_flow.acculat += (golbal_flow.cnt * 1000 / pulseCntValue); // 单位mL
pluse1L += golbal_flow.cnt;
golbal_flow.instant = golbal_flow.cnt / flowKValue; // 单位(mL/min)
if (golbal_flow.acculat >= 1000000) // 最大累计流量1000L
{
golbal_flow.acculat = 0;
}
}
else
{
golbal_flow.instant = 0;
}
golbal_flow.cnt = 0;
}
void EXTI1_IRQHandler(void)
{
if (EXTI_GetITStatus(YF_S401_EXTI_Line) != RESET)
{
golbal_flow.cnt++;
EXTI_ClearITPendingBit(YF_S401_EXTI_Line);
}
}在上述代码中,每接收到一个上升沿,程序将产生一次中断,将脉冲数加1,然后再计算瞬间流量和累计流量,并再LCD屏上进行显示实时显示。此外,需要根据水泵的实际情况,对流量参数中的参数进行修改。

本帖是液体流量检测仪活动的过程贴,针对开箱贴中的各个模块进行简单驱动,实际效果并没有达到活动要求,后面将对程序进行调试,以达到实验要求。
我要赚赏金
