/*! * \file adc.c * * \brief Target adc implementation * * \copyright Revised BSD License, see section \ref LICENSE. * * \code * * _ __ _ ________ _ * | |/ /(_)___ / ____/ /_ (_)___ * | // / __ \/ / / __ \/ / __ \ * / |/ / / / / /___/ / / / / /_/ / * /_/|_/_/_/ /_/\____/_/ /_/_/ .___/ * /_/ * (C) 2022-2025 XinChip * * \endcode * * \author ( XinChip ) Alex-J * * \author ( XinChip ) */ /*----------------------------------------------------------------------------------- INCLUDE HEADE FILES ------------------------------------------------------------------------------------*/ #include "adc.h" #include "xc6xxx_hal_adc.h" #include "xc6xxx_hal_adc_dmac.h" /*------------------------------------------------------------------------------------ Macros -------------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------------ Global Variables -------------------------------------------------------------------------------------*/ uint8_t adc_ch_buff[1000]; extern uint32_t adc_val_buff[500]; uint16_t adc_con = 0; /*------------------------------------------------------------------------------------ Functions -------------------------------------------------------------------------------------*/ /** * @brief adc_demo * @details * @param void * @retval void */ void adc_demo(void) { DEBUG("__ADC_DEMO__\r"); DEBUG("XC_ADC->RF_CTL:%x\n", XC_ADC->RF_CTL); uint16_t integer; uint16_t decimal; uint16_t adc_val = 0; adc_cfg adc_cfg; /*----- Special Pin -----*/ /*< SWD 和 SWCK 引脚也可以作为 ADC 使用, 注意 PIN 脚的功能重映射 >*/ // GPIO_MuxCtl(12,1); // GPIO_MuxCtl(13,1); /*-----------------------*/ // *((volatile unsigned *)(0x4002F000 + 0x03C)) &= ~(0x1<<14); adc_cfg.Freq = ADC_FREQ_2M; adc_cfg.RefVol = ADC_REF_VOL_3_3V; adc_cfg.SampEdge = ADC_SAMPEDGE_FALL; adc_cfg.ExtDataMode = ADC_DATA_MODE_32BIT; adc_cfg.ExtEdgeSel = ADC_EXT_EDGE_SEL_INTER; adc_cfg.ExtSampleNum = ADC_SAMPLE_NUM_8; adc_cfg.ExtTriggerSel = ADC_TRIGGER_SEL_PWM0; ADC_Init(XC_ADC, &adc_cfg); while (1) { DEBUG("XC_ADC->RF_CTL22:%x\n", XC_ADC->RF_CTL); ADC_StartGetValue(XC_ADC, ADC_CHANNEL4_PIN0, &adc_val); if (adc_cfg.RefVol == ADC_REF_VOL_3_3V) { integer = ((adc_val) * 3.3 * 100) / (1.0 * 4096) / 100; decimal = ((uint32_t)((adc_val * 3.3 * 100) / 4096) % 100); DEBUG("3.3v ref adc_vol=%d.%d ,adc_val=%d\n", integer, decimal, adc_val); } else if (adc_cfg.RefVol == ADC_REFVOL_2_33V) { integer = ((adc_val) * 2.33 * 100) / (1.0 * 4096) / 100; decimal = ((uint32_t)((adc_val * 2.33 * 100) / 4096) % 100); DEBUG("2.33v ref adc_vol=%d.%d ,adc_val=%d\n", integer, decimal, adc_val); } Delay_Ms(1000); } } /** * @brief adc_channel_sw_demo * @details * @param void * @retval void */ void adc_channelswitch_sw_demo(void) { DEBUG("ADC channelswitch sw demo\n"); uint16_t integer; uint16_t decimal; adc_cfg adc_cfg; Delay_Ms(500); *((volatile unsigned int *)(0x400001BC)) &= ~(1 << 12); // 防止GPIO6被接到运放,导致GADC\上拉无效问题 GPIO_InitTypeDef GPIO_InitCfg = {0}; GPIO_InitCfg.Mux = GPIO_Mux0; GPIO_InitCfg.FunSel = GPIO_Dx; GPIO_InitCfg.Pull = GPIO_NOPULL; // Board Led1 Initialization GPIO_InitCfg.Dir = GPIO_DIR_INPUT; GPIO_InitCfg.Int = NOT_INT; GPIO_InitCfg.Pin = 20; GPIO_Init(&GPIO_InitCfg); GPIO_InitCfg.Pin = 18; GPIO_Init(&GPIO_InitCfg); GPIO_InitCfg.Pin = 19; GPIO_Init(&GPIO_InitCfg); GPIO_InitCfg.Pin = 0; GPIO_Init(&GPIO_InitCfg); GPIO_FunSel(3, UART0_TX); // 更换打印口 GPIO_FunSel(2, UART0_RX); // *((volatile unsigned *)(0x4002F000 + 0x03C)) &= ~(0x1<<14); adc_cfg.Freq = ADC_FREQ_4M; adc_cfg.RefVol = ADC_REF_VOL_3_3V; adc_cfg.SampEdge = ADC_SAMPEDGE_FALL; adc_cfg.ExtDataMode = ADC_DATA_MODE_32BIT; adc_cfg.ExtEdgeSel = ADC_EXT_EDGE_SEL_INTER; // ADC_EXT_EDGE_SEL_EXTERN_RISE // // ADC_EXT_EDGE_SEL_EXTERN_BOTH adc_cfg.ExtSampleNum = ADC_SAMPLE_NUM_4; adc_cfg.ExtTriggerSel = ADC_TRIGGER_SEL_PWM0; ADC_Init(XC_ADC, &adc_cfg); __ADC_ChannelSet(XC_ADC, ADC_CHANNEL4_PIN0); //==================中断设置========================= ADC_Enable_IT(XC_ADC, ADC_INT_EN_READ_REQ_EN_ENABLE | ADC_INT_EN_FIFO_ERROR_EN_ENABLE); NVIC_EnableIRQ(GADC_IRQn); //=========================================== __ADC_FIFO_ReqIntLenthSet(XC_ADC); __ADC_FIFO_Flush(XC_ADC); __ADC_Clear_IT_Flag(XC_ADC); // ADC DMA enable // XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_DMAS_ON_ENABLE; // XC_ADC->MAIN_CTL |= ADC_MAIN_CTL_DMAS_ON_ENABLE; // ADC_DMA_Init(); __ADC_Enable(XC_ADC); uint32_t val; ADC_FIFO_TypeDef *fifo_val = NULL; while (1) { if (adc_con >= 500 && adc_con != 0xffff) { fifo_val = (ADC_FIFO_TypeDef *)&val; for (uint16_t i = 0; i < 500; i++) { val = adc_val_buff[i]; integer = ((uint32_t)(fifo_val->value_1) * (3.3 * 100)) / (1.0 * 4095) / 100; decimal = ((uint32_t)((fifo_val->value_1 * (3.3 * 100)) / 4095) % 100); DEBUG("i_dex1: %4d ch : %d val: %d adc_vol=%d.%02dV\n", i, fifo_val->chanel_1, fifo_val->value_1, integer, decimal); integer = ((uint32_t)(fifo_val->value_2) * (3.3 * 100)) / (1.0 * 4095) / 100; decimal = ((uint32_t)((fifo_val->value_2 * (3.3 * 100)) / 4095) % 100); DEBUG("i_dex2: %4d ch : %d val: %d adc_vol=%d.%02dV\n", i, fifo_val->chanel_2, fifo_val->value_2, integer, decimal); if ((i % 2)) DEBUG("\r\n\r\n"); // DEBUG("i_dex: %4d ch : %d val: %d\n",i, // adc_ch_buff[i],adc_val_buff[i]); } adc_con = 0xffff; } } } /** * @brief adc_channel_sw_demo * @details * @param void * @retval void */ void adc_channelswitch_hw_demo(void) { DEBUG("ADC channelswitch hw demo\n"); uint16_t integer; uint16_t decimal; adc_cfg adc_cfg; Delay_Ms(500); *((volatile unsigned int *)(0x400001BC)) &= ~(1 << 12); // 防止GPIO6被接到运放,导致GADC\上拉无效问题 GPIO_InitTypeDef GPIO_InitCfg = {0}; GPIO_InitCfg.Mux = GPIO_Mux0; GPIO_InitCfg.FunSel = GPIO_Dx; GPIO_InitCfg.Pull = GPIO_NOPULL; // Board Led1 Initialization GPIO_InitCfg.Dir = GPIO_DIR_INPUT; GPIO_InitCfg.Int = NOT_INT; GPIO_InitCfg.Pin = 20; GPIO_Init(&GPIO_InitCfg); GPIO_InitCfg.Pin = 18; GPIO_Init(&GPIO_InitCfg); GPIO_InitCfg.Pin = 19; GPIO_Init(&GPIO_InitCfg); GPIO_InitCfg.Pin = 0; GPIO_Init(&GPIO_InitCfg); GPIO_FunSel(3, UART0_TX); // 更换打印口 GPIO_FunSel(2, UART0_RX); // *((volatile unsigned *)(0x4002F000 + 0x03C)) &= ~(0x1<<14); adc_cfg.Freq = ADC_FREQ_4M; adc_cfg.RefVol = ADC_REF_VOL_3_3V; adc_cfg.SampEdge = ADC_SAMPEDGE_FALL; adc_cfg.ExtDataMode = ADC_DATA_MODE_32BIT; adc_cfg.ExtEdgeSel = ADC_EXT_EDGE_SEL_INTER; // ADC_EXT_EDGE_SEL_EXTERN_RISE // // ADC_EXT_EDGE_SEL_EXTERN_BOTH adc_cfg.ExtSampleNum = ADC_SAMPLE_NUM_4; adc_cfg.ExtTriggerSel = ADC_TRIGGER_SEL_PWM0; ADC_Init(XC_ADC, &adc_cfg); XC_ADC->TIMER1 = 62; XC_ADC->TIMER0 = 1; //=============设置需要切换的通道(1---4通道,1个bit表示一个通道)============= XC_ADC->CHAN_CTL &= ~ADC_CHAN_CTL_CHAN_AUTO_Msk; XC_ADC->CHAN_CTL |= 0xf << 8; // 使能ADC自动切换 XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_AUTO_SW_Msk; XC_ADC->MAIN_CTL |= ADC_MAIN_CTL_AUTO_SW_ENABLE; //(ADC_MAIN_CTL_AUTO_SW_ENABLE<MAIN_CTL &= ~ADC_MAIN_CTL_DMAS_ON_ENABLE; // XC_ADC->MAIN_CTL |= ADC_MAIN_CTL_DMAS_ON_ENABLE; // ADC_DMA_Init(); __ADC_Enable(XC_ADC); uint32_t val; ADC_FIFO_TypeDef *fifo_val = NULL; while (1) { if (adc_con >= 500 && adc_con != 0xffff) { fifo_val = (ADC_FIFO_TypeDef *)&val; for (uint16_t i = 0; i < 500; i++) { val = adc_val_buff[i]; integer = ((uint32_t)(fifo_val->value_1) * (3.3 * 100)) / (1.0 * 4095) / 100; decimal = ((uint32_t)((fifo_val->value_1 * (3.3 * 100)) / 4095) % 100); DEBUG("i_dex1: %4d ch : %d val: %d adc_vol=%d.%02dV\n", i, fifo_val->chanel_1, fifo_val->value_1, integer, decimal); integer = ((uint32_t)(fifo_val->value_2) * (3.3 * 100)) / (1.0 * 4095) / 100; decimal = ((uint32_t)((fifo_val->value_2 * (3.3 * 100)) / 4095) % 100); DEBUG("i_dex2: %4d ch : %d val: %d adc_vol=%d.%02dV\n", i, fifo_val->chanel_2, fifo_val->value_2, integer, decimal); if ((i % 2)) DEBUG("\r\n\r\n"); // DEBUG("i_dex: %4d ch : %d val: %d\n",i, // adc_ch_buff[i],adc_val_buff[i]); } adc_con = 0xffff; } } } void ADC_channelswitch_sw_Intr_Callback(void) { uint32_t adc_int; static uint8_t adc_start = 0; adc_int = XC_ADC->INT; if (!(adc_int & (ADC_INT_READ_REQ_INT_Msk | ADC_INT_FIFO_ERROR_INT_Msk))) { return; } if (adc_con >= 500) { //__ADC_Clear_IT_Flag(XC_ADC); return; } //__ADC_Disable(XC_ADC); __ADC_Clear_IT_Flag(XC_ADC); if (++adc_start > 3) adc_start = 0; switch (adc_start) { case 0: __ADC_ChannelSet(XC_ADC, ADC_CHANNEL1_PIN20); GPIO_Output_Low(1); GPIO_Output_High(1); break; case 1: __ADC_ChannelSet(XC_ADC, ADC_CHANNEL11_PIN2); // XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_AUTO_SW_Msk; break; case 2: __ADC_ChannelSet(XC_ADC, ADC_CHANNEL4_PIN0); // XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_AUTO_SW_Msk; break; case 3: __ADC_ChannelSet(XC_ADC, ADC_CHANNEL6_PIN4); // XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_AUTO_SW_Msk; break; // case 4: // __ADC_ChannelSet(XC_ADC, ADC_CHANNEL7_PIN5); // //XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_AUTO_SW_Msk; // break; // // case 5: // __ADC_ChannelSet(XC_ADC, ADC_CHANNEL2_PIN19); // //XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_AUTO_SW_Msk; // break; // // case 6: // __ADC_ChannelSet(XC_ADC, ADC_CHANNEL3_PIN18); // //XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_AUTO_SW_Msk; // break; // // case 7: // __ADC_ChannelSet(XC_ADC, ADC_CHANNEL4_PIN0); // //XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_AUTO_SW_Msk; // break; } for (int t = 0; t < ADC_FIFO_CTL_READ_REQ_THRESH_LEN_2; t++) { // val = XC_ADC->FIFO; adc_val_buff[adc_con] = XC_ADC->FIFO; adc_con++; } //__ADC_Enable(XC_ADC); //__ADC_FIFO_Flush(XC_ADC); //__ADC_Clear_IT_Flag(XC_ADC); } void ADC_channelswitch_hw_Intr_Callback(void) { uint32_t adc_int; adc_int = XC_ADC->INT; if (!(adc_int & (ADC_INT_READ_REQ_INT_Msk | ADC_INT_FIFO_ERROR_INT_Msk))) { return; } if (adc_con >= 500) { return; } //__ADC_Disable(XC_ADC); __ADC_Clear_IT_Flag(XC_ADC); for (int t = 0; t < ADC_FIFO_CTL_READ_REQ_THRESH_LEN_2; t++) { adc_val_buff[adc_con] = XC_ADC->FIFO; adc_con++; } } // void ADC_Intr_Callback(void) //{ // ADC_channelswitch_hw_Intr_Callback(); //adc硬件切换 //// ADC_channelswitch_sw_Intr_Callback();//adc软件切换 //// PGA_ADC_Intr_Callback(); //录音pga //}