本帖最后由 lyl5530330 于 2018-5-24 22:45 编辑
各位大神,小弟初学stm32,现在在项目中遇到一个问题,比如说我采集一个信号,只有一个通道,通过ADC123多重采样通过DMA传输到数组中,再通过串口输出可见,我采的是一个2V的直流电平,采到的图在附件,由图可以看出采到的数据有问题,大神能帮我看下程序嘛
以下是main函数:
- #define NUM 100
- int main(void)
- {
- u16 adcx1,adcx2,adcx3;
- u8 i,t,z=0;
- u32 adc_value[NUM];
- delay_init(168);
- uart_init(115200);
- LED_Init();
- MYDMA_DMA_DIR_PeripheralToMemoryConfig(DMA2_Stream0,DMA_Channel_0,(u32)&ADC->CDR,(u32)adc_value,NUM);
- MYADC_configure();
-
- while(1)
- {
-
- for(i=0;i<NUM;i++)
- {
- adcx1=adc_value[i]&0xffff0000>>16;
- USART_SendData(USART1,(adcx1&0xff00)>>8);
- while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
- USART_SendData(USART1,adcx1&0xff);
- while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
-
- adcx2=adc_value[i]&0xffff;
- USART_SendData(USART1,(adcx2&0xff00)>>8);
- while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
- USART_SendData(USART1,adcx2&0xff);
- while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
- }
-
- delay_ms(2000);
- LED0=!LED0;
- }
-
- }
复制代码 以下是adc配置函数- #include "adc.h"
- #include "sys.h"
- void MYADC_configure()//从adc中
- {
-
- GPIO_InitTypeDef GPIO_InitStructure;
- ADC_CommonInitTypeDef ADC_CommonInitStructure;
- ADC_InitTypeDef ADC_InitStructure;
-
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3|RCC_APB2Periph_ADC1|RCC_APB2Periph_ADC2, ENABLE);
-
- GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
- GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AN;
- GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL ;
- GPIO_Init(GPIOA,&GPIO_InitStructure);
-
-
- //复位ADC
- ADC_DeInit();
- //配置通用寄存器ADC_CCR
- ADC_CommonInitStructure.ADC_Mode=ADC_TripleMode_Interl;//三重交替模式
- ADC_CommonInitStructure.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles;
- ADC_CommonInitStructure.ADC_DMAAccessMode=ADC_DMAAccessMode_2;//DMA模式2
- ADC_CommonInitStructure.ADC_Prescaler=ADC_Prescaler_Div4;//84/4=21M
- ADC_CommonInit(&ADC_CommonInitStructure);
- //配置ADC3
- ADC_InitStructure.ADC_Resolution=ADC_Resolution_12b;//分辨率12位
- ADC_InitStructure.ADC_ScanConvMode=DISABLE;//关闭扫描模式
- ADC_InitStructure.ADC_ContinuousConvMode=ENABLE;//开启连续转换 CR2
- ADC_InitStructure.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_None;//不采用边沿触发
- ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//右对齐
- ADC_InitStructure.ADC_NbrOfConversion=1;//采样通道1个
- ADC_Init(ADC1,&ADC_InitStructure);
-
- ADC_Init(ADC2,&ADC_InitStructure);
- ADC_Init(ADC3,&ADC_InitStructure);
-
- //始能ADC
- ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_480Cycles ); //配置通道优先级 SMPR2,SQR3
- ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 1, ADC_SampleTime_480Cycles ); //配置通道优先级 SMPR2,SQR3
- ADC_RegularChannelConfig(ADC3, ADC_Channel_1, 1, ADC_SampleTime_480Cycles ); //配置通道优先级 SMPR2,SQR3
-
- ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);
-
- ADC_Cmd(ADC1, ENABLE);
- ADC_Cmd(ADC2, ENABLE);
- ADC_Cmd(ADC3, ENABLE);
-
- ADC_SoftwareStartConv(ADC1);
- ADC_SoftwareStartConv(ADC2);
- ADC_SoftwareStartConv(ADC3);
-
-
- }
复制代码- <span style="background-color: rgb(255, 255, 255);">
- </span>
复制代码 以上就是代码部分
|
1、楼主在主循环里不停地发送数据,如果ADC未转换结束,则可能会发送错误的数据。
2、只使用1个ADC,为何要打开3个ADC(ADC1、ADC2、ADC3)且使能三重交替模式?
3、DMA配置貌似未配置完整。ST官方代码可以参考:
评分
查看全部评分
评分
查看全部评分
2、先不要测变化量,先要测个归零量,稳定量,避免因采样的方式带来的误差
3、直流电平最好选择电池,开关电源有波纹,并不是想象的那么平;
4、幅度大于波纹,看看是否采样过快或过慢,造成数据不准
5、3个ADC都送一个DMA, 但DAM设置用的是 DMA_PeripheralInc = DMA_PeripheralInc_Disable
这与 “如果DMA选用的通道(CHx)有多个外设连接,需要使用外设递增模式:DMA_PeripheralInc_Enable;” 不同。
评分
查看全部评分
谢谢,您发的这个附件我下载下来是空的。。。。
我以为三个ADC都要打开转换所以就打开三个ADC软件转换了。
那这个循环里面该怎么写呢?有没有一个函数是开启/关闭从ADC-CDR寄存器的DMA传输的呢,就像ADC_DMACmd(ADC3,DISABLE);在使用串口传输的时候就不让DMA取数了
怎么用啊。。新手表示用不来
嗯嗯,我改用一下外设递增的模式试一下
但是三个ADC转换的数据都是存在ADC-CDR寄存器中的呀,这个也需要递增吗,如果改成外设递增的话那么传出来的数就全是0了
ADC_InitStructure.ADC_NbrOfConversion=1;//采样通道1个
"
这个设置与下面的配置有冲突把,如果是一个采样通道,相关DMA内容也要调整。
简单的方法你把ADC、DMA的内容Debug 出来,自然就明了
“
ADC_Init(ADC1,&ADC_InitStructure);
ADC_Init(ADC2,&ADC_InitStructure);
ADC_Init(ADC3,&ADC_InitStructure);
//始能ADC
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_480Cycles ); //配置通道优先级 SMPR2,SQR3
ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 1, ADC_SampleTime_480Cycles ); //配置通道优先级 SMPR2,SQR3
ADC_RegularChannelConfig(ADC3, ADC_Channel_1, 1, ADC_SampleTime_480Cycles ); //配置通道优先级 SMPR2,SQR3
”
什么意思呀,就只有一个通道的嘛
楼主应该在DMA中断里设置一个标志位,主循环检测到标志位后才发送数据并清标志位。
演示代码在ST官方资料库里很多的。