当前位置: 首页 > article >正文

ambiq apollo3 ADC实例程序注释

#include "am_mcu_apollo.h"       // Apollo MCU 外设寄存器定义和HAL库
#include "am_bsp.h"             // 板级支持包(引脚定义、LED函数等)
#include "am_util.h"            // 通用工具函数(如printf重定向)

//*****************************************************************************
//
// 全局变量
//
//*****************************************************************************
static void *g_ADCHandle;        // ADC设备句柄,用于操作ADC实例
uint32_t g_ui32SampleCount;      // ADC采样计数信号量(ISR与主程序同步)
uint16_t g_ui16ADCVDD_code;      // 电压分压器的ADC原始码值(电池电压)
uint16_t g_ui16ADCTEMP_code;     // 温度传感器的ADC原始码值

//*****************************************************************************
//
// ADC配置结构体
//
//*****************************************************************************
const static am_hal_adc_config_t g_sADC_Cfg =
{
    .eClock = AM_HAL_ADC_CLKSEL_HFRC_DIV2, // ADC时钟源选择高频RC时钟分频2(约6MHz)
    .ePolarity = AM_HAL_ADC_TRIGPOL_RISING,// 触发极性为上升沿
    .eTrigger = AM_HAL_ADC_TRIGSEL_SOFTWARE, // 触发源为软件触发(实际由Timer3触发)
    .eReference = AM_HAL_ADC_REFSEL_INT_1P5,// 内部1.5V参考电压
    .eClockMode = AM_HAL_ADC_CLKMODE_LOW_POWER, // 低功耗时钟模式
    .ePowerMode = AM_HAL_ADC_LPMODE1,       // 空闲时进入低功耗模式1
    .eRepeat = AM_HAL_ADC_REPEATING_SCAN    // 重复扫描模式(循环采样)
};

//*****************************************************************************
//
// 定时器3配置结构体(用于触发ADC采样)
//
//*****************************************************************************
am_hal_ctimer_config_t g_sTimer3 =
{
    0, // 不链接A和B定时器
    // Timer3A配置为PWM重复模式,时钟源为32Hz低频RC(LFRC)
    (AM_HAL_CTIMER_FN_PWM_REPEAT | AM_HAL_CTIMER_LFRC_32HZ),
    0  // Timer3B未使用
};

//*****************************************************************************
//
// ADC中断服务程序(ISR)
//
//*****************************************************************************
void am_adc_isr(void)
{
    uint32_t ui32IntStatus;
    
    // 获取并清除ADC中断状态
    am_hal_adc_interrupt_status(g_ADCHandle, &ui32IntStatus, true);
    am_hal_adc_interrupt_clear(g_ADCHandle, ui32IntStatus);

    am_devices_led_toggle(am_bsp_psLEDs, 3); // 切换LED3指示中断触发

    // 从ADC FIFO读取所有样本
    am_hal_adc_sample_t sSample;
    uint32_t ui32NumSamples = 1;
    while (AM_HAL_ADC_FIFO_COUNT(ADC->FIFO)) 
    {
        am_hal_adc_samples_read(g_ADCHandle, true, NULL, &ui32NumSamples, &sSample);
        
        // 根据Slot区分采样来源
        if (sSample.ui32Slot == 5) // Slot5配置为BATT通道(电池电压)
        {
            g_ui16ADCVDD_code = AM_HAL_ADC_FIFO_SAMPLE(sSample.ui32Sample);
        }
        else if (sSample.ui32Slot == 7) // Slot7配置为TEMP通道(温度传感器)
        {
            // 取高10位(精度配置为10bit),低6位舍去
            g_ui16ADCTEMP_code = sSample.ui32Sample & 0xFFC0; 
        }
    }
    g_ui32SampleCount++; // 更新采样计数(通知主程序)
}

