在现在很多设备中,大多数产品进行判断时,都是采用非阻塞式来进行运行。
阻塞式:程序一直卡在哪里,不能去执行气体任务
非阻塞式:随时可被打断去执行其他任务
这里使用的是无源蜂鸣器,其他操作可以跟这个类似:
首先需要创建一个结构体,用于存储我们需要的变量
typedef struct
{
uint8_t alarm_en; //无源蜂鸣器使能
uint8_t alarm_flag; //无源蜂鸣器开启标志位
uint16_t alarm_time; //无源蜂鸣器计时变量
uint8_t alarm_silencer; //无源蜂鸣器消音标志位
}Beep_base;
然后则是根据模块化思想,进行模块编写:
Beep_base beep_info={0};
/****************************************************************************************
蜂鸣器驱动函数
参数1:PWM输出句柄
参数2:PWM通道
参数3:运行时间
参数4:根据不同状态,响不同声音
****************************************************************************************/
void beep_time_run(TIM_HandleTypeDef *htim, uint32_t Channel, uint16_t time, uint8_t state)
{
if((beep_info.alarm_en == 1) && (beep_info.alarm_silencer == 0)) //无源蜂鸣器响0.5S
{
if((beep_info.alarm_en == 1) && (beep_info.alarm_flag == 0))
{
if(state == 1) //低报1khz
{
__HAL_TIM_SET_PRESCALER(htim,47);
}else if(state == 2) //高报3KHZ
{
__HAL_TIM_SET_PRESCALER(htim,15);
}else if(state == 3) //故障500HZ
{
__HAL_TIM_SET_PRESCALER(htim,95);
}
HAL_TIM_PWM_Start(htim,Channel);
beep_info.alarm_flag = 1;
beep_info.alarm_time = 0;
}
beep_info.alarm_time++;
if(beep_info.alarm_time >= time)
{
beep_info.alarm_en = 0;
beep_info.alarm_flag = 0;
beep_info.alarm_time = 0;
HAL_TIM_PWM_Stop(htim,Channel);
}
}else if((beep_info.alarm_silencer == 1) && (beep_info.alarm_en == 1))
{
beep_info.alarm_en = 0;
beep_info.alarm_flag = 0;
beep_info.alarm_time = 0;
HAL_TIM_PWM_Stop(htim,Channel);
}
那如何使用这个函数呢?
开启一个定时器,利用其中断,去查询蜂鸣器是否被开启了,如下:
HAL_TIM_Base_Start_IT(&htim15); //开启定时器
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == htim16.Instance) //定时器16作为RS485接收到数据后计数
{
beep_time_run(&htim3,TIM_CHANNEL_4,500,Info.system_state);
}
}
这样就可以实现了,再配合分时操作任务,就可以实现很好的一个效果。在一般项目里面进本上都是这样来进行使用的。
可以参考以下文章: