你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

查看: 7863|回复: 14

定时器触发4路ADC采样,并使用DMA传输 求找问题

[复制链接]

1

主题

3

回帖

0

蝴蝶豆

新手上路

最后登录
2015-6-8
发表于 2015-5-14 12:34:04 | 显示全部楼层 |阅读模式
本帖最后由 汪文龙 于 2015-5-14 12:50 编辑

想使用ADC进行4路采样,并将采样值由DMA存储在一个数组中。因为采样时间有将近1分钟,如果让ADC不停地采样,最终获得的数据量大的不行。所以决定用定时器触发ADC的方式,每0.5秒采样一次,1分钟的话,采样120次,共480个数据。
但是配置良久,ADC一直不工作,我真不知道怎么办了,所以在此求助大神。


请大家看看我下面的程序有什么问题,并给一点建议。




再者,小弟有几个问题,望前辈解惑。
1.多路ADC   是不是ADC每完成一路的转换,DMA就帮忙传送一次。
2.DMA_BufferSize ,好多地方都说这个是DMA缓冲大小,请问下这个有什么用,我的是四路ADC,所以我这里设置的是4,不知道是不是对的。




ADC+DMA程序段


#include "adc.h"
#include "led.h"
#include "stm32f4xx_adc.h"
#include "stm32f4xx_dma.h"
#include "stm32f4xx_gpio.h"

#define ADC3_DR_ADDRESS     ((uint32_t)0x4001224C)
extern int uhADC3ConvertedValue[504];

//------------------------------------------------------------------------------
//ADC3+DMA配置
//------------------------------------------------------------------------------
void ADC3_CH13_DMA_Config(void)
{
ADC_InitTypeDef        ADC_InitStructure;
ADC_CommonInitTypeDef  ADC_CommonInitStructure;
DMA_InitTypeDef       DMA_InitStructure;
GPIO_InitTypeDef      GPIO_InitStructure;
NVIC_InitTypeDef   NVIC_InitStructure;

//打开ADC3,DMA2,GPIO时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);

//配置DMA
DMA_DeInit(DMA2_Stream0);

DMA_InitStructure.DMA_Channel = DMA_Channel_2;  
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC3_DR_ADDRESS;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)uhADC3ConvertedValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = 4;
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_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;   

DMA_Init(DMA2_Stream0, &DMA_InitStructure);
DMA_Cmd(DMA2_Stream0, ENABLE);

//初始化采样端口
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_5 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
  


//配置ADC
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_Rising;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T5_CC1;           //设置为TIM5_CC1触发
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 4;
ADC_Init(ADC3, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC3, ADC_Channel_10, 1, ADC_SampleTime_3Cycles);
ADC_RegularChannelConfig(ADC3, ADC_Channel_11, 2, ADC_SampleTime_3Cycles);
ADC_RegularChannelConfig(ADC3, ADC_Channel_12, 3, ADC_SampleTime_3Cycles);
ADC_RegularChannelConfig(ADC3, ADC_Channel_13, 4, ADC_SampleTime_3Cycles);

ADC_DMACmd(ADC3, ENABLE);
ADC_Cmd(ADC3, ENABLE);

ADC_ITConfig(ADC3,ADC_IT_EOC,ENABLE);

NVIC_InitStructure.NVIC_IRQChannel  =ADC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//先占优先级0
NVIC_InitStructure.NVIC_IRQChannelSubPriority   = 0;   //从优先级0
NVIC_InitStructure.NVIC_IRQChannelCmd   = ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

void ADC_IRQHangler(void)         //程序调试
{
if(ADC_GetITStatus(ADC3,ADC_FLAG_EOC)==SET) //溢出中断
{
  if(IS_LED2_ON==1)
  {
   LED2_OFF;
  }
  else
  {
   LED2_ON;
  }
}
ADC_ClearITPendingBit(ADC3,ADC_FLAG_EOC);  //清除中断标志位

}



定时器TIM5程序段


#include "timer3.h"
#include "led.h"
#include "stm32f4xx_tim.h"


void TIM5_Int_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_OCInitTypeDef  TIM_OCInitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);