//*****************************************************************************
//
// ADC初始化函数
//
//*****************************************************************************
void adc_init(void)
{
    am_hal_adc_slot_config_t sSlotCfg = {0};
    
    // 初始化ADC实例并获取句柄
    if (am_hal_adc_initialize(0, &g_ADCHandle) != AM_HAL_STATUS_SUCCESS) {
        am_util_stdio_printf("ADC实例初始化失败!\n");
    }
    
    // 上电ADC模块
    am_hal_adc_power_control(g_ADCHandle, AM_HAL_SYSCTRL_WAKE, false);
    
    // 应用ADC全局配置
    am_hal_adc_configure(g_ADCHandle, (am_hal_adc_config_t*)&g_sADC_Cfg);
    
    // 配置各Slot参数(0-4、6未使用)
    for (int i = 0; i <= 6; i++) {
        if (i != 5) {
            sSlotCfg.bEnabled = false;
            am_hal_adc_configure_slot(g_ADCHandle, i, &sSlotCfg);
        }
    }
    
    // 配置Slot5(BATT电压分压器)
    sSlotCfg.bEnabled = true;
    sSlotCfg.eChannel = AM_HAL_ADC_SLOT_CHSEL_BATT; // 选择BATT通道
    sSlotCfg.ePrecisionMode = AM_HAL_ADC_SLOT_14BIT;// 14位精度模式
    am_hal_adc_configure_slot(g_ADCHandle, 5, &sSlotCfg);
    
    // 配置Slot7(温度传感器)
    sSlotCfg.eChannel = AM_HAL_ADC_SLOT_CHSEL_TEMP; // 选择TEMP通道
    sSlotCfg.ePrecisionMode = AM_HAL_ADC_SLOT_10BIT;// 10位精度模式
    am_hal_adc_configure_slot(g_ADCHandle, 7, &sSlotCfg);
    
    am_hal_adc_enable(g_ADCHandle); // 使能ADC模块
}

//*****************************************************************************
//
// 定时器初始化(配置Timer3A触发ADC采样)
//
//*****************************************************************************
static void timer_init(void)
{
    #define TIMERNUM 3 // Apollo3中仅Timer3支持ADC触发
    uint32_t ui32Period = 2000; // 2000ms周期(2秒)
    
    am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_LFRC_START, 0); // 启动LFRC(32Hz)
    
    am_hal_ctimer_clear(TIMERNUM, AM_HAL_CTIMER_TIMERA); // 清除Timer3A
    am_hal_ctimer_config(TIMERNUM, &g_sTimer3);          // 应用定时器配置
    
    // 计算比较寄存器值(32Hz时钟下,2000ms对应64个计数)
    ui32Period = ui32Period * 32 / 1000; 
    am_hal_ctimer_period_set(TIMERNUM, AM_HAL_CTIMER_TIMERA, 
                            ui32Period, (ui32Period >> 1));
    
    am_hal_ctimer_adc_trigger_enable(); // 使能Timer3触发ADC
    am_hal_ctimer_start(TIMERNUM, AM_HAL_CTIMER_TIMERA); // 启动Timer3A
}

