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扫描功能,可由芯片硬件完成通道切换。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
2023-09-04 CH58x三模键盘模组方案测试体验(CH555主控)