441 lines
14 KiB
C
441 lines
14 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
|
|
//}
|