//*****************************************************************************
//
// 主函数
//
//*****************************************************************************
int main(void)
{
    // 初始化系统时钟、缓存、低功耗模式等
    am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0);
    am_hal_cachectrl_config(&am_hal_cachectrl_defaults);
    am_hal_cachectrl_enable();
    am_bsp_low_power_init();
    
    // 外设初始化
    am_devices_led_array_init(am_bsp_psLEDs, AM_BSP_NUM_LEDS);
    am_hal_gpio_pinconfig(AM_BSP_GPIO_BUTTON0, g_AM_BSP_GPIO_BUTTON0);
    am_bsp_itm_printf_enable(); // 启用ITM调试输出
    
    // ADC和定时器初始化
    adc_init();
    timer_init();
    
    // 获取并打印温度校准参数(OTP中存储的工厂校准值)
    float fTrims[4];
    am_hal_adc_control(g_ADCHandle, AM_HAL_ADC_REQ_TEMP_TRIMS_GET, fTrims);
    am_util_stdio_printf("校准温度: %.3f°C, 电压: %.3fV, 偏移: %.3f\n", 
                        fTrims[0], fTrims[1], fTrims[2]);
    
    // 中断配置
    NVIC_EnableIRQ(ADC_IRQn);
    am_hal_interrupt_master_enable();
    am_hal_adc_interrupt_enable(g_ADCHandle, AM_HAL_ADC_INT_WCINC | AM_HAL_ADC_INT_FIFOOVR2);
    
    g_ui32SampleCount = 0;
    am_hal_adc_sw_trigger(g_ADCHandle); // 启动首次ADC转换
    
    // 主循环
    while (1) 
    {
        if (g_ui32SampleCount > 0) 
        {
            // 计算电池电压(基于分压比3:1)
            float fVBATT = (g_ui16ADCVDD_code * 3.0f * 1.5f) / (1024.0f / 64.0f);
            
            // 计算温度(通过HAL函数转换电压到摄氏度)
            float fVT[3] = { (g_ui16ADCTEMP_code * 1.5f) / (1024.0f * 64.0f), 0, 0 };
            am_hal_adc_control(g_ADCHandle, AM_HAL_ADC_REQ_TEMP_CELSIUS_GET, fVT);
            float fTempC = fVT[1];
            float fTempF = fTempC * 9.0f/5.0f + 32.0f; // 转换为华氏度
            
            am_util_stdio_printf("VBatt: %.2fV, Temp: %.1f°C (%.1f°F)\n", 
                                fVBATT, fTempC, fTempF);
            
            g_ui32SampleCount = 0; // 重置采样计数
        }
        
        // 进入深度睡眠,等待下次中断
        am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
    }
}

关键注解说明:

  1. ADC配置

    • 使用内部1.5V参考电压,适合测量小信号

    • 重复扫描模式实现连续采样

    • Slot5和Slot7分别对应BATT和TEMP通道,精度不同

  2. 定时器触发

    • Timer3A配置为32Hz LFRC时钟,产生2秒周期

    • 比较寄存器设置占空比50%,确保稳定触发

  3. 中断处理

    • 每次ADC完成转换后触发中断

    • 通过Slot编号区分不同通道数据

    • 原始数据存储到全局变量供主程序处理

  4. 电压计算

    c

    复制

    fVBATT = (ADC代码 * 3.0 * 1.5V) / (1024/64) 

    基于分压电阻比3:1和14位ADC量程(1.5V参考)

  5. 温度计算

    • 使用HAL库函数am_hal_adc_control直接转换

    • 公式依据Apollo3温度传感器特性曲线

  6. 低功耗设计

    • 主循环中进入DEEP SLEEP模式

    • ADC和Timer均使用低功耗时钟源

  7. 校准参数

    • 从芯片OTP中读取出厂校准值

    • 提高温度测量精度至±2°C以内

此程序实现了Apollo3芯片的电池电压监测和温度检测功能,通过定时器触发ADC采样,在中断中获取数据,主程序进行物理量转换和显示,具有低功耗特性。

相关文章:

ambiq apollo3 ADC实例程序注释

#include "am_mcu_apollo.h" // Apollo MCU 外设寄存器定义和HAL库 #include "am_bsp.h" // 板级支持包&#xff08;引脚定义、LED函数等&#xff09; #include "am_util.h" // 通用工具函数&#xff08;如printf重…...

[Windows] Edge浏览器_134.0.3124.83绿色便携增强版-集成官方Deepseek侧边栏

微软Edge浏览器 绿色便携增强版 长期更新 链接&#xff1a;https://pan.xunlei.com/s/VOMA-aVC_GPJiv-MzRS89lsVA1?pwdemxj# Edge浏览器_134.0.3124.83绿色便携增强版-集成官方Deepseek侧边栏...

