泰凌微TLSR825X开发三 ADC模数转换

本文详细介绍了TLSR825X芯片中逐次逼近型(SAR)ADC模块在差分模式下的模拟信号采样功能。内容包括ADC时钟的计算、10个输入通道的配置、差分模式的使用,以及电池电压测量的注意事项。代码示例展示了初始化、参数设置和数据读取的过程,特别提到了采样周期和数据转换的实现细节。此外,还提供了ADC采样数据的平均值计算和电压值转换的方法。
前言

TLSR825X集成了一个逐次逼近型(SAR)ADC模块,可以应用在电池电压、温度、单声道或立体声音频信号的采样
在这里插入图片描述

本章主要讲解下差分ADC模拟信号采样的功能,如有异议,欢迎留言指正

功能与参数
  • ADC时钟通过外部24MHz晶体时钟源通过分频因子分频后获得,公式如下
    • Fadc_clk = 24MHz/(adc_clk_div+1)
  • 如下支持ADC的10个管脚输入通道
GPIO_PinTypeDef ADC_GPIO_tab[10] = {
		GPIO_PB0,GPIO_PB1,
		GPIO_PB2,GPIO_PB3,
		GPIO_PB4,GPIO_PB5,
		GPIO_PB6,GPIO_PB7,
		GPIO_PC4,GPIO_PC5
};
  • ADC仅支持差分模式(differential mode),测量电池电压时可将负端配置到GND
  • ADC支持 Left、Right、Misc三个通道,无法同时工作,必须通过状态机切换来运行采样
    • 三个通道都包含一个设置set状态和捕获Capture状态
      在这里插入图片描述
代码实例
初始化
  • 参考例程app_adc.c,初始化adc代码如下
void app_adc_test_init(void)
{
    /******关闭adc电源********/
    adc_power_on_sar_adc(0);
    /****** 使能adc 24nhz时钟源********/
    adc_enable_clk_24m_to_sar_adc(1); 
    /******采用时钟 4MHz******/
    adc_set_sample_clk(5); //采样时钟 = 24M/(1+5)=4M   
    /******配置左右增益偏置,电池检测可以不用配置******/
    adc_set_left_gain_bias(GAIN_STAGE_BIAS_PER100);
    adc_set_right_gain_bias(GAIN_STAGE_BIAS_PER100);   
////Step 3: Config adc settings  as needed /////////////////////////////////////////////
#if (TEST_ADC_SELECT == TEST_ADC_GPIO)
    adc_gpio_ain_init();
#elif (TEST_ADC_SELECT == TEST_ADC_VBAT)
    adc_vbat_detect_init();
#endif
    /******开启adc电源********/
    adc_power_on_sar_adc(1);
}
设置参数
  • 配置使能adc通道参数与映射管脚
void adc_gpio_ain_init(void)
{
    //set misc channel en,  and adc state machine state cnt 2( "set" stage and "capture" state for misc channel)
    adc_set_chn_enable_and_max_state_cnt(ADC_MISC_CHN, 2); //使能MISC通道与状态数
    //set "capture state" length for misc channel: 240
    //set "set state" length for misc channel: 10
    //adc 状态机执行周期  = 24M/250 = 96K, T = 10.4 uS
    adc_set_state_length(240, 0, 10);  //设置 R_max_mc,R_max_c,R_max_s ,这里仅配置MISC通道的set与capture状态
    //PB4差分正端  GND为差分负端 
    gpio_set_func(GPIO_PB4, AS_GPIO);
    gpio_set_input_en(GPIO_PB4, 0);
    gpio_set_output_en(GPIO_PB4, 0);
    gpio_write(GPIO_PB4, 0);
    adc_set_ain_channel_differential_mode(ADC_MISC_CHN, B4P, GND);
    //采样分辨率14位;差分模式下最高位为符号位(bit13)
    adc_set_resolution(ADC_MISC_CHN, RES14);  //set resolution
    //参考电压1.2V
    adc_set_ref_voltage(ADC_MISC_CHN, ADC_VREF_1P2V);                   //set channel Vref
    //配置6个时钟周期为一次采样 6/4M = 1.5
    adc_set_tsample_cycle(ADC_MISC_CHN, SAMPLING_CYCLES_6);     //Number of ADC clock cycles in sampling phase
    //设置模拟输入缩放比例1/8,可支持输入0~9.6V
    adc_set_ain_pre_scaler(ADC_PRESCALER_1F8);
}
读取数据
  • 通过接口adc_sample_and_get_result读取转换结果
