ADC切换通道

前言:

ADC多通道切换讲解和代码参考。

一、ADC 中断切换通道:

查看代码
 #include "CH59x_common.h"

#define adctest 1
volatile uint8_t adclen;
volatile uint8_t DMA_end = 0;
uint16_t adcBuff[40];

uint8_t adcindex = 0;
uint8_t adcchannel = 0;
enum channel{
      channel_0,
      channel_1,
      channel_2,
      channel_3,
};

void DebugInit(void){
    GPIOB_SetBits(bTXD2);
    GPIOB_ModeCfg(bRXD2, GPIO_ModeIN_PU);
    GPIOB_ModeCfg(bTXD2, GPIO_ModeOut_PP_5mA);
    UART2_DefInit();
}

int main(){
    uint8_t i;
    signed short RoughCalib_Value = 0; // ADC粗调偏差值
    SetSysClock(CLK_SOURCE_PLL_60MHz);

    /* 配置串口调试 */
    DebugInit();
    UART2_BaudRateCfg(1500000);
    PRINT("Start @ChipID=%02X\n", R8_CHIP_ID);

    /* 单通道采样:中断方式,选择adc通道1做采样,对应 PA5引脚, 不带数据校准功能 */
    PRINT("\n6.Single channel sampling in interrupt mode...\n");
    GPIOA_ModeCfg(GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_12 | GPIO_Pin_13, GPIO_ModeIN_Floating);
    ADC_ExtSingleChSampInit(SampleFreq_3_2, ADC_PGA_0);
    ADC_ChannelCfg(adcchannel);
    ADC_ClearITFlag();
    PFIC_EnableIRQ(ADC_IRQn);
    ADC_StartUp();

    while(1){
        mDelaymS(100);
        printf("%d  %d  %d  %d\n",adcBuff[0],adcBuff[1],adcBuff[2],adcBuff[3] );

        memset(adcBuff, 0, 4);
        ADC_ClearITFlag();
        ADC_ChannelCfg(adcchannel);
        PFIC_EnableIRQ(ADC_IRQn);
        ADC_StartUp();
    }
}

__INTERRUPT
__HIGH_CODE
void ADC_IRQHandler(void) //adc中断服务程序
{
    if(ADC_GetITStatus())
    {
        ADC_ClearITFlag();

        switch(adcchannel)
        {
            case channel_0:
                adcBuff[adcindex] = ADC_ReadConverValue();
                adcindex++;
                adcchannel = channel_1;
                ADC_ChannelCfg(adcchannel); //先选择通道,再开启新一轮采样
                ADC_StartUp();// 作用清除中断标志并开启新一轮采样
            break;

            case channel_1:
                adcBuff[adcindex] = ADC_ReadConverValue();
                adcindex++;
                adcchannel = channel_2;
                ADC_ChannelCfg(adcchannel);
                ADC_StartUp();
            break;

            case channel_2:
                adcBuff[adcindex] = ADC_ReadConverValue();
                adcindex++;
                adcchannel = channel_3;
                ADC_ChannelCfg(adcchannel);
                ADC_StartUp();
            break;

            case channel_3:
                adcBuff[adcindex] = ADC_ReadConverValue();
                adcindex++;
                adcindex = 0;
                adcchannel = channel_0;
                PFIC_DisableIRQ(ADC_IRQn);
            break;

            default:
                break;
        }
    }
}

二、ADC DMA切换通道

查看代码
 #include "CH57x_common.h"
uint16_t abcBuff[40];
volatile uint8_t adclen;
volatile uint8_t DMA_end = 0;
volatile uint8_t DMA_endFlag = 0;

void DebugInit(void){
    GPIOA_SetBits(GPIO_Pin_9);
    GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);
    GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA);
    UART1_DefInit();
}

int main(){
    uint8_t i = 0;
    signed short RoughCalib_Value = 0; // ADC粗调偏差值

    SetSysClock(CLK_SOURCE_PLL_60MHz);

    /* 配置串口调试 */
    DebugInit();
    PRINT("Start @ChipID=%02X\n", R8_CHIP_ID);

    /* DMA单通道采样:选择adc通道0做采样,对应 PA4引脚 */
    while(1){
        GPIOA_ModeCfg(GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_12 | GPIO_Pin_13, GPIO_ModeIN_Floating);
        ADC_ExtSingleChSampInit(SampleFreq_3_2, ADC_PGA_0);
        ADC_ChannelCfg(DMA_endFlag);
        ADC_AutoConverCycle(192); // 采样周期为 (256-192)*16个系统时钟
        ADC_DMACfg(ENABLE, (uint16_t)(uint32_t)&abcBuff[0], (uint16_t)(uint32_t)&abcBuff[40], ADC_Mode_Single);
        PFIC_EnableIRQ(ADC_IRQn);
        ADC_StartDMA();
        while(!DMA_end);
        DMA_end = 0;
        PRINT("ADC DMA end \n");
        for(i = 0; i < 40; i++){
            abcBuff[i] = ADC_ExcutSingleConver() + RoughCalib_Value; // 连续采样20次
        }
        for(i = 0; i < 40; i++){
            PRINT("Channel %d = %d \n", (DMA_endFlag - 1), abcBuff[i]);
        }
        if(DMA_endFlag == 4){
            break;
        }
    }
    while(1);
}

__attribute__((interrupt("WCH-Interrupt-fast")))
__attribute__((section(".highcode")))
void ADC_IRQHandler(void)
{
    if(ADC_GetDMAStatus()) {
        printf("R8_ADC_DMA_IF = %x\n", R8_ADC_DMA_IF);
        ADC_ClearDMAFlag();
        ADC_StopDMA();
        PFIC_DisableIRQ(ADC_IRQn);
        R16_ADC_DMA_BEG = (uint16_t)(uint32_t)&abcBuff[0];
//        R8_ADC_DMA_IF |= RB_ADC_IF_END_ADC | RB_ADC_IF_DMA_END;
        DMA_end = 1;
        DMA_endFlag++;
    }
    if(ADC_GetITStatus()){
        ADC_ClearITFlag();
        if(adclen < 20){
            abcBuff[adclen] = ADC_ReadConverValue();
            ADC_StartUp(); // 作用清除中断标志并开启新一轮采样
        }
        adclen++;
    }
}

三、CH592ADC扫描(未完成)

CH592新增ADC扫描功能,可由芯片硬件完成通道切换。

posted @ 2024-09-04 16:02  SweetTea_lllpc  阅读(115)  评论(0编辑  收藏  举报