Python大数据方向就业

一、基础必备技能 1. ​Python编程 ​核心语法&#xff1a;熟练掌握函数、面向对象、异常处理、文件操作等。​数据处理库&#xff1a;Pandas&#xff08;数据清洗、分析&#xff09;、NumPy&#xff08;数值计算&#xff09;、Matplotlib/Seaborn&#xff08;数据可视化&…...

从零构建大语言模型全栈开发指南:第二部分:模型架构设计与实现-2.2.3实战案例:在笔记本电脑上运行轻量级LLM

👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 实战案例:在笔记本电脑上运行轻量级LLM2.2.3 模型架构设计与实现1. 环境与工具准备1.1 硬件要求1.2 软件栈选择2. 轻量级模型架构设计2.1 模型参数配置2.2 关键技术优化3. 实战流程3.1 数据准备流程3.2…...

CAN基础知识学习二

一、控制器局域网总线&#xff08;CAN&#xff0c;Controller Area Network&#xff09;&#xff1b; 二、CAN FD 是CAN with Flexible Data rate的缩写&#xff0c;翻译为【可变速率的 CAN】 CAN-FD 采用了两种位速率&#xff1a;从控制场中的 BRS 位到 ACK 场之前&#xff08…...

新能源行业:卓越 UE/UI 设计,引领业务腾飞的新引擎

在全球积极推动可持续发展的大背景下&#xff0c;新能源行业蓬勃兴起&#xff0c;成为经济发展的新引擎。在这个充满机遇与挑战的赛道上&#xff0c;优秀的用户体验&#xff08;UE&#xff09;和用户界面&#xff08;UI&#xff09;设计正扮演着愈发关键的角色&#xff0c;它不…...

Webview详解(上)

第一阶段&#xff1a;基础入门 WebView基础概念 什么是Webview&#xff1f; WebView是一种用于在移动应用程序中展示网页内容的嵌入式浏览器组件。它允许开发者将网页内容直接加载到应用界面中&#xff0c;用户无需离开应用即可浏览网页。WebView 通常用于加载 HTML、CSS、J…...

Docker镜像相关命令(Day2)

文章目录 前言一、问题描述二、相关命令1.查看镜像2.搜索镜像3.拉取镜像4.删除镜像5.镜像的详细信息6.标记镜像 三、验证与总结 前言 Docker 是一个开源的容器化平台&#xff0c;它让开发者能够将应用及其依赖打包到一个标准化的单元&#xff08;容器&#xff09;中运行。在 D…...

C++值传递和引用传递

系列文章目录 值传递和引用传递是 C 中两种常见的参数传递方式&#xff0c;它们的主要区别在于函数内部对参数的操作是否会影响原始数据 C值传递和引用传递 系列文章目录1、值传递2、引用传递3 、常量引用传递4、值传递 vs 引用传递总结 1、值传递 值传递会复制传入的参数&…...

LangChain4J开源开发框架简介

目录 1.1、前言1.2、集成方式简单1.3、核心功能与优势1.4、两种调用方式1.5、链式调用示例代码1.6、AI服务调用示例代码1.7、典型使用场景1.8、总结 1.1、前言 LangChain4J 是一个专为 Java 开发者设计的开源框架&#xff0c;旨在简化大型语言模型&#xff08;LLMs&#xff09;…...

Qt图形视图框架在项目中的应用

一、基本概念 Qt 的图形视图框架&#xff08;Graphics View Framework&#xff09;提供了一套用于显示和管理2D图形对象的框架。它提供了一组类&#xff0c;这些类可以组合使用来构建用户界面、处理图形对象、实现缩放、平移、旋转等操作。以下是Qt GraphicsView框架的主要组件…...

SpringBoot集成Elasticsearch 7.x spring-boot-starter-data-elasticsearch 方式

