STM32标准库ADC定时器触发-DMA转运

更新

后续在实验过程中发现ADC采集的数据很多时候都是不准的,分析发现原因是当我想要在ADC_BUFFER中进行取平均求值的时候,ADC_BUFFER中的数据仍在进行转换,这样在测量动态数据的时候ADC取平均返回的数据就不准了,解决办法是在要取ADC值之前关闭DMA传输,取值后再开启DMA传输。

引言

最近想用在单片机上实现DFT并在屏幕上显示波形,之前的想法是定时器中断计时,软件触发ADC,采集到一定数量的点数后计算一次DFT,然后在屏幕上画出波形,由于DFT需要的采样点数比波形的点数少,结果发现在DFT点数之后会丢失十几个数据,认为是DFT的计算时间太长了,在DFT计算过程中的这段数据就没法进行软件触发采样而导致丢失。
因此想直接用定时器触发ADC-DMA模式,这样所有的AD转换过程都不用通过CPU,就不存在因DFT计算时间长导致采样不连续的问题了。

一、定时器设置

定时器采用TIM3,同时开启中断和更新时间触发。中断是用来计时的,这里我的采样频率是1kHz,中断是1ms触发一次

u16 ms = 0;				//ms计时

void TIM3_Init(u16 arr,u16 psc)
{
	TIM_TimeBaseInitTypeDef Tim3;
	NVIC_InitTypeDef NVIC_Tim;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3 ,ENABLE);
	Tim3.TIM_Period = arr;
	Tim3.TIM_CounterMode = TIM_CounterMode_Up ;
	Tim3.TIM_Prescaler = psc;
	Tim3.TIM_ClockDivision = TIM_CKD_DIV1 ;
	TIM_TimeBaseInit(TIM3,&Tim3);
		
	TIM_ITConfig(TIM3,TIM_IT_Update ,ENABLE );//允许更新中断
	
	NVIC_Tim .NVIC_IRQChannel = TIM3_IRQn ;
	NVIC_Tim .NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_Tim .NVIC_IRQChannelSubPriority = 0;
	NVIC_Tim .NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_Tim);
	
	TIM_SelectOutputTrigger(TIM3,TIM_TRGOSource_Update);//配合ADC用Tim3TRGO触发
	
	TIM_Cmd(TIM3,ENABLE);
	
}

//中断函数
void TIM3_IRQHandler(void)   //TIM3中断
{
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
		{
			TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx更新中断标志
			ms++;
		}
}

二、DMA设置

因为ADC是定时器连续转换,DMA应该设置成循环模式,从外设到内存,内存地址自增,外设地址不自增
通过查看stm32F4的数据手册可以看到ADC都在DMA2上,这里我用的是ADC1,有

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值