微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > STM32的ADC DMA USART综合学习

STM32的ADC DMA USART综合学习

时间:12-02 来源:互联网 点击:

aSize_HalfWord;

DMA_InitStructure.DMA_Mode=DMA_Mode_Circular;

//循环模式开启,Buf写满后,自动回到初始地址开始传输

DMA_InitStructure.DMA_Priority=DMA_Priority_High;//优先级高

DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;

ADC配置:

//ADC配置

ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;//独立转换模式

ADC_InitStructure.ADC_ScanConvMode=ENABLE;//开启扫描模式

ADC_InitStructure.ADC_ContinuousConvMode=ENABLE;//开启连续转换模式

ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//ADC外部开关,关闭状态

ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//对齐方式,右对齐方式

ADC_InitStructure.ADC_NbrOfChannel=4;//开启通道数,4个

ADC_Init(ADC1,&ADC_InitStructure);//初始化ADC

ADC_RegularChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_55Cycles5);

ADC_RegularChannelConfig(ADC1,ADC_Channel_11,2,ADC_SampleTime_55Cycles5);

ADC_RegularChannelConfig(ADC1, ADC_Channel_12,3,ADC_SampleTime_55Cycles5);

ADC_RegularChannelConfig(ADC1,ADC_Channel_13,4,ADC_SampleTime_55Cycles5);;

//ADC通道组,第10、11、12、13个通道,采样顺序分别是1,2,3,4转换时间55.5个周期

ADC_DMACmd(ADC1, ENABLE);//使能ADC1模块DMA

ADC_Cmd(ADC1, ENABLE);//打开ADC1

ADC_ResetCalibration(ADC1);//重置ADC1校准寄存器

while(ADC_GetResetCalibrationStatus(ADC1));//等待ADC1校准重置完成

ADC_StartCalibration(ADC1);//开始ADC1校准

while(ADC_GetCalibrationStatus(ADC1));//等待ADC1校准完成

ADC_SoftwareStartConvCmd(ADC1,ENABLE);//使能ADC1软件开始转换

中断是采用DMA中断,当DMA第一轮传输结束时,设一个标志位,当标志位为1时,表明第一轮转化和传输完成,此时就可以读取数组中的数据,经过处理就可以通过串口显示出来。

void DMAChannel1_IRQHandler(void)

{

ADC_DMA_OK=1;

DMA_ClearITPendingBit(DMA1_IT_TC1);

}中断函数。

第二个任务大概就这样子。

第三个任务:AD以DMA方式采集一路,DMA深度为一级。

这个任务不难,关键要理解到DMA深度,用自己的语言来理解哈DMA深度吧,当ADC以一路采集时,ADC转换完成就自动把转换结果通过DMA传给目的地址,如果传输一次结束DMA就产生中断的话,DMA的深度就为一级,如果连续传输N次,DMA的深度就位N级,当然这个N是又范围的,因为受目的地址的内存大小控制和数据宽度,这个大家应该豆明白的。

这个任务在第一个任务的基础上我通过DMA传输,意思是AD配置没什么区别。DMA配置和第二个任务的区别就是DMA_BufferSize的宽度不同。

#defineDR_ADDRESS(u32)0x4001244cADC的地址

#defineDMA_Count1DMA深度,也就是连续传输的次数

#defineADC_Channle1ADC通道

数据处理和串口通讯这里不重复叙述。DMA中断和任务二的类似。

第四个任务:AD以DMA方式采集四路,每路DMA深度为128级,并滤波,说明滤波原理。

这个任务和是个综合性任务,只要弄懂前面三个任务,难点是再如何滤波,开始的时候我也不知道怎么滤波,同事提醒我才知道怎么滤波的,我大概说哈我的理解,把四路通道采集的数据分别放到四个数组中,然后给他来个排序,降序,升序都行,把首位两个数丢掉,然后加起来求平均值。但是我这里因为DMA的深度为128级,也就是四个通道分别采样了128次,大家都知道,数据越多,求平均值就越准确,所以我就没有采用什么排序法了,直接给他们分别求平均值,具体如下:

#defineDR_ADDRESS(u32)0x4001244cADC的地址

#defineDMA_Count128DMA深度,也就是连续传输的次数

#defineADC_Channle4ADC通道

for(i=0;i<(ADC_Channle*DMA_Count);i+=4)

{

Value1[j]=Buf[i+0];

Sum1+=Value1[j];

Value2[j]=Buf[i+1];

Sum2+=Value2[j];

Value3[j]=Buf[i+2];

Sum3+=Value3[j];

Value4[j]=Buf[i+3];

Sum4+=Value4[j];

j++;

}

Valu1=Sum1/DMA_Count;

Valu2=Sum2/DMA_Count;

Valu3=Sum3/DMA_Count;

Valu4=Sum4/DMA_Count;

Delay(100000);

printf("\r\n当前AD_0值:0x%x,电压值:%d.%d%dV\n\r",

Valu1,((Valu1*100/4096)*33)/1000,((Valu1*100/4096)*33)%1000/100,((Valu1*100/4096)*33)%100/10);

Delay(100000);

printf("\r\n当前AD_1值:0x%x,电压值:%d.%d%dV\n\r",

Valu2,((Valu2*100/4096)*33)/1000,((Valu2*100/4096)*33)%1000/100,((Valu2*100/4096)*33)%100/10);

Delay(100000);

printf("\r\n当前AD_2值:0x%x,电压值:%d.%d%dV\n\r",

Valu3,((Valu3*100/4096)*33)/1000,((Valu3*100/4096)*33

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top