SpringBoot集成Elasticsearch 7.x | spring-boot-starter-data-elasticsearch 方式 前言添加maven依赖配置application.properties测试实体类 方式一&#xff1a;继承 ElasticsearchRepository&#xff08;适合简单查询&#xff09; 直接使用想自定义自己的Repository接口 方式…...

STM32蜂鸣器播放音乐

STM32蜂鸣器播放音乐 STM32蜂鸣器播放音乐 Do, Re, Mi, Fa, 1. 功能概述 本系统基于STM32F7系列微控制器&#xff0c;实现了以下功能&#xff1a; 通过7个按键控制蜂鸣器发声&#xff0c;按键对应不同的音符。每个按键对应一个音符&#xff08;Do, Re, Mi, Fa, Sol, La, Si&a…...

GitLab 中文版17.10正式发布,27项重点功能解读【二】

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 学习极狐GitLab 的相关资料&#xff1a; 极狐GitLab 官网极狐…...

解码未来:DeepSeek开源FlashMLA,推理加速核心技术,引领AI变革

前言&#xff1a; DeepSeek 兑现了自己的诺言&#xff0c;开源了一款用于 Hopper GPU 的高效型 MLA 解码核&#xff1a;FlashMLA。 项目地址&#xff1a;https://github.com/deepseek-ai/FlashMLA 1:FlashMLA 是什么呀&#xff1f; MLA是DeepSeek大模型的重要技术创新点&…...

leetcode:136. 只出现一次的数字(python3解法)

难度&#xff1a;简单 给你一个 非空 整数数组 nums &#xff0c;除了某个元素只出现一次以外&#xff0c;其余每个元素均出现两次。找出那个只出现了一次的元素。 你必须设计并实现线性时间复杂度的算法来解决此问题&#xff0c;且该算法只使用常量额外空间。 示例 1 &#xf…...

Isaac Sim与Isaac Lab初使用

目录 基于Omiverse下载Isaacsim安装Isaac Lab配置isaacsim环境测试克隆仓库配置python环境强化学习训练的测试 IsaacLab模板配置vscode环境ros接口安装 作为nvidia出品的仿真软件&#xff0c;很多机器人、机器狗【具身智能】都可以有很不错的效果&#xff0c;所以会使用isaac s…...

Spring AI Alibaba 工具(Function Calling)使用

一、工具(Function Calling)简介 Spring AI Alibaba工具(Function Calling)&#xff1a;https://java2ai.com/docs/1.0.0-M6.1/tutorials/function-calling/ 1、工具(Function Calling) “工具&#xff08;Tool&#xff09;”或“功能调用&#xff08;Function Calling&#xf…...

Touch Diver:Weart为XR和机器人遥操作专属设计的触觉反馈动捕手套

在虚拟现实&#xff08;VR&#xff09;和扩展现实&#xff08;XR&#xff09;领域&#xff0c;触觉反馈技术正逐渐成为提升沉浸感和交互体验的重要因素。Weart作为这一领域的创新者&#xff0c;凭借其TouchDIVER Pro和TouchDIVER G1触觉手套&#xff0c;为用户带来了高度逼真的…...

[深度学习]图片分类任务

图片分类任务 文章目录 图片分类任务分类任务回归和分类如何做分类的输出 图片分类卷积神经网络保持特征图大小不变更大的卷积核和更多的卷积核层数特征图怎么变小卷积神经网络中特征图改变卷积到全连接分类任务的LOSS一个基本的分类神经网络 经典神经网络AlexNetVggNetResNet …...

关系图:赋能数据可视化的动态扩展

关系图 关系图是一种用于展示节点之间关系和连接的图表类型。具有高度的可定制性、丰富的交互功能和动画效果&#xff0c;能够展示节点之间的和连接&#xff0c;以及随着数据的变化而呈现的动态效果。 【组件概述】 1.节点和边的可定制性&#xff1a; 关系图提供了丰富的配置…...

