我是靠谱客的博主 英俊钢铁侠,最近开发中收集的这篇文章主要介绍杰理AC6926X-多通道ADC设置,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

定义在adc_api.h
系统定义adc扫描的处理周期,2ms一次,每次扫描一个通道。

#if !ADKEY_SD_MULT_EN
LOOP_DETECT_REGISTER(adc_scan_detect) = {
    .time = 1,
    .fun  = adc_scan,
};
#endif

每次扫描一个通道,总共5个通道,系统默认第一个通道为AD按键通道,在下面数组变量中体现

void adc_scan()
{
    static u8 channel = 0;
    u8 next_channel;

    next_channel = channel + 1;

    if (next_channel == R_MAX_AD_CHANNEL) {
        next_channel = 0;
    }
/*    这些是无关紧要的代码块 
#if ADKEY_SD_MULT_EN    
    if (next_channel == R_AD_CH_KEY) {
        if (adkey_sd_mult_sd_suspend() == true) {
            key_ad_info.key_init();
            adc_value[channel++] = adc_res_api(ad_table[next_channel]);
            if (channel == R_MAX_AD_CHANNEL) {
                channel = 0;
            }
            next_channel = channel + 1;
            adc_value[channel++] = adc_res_api(ad_table[next_channel]);
            adkey_sd_mult_set_sd_io();
            adkey_sd_mult_sd_resume();
            return;
        } else {
            adc_value[channel] = adc_res_api(ad_table[next_channel + 1]); //跳过ADKEY的通道
            channel += 2;
            if (channel >= R_MAX_AD_CHANNEL) {
                channel -= R_MAX_AD_CHANNEL;
            }
            return;
        }
    }
#endif 
*/ 
    adc_value[channel++] = adc_res_api(ad_table[next_channel]); //核心处理部分
//    otp_printf("c=%d   v=%d   ",channel-1,adc_value[channel-1]);

    if (channel == R_MAX_AD_CHANNEL) {
        channel = 0;
    }
}

ad转换函数,输入采集通道,返回通道采集值

u16 adc_res_api(u32 channel)
{
    u16 adc_value = 0;
    u16 adc_con_tmp = 0;

    while (!(BIT(7) & JL_ADC->CON));	  //wait pending
    adc_value = JL_ADC->RES;

    adc_con_tmp = JL_ADC->CON & (~0x0F00);
    JL_ADC->CON = adc_con_tmp | (channel & 0xFFFF);//channel; //AD channel select
    if ((channel & 0xFFFF) == AD_CH_RTC) {
        adc_mux_ch_set((channel & 0xFFFF0000) >> 16);
    } else if ((channel & 0xFFFF) == AD_CH_PMU) {
        adc_ldo_ch_sel((channel & 0xFFFF0000) >> 16);
    } else if ((channel & 0xFFFF) == AD_CH_BT) {
        WLA_CON0 |= ((0x1 & 0X1) << 0) | 
                    ((0x0 & 0X1) << 1) | 
                    ((0x1 & 0X3) << 2) | 
                    ((0x08 & 0X1f) << 6) | 
                    ((0x2 & 0x3) << 11) | 
                    ((0x8 & 0xf) << 13);
    }
    JL_ADC->CON |= BIT(6);             //AD start

    return adc_value;
}

AC6926X一共定义了16个通道 位于JL_ADC->CON的bit[8-11]

//AD channel define JL_ADC->CON的bit[8-11]
#define AD_CH_PA3    (0x0<<8)
#define AD_CH_PA4    (0x1<<8)
#define AD_CH_PA5    (0x2<<8)
#define AD_CH_PA6    (0x3<<8)
#define AD_CH_PC4    (0x4<<8)
#define AD_CH_PA10   (0x5<<8)
#define AD_CH_PB0    (0x6<<8)
#define AD_CH_PB1    (0x7<<8)
#define AD_CH_PB4    (0x8<<8)
#define AD_CH_PB5    (0x9<<8)
#define AD_CH_PC3    (0xA<<8)
#define AD_CH_DM     (0xB<<8)
#define AD_CH_RTC    (0xC<<8)
#define AD_CH_PMU    (0xD<<8)
#define AD_CH_BT     (0xE<<8)
#define AD_CH_AUDIO  (0xF<<8)

#define ADC_RTC_MUX_PR1       (0x1<<16)
#define ADC_RTC_MUX_PR2       (0x2<<16)
#define ADC_RTC_MUX_RTC_HOSC  (0x3<<16)
#define ADC_RTC_MUX_RTC_LOSC  (0x4<<16)
#define ADC_RTC_MUX_RTCVDD    (0x5<<16)

