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扫描功能,可由芯片硬件完成通道切换。