k8s存储介绍(三)valume概述与emptydir

目录 一、Kubernetes 中的 Volume 详解 基本概念 Volume 的主要类型&#xff08;这里简单介绍&#xff0c;后续章节会详细介绍&#xff09; 1. 本地存储类型 2. 网络存储类型 3. 云提供商存储 4. 特殊用途类型 PersistentVolume (PV) 和 PersistentVolumeClaim (PVC) S…...

Nodejs 项目打包部署方式

方式一&#xff1a;PM2 一、准备工作 确保服务器上已安装 Node.js 环境建议使用 PM2 进行进程管理&#xff08;需要额外安装&#xff09; 二、部署步骤 1.首先在服务器上安装 PM2&#xff08;推荐&#xff09;&#xff1a; npm install -g pm22.将项目代码上传到服务器&…...

uv - Getting Started 开始使用 [官方文档翻译]

文章目录 uv亮点安装项目脚本工具Python 版本pip 接口了解更多 入门安装 uv安装方法独立安装程序PyPICargoHomebrewWinGetScoopDockerGitHub 发布 升级 uvShell 自动补全卸载 第一次使用 uv特性Python 版本脚本项目工具pip 接口实用工具 获取帮助帮助菜单查看版本故障排除问题在…...

C++类与对象的的第三个简单的实战练习-3.25笔记

哔哩哔哩C面向对象高级语言程序设计教程&#xff08;118集全&#xff09; 简单实战三 创建项目 打开VS&#xff0c;点击创建一个新项目 创建一个空项目 点击下一步 点击工程名称&#xff0c;选择添加 选择新建项 选择C类 取名 点击确定&#xff0c;这时候还需要一个main.cpp …...

CentOS安装sshpass工具-自动化SSH密码认证

sshpass是一个在Linux环境下用于自动化SSH密码认证的工具。 一、功能特点 自动化SSH登录&#xff1a;sshpass允许用户在命令行中直接传递密码&#xff0c;从而无需在SSH连接时手动输入密码。这对于自动化脚本和批处理任务非常有用&#xff0c;因为它可以在非交互式环境下完成…...

k8s中service概述(一)ClusterIP

ClusterIP 是 Kubernetes 中最基础且常用的 Service 类型&#xff0c;主要用于在集群内部提供稳定的网络访问端点。以下是关于 ClusterIP Service 的详细说明&#xff1a; 1. ClusterIP 的核心功能 集群内部访问&#xff1a;ClusterIP 提供一个集群内部的虚拟 IP&#xff08;VI…...

详解接口的常见请求方式

详解接口的常见请求方式 一、 常见接口请求方式1. GET2. POST3. PUT4. DELETE5. PATCH6. HEAD7. OPTIONS 二、 实现方法1. 前端实现2. 后端实现 三、 作用与主要区别四、 举例讲解1. 创建 Spring Boot 工程2. 添加依赖3. 编写 Controller 实现接口关键点说明 4. 启动与测试5. 总…...

HarmonyOS-ArkUI Grip组件

我们在学习List的时候&#xff0c;已经捎带引入了Grid。讲解如下图所示&#xff1a; 也就是&#xff0c;如果一个表&#xff0c;长宽基本都是一致的&#xff0c;那么此时可以完全不用Grid也可以实现&#xff0c;并且&#xff0c;优先考虑的就是List。 如果List实现不了的情况下…...

2025清华大学:DeepSeek教程全集(PDF+视频精讲,共10份).zip

一、资料列表 第一课&#xff1a;Deepseek基础入门 第二课&#xff1a;DeepSeek赋能职场 第三课&#xff1a;普通人如何抓住DeepSeek红利 第四课&#xff1a;让科研像聊天一样简单 第五课&#xff1a;DeepSeek与AI幻觉 第六课&#xff1a;基于DeepSeek的AI音乐词曲的创造法 第…...