求助STM32F051 ADC出来的分类汇总数据复制出来一直为0

查看: 1211|回复: 8
ADC DMA USART为何输出全是0呢?
主题帖子精华
初级会员, 积分 54, 距离下一级还需 146 积分
在线时间0 小时
各位师兄师姐,这个问题我想了一个星期了,还是解决不了。采样得到的AD值一直是0.代码如下:
& & &adc.c&,&main.c&
#include "adc.h"
#include "delay.h"
#include "stm32f10x_flash.h"
#include "stm32f10x_dma.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
//#include "includes.h"
//初始化ADC
#define ADC1_DR_Address & &((u32)0x4001244C)
vu16 AD_Value[N][M]; //用来存放ADC转换结果,也是DMA的目标地址 ,N=50,M=16
vu16 After_filter[M]; //用来存放求平均值之后的结果
void RCC_Configuration(void) //我使用的是stm32f107vct6,采样外部25M晶振,所以需配置一下RCC。
ErrorStatus HSEStartUpS
RCC_DeInit(); //RCC 系统复位
RCC_HSEConfig(RCC_HSE_ON); //开启HSE, 外部高速晶振。
HSEStartUpStatus = RCC_WaitForHSEStartUp(); //等待HSE准备好
if(HSEStartUpStatus == SUCCESS)
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //Enable Prefetch Buffer
FLASH_SetLatency(FLASH_Latency_2); //Set 2 Latency cycles
RCC_HCLKConfig(RCC_SYSCLK_Div1); //AHB clock = SYSCLK &,把系统时钟设置为72MHz
RCC_PCLK2Config(RCC_HCLK_Div1); //APB2 clock = HCLK
& ,不能超过72M
RCC_PCLK1Config(RCC_HCLK_Div2); //APB1 clock = HCLK/2 &,不能超过36M
// Configure PLLs 由于外部晶振HSE=25M,与8M不同,STM32F10X_CL中有PLL和PLL2两个,所以可以配置成为72M/
& &// PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz&
& &RCC_PREDIV2Config(RCC_PREDIV2_Div5);
& &RCC_PLL2Config(RCC_PLL2Mul_8);
& &/* Enable PLL2 */
& &RCC_PLL2Cmd(ENABLE);
& &/* Wait till PLL2 is ready */
& &while (RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET)
& &/* PLL configuration: PLLCLK = (PLL2 / 5) * 9 = 72 MHz */&
& &RCC_PREDIV1Config(RCC_PREDIV1_Source_PLL2, RCC_PREDIV1_Div5);
& &RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_9); //PLLCLK = 8MHz * 9 = 72 MHz
RCC_PLL3Config(RCC_PLL3Mul_11);
RCC_PLL3Cmd(ENABLE);
while(RCC_GetFlagStatus(RCC_FLAG_PLL3RDY)== RESET)
& &RCC_I2S3CLKConfig(RCC_I2S3CLKSource_PLL3_VCO);
& &RCC_I2S2CLKConfig(RCC_I2S2CLKSource_PLL3_VCO);&
RCC_PLLCmd(ENABLE); //Enable PLL
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //Wait till PLL is ready
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //Select PLL as system clock source
while(RCC_GetSYSCLKSource() != 0x08); //Wait till PLL is used as system clock source
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB
| RCC_APB2Periph_GPIOC |RCC_APB2Periph_ADC1 | RCC_APB2Periph_AFIO |RCC_APB2Periph_USART1, ENABLE ); //使能ADC1通道时钟,各个管脚时钟
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //72M/6=12M,ADC最大时间不能超过14M
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA传输
void GPIO_Configuration(void)
GPIO_InitTypeDef GPIO_InitS
//PA0到PA7 作为模拟通道输入引脚
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOC, ENABLE);
& & & & & & & & & & & &&
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0| GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4| GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
//模拟输入引脚
GPIO_Init(GPIOA, &GPIO_InitStructure);
//PB0、PB1作为模拟通道输入引脚 & & & & & & & & & & & &&
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0| GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
//模拟输入引脚
GPIO_Init(GPIOB, &GPIO_InitStructure);
//PC0到PC5 作为模拟通道输入引脚 & & & & & & & & & & & &&
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0| GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4| GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
//模拟输入引脚
GPIO_Init(GPIOC, &GPIO_InitStructure);
void ADC1_Configuration(void)
ADC_InitTypeDef ADC_InitS
NVIC_InitTypeDef NVIC_InitS
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1 , ENABLE );
&//使能ADC1通道时钟
// RCC_ADCCLKConfig(RCC_PCLK2_Div8); //72M/8=9M,ADC最大时间不能超过14M 已在RCC中定义
ADC_DeInit(ADC1); //将外设 ADC1 的全部寄存器重设为缺省值
ADC_InitStructure.ADC_Mode = ADC_Mode_I //ADC工作模式:ADC1和ADC2工作在独立模式
ADC_InitStructure.ADC_ScanConvMode =ENABLE; //模数转换工作在扫描模式
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //模数转换工作在连续转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_N //外部触发转换关闭
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_R //ADC数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = M; //顺序进行规则转换的ADC通道的数目
ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
// & //ADC NVIC 配置,使用DMA后不需要AD中断 &
// &NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
// NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//抢占优先级0
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
//子优先级1
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//IRQ通道使能
// NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
//设置指定ADC的规则组通道,设置它们的转化顺序和采样时间
//ADC1,ADC通道x,规则采样顺序值为y,采样时间为239.5周期
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 5, ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 6, ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 7, ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 8, ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 9, ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 10, ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 11, ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 12, ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 13, ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 14, ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 15, ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 16, ADC_SampleTime_239Cycles5 );
// 开启ADC的DMA支持(要实现DMA功能,还需独立配置DMA通道等参数)
ADC_DMACmd(ADC1, ENABLE);
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);//主函数中
void DMA_Configuration(void)
// RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA传输
DMA_InitTypeDef DMA_InitS
DMA_DeInit(DMA1_Channel1); //将DMA的通道1寄存器重设为缺省值
// DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1-&DR; //DMA外设ADC基地址
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_A //DMA外设ADC基地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)AD_V //DMA内存基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //内存作为数据传输的目的地
DMA_InitStructure.DMA_BufferSize = N*M; //DMA通道的DMA缓存的大小,N*M=50*16
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_D //外设地址寄存器不变
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_E //内存地址寄存器递增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfW //数据宽度为16位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfW //数据宽度为16位
DMA_InitStructure.DMA_Mode = DMA_Mode_C //工作在循环缓存模式
DMA_InitStructure.DMA_Priority = DMA_Priority_H //DMA通道1拥有高优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_D //DMA通道x没有设置为内存到内存传输
DMA_Init(DMA1_Channel1, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道
// DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE); //新加
DMA_Cmd(DMA1_Channel1, ENABLE); //启动DMA通道,主函数中
void Init_All_Periph(void)
RCC_Configuration();
GPIO_Configuration();
ADC1_Configuration();
DMA_Configuration();
//得到电压值
u16 GetVolt(u16 advalue)
return (u16)(advalue * 330/ 4096); //求的结果扩大100倍,方便下面求出小数。
//求平均值
void filter(void) &
int sum = 0;
for(i=0;i&M;i++)
for ( count=0;count&N;count++) //N=50
sum += AD_Value[count]; //AD_Value[N][M]用来存放ADC转换结果,也是DMA的目标地址
After_filter=sum/N;
& //用来存放求平均值之后的结果
int main()
u16 value[M];
void Init_All_Periph(void);
delay_init();
//延时函数初始化,需修改,外部晶振为25M,不是8M
uart_init(9600);
//串口初始化为9600,usart.c中是关于串口1的初始化。
LED_Init();
// DMA_Cmd(DMA1_Channel1, ENABLE); //启动DMA通道
// ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);//等待传输完成否则第一位数据容易丢失
//求采集50次AD后的平均值
for(i=0;i&M;i++)
value= GetVolt(After_filter); //得到的电压值
printf("\r\n The current value[%d] = \t%d.%dv\n",i,value/100,value%100);&
printf("\r\n The current After_filter[%d] = 0x%04X \r\n",i, After_filter);
delay_ms(100);
这个问题已经解决啦,是时钟配置问题。我把时钟配置独立写到一个.c文件中。每次用到就调用。
主题帖子精华
初级会员, 积分 54, 距离下一级还需 146 积分
在线时间0 小时
这个问题已经解决啦,是时钟配置问题。我把时钟配置独立写到一个.c文件中。每次用到就调用。
主题帖子精华
初级会员, 积分 54, 距离下一级还需 146 积分
在线时间0 小时
有木有人呢,跪求,跪求
主题帖子精华
在线时间837 小时
高人也帮不了太多,
三个物理过程,架仿真器逐步跟踪吧,保证每个环节都正确。
做到这一步,最后串起来就会正确。
主题帖子精华
初级会员, 积分 54, 距离下一级还需 146 积分
在线时间0 小时
回复【3楼】xuande:
--------------------------------
您好,我用别的开发板的一个例程试了下,没有用DMA,可以用。这样说明AD采集是正常的,但是用DMA传输的话,就不行了。这是什么原因呢?DMA传输过来的数据一直是0.我用的外部晶振是25M,可是我上面的RCC也配置好了啊,不知道这种情况大概是什么原因呢?
主题帖子精华
在线时间837 小时
这件事分了三个步骤,别想一下子搞定,高手也不会很顺利。
必须每个步骤都搞清楚。
主题帖子精华
高级会员, 积分 510, 距离下一级还需 490 积分
在线时间69 小时
DMA中第一句不能注释掉,位置要这样
DMA_InitTypeDef&DMA_InitS
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,&ENABLE); //使能DMA外设时钟
主题帖子精华
初级会员, 积分 54, 距离下一级还需 146 积分
在线时间0 小时
回复【6楼】zc123:
---------------------------------
非常感谢。不过,DMA中注释的第一句在RCC中已经写了啊,就是最后一句,那样不行吗?
主题帖子精华
初级会员, 积分 69, 距离下一级还需 131 积分
在线时间167 小时
这个问题已经解决啦,是时钟配置问题。我把时钟配置独立写到一个.c文件中。每次用到就调用。
不太懂这个解决方法,?楼主能详细说明下么
Powered by21ic官方微信-->
后使用快捷导航没有帐号?
请完成以下验证码
查看: 906|回复: 1
STM32F051 多通道AD读取不正常
&&未结帖(20)
主题帖子积分
实习生, 积分 24, 距离下一级还需 26 积分
实习生, 积分 24, 距离下一级还需 26 积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
实习生, 积分 24, 距离下一级还需 26 积分
实习生, 积分 24, 距离下一级还需 26 积分
大家帮我看看& &小弟我单独设置一路AD通道&&读取的值是OK的,&&但是我多添加几路AD后,读取的AD值就不停的跳变& &是不是我读取的方法有问题& &请大家帮我指正一下& &谢谢!
#include &ADC.h&
__IO uint16_t ADC1ConvertedValue1 = 0,ADC1ConvertedValue2 = 0,
& & & & & & & & & & & & & & & & & & & & & & & & & & & & ADC1ConvertedValue3 = 0,ADC1ConvertedValue4 = 0,
& & & & & & & & & & & & & & & & & & & & & & & & & & & & ADC1ConvertedValue5 = 0;
void Get_ADC_Data(void)
& & & & static __IO uint16_
& & & & uint16_
& & & & if(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) != RESET)
& & & & {& & & & & & & & temp= ADC_GetConversionValue(ADC1);
& & & & & & & &
& & & & & & & & & & & & if((++count)&5)
& & & & & & & & & & & & & & & & count=1;
& & & & & & & & & & & & switch(count)
& & & & & & & & & & & & {& & & & case 1:
& & & & & & & & & & & & & & & & & & & & ADC1ConvertedValue1=
& & & & & & & & & & & & & & & && & & & & & & &
& & & & & & & & & & & & & & & & case 2:
& & & & & & & & & & & & & & & & & & & & ADC1ConvertedValue2=& & & & & & & & & & & &
& & & & & & & & & & & & & & & && & & &
& & & & & & & & & & & & & & & & case 3:
& & & & & & & & & & & & & & & & & & & & ADC1ConvertedValue3=
& & & & & & & & & & & & & & & && & & &
& & & & & & & & & & & & & & & & case 4:& & & &
& & & & & & & & & & & & & & & & & & & & ADC1ConvertedValue4=
& & & & & & & & & & & & & & & && & & & & & & & & & & &
& & & & & & & & & & & & & & & & case 5:& & & &
& & & & & & & & & & & & & & & & & & & & ADC1ConvertedValue5=
& & & & & & & & & & & & & & & && & & & & & & & & & & &
& & & & & & & & & & & & & & & & default:
& & & & & & & & & & & & & & & & & & & & ADC1ConvertedValue1=0;
& & & & & & & & & & & & & & & & & & & & ADC1ConvertedValue2=0;
& & & & & & & & & & & & & & & & & & & & ADC1ConvertedValue3=0;
& & & & & & & & & & & & & & & & & & & & ADC1ConvertedValue4=0;
& & & & & & & & & & & & & & & & & & & & ADC1ConvertedValue5=0;
& & & & & & & & & & & & & & & &
& & & & & & & & & & & & }
void ADC1_Config(void)
&&ADC_InitTypeDef& && && & ADC_InitS
&&GPIO_InitTypeDef& && && &GPIO_InitS
& & & & /* ADC1 Configuration *******************************************************/
&&/* ADCs DeInit */&&
&&ADC_DeInit(ADC1);
&&/* GPIOA Periph clock enable */
&&RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
&&/* ADC1 Periph clock enable */
&&RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
&&/* Configure ADC Channel_11 as analog input */
&&GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
&&GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
&&GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
&&GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Initialize ADC structure */
&&ADC_StructInit(&ADC_InitStructure);
&&/* Configure the ADC1 in continous mode withe a resolutuion equal to 12 bits*/
&&ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
&&ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
&&ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_N& &
&&ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_R
&&ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_U //?ò?°?¨?è&&0-18
&&ADC_Init(ADC1, &ADC_InitStructure);
&&/* Convert the ADC1 Channel 11 with 13.5 Cycles as sampling time */
&&ADC_ChannelConfig(ADC1, ADC_Channel_0, ADC_SampleTime_28_5Cycles);& &
& & & & ADC_ChannelConfig(ADC1, ADC_Channel_1, ADC_SampleTime_28_5Cycles);
& & & & ADC_ChannelConfig(ADC1, ADC_Channel_2, ADC_SampleTime_28_5Cycles);
& & & & ADC_ChannelConfig(ADC1, ADC_Channel_3, ADC_SampleTime_28_5Cycles);
&&ADC_ChannelConfig(ADC1, ADC_Channel_4, ADC_SampleTime_28_5Cycles);& &
&&/* ADC Calibration */
&&ADC_GetCalibrationFactor(ADC1);& & & & & & & & //adjust adc
&&/* Enable ADCperipheral[PerIdx] */
&&ADC_Cmd(ADC1, ENABLE);& &&&
&&/* Wait the ADCEN falg */
&&while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN));
&&/* ADC1 regular Software Start Conv */
&&ADC_StartOfConversion(ADC1);
主题帖子积分
主题帖子积分
专家等级:结帖率:95%打赏:6.66受赏:2010.00
主题帖子积分
你添加的几路AD实际电压有没有变化啊?
工程师是科学家,工程师是艺术家,工程师也是思想家。
时间类勋章
技术奇才奖章
人才类勋章
沉静之湖泊
发帖类勋章
突出贡献奖章
等级类勋章stm32 双adc 采集问题 dma数据有一个没有 adc2为0 - ARM单片机 - 电子工程世界网
stm32 双adc 采集问题 dma数据有一个没有 adc2为0
12:24:43来源: eefocus
配置那些就不说了,我这里是同步规则采样,共4通道:
/*&Regular&Channel&E&&O&A²&E¼&&E³Ð&&&I&E&¼&.&E&&O&A³&E&E&&&,dma&O&A32bit&&&E&,&&I16bit&E&Cadc1&I&&&A,&&16bit&E&Cadc2&I&&&A&*/&&
&&&&ADC_RegularChannelConfig(ADC1,&CH0_ADL1,&&&1,&ADC_SampleTime_13Cycles5);//0&&
&&&&ADC_RegularChannelConfig(ADC1,&CH1_ADL2,&&&&2,&ADC_SampleTime_13Cycles5);//&2&&
&&&&ADC_RegularChannelConfig(ADC1,&CH8_ADR1,&3,&ADC_SampleTime_13Cycles5);//&4&&
&&&&ADC_RegularChannelConfig(ADC1,&CH9_ADR2,&&&4,&ADC_SampleTime_13Cycles5);//6&&
&&&&/*&Regular&Channel&*/&&
ADC_RegularChannelConfig(ADC2,&CH9_ADR2,1,&ADC_SampleTime_13Cycles5);//&1&&
ADC_RegularChannelConfig(ADC2,&CH8_ADR1,&&2,&ADC_SampleTime_13Cycles5);//&3&&
&&&&ADC_RegularChannelConfig(ADC2,&CH1_ADL2,&&&&3,&ADC_SampleTime_13Cycles5);//5&&
&&&&ADC_RegularChannelConfig(ADC2,&CH0_ADL1,&4,&ADC_SampleTime_13Cycles5);//7&&
使用的是ac连续采样,dma连续搬运模式。注意点如下:
1、数组要定义为u32的,例如u32 buf[4],不要定义为u16 buf[8],经过测试,如果使用 u16 buf[8] 最后一个16bit buf[7]会为0,不知道为什么。
2、adc2有2种方式可以启动,一种是:
ADC_ExternalTrigConvCmd(ADC2,ENABLE); & /*adc2¹&&O&&I&&&A&I&²&&&&& */
另一种是:
ADC_SoftwareStartConvCmd(ADC2,ENABLE);
这2种方法会带来一个不同的结果,细分析如下:
如上所述转换序列,正常情况是buf32[0] & 0xFFFF与(buf32[3]>>0xFFFF)是同一组数据,拿buf16[8]来说就是buf16[0]、buf[7]是一组数据,可是改变adc2的触发方式有什么区别呢?
================使用buf16[8] +&ADC_SoftwareStartConvCmd(ADC2,ENABLE);方式===============
此组合可以得到正确的数组对应方式,即dma搬来的数据与我们预期的是对应的。但是buf16[7]=0
================使用buf16[8] +&ADC_ExternalTrigConvCmd(ADC2,ENABLE);方式===============
此组合不可以得到正确的数组对应方式,即dma搬来的数据与我们预期的是不对应的。而且buf16[7]=0
================使用buf32[4] +&ADC_SoftwareStartConvCmd(ADC2,ENABLE);方式===============
此组合不可以得到正确的数组对应方式,即dma搬来的数据与我们预期的是不对应的。
================使用buf32[4] +&ADC_ExternalTrigConvCmd(ADC2,ENABLE);方式===============
此组合可以得到正确的数组对应方式,即dma搬来的数据与我们预期的是对应的。
好,这就是我的调试心得,大家避免注意下就好了。
这里有一个单ADC同步规则+同步注入的例子:/html/itweb/22_.htm。
貌似单个ADC好用,两个的同步注入有问题????
===========继续补充================
之前的注入通道数据有问题,把他的采样率该慢点就可以了,视自己情况而定,慢慢调试吧!
关键字:&&&&&&
编辑:什么鱼 引用地址:
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。
微信扫一扫加关注 论坛活动 E手掌握
微信扫一扫加关注
芯片资讯 锐利解读
大学堂最新课程
汇总了TI汽车信息娱乐系统方案、优质音频解决方案、汽车娱乐系统和仪表盘参考设计相关的文档、视频等资源
热门资源推荐
频道白皮书
何立民专栏
北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。21ic官方微信-->
后使用快捷导航没有帐号?
ST MCU Finder
安装免费手机应用,
寻找理想的ST MCU
请完成以下验证码
查看: 2599|回复: 6
STM32F051 ADC单通道数据采集(中断方式实现)
&&已结帖(0)
主题帖子积分
资深技术员, 积分 342, 距离下一级还需 158 积分
资深技术员, 积分 342, 距离下一级还需 158 积分
主题帖子积分
专家等级:结帖率:94%
主题帖子积分
资深技术员, 积分 342, 距离下一级还需 158 积分
资深技术员, 积分 342, 距离下一级还需 158 积分
STM32F0 #02进程帖(三)---STM32F051 ADC单通道数据采集(中断方式实现)
&&按照正常的进度,应该是先把ADC方面的内容传上来的,后来因为采用DMA 中断方式-采集多通道数据时,出现了点小问题,一直没有解决好,后只有先放手去解决别的问题了。直到今天,终于解决了那个小问题,ADC数据采集方面的工作进度算是全部完成。
& & 由于本人以前采用LM系列ARM M3,对STM32不太熟悉,故利用此机会系统的实验了一下STM32的ADC模块。主要包括:
& &A--软件查询方式实现的ADC采集(单路)。
& &B--中断方式实现的ADC采集(单路)。
& &C--DMA软件查询方式实现的ADC采集(单路)。
& &D--DMA中断方式实现的ADC采集(多路)。
&&实验只是简单的测试一下,并没有进行滤波或只简单的进行了平均,如果用在项目中的话,需要实现更复杂的滤波算法才行(目前流行的滤波算法也有十几种吧)。个人感觉,相比较其他的M3/MO,STM32最大的特色就在于其12位ADC,高精度,高速度。对ADC模块整个STM32F0来说,目前的学习也仅是一点皮毛,只有后续不断的努力,才能更好的应用它。
&&下面上一个用ADC中断方式实现的采集进度图和部分代码。
【部分代码】
/*********************************Copyright (c)*********************************& && && && && && && && && && && && &&&
&&*& && && && && && && && && && && && && && && && && &
&&******************************************************************************
&&* 文件名称:ADC_51R8T6.C
&&* 描& & 述:ADC模块
&&* 创 建 者: fengye5340
&&* 创建日期: & &&&
&&* 修 改 者:& && && && &
&&* 修改日期: & &
&&* 版& & 本: v1.0.1
&&******************************************************************************
&&* attention
&&******************************************************************************
/*Includes --------------------------------------------------------------------*/
#include&&&stm32f0xx.h&
#include&&&stm32f0xx_it.h&
#include&&&stm32f0xx_adc.h&
#include&&&ADC_51R8T6.H&
#include&&&UART_51R8T6.H&
#include&&&TIMER_51R8T6.H&
/* 类型定义 typedef-----------------------------------------------------------*/
/* 预定义字符& &&&------------------------------------------------------------*/
/* 宏定义& && &&&-------------------------------------------------------------*/
/* 变量定义& && && & ---------------------------------------------------------*/
extern unsigned int&&Adc_val = 0;
extern float& && && &Ad_Val =0;
extern float& && && &Ad_Val_Averge={0.0};
/*******************************************************************************
* 函数名称: ADC_GPIO_Init();
* 功能描述: ADC--GPIO输入引脚配置---在此可以设置16路外部输入通道
********************************************************************************/
void ADC_GPIO_Init(void)
& &&&GPIO_InitTypeDef&&GPIO_InitS
& &&&RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);& &
& &&&GPIO_InitStructure.GPIO_Pin& &= GPIO_Pin_0 ;
& &&&GPIO_InitStructure.GPIO_Mode&&= GPIO_Mode_AN;
& &&&//GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
& &&&//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; // 做输入时不用设置速率
& &&&GPIO_InitStructure.GPIO_PuPd&&= GPIO_PuPd_NOPULL;
& &&&GPIO_Init(GPIOB, &GPIO_InitStructure);
/*******************************************************************************
* 函数名称:&&ADC_Reset()
* 功能描述:&&ADC模块初始化
********************************************************************************/
void ADC_Reset(void)
& &&&ADC_InitTypeDef&&ADC_InitS
& &&&RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);&&//使能ADC1通道时钟
& &&&ADC_DeInit(ADC1);&&//复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
& &&&ADC_StructInit(&ADC_InitStructure);
& &&&ADC_GPIO_Init(); //ADC-GPIO引脚初始化
& &&&/* 配置 ADC1 连续采集模式-12位精度 */
& &&&ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; //12位精度
& &&&ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;& &&&// 连续转换模式
& &&&ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_N //转换由软件而不是外部触发启动
& &&&ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_R //数据右对齐
& &&&ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_U //后前:0--18通道
& &&&ADC_Init(ADC1, &ADC_InitStructure);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
& & #if TEMP_TEST
& && &&&ADC_ChannelConfig(ADC1, ADC_Channel_TempSensor, ADC_SampleTime_55_5Cycles);
& && &/* 配置ADC1 温度传感器239.5 周期(&2.2us)采样时间
& && &1--ADC_SampleTime_1_5Cycles& && && && && && &&&
& && &2--ADC_SampleTime_7_5Cycles& && && && && && &&&
& && &3--ADC_SampleTime_13_5Cycles& && && && && && &
& && &4--ADC_SampleTime_28_5Cycles& && && && && &&&
& && &5--ADC_SampleTime_41_5Cycles& && && && && &
& && &6--ADC_SampleTime_55_5Cycles& && && && && && &
& && &7--ADC_SampleTime_71_5Cycles& && && && && &
& && &8--ADC_SampleTime_239_5Cycles
& && & ADC_TempSensorCmd(ENABLE); //使能内部温度传感器
& &#if VREF_TEST
& && & ADC_ChannelConfig(ADC1, ADC_Channel_Vrefint , ADC_SampleTime_55_5Cycles);
& && & ADC_VrefintCmd(ENABLE);
& &&&#endif
& &&&#if ADC_TEST
& && & ADC_ChannelConfig(ADC1, ADC_Channel_8 , ADC_SampleTime_55_5Cycles);
& &&&#endif
& &#if ADC_IPQ&&
& && && &ADC_ChannelConfig(ADC1, ADC_Channel_8 , ADC_SampleTime_239_5Cycles);
& && && &ADC_ITConfig(ADC1, ADC_IT_EOC,ENABLE);//开启ADC转换结束中断。
& &&&#endif
////////////////////////////////////////////////////////////////////////////////////////& &
& &&&ADC_GetCalibrationFactor(ADC1);& && &&&// 开始ADC校准
& &&&ADC_Cmd(ADC1, ENABLE);& && && && && & //&&使能指定的ADC1
& &&&while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN));& &/* 等待ADC准备好 */
& &&&ADC_StartOfConversion(ADC1); //开始温度转换;
/*******************************************************************************
* 函数名称:&&Temperature_Test()
* 功能描述:&&软件查询方式实现的内部温度传感器测试
********************************************************************************/
void Temperature_Test(void)
& &&&unsigned int&&Temperature = 0;
if(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) != RESET)
& & Delay_Ms(1000);
& &&&Temperature = ADC_GetConversionValue(ADC1);
& &&&Temperature= (1.42 - Temperature*3.3//4.35 + 25; //计算算法
& &&&printf(&The temperature = %d℃ \r\n&, Temperature);
/*******************************************************************************
* 函数名称:&&Vref_Test()
* 功能描述:&&内部参考电压采集测试---没有进行滤波算法处理
********************************************************************************/
void Vref_Test(void)
& &&&unsigned int&&Vref = 0;
& & float&&Vref_Value =0;
& &if(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) != RESET)
& &&&Delay_Ms(1000);
& && &Vref=ADC_GetConversionValue(ADC1);
& && &Vref_Value =(float)Vref/; //计算算法
& && &printf(&The Voltage = %f V \r\n&, Vref_Value);
主题帖子积分
资深技术员, 积分 342, 距离下一级还需 158 积分
资深技术员, 积分 342, 距离下一级还需 158 积分
主题帖子积分
专家等级:结帖率:94%
主题帖子积分
资深技术员, 积分 342, 距离下一级还需 158 积分
资深技术员, 积分 342, 距离下一级还需 158 积分
继续没发完的,唉,还有长度限制~~~[em:12:][em:12:][em:12:][em:12:][em:12:]
/*******************************************************************************
* 函数名称:&&ADC_Test()
* 功能描述:&&电压采集测试--没有进行滤波算法处理
********************************************************************************/
void ADC_Test(void)
& &&&unsigned int&&Adc_value = 0;
& &&&float& && &&&Ad_Value =0;
& && &if(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) != RESET)
& &&&Delay_Ms(1000);
& && &Adc_value =ADC_GetConversionValue(ADC1);
& && &Ad_Value =(float)Adc_value/; //计算算法
& && &Ad_Value = (1.2*Ad_Value)/1.36;& && &//精度误差补偿&&
& && &printf(&The Voltage = %f V \r\n&, Ad_Value);
//主程序--数据处理部分
& && &// 1--闪灯程序
& && && &// Led_Test();
& && && && && && && & // 2--DS18B20模块
& && &&&// DS18B20_Test();
& && && &//3-- ADC内部测温
& && && &#if&&TEMP_TEST
& && && && &&&Temperature_Test();
& && && &#endif
& && && &#if&&VREF_TEST
& && && && &Vref_Test();
& && & #endif
& && && &&&#if ADC_TEST
& && && && &&&ADC_Test();
& && && &&&#endif&&
& && && &&&#if ADC_IPQ
& && && && &&&printf(&当前电压是 %f V \r\n&, sum);
& && && &&&#endif&&
// 中断处理部分
extern unsigned int&&Adc_
extern float& && && &Ad_Val_A
extern float& && && &Ad_V
extern float& && && && &
extern void Delay(unsigned int ucout);
/*******************************************************************************
* 函数名称: ADC1_COMP_IRQHandler()
* 功能描述: ADC1中断处理函数
********************************************************************************/
void ADC1_COMP_IRQHandler(void)&&
& & if(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) != RESET)
& &&&Delay(50000);
& && &Adc_val =ADC_GetConversionValue(ADC1);
& && &Ad_Val =(float)Adc_val/; //计算算法
& && &Ad_Val = (1.2*Ad_Val)/1.36;& && &//精度误差补偿 --采集内部电压误差大,需进一步修正
& && && &Ad_Val_Averge = Ad_V
& && &if(index ==31)
& && && && && && &
& && & sum =0;
& && & for(i = 0; i & 32; i++)
& && && && && & sum += Ad_Val_A
& && && && &sum = sum/32;& && && && && && && && && &//除以32求平均值& &&&
& && && && &index = 0;
& && && &}
& && && &ADC_ClearFlag(ADC1, ADC_FLAG_EOC);
& && && &}
主题帖子积分
初级工程师, 积分 2374, 距离下一级还需 626 积分
初级工程师, 积分 2374, 距离下一级还需 626 积分
主题帖子积分
专家等级:结帖率:96%
主题帖子积分
初级工程师, 积分 2374, 距离下一级还需 626 积分
初级工程师, 积分 2374, 距离下一级还需 626 积分
顶贴.........
努力学习,积极回复,只为申请版主.......
主题帖子积分
中级技术员, 积分 153, 距离下一级还需 147 积分
中级技术员, 积分 153, 距离下一级还需 147 积分
主题帖子积分
专家等级:结帖率:66%
主题帖子积分
中级技术员, 积分 153, 距离下一级还需 147 积分
中级技术员, 积分 153, 距离下一级还需 147 积分
主题帖子积分
中级技术员, 积分 153, 距离下一级还需 147 积分
中级技术员, 积分 153, 距离下一级还需 147 积分
主题帖子积分
专家等级:结帖率:66%
主题帖子积分
中级技术员, 积分 153, 距离下一级还需 147 积分
中级技术员, 积分 153, 距离下一级还需 147 积分
最近也在用STM0的片子,好好学习一下
主题帖子积分
资深技术员, 积分 469, 距离下一级还需 31 积分
资深技术员, 积分 469, 距离下一级还需 31 积分
主题帖子积分
专家等级:结帖率:100%
主题帖子积分
资深技术员, 积分 469, 距离下一级还需 31 积分
资深技术员, 积分 469, 距离下一级还需 31 积分
中断函数,取平均值的计算中,怎么没有找到index++,计算有问题吧
主题帖子积分
中级技术员, 积分 169, 距离下一级还需 131 积分
中级技术员, 积分 169, 距离下一级还需 131 积分
主题帖子积分
专家等级:结帖率:85%
主题帖子积分
中级技术员, 积分 169, 距离下一级还需 131 积分
中级技术员, 积分 169, 距离下一级还需 131 积分
中断加delay不可取吧!
时间类勋章
技术新星奖章
人才类勋章
晶莹之水滴
发帖类勋章
技术奇才奖章
人才类勋章
时间类勋章
湍急之河流
发帖类勋章
精华达人奖章
等级类勋章
时间类勋章
涓涓之细流
发帖类勋章
时间类勋章}

我要回帖

更多关于 数据库有数据查不出来 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信