u32 tick_adc_sample = 0;
void app_adc_test_start(void)
{
    if(clock_time_exceed(tick_adc_sample, 200000)){//200ms读取一次
        tick_adc_sample = clock_time();
        Adc_cur_rawData =  adc_sample_and_get_result();//获取采样数据
        Adc_raw_data[Adc_raw_datIndex ++]  = Adc_cur_rawData;
        
#if 1 //debug 显示使用
        Adc_cur_vol_oct =   (Adc_cur_rawData/1000)<<12 | ((Adc_cur_rawData/100)%10)<<8 \
                                      | ((Adc_cur_rawData%100)/10)<<4  | (Adc_cur_rawData%10);
        Adc_cal_vol_oct[Adc_cal_vol_octIndex ++] = Adc_cur_vol_oct; //用作显示
#endif
    }
}
采样接口解读
  • 采样读取接口代码,内部会进行8次读取并取平均,最终返回电压值;这里强调下adc_vol_mv换算需要根据自己实际配置来做相对应的修改
  • ADC采样数据的获取使用了Dfifo mode,默认采样8byte数据,adc采样周期为10.4uS,总数据获取时长为83uS
    • 例程中仅配置了Misc,Td时间计算公式为 Td = (1r_max_s + 1max_mc)/24M = (240+10)/24 ≈ 10.4uS
      在这里插入图片描述
#define ADC_SAMPLE_NUM      8 //一次采集8个数据
/**
 * @brief This function serves to set adc sampling and get results.
 * @param[in]  none.
 * @return the result of sampling.
 */
unsigned int adc_sample_and_get_result(void)
{
    unsigned short temp;
    volatile signed int adc_data_buf[ADC_SAMPLE_NUM];  //size must 16 byte aligned(16/32/64...)
    int i,j;
    unsigned int  adc_vol_mv = 0;
    unsigned short adc_sample[ADC_SAMPLE_NUM] = {0};//数据缓存
    unsigned short  adc_result=0;
    adc_reset_adc_module();//复位adc模块
    unsigned int t0 = clock_time();
    for(i=0;i<ADC_SAMPLE_NUM;i++){      //清缓存数据
        adc_data_buf[i] = 0;
    }
    while(!clock_time_exceed(t0, 25));  //等待至少2个采样周期 wait at least 2 sample cycle(f = 96K, T = 10.4us)
    //buf缓存地址映射dfifo setting will lose in suspend/deep, so we need config it every time
    adc_config_misc_channel_buf((unsigned short *)adc_data_buf, ADC_SAMPLE_NUM<<2);  //size: ADC_SAMPLE_NUM*4
    dfifo_enable_dfifo2();//使能dfifo
//////////////// get adc sample data and sort these data ////////////////
    for(i=0;i<ADC_SAMPLE_NUM;i++){
        /*wait for new adc sample data, When the data is not zero and more than 1.5 sampling times (when the data is zero),
     The default data is already ready.*/
        while((!adc_data_buf[i])&&(!clock_time_exceed(t0,25)));//通过判断数据非0与等待1.5个采样时间
         t0 = clock_time();
        if(adc_data_buf[i] & BIT(13)){  //判断符号位  14 bit resolution, BIT(13) is sign bit, 1 means negative voltage in differential_mode
            adc_sample[i] = 0;
        }
        else{
            adc_sample[i] = ((unsigned short)adc_data_buf[i] & 0x1FFF);  //BIT(12..0) is valid adc result
        }
        //排序 insert sort
        if(i){
            if(adc_sample[i] < adc_sample[i-1]){
                temp = adc_sample[i];
                adc_sample[i] = adc_sample[i-1];
                for(j=i-1;j>=0 && adc_sample[j] > temp;j--){
                    adc_sample[j+1] = adc_sample[j];
                }
                adc_sample[j+1] = temp;
            }
        }
    }
//////////////////////////////////////////////////////////////////////////////
    dfifo_disable_dfifo2();   //禁用dfifo  misc channel data dfifo disable
///// get average value from raw data(abandon some small and big data ), then filter with history data //////
#if (ADC_SAMPLE_NUM == 4)   //use middle 2 data (index: 1,2)
    unsigned int adc_average = (adc_sample[1] + adc_sample[2])/2;
#elif(ADC_SAMPLE_NUM == 8)  //use middle 4 data (index: 2,3,4,5)
    unsigned int adc_average = (adc_sample[2] + adc_sample[3] + adc_sample[4] + adc_sample[5])/4; //均值滤波
#endif
    adc_code=adc_result = adc_average;
     //////////////// adc sample data convert to voltage(mv) ////////////////
    //                          (Vref, 1/8 scaler)   (BIT<12~0> valid data)
    //           =  adc_result * Vref * 8 / 0x2000
    //           =  adc_result * Vref >>10
    adc_vol_mv  = (adc_result * adc_vref_cfg.adc_vref)>>10; //换算电压值
    return adc_vol_mv;
}

