大学生
最后登录 1970-1-1
在线时间 小时
注册时间 2016-1-26
20 火花
我设置了三重ADC同步,但是设置DMA_InitStructure.DMA_BufferSize = 3;,传完后就进入中断,但是它会连续进入两次中断,在调试中,只有第二次中断里面才把 DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);执行,清零,这是为什么呢???急!火哥???
/*
* FILE : adc.c
* DESCRIPTION : --
* Author : ysloveivy.
* Copyright :
*
* History
* --------------------
* Rev : 0.00
* Date : 2/20/2017
*
* create.
* --------------------
*/
//------------------------ Include files ------------------------//
#include "..\FWlib\inc\stm32f4xx_adc.h"
#include "..\FWlib\inc\stm32f4xx_gpio.h"
#include "..\FWlib\inc\stm32f4xx_rcc.h"
#include "..\include\adc.h"
#include "..\include\usart.h"
//--------------------- Function Prototype ----------------------//
//static int initialize(void);
//static int read_adc(int);
__IO uint16_t ADC_ConvertedValue[3];
__IO uint16_t C=10;
//-------------------------- Variable ---------------------------//
static void ADC_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
//RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);
//ADC2 GPIO Configuration PC3 ------> ADC2_IN 13
//ADC3 GPIO Configuration PC1 ------> ADC3_IN 11
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; //模拟输入
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &GPIO_InitStructure);
//ADC1 GPIO Configuration PA2 ------> ADC1_IN 2
//
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; //模拟输入
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
static void ADC_Mode_Config(void)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
DMA_InitTypeDef DMA_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //使能ADC1时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE); //使能ADC3时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE); //使能ADC2
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
DMA_DeInit(DMA2_Stream0);
DMA_InitStructure.DMA_PeripheralBaseAddr = CDR_ADDRESS;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ADC_ConvertedValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = 3;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
DMA_Cmd(DMA2_Stream0, ENABLE);
ADC_CommonInitStructure.ADC_Mode = ADC_TripleMode_RegSimult; //ADC为独立模式
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; //设置两个采样阶段之间的延迟周期数为5个周期
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1; //DMA mode 1 enabled (2 / 3 half-words one by one - 1 then 2 then 3)
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; //ADCCLK=PCLK2/2=60/2=30;
ADC_CommonInit(&ADC_CommonInitStructure);
//DMA模式1:每发出一个DMA请求,就会传输一个表示ADC转换的数据项的半字,在三重ADC模式下,发出第一个请求时传输
//ADC1的数据,发出第二个请求时传输ADC2的数据,发出第三个请求时传输ADC3的数据,重复此序列,DMA首先传输ADC1的数据
//随后传输ADC2的数据,在传输ADC3的数据
//初始化ADC
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; //ADC转换分辨率12位
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //非扫描模式
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //关闭连续转换模式
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //禁止触发检测
//使用软件触发,外部触发不用配置,
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //右对齐方式
ADC_InitStructure.ADC_NbrOfConversion = 1; //1个转换在规则序列中
ADC_Init(ADC1, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_480Cycles);
ADC_Init(ADC2, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC2, ADC_Channel_13, 1, ADC_SampleTime_480Cycles);
ADC_Init(ADC3, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC3, ADC_Channel_11, 1, ADC_SampleTime_480Cycles);
ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);
ADC_DMACmd(ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE);
ADC_Cmd(ADC2, ENABLE);
ADC_Cmd(ADC3, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
DMA_ITConfig(DMA2_Stream0,DMA_IT_TC,ENABLE);//打开DMA传输完成中断
// DMA_ClearFlag(DMA2_Stream0, DMA_FLAG_TCIF0);
ADC_SoftwareStartConv(ADC1);
}
void ADC_DMA_Config(void)
{
ADC_GPIO_Config();
ADC_Mode_Config();
}
void DMA2_Stream0_IRQHandler(void)
{
if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0)==SET)
{
DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
DMA_Cmd(DMA2_Stream0, DISABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, DISABLE);
ADC_Cmd(ADC1, DISABLE);
ADC->CCR &= ~ADC_CCR_DDS;
C=C-1;
//usart4.printf("\r\n The current AD value = 0x%08X \r\n", ADC_ConvertedValue[0]);
// usart4.printf("\r\n The current AD value = 0x%08X \r\n", ADC_ConvertedValue[1]);
//usart4.printf("\r\n The current AD value = %f V \r\n", (float)((uint16_t)ADC_ConvertedValue[1]*2.5/4096));
// usart4.printf("\r\n The current AD value = 0x%08X \r\n", ADC_ConvertedValue[2]);
// ADC_Cmd(ADC1, DISABLE);
// ADC_Cmd(ADC2, DISABLE);
// ADC_Cmd(ADC3, DISABLE);
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, DISABLE);
//DMA_Cmd(DMA2_Stream0, DISABLE);
}
}
我来回答