TIM_TimeBaseInitStructure.TIM_Period=4200-1;
TIM_TimeBaseInitStructure.TIM_Prescaler=10000-1;
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Down;
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;

TIM_TimeBaseInit(TIM5,&TIM_TimeBaseInitStructure);
  
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse=0x7F;
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;

TIM_OC1Init(TIM5,&TIM_OCInitStructure);
TIM_Cmd(TIM5,ENABLE);
TIM_ITConfig(TIM5,TIM_IT_CC1,ENABLE);
TIM_CtrlPWMOutputs(TIM5, ENABLE);


}


main函数:
int main(void)
{

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
GPIO_Switch_Init();
LED_Init();

TIM3_Int_Init();


LCD_Init();           //LCD初始化
LCD_LayerInit();        //LCD层次显示初始化  
  
LTDC_Cmd(ENABLE);        //打开LTDC
  
LCD_GUIDisplay();

TIM2_Int_Init();

ADC3_CH13_DMA_Config();    //配置ADC3
TIM5_Int_Init();


while(1)
{   

}
}




回复

使用道具 举报

26

主题

178

回帖

0

蝴蝶豆

金牌会员

最后登录
2020-6-11
发表于 2015-5-14 12:45:00 | 显示全部楼层
玩得真高端,  还没玩会串口的飘过
回复 支持 反对

使用道具 举报

12

主题

1347

回帖

0

蝴蝶豆

金牌会员

最后登录
2020-9-2
发表于 2015-5-14 13:32:55 | 显示全部楼层
ddddd.png
回复 支持 反对

使用道具 举报

12

主题

1347

回帖

0

蝴蝶豆

金牌会员

最后登录
2020-9-2
发表于 2015-5-14 13:33:47 | 显示全部楼层
我的帖子里有一篇讲AD的,纯属个人见解。
回复 支持 反对

使用道具 举报

33

主题

1243

回帖

0

蝴蝶豆

论坛元老

最后登录
2019-3-9
发表于 2015-5-14 13:45:51 | 显示全部楼层
没有选择ADC的时钟,RCC_ADCCLKConfig();
没有开启ADC转换,ADC_StartConversion();
回复 支持 反对

使用道具 举报

1

主题

3

回帖

0

蝴蝶豆

新手上路

最后登录
2015-6-8
 楼主| 发表于 2015-5-14 15:05:35 | 显示全部楼层
Winddddd 发表于 2015-5-14 13:45
没有选择ADC的时钟,RCC_ADCCLKConfig();
没有开启ADC转换,ADC_StartConversion();

您好,我上面有使能ADC时钟呀
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);
下面这句应该就是启动啊ADC的吧。
ADC_Cmd(ADC3, ENABLE);

朋友你说的两个函数我的库里面貌似都没有,我用的是STM32F428ZI的芯片
回复 支持 反对

使用道具 举报

1

主题

3

回帖

0

蝴蝶豆

新手上路

最后登录
2015-6-8
 楼主| 发表于 2015-5-14 15:06:58 | 显示全部楼层
回复 支持 反对

使用道具 举报

134

主题

4489

回帖

239

蝴蝶豆

版主

最后登录
2020-12-9
发表于 2015-5-14 15:38:22 | 显示全部楼层
DMA可以,设置为采集4路的倍数,比如采集十次,就改为40,数组定义不能小于40.
DMA缓冲区满了以后会触发一次中断,这个时候处理就可以了。
回复 支持 反对

使用道具 举报

33

主题

1243

回帖

0

蝴蝶豆

论坛元老

最后登录
2019-3-9
发表于 2015-5-14 15:49:35 | 显示全部楼层
汪文龙 发表于 2015-5-14 15:05
您好,我上面有使能ADC时钟呀
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);
下面这句应该就是 ...

库不一样吧,仔细看下你的库,最好能有库函数说明用户手册,看是不是漏掉了什么
回复 支持 反对

使用道具 举报

21

主题

80

回帖

2

蝴蝶豆

中级会员

最后登录
2020-7-19
发表于 2015-5-14 16:01:44 | 显示全部楼层
你的adc是独立模式,要想用定时器触发采样,应该设置成注入模式,此外中断源为定时器中断,属于内部中断。
回复 支持 反对

使用道具 举报

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版