Files
hpw421/component/xc6xx_drivers/Drivers/test_case/ADC/adc.c
T
2026-07-03 18:08:25 +08:00

441 lines
13 KiB
C

/*!
* \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<<ADC_MAIN_CTL_AUTO_SW_Pos);
//==================中断设置=========================
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;
}
}
}
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
//}