#define ADC_PMU_MUX_VBG       (0x0<<16)
#define ADC_PMU_MUX_VDD       (0x1<<16)
#define ADC_PMU_MUX_VDDDA     (0x2<<16)
#define ADC_PMU_MUX_VDC13     (0x3<<16)
#define ADC_PMU_MUX_VBAT      (0x4<<16)
#define ADC_PMU_MUX_LDOIN     (0x5<<16)
#define ADC_PMU_MUX_RTCLDO33  (0x6<<16)
#define ADC_PMU_MUX_CHARGE    (0x7<<16)

#define AD_CH_PR1       (AD_CH_RTC | ADC_RTC_MUX_PR1)
#define AD_CH_PR2       (AD_CH_RTC | ADC_RTC_MUX_PR2)
#define AD_CH_RTC_HOSC  (AD_CH_RTC | ADC_RTC_MUX_RTC_HOSC)
#define AD_CH_RTC_LOSC  (AD_CH_RTC | ADC_RTC_MUX_RTC_LOSC)
#define AD_CH_RTCVDD    (AD_CH_RTC | ADC_RTC_MUX_RTCVDD)

枚举变量用于定义每个变量的名字 例如adc_value[R_AD_CH_KEY] = adc_value[0]
而对应的ad_table[]则保存对应通道的JL_ADC->CON的bit[8-11]值。
自行添加修改通道是时,需要对应2个数组的位置,以免读错通道值,所有通道扫描一次时间2ms*最大通道数,如果通道太多,ad按键就需要微调,不然可能会有不灵敏的感觉

/*AD通道定义*/
enum {
#if KEY_AD_RTCVDD_EN
    R_AD_CH_KEY = 0,
    R_AD_CH_RTCVDD,
#elif KEY_AD_VDDIO_EN
    R_AD_CH_KEY = 0,
#endif
#if POWER_EXTERN_DETECT_EN
    R_AD_CH_EXTERN_POWER,
#endif
 //   R_AD_CH_VBAT,
 //   R_AD_CH_CHARGE,
    R_AD_CH_temporary, //PB1
    R_AD_CH_battery,   //PR1
    // R_AD_CH_LDOIN,
    R_AD_CH_LDOREF,
    R_AD_CH_BT,
    R_MAX_AD_CHANNEL,
};

adc_api.c下定义了两个数组只有5个元素,adc_value[]

u16 adc_value[R_MAX_AD_CHANNEL];
const u32 ad_table[] = {
#if KEY_AD_RTCVDD_EN
    AD_KEY_CH,
    AD_CH_RTCVDD,
#elif KEY_AD_VDDIO_EN
    AD_KEY_CH,
#endif
#if POWER_EXTERN_DETECT_EN
    AD_POWER_EXTERN_CH,
#endif
    //AD_CH_VBAT,
    // AD_CH_CHARGE,
    AD_CH_PB1, 
    AD_CH_PR1, 
    /* AD_CH_LDOIN, */
    AD_CH_LDOREF,
    AD_CH_BT, // 1110 ,BT to ADC
};

操作很简单,只需要修改制定的通道及名称就可以,在需要使用到的地方调用数组的值即可,例如SDK的ad按键部分,函数体中直接取出对应的数组值。
key_value =adc_value[R_AD_CH_KEY];

u8 get_adkey_value(void)
{
    u8 key_number;
    u32 key_value;
    static u8 aux_in_cnt = 0;
    static u8 aux_out_cnt = 0;

    key_value = adc_value[R_AD_CH_KEY];

后面一些特殊的ADC通道不明确有什么特殊的配置需要,普通IO口的采样直接配置数组就可以,配置好后,在上面的的枚举和数组中添加对应的ad通道号就行了

	// PB1 配置AD输入  ADC7
    JL_PORTB->PU  |= BIT(1);    //使用内部上拉要打开上拉
    JL_PORTB->PD  &= ~BIT(1);
    JL_PORTB->DIR |=  BIT(1); //GPIO设置输入模式
    JL_PORTB->DIE &= ~BIT(1); //GPIO输入关闭,使用ADC模式
    //PR1 adc12 配置AD输入
    PORTR_PU (PORTR1, 1);
    PORTR_PD (PORTR1, 0);
    PORTR_DIR(PORTR1, 1);
    PORTR_DIE(PORTR1, 0);
    PORTR1_ADCEN_CTL(1);

最后

以上就是英俊钢铁侠为你收集整理的杰理AC6926X-多通道ADC设置的全部内容,希望文章能够帮你解决杰理AC6926X-多通道ADC设置所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部