zoukankan      html  css  js  c++  java
  • [TLSR8267] 泰凌微 telink tlsr8267 ble ADC 用法浅谈


    1、读 datasheet

    在《DS_TLSR8267-E21_Datasheet for Telink BLE SoC TLSR8267.pdf》第11章详细介绍了ADC相关属性及参数。

    条目 说明
    ADC clock 参考电压选择AVDD时候不能低于5Mhz;参考电压选择1.224V或者1.428V的时候不能低于4MHz
    input range 1.428V,AVDD or 1.224V
    resolution 7, 9, 10, 11, 12, 13, 14bits
    sampling time 3, 6, 9, 12, 18, 24, 48 or 144 * ADC clock period
    input mode ADC supports two input modes and 12 input channels
    Enable auto mode and output 自动模式

    2、看封装好驱动

    在sdk/proj/mcu_spec/adc_8267.c中实现了8267 adc的封装,对外函数比较简单:

    • (普通12个channels初始化) void adc_Init(enum ADCCLOCK adc_clk,enum ADCINPUTCH chn,enum ADCINPUTMODE mode,enum ADCRFV ref_vol, enum ADCRESOLUTION resolution,enum ADCST sample_cycle)
    • (电池检测初始化)void adc_BatteryCheckInit(enum ADCCLOCK adc_clk,unsigned char div_en,enum ONETHIRD_INPUTCHN oneThirdChn,enum ADCINPUTCH notOneThirdChn, enum ADCINPUTMODE mode,enum ADCRFV ref_vol,enum ADCRESOLUTION resolution,enum ADCST sample_cycle)
    • (温度检测初始化)void adc_TemSensorInit(enum ADCCLOCK adc_clk,enum ADCINPUTCH chn,enum ADCINPUTMODE mode,enum ADCRFV ref_vol, enum ADCRESOLUTION resolution,enum ADCST sample_cycle)
    • (读取ADC数据)unsigned short adc_SampleValueGet(void)
    • (读取电池电量数据)unsigned short adc_BatteryValueGet(void)

    用起来比较简单,初始化,然后读取!对于初始化中的枚举参数,可以看看定义处,就明白了。下面举个简单的B6通道读取数据的例子:

    adc_Init(ADC_CLK_4M, B6, SINGLEEND, RV_AVDD, RES14, S_6);
    
    while(1<2){
    	u16 ret = adc_SampleValueGet();
    }
    

    3、计算实际数值

    在/sdk/vendor/826x_driver_test/app_adc.c写了一个电池电量读取的DEMO,里面初始化和数据读取和我们第二节介绍的大同小异,其中有个读取的ret值转换为实际电压值的小程序片段:

    switch(ref_vol){
    	case RV_1P428:
    	#if (BATT_CHECK_ENABLE)
    		app_adc_test_Vol = 3*(1428*(average_data-128)/(16383-256)); //2^14 - 1 = 16383;
    	#else
    		app_adc_test_Vol = 1428*(average_data-128)/(16383-256); //2^14 - 1 = 16383;
    	#endif
    	break;
    case RV_AVDD:
    	#if (BATT_CHECK_ENABLE)
    		app_adc_test_Vol = 3*(3300*(average_data-128)/(16383-256)); //2^14 - 1 = 16383;
    	#else
    		app_adc_test_Vol = 3300*(average_data-128)/(16383-256); //2^14 - 1 = 16383;
    	#endif
    	break;
    case RV_1P224:
    	#if (BATT_CHECK_ENABLE)
    		app_adc_test_Vol = 3*(1224*(average_data-128)/(16383-256)); //2^14 - 1 = 16383;
    	#else
    		app_adc_test_Vol = 1224*(average_data-128)/(16383-256); //2^14 - 1 = 16383;
    	#endif
    	break;
    }
    

    其中由于分辨率为RES14=14bits=2^14-1


    4、设计读取两个channels的值

    从第二节我们知道初始化后直接可以loop读取ADC值,那如果我想要同时读取两个channels的ADC该怎么办呢?

    通过观察sdk/proj/mcu_spec/adc_8267.c中的adc_Init发现,有一个static inline函数可以切换channel:

    /********************************************************
    *
    *	@brief		set ADC analog input channel
    *
    *	@param		adcCha - enum variable adc channel.
    *				adcInCha - enum variable of adc input channel.
    *
    *	@return		None
    */
    static inline void adc_AnaChSet(enum ADCINPUTCH adcInCha){
    	unsigned char cnI;
    
    	cnI = (unsigned char)adcInCha;
    	BM_CLR(reg_adc_chn_m_sel,FLD_ADC_CHN_SEL);
    	reg_adc_chn_m_sel |= MASK_VAL(FLD_ADC_CHN_SEL,cnI);
    }
    

    那么能否想要读取B6 channel时候切换到B6读取,想要读取B4的时候切换到B4?所以先写个代码试试:

    void my_adc_init(void){
        adc_Init(ADC_CLK_4M, B6, SINGLEEND, RV_AVDD, RES14, S_6);
    }
    
    void adc_AnaChSet(enum ADCINPUTCH adcInCha){
    	unsigned char cnI;
    
    	cnI = (unsigned char)adcInCha;
    	BM_CLR(reg_adc_chn_m_sel,FLD_ADC_CHN_SEL);
    	reg_adc_chn_m_sel |= MASK_VAL(FLD_ADC_CHN_SEL,cnI);
    }
    
    void my_adc_run(void){
        u16 ret;
        u8 res;
    
        static u16 cnt = 0;
    
        if(cnt == 0 || cnt == 4000){
            adc_AnaChSet(B6);
            cnt = 0;
        }else if(cnt == 2000){
            adc_AnaChSet(B4);
        }
        cnt ++;
    
        ret = adc_SampleValueGet();
        res = 3300*(ret-128)/(16383-256)/100;//100mV
        my_uart_send_data(&res,1);
    }
    

    起初,我直接俄高频切换、读取、再切换、再读取,会出现意想不到的结果,推测可能是切换和读取太快,频率快于AUTO模式的数据采集了,因此用一个cnt分段切换通道读取,发现效果很好。


    5、重要常用输入资源表

    有了下面的枚举类型,很容易看出8267的ADC输入资源情况,方便选择正确的IO口:

    //ADC analog input channel selection enum
    enum ADCINPUTCH{
    	NOINPUT,
    	C0,//GPIO_PC0
    	C1,
    	C6,
    	C7,
    	B0,
    	B1,
    	B2,
    	B3,
    	B4,
    	B5,
    	B6,
    	B7,
    	PGAVOM,
    	PGAVOP,
    	TEMSENSORN,
    	TEMSENSORP,
    	AVSS,
    	OTVDD,//1/3 voltage division detection
    };
    

    : 蓝牙芯片:国产芯片的技术博客比外国芯片少一些,经常查不到~
    大家觉得不错,可以点推荐给更多人~

    [1]. telink官网
    [2]. 搭建tlsr8266编译框架在win服务器中


    @beautifulzzzz
    以蓝牙技术为基础的的末梢无线网络系统架构及创新型应用探索!
    领域:智能硬件、物联网、自动化、前沿软硬件
    博客:https://www.cnblogs.com/zjutlitao/
    微信交流群|微信:园友交流群|btfzzzz
    
  • 相关阅读:
    【SpringBoot1.x】SpringBoot1.x 安全
    WebStorm快捷键(Mac版)
    iOS 容联离线消息推送
    iOS使用TestFlight进行内部和外部人员测试
    iOS Runtime常用方法整理
    模仿斗鱼直播
    一个很好用的侧滑框架ICSDrawerController实现的 QQ 侧滑及换肤功能
    swift3.0 项目引导页
    使用 swift3.0高仿新浪微博
    swift 监听键盘弹出的高度
  • 原文地址:https://www.cnblogs.com/zjutlitao/p/11658081.html
Copyright © 2011-2022 走看看