本帖最后由 kktron 于 2023-2-14 17:10 编辑
ADC接了PB00, ADC上电压在变化(0~2v),但ADCRxBuf 全部是值0
定时器3 现在可以中断进入触发,adc也可以进中断,目的是想间隔10us 采集一次ADC,采集200个数据。
请问哪边配置不对呢?
uint16_t ADCRxBuf[200];
/**
******************************************************************************
** \brief adc_init
**
** \return 无
******************************************************************************/
void adc_init(void)
{
adc_GpioInit(); ///< GPIO初始化
adc_CfgInit(); ///< DAC初始化
adc_DmaInit(); ///< DMA初始化 24M外接晶振倍频到48M max
adc_Timer3Cfg(30); ///< Timer5 配置; 16分频,周期-->30*(1/48M) * 16 = 10us
Tim3_M0_Run(); ///< TIM3 运行
}
/**
******************************************************************************
** \brief adc端口
**
** @param 无
** \retval 无
**
******************************************************************************/
void adc_GpioInit(void)
{
///< 开启ADC/BGR GPIO外设时钟
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);
Gpio_SetAnalogMode(GpioPortB, GpioPin0); //PB00 (AIN0)
}
/**
******************************************************************************
** \brief adc配置
**
** @param 无
** \retval 无
**
******************************************************************************/
void adc_CfgInit(void)
{
stc_adc_cfg_t stcAdcCfg;
DDL_ZERO_STRUCT(stcAdcCfg);
Sysctrl_SetPeripheralGate(SysctrlPeripheralAdcBgr, TRUE);
//Bgr_BgrEnable(); ///< 开启BGR
//Adc_Enable();
//adc每次转换单个通道需要24个时钟,adc采样频率是1Msps
stcAdcCfg.enAdcMode = AdcSglMode; ///<采样模式-扫描
stcAdcCfg.enAdcClkDiv = AdcMskClkDiv1; ///<采样分频-1
stcAdcCfg.enAdcSampCycleSel = AdcMskSampCycle8Clk; ///<采样周期数-8
stcAdcCfg.enAdcRefVolSel = AdcMskRefVolSelAVDD; ///<参考电压选择-VCC
stcAdcCfg.enAdcOpBuf = AdcMskBufDisable; ///<OP BUF配置-关
stcAdcCfg.enInRef = AdcMskInRefDisable; ///<内部参考电压使能-关
stcAdcCfg.enAdcAlign = AdcAlignRight; ///<转换结果对齐方式-右
Adc_Init(&stcAdcCfg);
Adc_CfgSglChannel(AdcExInputCH8); ///< PB00
Adc_EnableIrq(); ///< ADC 中断使能
EnableNvic(ADC_DAC_IRQn, IrqLevel1, TRUE);
Adc_SGL_Start(); ///< ADC 开启转换
}
/**
******************************************************************************
** \brief 配置DMA
**
** @param 无
** \retval 无
**
******************************************************************************/
void adc_DmaInit(void)
{
stc_dma_cfg_t stcDmaCfg;
DDL_ZERO_STRUCT(stcDmaCfg); //初始化变量
Sysctrl_SetPeripheralGate(SysctrlPeripheralDma,TRUE); //使能DMAC外设时钟门控开关
stcDmaCfg.enMode = DmaMskBlock; ///< 选择块传输
stcDmaCfg.u16BlockSize = 1; ///< 块传输个数
stcDmaCfg.u16TransferCnt = 200; ///< 块传输次数,一次传输数据大小为 块传输个数*BUFFER_SIZE
stcDmaCfg.enTransferWidth = DmaMsk32Bit; ///< 传输数据的宽度,此处选择字(16Bit)宽度
stcDmaCfg.enSrcAddrMode = DmaMskSrcAddrFix; ///< 源地址自增
stcDmaCfg.enDstAddrMode = DmaMskDstAddrInc; ///< 目的地址自增
stcDmaCfg.enDestAddrReloadCtl = DmaMskDstAddrReloadDisable; ///< 禁止重新加载传输目的地址
stcDmaCfg.enSrcAddrReloadCtl = DmaMskSrcAddrReloadDisable; ///< 使能重新加载传输源地址
stcDmaCfg.enSrcBcTcReloadCtl = DmaMskBcTcReloadDisable; ///< 使能重新加载BC/TC值
stcDmaCfg.u32SrcAddress = (uint32_t)&(M0P_ADC->RESULT);; ///< 源地址
stcDmaCfg.u32DstAddress = (uint32_t)&ADCRxBuf[0]; ///< 目标地址
stcDmaCfg.enRequestNum = DmaSWTrig; ///< 设置触发
stcDmaCfg.enTransferMode = DmaMskOneTransfer; ///< 传输
stcDmaCfg.enPriority = DmaMskPriorityFix; ///< 各通道固定优先级,CH0优先级 > CH1优先级
Dma_InitChannel(DmaCh1,&stcDmaCfg); ///< 初始化dma通道1
Dma_Enable(); ///< 使能DMA
Dma_EnableChannel(DmaCh1); ///< 使能DMA通道1
Dma_ClrStat(DmaCh1); ///< 清零:STAT[2:0]
}
/**
******************************************************************************
** \brief adc中断函数
**
** @param 无
** \retval 无
**
******************************************************************************/
void Adc_IRQHandler(void)
{
if(TRUE == Adc_GetIrqStatus(AdcMskIrqSgl))
{
Adc_ClrIrqStatus(AdcMskIrqSgl);
}
}
/**
******************************************************************************
** \brief TIME3 配置
**
** @param u16Period PCLK为外设总线APB提供时钟信号
** \retval 无
**
******************************************************************************/
void adc_Timer3Cfg(uint16_t u16Period)
{
uint16_t u16ArrValue;
uint16_t u16CntValue;
stc_tim3_mode0_cfg_t stcTim3BaseCfg;
//结构体初始化清零
DDL_ZERO_STRUCT(stcTim3BaseCfg);
Sysctrl_SetPeripheralGate(SysctrlPeripheralTim3, TRUE); //Base Timer外设时钟使能
stcTim3BaseCfg.enWorkMode = Tim3WorkMode0; //定时器模式
stcTim3BaseCfg.enCT = Tim3Timer; //定时器功能,计数时钟为内部PCLK
stcTim3BaseCfg.enPRS = Tim3PCLKDiv16; //PCLK/16
stcTim3BaseCfg.enCntMode = Tim316bitArrMode; //自动重载16位计数器/定时器
stcTim3BaseCfg.bEnTog = FALSE;
stcTim3BaseCfg.bEnGate = FALSE;
stcTim3BaseCfg.enGateP = Tim3GatePositive;
Tim3_Mode0_Init(&stcTim3BaseCfg); //TIM3 的模式0功能初始化
u16ArrValue = 0x10000 - u16Period ;
Tim3_M0_ARRSet(u16ArrValue); //设置重载值(ARR = 0x10000 - 周期)
u16CntValue = 0x10000 - u16Period;
Tim3_M0_Cnt16Set(u16CntValue); //设置计数初值
Tim3_ClearIntFlag(Tim3UevIrq); //清中断标志
Tim3_Mode0_EnableIrq(); //使能TIM3中断(模式0时只有一个中断)
EnableNvic(TIM3_IRQn, IrqLevel0, TRUE); //TIM3 开中断
}
/**
******************************************************************************
** \brief TIME3 中断服务函数
**
** @param 无
** \retval 无
**
******************************************************************************/
void Tim3_IRQHandler(void)
{
//Timer3 模式0 计时溢出中断
if(TRUE == Tim3_GetIntFlag(Tim3UevIrq))
{
Adc_SGL_Start(); //进入中断之后,再次ADC 开启转换
Tim3_ClearIntFlag(Tim3UevIrq); //Timer3模式0 中断标志清除
}
}
|