[i=s] 本帖最后由 WildboarG 于 2025-2-22 10:27 编辑 [/i]
一起来监控WB2设备温度吧

说明
在打开任何终端设备,一般大家都喜欢先 neofetch
打印设备状态,比如内存,硬盘,显卡驱动,系统内核,开机时间,温度等信息。监控设备状态是一个好习惯。避免设备状态异常导致永久性的损坏。
我们用的WB2 也带温度检测,那么就可以利用ADC来采集设备内部温度,反馈给我们操作系统或者让他报警,避免温度过高烧坏芯片(尤其是夏天)

ADC
ADC(Analog-to-Digital Converter,模拟到数字转换器)是将模拟信号(例如温度、压力、光线等)转换为数字信号的电子组件。它的主要作用是使微控制器能够处理来自物理世界的模拟信号,并通过数字处理进行分析、控制或显示。以下是ADC的几个常见用途:
- 温度传感器(如热敏电阻、热电偶)输出的电压随着温度变化而变化,使用ADC读取该电压,然后通过数字处理计算出温度值。
- 光敏电阻的电压变化可以通过ADC读取,转换为光强数据。
- 声音传感器或麦克风输出的模拟信号需要通过ADC转换为数字信号,然后用于音频处理、数字音频处理(例如语音识别、噪声消除)等。
- 电位器可以用来调节音量、亮度等,ADC读取电位器的模拟输出,转换为数字值,供系统使用。
- 在无线通信、医学仪器、工业测量等领域,ADC用于采集模拟信号(如传感器数据),并进行数据分析、计算等操作。
- 在电机控制系统中,ADC读取电机的电压或电流信号,用于调节电机的速度或方向。
ADC功能框图

这是WB2的adc内部组成:
- 前端输入通道选择器
- 程控放大器
- ADC 采样模块
- 数据处理模块
- FIFO
WB2 模拟通道数:
- 12 路外部模拟通道(最多)
- 2 路DAC 内部通道
- 1路VBAT通道
- 1路内部温度通道
外部通道与GPIO对应表

常用API
函数
int hosal_adc_init(hosal_adc_dev_t *adc)
初始化ADC接口准备用于采样的 ADC 硬件接口
返回值
参数
int hosal_adc_add_channel(hosal_adc_dev_t *adc, uint32_t channel)
添加向ADC设备添加ADC通道
返回值
参数
- adc: adc设备块
- channel: adc采集的通道
int hosal_adc_remove_channel(hosal_adc_dev_t *adc, uint32_t channel)
移除ADC通道
返回值
参数
- adc: adc设备块
- channel: adc要移除的通道
hosal_adc_dev_t *hosal_adc_device_get(void)
获取ADC句柄
参数
int hosal_adc_value_get(hosal_adc_dev_t *adc, uint32_t channel, uint32_t timeout)
取单个ADC采样结果
返回值
参数
- adc: ADC设备句柄
- channel: ADC通道
- timeout: 超时时间
int hosal_adc_tsen_value_get(hosal_adc_dev_t *adc)
采集WB2设备温度
返回值
参数
int hosal_adc_sample_cb_reg(hosal_adc_dev_t *adc, hosal_adc_cb_t cb)
注册ADC回调函数
返回值
参数
- adc: ADC设备句柄
- cb: 非零指针是示例回调处理程序 cb 中用于发送取消注册作的 NULL 指针 adc 必须与传递给驱动程序的 adc 指针相同hosal_adc_sample_cb_reg如果 ADC 数据在硬件或内存 (DMA) 中准备就绪,则必须通过调用 cb 通知上层
查看更多请点击API
如果还不懂ADC,请看园长的【Ai-WB2中级篇】ADC模数转换
示例
接下来就来配置ADC ,用ADC接入内部温度采集通道监控设备
- 首先申请ADC块设备(或者叫句柄)填充需要设置的参数
static hosal_adc_dev_t adc0 = { //申请句柄并初始化
.cb = NULL,
.config ={
.mode = HOSAL_ADC_ONE_SHOT,
.pin = 12,
//这里针脚可以任意选只要是ADC的就行
.sampling_freq = 340,
},
.dma_chan = 0,
.p_arg = NULL,
.port = 0,
};
- 然后初始化这个ADC块设备
hosal_adc_init(&adc0); //初始化ADC
- 添加adc通道
hosal_adc_add_channel(&adc0, 14);
- 接着开启adc
这个官方API没有实现,但是在读取函数中已经启动了adc
- 稍作片刻,就可以去读出ADC量化过得数字值
temp = hosal_adc_tsen_value_get(&adc0); // 获取板子温度
完整代码
#include <FreeRTOS.h>
#include <blog.h>
#include <hosal_adc.h>
#include <stdio.h>
#include <string.h>
#include <task.h>
/********** BL602 ************
* channel0 -----> gpio12
* channel1 -----> gpio4
* channel2 -----> gpio14
* channel3 -----> gpio13
* channel4 -----> gpio5
* channel5 -----> gpio6
* channel7 -----> gpio9
* channel9 -----> gpio10
* channel10 -----> gpio11
* channel11 -----> gpio15
*/
#define GPIO_ADC_PIN 11
#define ADC_TEMPCHANNEL 14
void main(void) {
static hosal_adc_dev_t adc0 = {
.cb = NULL,
.config =
{
.mode = HOSAL_ADC_ONE_SHOT,
.pin = 12,
.sampling_freq = 340,
},
.dma_chan = 0,
.p_arg = NULL,
.port = 0,
};
hosal_adc_init(&adc0);
hosal_adc_add_channel(&adc0, ADC_TEMPCHANNEL);
for (;;) {
int temp = hosal_adc_tsen_value_get(&adc0); // 获取板子温度
blog_info("BOARD temp = %d C\r\n", temp);
vTaskDelay(pdMS_TO_TICKS(5000));
}
}
然后烧录进板子里边。
报错!!!
查看API的实现,发现一堆关于 CONF_ADC_ENABLE_TSEN
的条件编译
#ifdef CONF_ADC_ENABLE_TSEN
#define ADC_CHANNEL_MAX 11 /*CHANNEL14 FOR Tsen*/
#else
#define ADC_CHANNEL_MAX 10
#endif
这里它告诉我们内部温度所用的通道是14,所以刚才我添加ADC通道是14
看样子这里条件使能才有效,所以手动加一个
#define CONF_ADC_ENABLE_TSEN 1
然后再次编译通过,串口查看

已经可以读取内部温度了