kktron 发表于 2023-2-14 16:10

ADC收不到数据会是什么问题

本帖最后由 kktron 于 2023-2-14 17:10 编辑

ADC接了PB00, ADC上电压在变化(0~2v),但ADCRxBuf 全部是值0
定时器3 现在可以中断进入触发,adc也可以进中断,目的是想间隔10us 采集一次ADC,采集200个数据。
请问哪边配置不对呢?

uint16_t ADCRxBuf;
/**
******************************************************************************
** \briefadc_init
**
** \return 无
******************************************************************************/
voidadc_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 运行
}
/**
******************************************************************************
    ** \briefadc端口
    **
    ** @param无
    ** \retval 无
    **
******************************************************************************/
void adc_GpioInit(void)
{
    ///< 开启ADC/BGR GPIO外设时钟
    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);
    Gpio_SetAnalogMode(GpioPortB, GpioPin0);      //PB00 (AIN0)
}

/**
******************************************************************************
    ** \briefadc配置
    **
    ** @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;         ///< 目标地址
    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
}

/**
******************************************************************************
    ** \briefadc中断函数
    **
    ** @param无
    ** \retval 无
    **
******************************************************************************/
void Adc_IRQHandler(void)
{
    if(TRUE == Adc_GetIrqStatus(AdcMskIrqSgl))
    {
      Adc_ClrIrqStatus(AdcMskIrqSgl);
    }
}


/**
******************************************************************************
    ** \briefTIME3 配置
    **
    ** @paramu16PeriodPCLK为外设总线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 开中断
}
/**
******************************************************************************
    ** \briefTIME3 中断服务函数
    **
    ** @param无
    ** \retval 无
    **
******************************************************************************/
void Tim3_IRQHandler(void)
{
    //Timer3 模式0 计时溢出中断
    if(TRUE == Tim3_GetIntFlag(Tim3UevIrq))
    {
      Adc_SGL_Start();                //进入中断之后,再次ADC 开启转换
      Tim3_ClearIntFlag(Tim3UevIrq);//Timer3模式0 中断标志清除
    }
}


martinhu 发表于 2023-2-16 09:12

DMA的触发设置不对吧,应该是ADC转完触发DAM传输,每转换完成一次传输一次ADC数据,你设置的是软件触发啊……

kktron 发表于 2023-2-17 09:05

martinhu 发表于 2023-2-16 09:12
DMA的触发设置不对吧,应该是ADC转完触发DAM传输,每转换完成一次传输一次ADC数据,你设置的是软件触发啊… ...

DmaADCJQRTrig   
DmaADCSQRTrig         

170只有这2个源,都不行吧?
没有DmaADC"完成"Trig   

woai32lala 发表于 2023-2-17 17:42

10us采集一次/采集完成了么

ddxx 发表于 2023-2-20 10:36

kktron 发表于 2023-2-17 09:05
DmaADCJQRTrig   
DmaADCSQRTrig         



就是DmaADCSQRTrig触发

tpgf 发表于 2023-3-7 15:14

首选确定信号源肯定是一直在变化的是吧

wakayi 发表于 2023-3-7 15:33

楼主使用的转换速度是不是过快或者过慢了啊

wowu 发表于 2023-3-7 15:48

为什么需要这么高的采集速度呢有可能没有转换结束吧

xiaoqizi 发表于 2023-3-7 16:00

楼主使用的是ad的什么模式进行采集的呢?

木木guainv 发表于 2023-3-7 16:26

转换完成之后使用中断模式来读取数据寄存器的值?

磨砂 发表于 2023-3-7 16:39

AD转换不同通道的结果对应的寄存器不同 是不是读取结果读错寄存器了啊

朝生 发表于 2023-3-9 14:07

这种情况下,肯定ADC配置或者接收出问题的。

LLGTR 发表于 2023-3-9 14:08

10us采集一个次ADC?那采样率要100kHz,内部ADC达不到这么快吧。

天天向善 发表于 2023-3-9 14:08

你先正常采集,不用中断和ADC看看能不能采集到吧。
页: [1]
查看完整版本: ADC收不到数据会是什么问题