先自己写了,不对,然后网上找了很多也不对都是第一次采样以后就没了,研究了很久不知道错在那里,请帮忙看看。
/**
* @brief 配置ADC1的工作模式为MDA模式
* @param 无
* @retval 无
*/
void ADC_Config()
{
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //使能ADC时钟
ADC_DeInit(ADC1); //复位ADC
ADC_StructInit(&ADC_InitStructure); //初始化ADC结构体
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //采样数据右对齐
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;//上升沿触发
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO; //外部触发设置为TIM2
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; //12位分辨率
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //禁用连续转换模式
ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;//向上扫描0-18通道
ADC_Init(ADC1, &ADC_InitStructure);
ADC_OverrunModeCmd(ADC1, ENABLE); //使能数据覆盖模式
ADC_ChannelConfig(ADC1, ADC_Channel_2 , ADC_SampleTime_13_5Cycles); //配置采样通道,采样时间125nS
/* Convert the ADC1 temperature sensor with 55.5 Cycles as sampling time 1448*/
ADC_ChannelConfig(ADC1, ADC_Channel_16 , ADC_SampleTime_13_5Cycles);
ADC_TempSensorCmd(ENABLE);
ADC_GetCalibrationFactor(ADC1); //使能前校准ADC
ADC_Cmd(ADC1, ENABLE); //使能ADC1
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN) == RESET); //等待ADC1使能完成
ADC_DMACmd(ADC1, ENABLE); //使能ADC_DMA
ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular); //配置DMA请求模式为循环模式
ADC_StartOfConversion(ADC1); //开启一次转换(必须)
}
void ADC_DMA_INIT()
{
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA时钟
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn; //选择DMA1通道中断
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //中断使能
NVIC_InitStructure.NVIC_IRQChannelPriority = 0; //优先级设为0
NVIC_Init(&NVIC_InitStructure);
DMA_DeInit(DMA1_Channel1); //复位DMA1_channel1
DMA_StructInit(&DMA_InitStructure); //初始化DMA结构体
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue[0];//缓存数据数组起始地址
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &(ADC1->DR);//取值的外设地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //DMA方向:外设作为数据源
DMA_InitStructure.DMA_BufferSize = DMA_BUFFER_SIZE; //DMA缓存数组大小设置
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址递增禁用
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址递增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外设取值大小设置为Halfword
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//数据大小设置为Halfword
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //DMA循环模式,即完成后重新开始覆盖
// DMA_InitStructure.DMA_M2M = DISABLE; //内存到内存禁用
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA优先级设置为高
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); //使能DMA中断
DMA_ClearITPendingBit(DMA_IT_TC); //清除一次DMA中断标志
DMA_Cmd(DMA1_Channel1, ENABLE); //使能DMA1
}
void ADC_TIM2_INIT()
{
TIM_TimeBaseInitTypeDef TIM2_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能TIM2时钟
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //选择TIM2中断通道
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能TIM2中断
NVIC_InitStructure.NVIC_IRQChannelPriority = 0; //优先级为0
NVIC_Init(&NVIC_InitStructure);
TIM_DeInit(TIM2); //复位TIM2
TIM_TimeBaseStructInit(&TIM2_TimeBaseStructure); //初始化TIMBASE结构体
TIM2_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //系统时钟,不分频,48M
TIM2_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
TIM2_TimeBaseStructure.TIM_Period = 20000; //每312 uS触发一次中断,开启ADC
TIM2_TimeBaseStructure.TIM_Prescaler = 72-1; //计数时钟预分频,f=1M,systick=1 uS
TIM2_TimeBaseStructure.TIM_RepetitionCounter = 0x00; //发生0+1次update事件产生中断
TIM_TimeBaseInit(TIM2, &TIM2_TimeBaseStructure);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); //使能TIM2中断
TIM_ClearFlag(TIM2,TIM_FLAG_Update);
TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update); //选择TIM2的update事件更新为触发源
TIM_Cmd(TIM2, ENABLE); //使能TIM2
}
/**
* @brief ADC1初始化
* @param 无
* @retval 无
*/
void ADC1_Init(void)
{
ADC1_GPIO_Config();
ADC_Config();
ADC_DMA_INIT();
ADC_TIM2_INIT();
}
下面是中断处理
void TIM2_IRQHandler()
{
if(TIM_GetITStatus(TIM2, TIM_IT_Update)) //判断发生update事件中断
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); //清除update事件中断标志
GPIOB->ODR ^=GPIO_Pin_15;
}
}
void DMA1_Channel1_IRQHandler()
{ // while((DMA_GetFlagStatus(DMA1_FLAG_TC1)) == RESET );
if(DMA_GetITStatus(DMA_IT_TC)) //判断DMA传输完成中断
{
ADC_ValueDC[sample_index] = ADC_ConvertedValue[0];
ADC_ValueTEP[sample_index] = ADC_ConvertedValue[1];
if(n >= 128) //注意防止数组越界导致未知错误
{
n = 0;
TIM_Cmd(TIM2, DISABLE); //完成周波采样,停止定时器
DMA_Cmd(DMA1_Channel1, DISABLE); //完成周波采样,停止DMA
m = 1; //置采样完成标志位
}
}
// DMA_ClearFlag(DMA1_FLAG_TC1);
DMA_ClearITPendingBit(DMA_IT_TC); //清除DMA中断标志位
} |