实现单片机脉宽测量功能

241 阅读3分钟

前言

shineblink core 开发板(简称Core)的库函数支持脉宽测量功能,所以只需要调用两三个API,即可实现对一串方波的脉宽测试功能,测量时间精度能够达到1us。

PS:Core 仅用五、六行代码即可实现Wifi/Ble/NB/Lora/ThreadMesh/RFID/Eth/Usb/RS485/RS232通信、以及30多种传感器/10多种硬件外设/10多种Mcu内设功能,并且这些功能最多可以 5 种随机组合同时运行。更多关于Core的内容可以在 shineblink.com 上了解。

在这里插入图片描述
在这里插入图片描述

一、实现功能

Core的D4引脚可以用来测量单个或多个脉宽,时间精度可达到1us,并且可以设置滤波功能。

本章节所实现的功能描述:外部向Core的D4引脚输入一个1Khz的方波,Core每隔10秒测量一次该方波,每次连续测60个该方波的高低电平脉宽,并通过print()打印出来。

这里演示了测量多个连续脉宽的实例,如果您只需要测量单个脉冲的宽度的话在代码中将60改为1即可。同样这里每隔10秒测量一次也为了方便演示,开发者可以在任何时间开启测量,但需要控制好节奏,需等本次测量结束后再开启下一次测量。

二、接线图

在这里插入图片描述

三、完整代码

--全局变量定义
timer1 = 0
--初始化
function Init()
	--配置USB为虚拟串口模式,这样print()就可以在电脑串口调试终端上打印输出结果了
	LIB_UsbConfig("CDC")
	--使能10毫秒定时器开始工作
	LIB_10msTimerConfig("ENABLE")
	--配置测量脉宽的D4引脚内部上拉,触发条件为下降沿,滤掉脉宽小于100us的波形
	LIB_PulseWidthMeasureConfig("PullUp","Fall",100)
end

--定义10毫秒定时器中断回调函数
function LIB_10msTimerCallback()
	timer1 = timer1 + 10
end

--初始化
Init()
--开始大循环
while(GC(1) == true)
do
	--每10s使能一次脉宽检测任务
	if timer1 >= 10000 then
		timer1 = 0
		--开始脉宽测量,希望在5秒内测到60个高低电平的脉宽(最多可测255个脉宽)
		LIB_PulseWidthMeasureStart(60,5000)
	end
	--查询测量工作是否结束
	finish_flag, data_tab = LIB_PulseWidthMeasureFinishCheck()
	if finish_flag == 1 then
		--测量超时,未在5秒内测量到60个高低电平,仅打印出测量到的
		if #data_tab < 60 then
			print(string.format("Time out, num: %d\r\n", #data_tab))
			for k,v in pairs(data_tab) do
				print(k,v)
			end
		--测量完成,打印完整的60个高低电平的脉宽
		else
			print(string.format("Job over, num: %d\r\n", #data_tab))
			for k,v in pairs(data_tab) do
				print(k,v)
			end
		end
	end
end

如果感兴趣,上面代码中出现的LIB开头的库函数可以在API文档中通过Ctrl+F查询。

三、实际输入波形如下图:

在这里插入图片描述

四、程序运行结果

在PC串口调试终端软件上,我们可以看到如下打印的部分结果:

在这里插入图片描述

上图可以看出实际一共测量了61个脉宽,比预设的60个多一个,这是因为脉宽测量功能的实现是在驱动层,而我们是在最上层的Lua应用层查询测量结果,应用层代码执行速度跟驱动层相比会慢一些,但是驱动层会为应用层缓存结果,所有我们不用担心会漏掉测量结果,所以我们只用取前60个脉冲即可,将第61个脉宽舍弃。