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 中断标志清除
}
}
DMA的触发设置不对吧,应该是ADC转完触发DAM传输,每转换完成一次传输一次ADC数据,你设置的是软件触发啊…… martinhu 发表于 2023-2-16 09:12
DMA的触发设置不对吧,应该是ADC转完触发DAM传输,每转换完成一次传输一次ADC数据,你设置的是软件触发啊… ...
DmaADCJQRTrig
DmaADCSQRTrig
170只有这2个源,都不行吧?
没有DmaADC"完成"Trig 10us采集一次/采集完成了么 kktron 发表于 2023-2-17 09:05
DmaADCJQRTrig
DmaADCSQRTrig
就是DmaADCSQRTrig触发 首选确定信号源肯定是一直在变化的是吧 楼主使用的转换速度是不是过快或者过慢了啊 为什么需要这么高的采集速度呢有可能没有转换结束吧 楼主使用的是ad的什么模式进行采集的呢? 转换完成之后使用中断模式来读取数据寄存器的值? AD转换不同通道的结果对应的寄存器不同 是不是读取结果读错寄存器了啊 这种情况下,肯定ADC配置或者接收出问题的。 10us采集一个次ADC?那采样率要100kHz,内部ADC达不到这么快吧。 你先正常采集,不用中断和ADC看看能不能采集到吧。
页:
[1]