[技术问答]

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

[复制链接]
641|13
手机看帖
扫描二维码
随时随地手机跟帖
kktron|  楼主 | 2023-2-14 16:10 | 显示全部楼层 |阅读模式
本帖最后由 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 中断标志清除
    }
}


使用特权

评论回复
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看看能不能采集到吧。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

9

主题

44

帖子

0

粉丝