新手上路
- 积分
- 32
- 金钱
- 32
- 注册时间
- 2021-6-4
- 在线时间
- 10 小时
|
3金钱
有个问题请教一下大家,我用TIM3的TRGO信号每0.25ms触发ADC采四路数据,然后使用DMA传输数据,在DMA传输指定长度后进入中断切换双缓冲,然后现在问题是在DMA中断中如果不先失能ADC再使能会出现通道乱序的问题,但是先失能再使能ADC跑了几个周期后就停止了,也就是不进入DMA中断了。用的是国民的N32芯片,基本可以和STM32F103的大部分适配,可以当成STM32的代码看,代码如下,大佬可以帮忙分析一下或者有什么方法解决吗?
/*******************************************************************************
* 功能描述 : 初始化ADC(开启通道1、2、4、11)
* 输入参数 :
* 输出参数 :
* 返回值 :
*******************************************************************************/
void Adc1_Init(void)
{
ADC_InitType ADC_InitStructure;
GPIO_InitType GPIO_InitStructure;
RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_ADC1, ENABLE); //使能ADC通道时钟
ADC_ConfigClk(ADC_CTRL3_CKMOD_AHB,RCC_ADCHCLK_DIV2); //设置ADC分频因子6 72M/6=12
//PA0,1,2,3 作为模拟通道输入引脚 IA,IB,IN,IC
GPIO_InitStructure.Pin = ADC1_IA_GPIO | ADC1_IB_GPIO | ADC1_IC_GPIO | ADC1_IN_GPIO;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitPeripheral(ADC1_PORT, &GPIO_InitStructure);
ADC_DeInit(ADC1); //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
ADC_InitStructure.WorkMode = ADC_WORKMODE_INDEPENDENT; //ADC工作模式:ADC1和ADC2工作在独立模式
ADC_InitStructure.MultiChEn = ENABLE; //模数转换工作在扫描(多通道)模式
ADC_InitStructure.ContinueConvEn = DISABLE; //模数转换工作在单次转换模式
ADC_InitStructure.ExtTrigSelect = ADC_EXT_TRIGCONV_T3_TRGO; //转换由TIM3触发
ADC_InitStructure.DatAlign = ADC_DAT_ALIGN_R; //ADC数据右对齐
ADC_InitStructure.ChsNumber = 4; //指定将使用常规通道组的定序器转换的 ADC 通道数
ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
ADC_EnableExternalTrigConv(ADC1, ENABLE);
ADC_ConfigRegularChannel(ADC1,ADC_CH_1,1,ADC_SAMP_TIME_239CYCLES5);
ADC_ConfigRegularChannel(ADC1,ADC_CH_2,2,ADC_SAMP_TIME_239CYCLES5);
ADC_ConfigRegularChannel(ADC1,ADC_CH_4,3,ADC_SAMP_TIME_239CYCLES5);
ADC_ConfigRegularChannel(ADC1,ADC_CH_11,4,ADC_SAMP_TIME_239CYCLES5);
ADC_Enable(ADC1, ENABLE); //使能指定的ADC1
//ADC_EnableDMA(ADC1, ENABLE); //ADC1的DMA使能
while(ADC_GetFlagStatusNew(ADC1,ADC_FLAG_RDY) == RESET); //等待ADC1准备开始
ADC_StartCalibration(ADC1); //开启AD校准
while (ADC_GetCalibrationStatus(ADC1)); //等待校准结束
ADC_EnableDMA(ADC1, ENABLE); //ADC1的DMA使能
ADC_EnableSoftwareStartConv(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
}
static DMA_InitType DMA_InitStructure;
/*******************************************************************************
* 功能描述 : DMA1配置
* 输入参数 :
* 输出参数 :
* 返回值 :
*******************************************************************************/
void DMA1_Init(void)
{
NVIC_InitType NVIC_InitStructure;
RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_DMA1, ENABLE);
/* DMA1 Channel1 Configuration ----------------------------------------------*/
DMA_DeInit(DMA1_CH1);
DMA_InitStructure.PeriphAddr = (uint32_t)&ADC1->DAT;
DMA_InitStructure.MemAddr = (uint32_t)ADC_ConvertedValue0;
DMA_InitStructure.Direction = DMA_DIR_PERIPH_SRC; //设置方向为外设-->存储器
DMA_InitStructure.BufSize = ADC_BUFF_LEN*4; //设置传输数据的个数
DMA_InitStructure.PeriphInc = DMA_PERIPH_INC_DISABLE; //失能外设寄存器增量
DMA_InitStructure.DMA_MemoryInc = DMA_MEM_INC_ENABLE;
DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_HALFWORD;
DMA_InitStructure.MemDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.CircularMode = DMA_MODE_NORMAL;
DMA_InitStructure.Priority = DMA_PRIORITY_HIGH;
DMA_InitStructure.Mem2Mem = DMA_M2M_DISABLE; //失能存储器之间的传输
DMA_Init(DMA1_CH1, &DMA_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
DMA_ClearFlag(DMA_INT_TXC, DMA1);
DMA_ConfigInt(DMA1_CH1, DMA_INT_TXC, ENABLE);
DMA_EnableChannel(DMA1_CH1, ENABLE);
//ADC_EnableDMA(ADC1, ENABLE); //ADC1的DMA使能
//ADC_EnableSoftwareStartConv(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
g_bAdBufIndex = 0;
}
/*******************************************************************************
* 功能描述 : DMA 双缓冲切换
* 输入参数 :
* 输出参数 :
* 返回值 :
*******************************************************************************/
void DMA1_SwitchBuffer(void)
{
DMA_EnableChannel(DMA1_CH1, DISABLE);
//ADC_Enable(ADC1, DISABLE);
if(g_bAdBufIndex == 0)
{
g_bAdBufIndex = 1;
DMA_InitStructure.MemAddr = (uint32_t)ADC_ConvertedValue1; // 设置接收缓冲区首地址
DMA_Init(DMA1_CH1, &DMA_InitStructure); // 写入配置
}
else
{
g_bAdBufIndex = 0;
DMA_InitStructure.MemAddr = (uint32_t)ADC_ConvertedValue0; // 设置接收缓冲区首地址
DMA_Init(DMA1_CH1, &DMA_InitStructure); // 写入配置
}
DMA_EnableChannel(DMA1_CH1, ENABLE);
//ADC_Enable(ADC1, ENABLE);
//ADC_EnableSoftwareStartConv(ADC1, ENABLE);
}
/*******************************************************************************
* 功能描述 : DMA 中断
* 输入参数 :
* 输出参数 :
* 返回值 :
*******************************************************************************/
void DMA1_Channel1_IRQHandler(void)
{
if (DMA_GetIntStatus(DMA1_INT_TXC1, DMA1))
{
DMA_ClrIntPendingBit(DMA1_INT_GLB1, DMA1);
DMA1_SwitchBuffer();
}
else
{
DMA_ClrIntPendingBit(DMA1_INT_GLB1, DMA1);
DMA1_Init();
//DMA_ClrIntPendingBit(DMA1_INT_ERR1, DMA1);
}
}
/*******************************************************************************
* 功能描述 : TIM3 配置
* 输入参数 :
* 输出参数 :
* 返回值 :
*******************************************************************************/
void TIM3_Configuration(void)
{
TIM_TimeBaseInitType TIM_TimeBaseStructure;
NVIC_InitType NVIC_InitStructure;
RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM3, ENABLE);
TIM_TimeBaseStructure.Period = 2000; //设置0.25s一次TIM2比较周期 2000*0.125us = 0.25ms
TIM_TimeBaseStructure.Prescaler = 9; //系统主频72M,这里分频9,相当于8MHz定时器3时钟 //LUTHER
TIM_TimeBaseStructure.ClkDiv = 0x00;
TIM_TimeBaseStructure.CntMode = TIM_CNT_MODE_UP;
TIM_InitTimeBase(TIM3, &TIM_TimeBaseStructure);
TIM_SelectOutputTrig(TIM3,TIM_TRGO_SRC_UPDATE); //选择TRGO触发源为计时器更新时间
//中断分组初始化
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4; //先占优先级4级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //从优先级1级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
TIM_ClearFlag(TIM3, TIM_FLAG_UPDATE);
TIM_ConfigInt(TIM3, TIM_INT_UPDATE, ENABLE);
TIM_Enable(TIM3, ENABLE);
}
/*******************************************************************************
* 功能描述 : TIM3 0.25ms中断
* 输入参数 :
* 输出参数 :
* 返回值 :
*******************************************************************************/
void TIM3_IRQHandler(void)
{
if(TIM_GetIntStatus(TIM3, TIM_INT_UPDATE) != RESET )
{
TIM_ClrIntPendingBit(TIM3, TIM_INT_UPDATE);
}
}
/*******************************************************************************
* 功能描述 : ADC初始化
* 输入参数 :
* 输出参数 :
* 返回值 :
*******************************************************************************/
void Adcx_Init(void)
{
Adc1_Init();
BSP_Delay_Ms(200); //延时200ms,避免开始采集的数据为0
DMA1_Init();
TIM3_Configuration();
}
|
|