一个基于 Apollo3 芯片 和 FreeRTOS 的软件定时器应用实例

一个基于 Apollo3 芯片 和 FreeRTOS 的软件定时器应用实例,结合低功耗特性实现周期性任务。代码详细适配 Apollo3 的硬件环境,并包含详细注释。

场景描述
假设我们需要在 Apollo3 上实现一个 每秒读取一次温度传感器 的任务,并通过串口发送数据。同时,在空闲时进入低功耗模式(Sleep Mode)。

完整代码示例

#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "am_mcu_apollo.h"   // Apollo3 硬件库
#include "am_util.h"         // Apollo3 工具库

// 定义定时器参数
#define TEMP_READ_TIMER_NAME     "TempTimer"
#define TEMP_READ_PERIOD_MS      1000     // 1秒周期
#define TIMER_AUTO_RELOAD        pdTRUE   // 自动重载
#define TIMER_ID                 123      // 自定义定时器ID(用于传递参数)

// 全局变量
TimerHandle_t xTempTimer = NULL;

//-----------------------------------------------------------------------------
// 温度传感器模拟读取函数(实际需替换为硬件操作)
//-----------------------------------------------------------------------------
static float read_temperature_sensor(void)
{
    // Apollo3 内置温度传感器读取示例(需根据实际硬件调整)
    float temp;
    am_hal_tsen_read(&temp);  // 使用Ambiq HAL库读取温度
    return temp;
}

//-----------------------------------------------------------------------------
// 定时器回调函数:读取温度并打印
//-----------------------------------------------------------------------------
void vTempTimerCallback(TimerHandle_t xTimer)
{
    // 获取用户数据(通过ID传递)
    UBaseType_t timer_id = (UBaseType_t)pvTimerGetTimerID(xTimer);
    if (timer_id != TIMER_ID) return; // 验证ID

    // 1. 读取温度
    float temperature = read_temperature_sensor();

    // 2. 通过串口发送数据(Apollo3 UART示例)
    am_util_stdio_printf("Temperature: %.2f°C\n", temperature);

    // 3. 可在此处添加低功耗唤醒后的处理逻辑
}

//-----------------------------------------------------------------------------
// 硬件初始化:配置温度传感器和串口
//-----------------------------------------------------------------------------
static void hardware_init(void)
{
    // 1. 初始化Apollo3核心硬件
    am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0);
    am_hal_cachectrl_config(&am_hal_cachectrl_defaults);
    am_hal_cachectrl_enable();

    // 2. 初始化温度传感器
    am_hal_tsen_config_t tsen_config = 
    {
        .eClock = AM_HAL_TSEN_CLKSEL_HFRC_3MHZ,
        .ePrecision = AM_HAL_TSEN_ADC_14BIT,
        .eTrigger = AM_HAL_TSEN_TRIG_SOFT
    };
    am_hal_tsen_initialize(0, &tsen_config);
    am_hal_tsen_power_ctrl(0, AM_HAL_TSEN_POWER_ON);

    // 3. 初始化串口(以UART0为例)
    am_util_stdio_uart_init(0); // 使用默认引脚和波特率
}

//-----------------------------------------------------------------------------
// 主函数
//-----------------------------------------------------------------------------
int main(void)
{
    // 1. Apollo3 硬件初始化
    hardware_init();

    // 2. 创建软件定时器
    xTempTimer = xTimerCreate(
        TEMP_READ_TIMER_NAME,          // 定时器名称
        pdMS_TO_TICKS(TEMP_READ_PERIOD_MS), // 转换为Tick数
        TIMER_AUTO_RELOAD,             // 自动重载
        (void*)TIMER_ID,               // 传递用户数据(ID)
        vTempTimerCallback             // 回调函数
    );

    if (xTempTimer == NULL)
    {
        am_util_stdio_printf("Failed to create timer!\n");
        while(1); // 错误处理
    }

    // 3. 启动定时器
    if (xTimerStart(xTempTimer, 0) != pdPASS)
    {
        am_util_stdio_printf("Failed to start timer!\n");
        while(1);
    }

    // 4. 启动FreeRTOS调度器
    vTaskStartScheduler();

    // 程序不应执行到这里
    while(1);
}
关键代码解析
1. 定时器创建与配置

xTempTimer = xTimerCreate(
    "TempTimer",
    pdMS_TO_TICKS(1000),  // Apollo3的Tick频率需在FreeRTOSConfig.h中配置
    pdTRUE,               // 自动重载
    (void*)TIMER_ID,      // 用户数据(可用于区分多个定时器)
    vTempTimerCallback    // 严格匹配TimerHandle_t参数的回调函数
);
pdMS_TO_TICKS:将毫秒转换为 FreeRTOS Tick 数,需确保 configTICK_RATE_HZ 在 FreeRTOSConfig.h 中正确定义(例如 1000Hz 对应 1ms/Tick)。

2. 低功耗优化(Apollo3 特性)
在 FreeRTOSConfig.h 中启用 Tickless Idle 模式:

#define configUSE_TICKLESS_IDLE    1  // 启用低功耗Tickless模式
Tickless Idle:当系统空闲时,Apollo3 会停止时钟中断,显著降低功耗。

传感器唤醒:可通过 Apollo3 的 GPIO 中断或 RTC 唤醒系统。

3. 温度传感器读取

am_hal_tsen_read(&temp);  // 使用Ambiq HAL库操作内置温度传感器
实际开发中需根据 Apollo3 的数据手册配置传感器精度和时钟源。

4. 串口输出
am_util_stdio_printf("Temperature: %.2f°C\n", temperature); // 使用Ambiq简化UART API
am_util_stdio_printf 是 Apollo3 SDK 提供的简化串口输出函数,底层依赖 UART 硬件。

适配 Apollo3 的注意事项
时钟配置:

在 hardware_init() 中通过 am_hal_clkgen_control 设置系统时钟。

根据功耗需求选择 HFRC(高频内部时钟)或 LFRC(低频时钟)。

低功耗模式:

在 vTempTimerCallback 中尽量减少处理时间,使系统尽快回到空闲状态。

使用 am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP); 手动进入深度睡眠。

FreeRTOS 配置:

在 FreeRTOSConfig.h 中为 Apollo3 优化栈大小和优先级:

#define configTIMER_TASK_STACK_DEPTH    512  // 定时器守护任务栈
#define configMAX_PRIORITIES            8    // 合理规划优先级
运行结果
系统会每秒打印一次温度值,空闲时进入低功耗模式:

Temperature: 25.60°C
Temperature: 25.62°C
Temperature: 25.58°C
...
扩展场景
多定时器协作:创建多个定时器处理不同任务(如传感器校准、无线通信)。

动态修改周期:通过 xTimerChangePeriod() 实现自适应采样率。

错误恢复:在回调函数中添加硬件异常检测,重启定时器或系统。

此示例展示了 Apollo3 芯片与 FreeRTOS 软件定时器的深度集成,兼顾实时性和低功耗需求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值