PS:adc寄存器可查看数据手册第11章11.4节

TLSR8250 是泰凌微电子(Telink)推出的一款低功耗蓝牙芯片,广泛应用于物联网设备中,尤其是在需要低功耗、高集成度的场景中,例如可穿戴设备、智能家居节点等。虽然官方资料和开发文档中并未直接提供针对 TLSR8250 的锂电池 BMS(Battery Management System)设计手册或应用笔记,但可以通过以下方式构建与 TLSR8250 芯片结合使用的 BMS 设计方案。 ### 电池管理功能实现方式 TLSR8250 本身集成了 ADC模数转换器),可以用于监测电池电压,实现基本的电量检测功能。通过 ADC 采集电池电压值,并结合软件算法实现电池电量估算,是常见的低功耗蓝牙设备中实现 BMS 的方法之一。该功能可以用于低电量告警、电量百分比显示等场景。 例如,通过以下代码片段可以读取电池电压: ```c #include "analog.h" #include "adc.h" void battery_monitor_init(void) { // 初始化 ADC adc_init(); } uint16_t read_battery_voltage(void) { // 读取电池电压,假设使用通道 0 uint16_t voltage = adc_read(ADC_CHN0); return voltage; } ``` 上述代码通过 ADC 读取电池电压值,开发人员可以根据电压范围映射到电量百分比,实现简单的 BMS 功能[^1]。 ### 外部 BMS 芯片集成 对于更复杂的锂电池管理需求,如过充保护、过放保护、充放电电流监测、温度监控等,通常需要使用专用的锂电池 BMS 芯片。例如 TI 的 BQ27441、MCP73831 充电管理芯片等,可以与 TLSR8250 配合使用,实现完整的电池管理系统。 在硬件设计中,TLSR8250 可以通过 I2C 或 GPIO 接口与 BMS 芯片通信,读取电池状态信息并进行处理。例如: ```c #include "i2c.h" #include "bq27441.h" void bms_init(void) { i2c_init(); bq27441_init(); } uint16_t get_battery_capacity(void) { return bq27441_get_capacity(); } ``` 上述代码展示了如何通过 I2C 接口与 BQ27441 通信,读取电池容量信息[^2]。 ### 低功耗优化与电池寿命延长 TLSR8250 支持多种低功耗模式,包括睡眠模式、深度睡眠模式等,这在电池供电设备中尤为重要。通过合理配置芯片的功耗模式,可以显著延长电池续航时间。例如: ```c #include "pm.h" void enter_low_power_mode(void) { // 进入深度睡眠模式 pm_enter_deep_sleep(); } ``` 结合低功耗蓝牙协议栈的特性,TLSR8250 可以在不活跃状态下进入低功耗模式,仅在需要通信时唤醒,从而优化整体功耗[^3]。 ### 开发资源与社区支持 尽管目前没有官方发布的专门针对 TLSR8250 的锂电池 BMS 设计文档,但安信可科技与泰凌微电子提供了丰富的开发资料和示例代码,开发者可以基于这些资源进行二次开发和功能扩展。此外,开源社区和论坛(如 GitHub、优快云、电子发烧友等)也提供了许多与低功耗蓝牙芯片结合使用的 BMS 实现案例,可供参考。
评论 10
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值