本帖最后由 Learning 于 2017-7-17 23:28 编辑
我想用ADC1和ADC2采样4个端口数据,并用DMA2传输。数据处理在DMA中断中完成,由于串口坏了,我用LED小灯检测是否正常。结果发现中断可以进入,但是不管我接地或者3.3,DMA返回的值一直为0(LED2常亮),反复对照例程和网上的问题也没有发现哪里错了。
下面是主程序:
float temp;
int main(void)
{
NVIC_SetPriorityGrouping(PRIORITY_GROUP);
SystemInit();
LED_Init();
ADC_Inits();
while(1)
{
MEA_StartConv();
temp = Get_ADC_IP()*3.3/4095;
if (temp > 3 ){
LED3 = 0;
}
else
LED3 = 1;
if (temp < 0.5){
LED2 = 0;
}
else
LED2 = 1;
}
}
下面给出我的ADC程序
#include "ADC.h"
#include "interrupt_priority_conf.h"
#include "LED.h"
static uint16_t ADC1_Buf[16], ADC2_Buf[16];
static float MEA_CONV_RATIO[4] = {ADC_IP_CONV_RATIO, ADC_BUCK1_CONV_RATIO, ADC_BUCK2_CONV_RATIO, ADC_BUCK3_CONV_RATIO};
static uint16_t ADC_IP[1];
static uint16_t ADC_BUCK[4];
void ADC_Inits(void)
{
ADC_GPIO_Init();
ADC_DMA_Init();
}
/********************************************************************
*********************************************************************/
void ADC_GPIO_Init(void)
{
TIM_ADC_GPIO_INIT_CLK(ADC_IP_GPIO_CLK | ADC_BUCK1_GPIO_CLK | ADC_BUCK2_GPIO_CLK | ADC_BUCK3_GPIO_CLK, ENABLE); /* Enable ADC1 and GPIOA clock */
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Pin = ADC_BUCK1_Pin;
GPIO_Init(ADC_BUCK1_GPIO, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = ADC_BUCK2_Pin;
GPIO_Init(ADC_BUCK2_GPIO, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = ADC_BUCK3_Pin;
GPIO_Init(ADC_BUCK3_GPIO, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = ADC_IP_Pin ;
GPIO_Init(ADC_IP_GPIO, &GPIO_InitStructure);
}
/********************************************************************
鍑芥暟鍚嶎柟static void ADC1_Mode_Init(void)
*********************************************************************/
void ADC_DMA_Init(void)
{
DMA_InitTypeDef DMA_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
FLASH_PrefetchBufferCmd(ENABLE);
FLASH_DataCacheCmd(ENABLE);
FLASH_InstructionCacheCmd(ENABLE);
PWR->CR |= (uint32_t) PWR_CR_ADCDC1;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2,ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
DMA_DeInit(MEA_ADC1_DMA_STREAM);
DMA_DeInit(MEA_ADC2_DMA_STREAM);
/*************************************DMA_ADC1********************************************/
DMA_InitStructure.DMA_Channel = MEA_ADC1_DMA_CHANNEL;
DMA_InitStructure.DMA_BufferSize = 16;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) ADC1_Buf;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC4;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_PeripheralBaseAddr = ((uint32_t)(ADC1+0x4c));
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_Init(MEA_ADC1_DMA_STREAM, &DMA_InitStructure);
DMA_Cmd(MEA_ADC1_DMA_STREAM, ENABLE);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);
NVIC_InitStructure.NVIC_IRQChannel = MEA_ADC1_DMA_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = MEA_ADC1_DMA_PREPRIO;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = MEA_ADC1_DMA_SUBPRIO;
NVIC_Init(&NVIC_InitStructure);
DMA_ITConfig(MEA_ADC1_DMA_STREAM, DMA_IT_TC, ENABLE);
/*************************************DMA_ADC2********************************************/
DMA_InitStructure.DMA_Channel = MEA_ADC2_DMA_CHANNEL;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) ADC2_Buf;
DMA_InitStructure.DMA_PeripheralBaseAddr = ((uint32_t)(ADC2+0x4c));
DMA_Init(MEA_ADC2_DMA_STREAM, &DMA_InitStructure);
DMA_Cmd(MEA_ADC2_DMA_STREAM, ENABLE);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC2,ENABLE);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC2,DISABLE);
NVIC_InitStructure.NVIC_IRQChannel = MEA_ADC2_DMA_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = MEA_ADC2_DMA_PREPRIO;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = MEA_ADC2_DMA_SUBPRIO;
NVIC_Init(&NVIC_InitStructure);
DMA_ITConfig(MEA_ADC2_DMA_STREAM, DMA_IT_TC, ENABLE);
/*************************************ADC2********************************************/
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_NbrOfConversion = 16;
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_Init(ADC2, &ADC_InitStructure);
int i;
for (i = 0; i < 8; ++i) {
ADC_RegularChannelConfig(ADC1, ADC_IP_CHANNEL, i * 2 + 1, ADC_SampleTime_3Cycles);
ADC_RegularChannelConfig(ADC1, ADC_BUCK1_CHANNEL, i * 2 + 2, ADC_SampleTime_3Cycles);
ADC_RegularChannelConfig(ADC2, ADC_BUCK2_CHANNEL, i * 2 + 1, ADC_SampleTime_3Cycles);
ADC_RegularChannelConfig(ADC2, ADC_BUCK3_CHANNEL, i * 2 + 2, ADC_SampleTime_3Cycles);
}
ADC_Cmd(ADC1, ENABLE);
ADC_DMACmd(ADC1, ENABLE);
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
ADC_Cmd(ADC2, ENABLE);
ADC_DMACmd(ADC2, ENABLE);
ADC_DMARequestAfterLastTransferCmd(ADC2, ENABLE);
MEA_StartConv();
while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC ==RESET));
while(ADC_GetFlagStatus(ADC2,ADC_FLAG_EOC ==RESET));
}
/*******************************************************************
均值处理
***************************************************************/
void MEA_CalcAvg(uint16_t buf[16], uint16_t* ji_shu, uint16_t* ou_shu)
{
uint16_t i, j, p, tmp;
for(i = 0; i<4; ++i){
p = i;
for(j = p+2; j<16; j+=2){
if(buf[j] > buf[p])
p = j;
}
tmp = buf;
buf = buf[p];
buf[p] = tmp;
}
for(i = 4; i<8; ++i){
p = i;
for(j = p+2; j<16; j+=2){
if(buf[j] < buf[p])
p = j;
}
tmp = buf;
buf = buf[p];
buf[p] = tmp;
}
tmp = 0;
// buf[9],[11],[13],[15]
for(i = 9; i<16; i+=2){
tmp += buf;
}
*ji_shu = (tmp+2)/4;//鍔�2闄や互4锛屽洓鑸嶄簲鍏�
tmp = 0;
// buf[8],[10],[12],[14]
for(i = 8; i<16; i+=2){
tmp += buf;
}
*ou_shu = (tmp+2)/4;
}
/*******************************************************************
***************************************************************/
static int ADC_ConvDoneFlag = 0;
void MEA_ADC1_DMA_IRQHandler()
{
if(DMA_GetITStatus(MEA_ADC1_DMA_STREAM, MEA_ADC1_DMA_IT_TCIF)){ //濡傛灉DMA_ADC1鏁版嵁娴佷紶杈撲腑鏂?畬鎴�
DMA_ClearITPendingBit(MEA_ADC1_DMA_STREAM, MEA_ADC1_DMA_IT_TCIF); //娓呴櫎涓?柇鏍囧織浣�//ADC1閲囨牱鍊煎彇骞冲潎锛屽瓨鍌ㄧ粨鍒癕EA_Result[0],MEA_Result[3]
}
ADC_ConvDoneFlag |= 1;
if(ADC_ConvDoneFlag == 0x03){
MEA_CalcAvg(ADC1_Buf, &ADC_IP[0], &ADC_BUCK[1]);
ADC_ConvDoneFlag = 0;
// LED3 = !LED3;
}
}
void MEA_ADC2_DMA_IRQHandler()
{
if(DMA_GetITStatus(MEA_ADC2_DMA_STREAM, MEA_ADC2_DMA_IT_TCIF)){
DMA_ClearITPendingBit(MEA_ADC2_DMA_STREAM, MEA_ADC2_DMA_IT_TCIF);
}
ADC_ConvDoneFlag |= 2;
if(ADC_ConvDoneFlag == 0x03){
MEA_CalcAvg(ADC2_Buf, &ADC_BUCK[2], &ADC_BUCK[3]);
ADC_ConvDoneFlag = 0;
// LED3 = !LED3;
}
}
float Get_ADC_IP(void)
{
return ADC_IP[0];
}
float Get_ADC_BUCK(int Channel)
{
assert_param(Channel >= 0 && Channel < 4);
return ADC_BUCK[Channel]*MEA_CONV_RATIO[Channel];
}
void MEA_StartConv(void)
{
ADC_SoftwareStartConv(ADC1);
ADC_SoftwareStartConv(ADC2);
ADC_SoftwareStartConv(ADC3);
}
ADC中定义的参数:
/*
* ADC.h
*
*
*/
#ifndef ADC_H_
#define ADC_H_
#include "stm32f4xx.h"
//////////////////////////////////////////////////////////////////////////////////
#define TIM_ADC_GPIO_INIT_CLK RCC_APB1PeriphClockCmd
#define ADC_IP_GPIO_CLK RCC_AHB1Periph_GPIOA
#define ADC_IP_GPIO GPIOA
#define ADC_IP_Pin GPIO_Pin_0
#define ADC_IP_CHANNEL ADC_Channel_0
#define ADC_IP_INDEX 0
#define ADC_IP_CONV_RATIO 20*(3.3/4095)
#define ADC_BUCK1_GPIO_CLK RCC_AHB1Periph_GPIOA
#define ADC_BUCK1_GPIO GPIOA
#define ADC_BUCK1_Pin GPIO_Pin_1
#define ADC_BUCK1_CHANNEL ADC_Channel_1
#define ADC_BUCK1_INDEX 1
#define ADC_BUCK1_CONV_RATIO (3.3/4095)
#define ADC_BUCK2_GPIO_CLK RCC_AHB1Periph_GPIOA
#define ADC_BUCK2_GPIO GPIOA
#define ADC_BUCK2_Pin GPIO_Pin_2
#define ADC_BUCK2_CHANNEL ADC_Channel_2
#define ADC_BUCK2_INDEX 2
#define ADC_BUCK2_CONV_RATIO (3.3/4095)
#define ADC_BUCK3_GPIO_CLK RCC_AHB1Periph_GPIOA
#define ADC_BUCK3_GPIO GPIOA
#define ADC_BUCK3_Pin GPIO_Pin_3
#define ADC_BUCK3_CHANNEL ADC_Channel_3
#define ADC_BUCK3_INDEX 3
#define ADC_BUCK3_CONV_RATIO (3.3/4095)
#define MEA_ADC1_DMA_STREAM DMA2_Stream0
#define MEA_ADC1_DMA_CHANNEL DMA_Channel_0
#define MEA_ADC1_DMA_IRQChannel DMA2_Stream0_IRQn
#define MEA_ADC1_DMA_IRQHandler DMA2_Stream0_IRQHandler
#define MEA_ADC1_DMA_IT_TCIF DMA_IT_TCIF0
#define MEA_ADC2_DMA_STREAM DMA2_Stream2
#define MEA_ADC2_DMA_CHANNEL DMA_Channel_1
#define MEA_ADC2_DMA_IRQChannel DMA2_Stream2_IRQn
#define MEA_ADC2_DMA_IRQHandler DMA2_Stream2_IRQHandler
#define MEA_ADC2_DMA_IT_TCIF DMA_IT_TCIF2
2 2个adc采集4个通道么?不知道线路的样子;
3 adc通过dma采集,先看下adc的测量点的电压,用万用表量下是否为0呢?排查硬件线路;
4 之后再通过断点查看下adc开启转换后,adc-> DR寄存器是否有变化,对应的4096/3.3v的关系,看下转换出来是多少v;
5 最后再查看dma采集;
个人小建议;
一周热门 更多>