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

新手求助,多重ADC采集单通道通过DMA传输到内存数组中的...

[复制链接]
lyl5530330 提问时间:2018-5-24 22:43 /
本帖最后由 lyl5530330 于 2018-5-24 22:45 编辑

各位大神,小弟初学stm32,现在在项目中遇到一个问题,比如说我采集一个信号,只有一个通道,通过ADC123多重采样通过DMA传输到数组中,再通过串口输出可见,我采的是一个2V的直流电平,采到的图在附件,由图可以看出采到的数据有问题,大神能帮我看下程序嘛

以下是main函数:
  1. #define NUM 100
  2. int main(void)
  3. {
  4.         u16 adcx1,adcx2,adcx3;
  5.         u8 i,t,z=0;
  6.         u32 adc_value[NUM];
  7.         delay_init(168);
  8.         uart_init(115200);
  9.         LED_Init();
  10.         MYDMA_DMA_DIR_PeripheralToMemoryConfig(DMA2_Stream0,DMA_Channel_0,(u32)&ADC->CDR,(u32)adc_value,NUM);
  11.         MYADC_configure();

  12.         
  13. while(1)        
  14. {
  15.         
  16.         for(i=0;i<NUM;i++)
  17.                 {                        
  18.                         adcx1=adc_value[i]&0xffff0000>>16;
  19.                         USART_SendData(USART1,(adcx1&0xff00)>>8);
  20.                         while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
  21.                         USART_SendData(USART1,adcx1&0xff);
  22.                         while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
  23.                         
  24.                         adcx2=adc_value[i]&0xffff;
  25.                         USART_SendData(USART1,(adcx2&0xff00)>>8);
  26.                         while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
  27.                         USART_SendData(USART1,adcx2&0xff);
  28.                         while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
  29.          }
  30.         
  31.                 delay_ms(2000);
  32.           LED0=!LED0;
  33. }
  34.         
  35. }
复制代码
以下是adc配置函数
  1. #include "adc.h"
  2. #include "sys.h"

  3. void MYADC_configure()//从adc中
  4. {
  5.        
  6.         GPIO_InitTypeDef GPIO_InitStructure;
  7.         ADC_CommonInitTypeDef ADC_CommonInitStructure;
  8.         ADC_InitTypeDef ADC_InitStructure;
  9.        
  10.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
  11.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3|RCC_APB2Periph_ADC1|RCC_APB2Periph_ADC2, ENABLE);
  12.        
  13.         GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
  14.         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AN;
  15.         GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL ;
  16.         GPIO_Init(GPIOA,&GPIO_InitStructure);
  17.        
  18.        
  19.         //复位ADC
  20.         ADC_DeInit();
  21.         //配置通用寄存器ADC_CCR
  22.         ADC_CommonInitStructure.ADC_Mode=ADC_TripleMode_Interl;//三重交替模式
  23.         ADC_CommonInitStructure.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles;
  24.         ADC_CommonInitStructure.ADC_DMAAccessMode=ADC_DMAAccessMode_2;//DMA模式2
  25.         ADC_CommonInitStructure.ADC_Prescaler=ADC_Prescaler_Div4;//84/4=21M
  26.         ADC_CommonInit(&ADC_CommonInitStructure);
  27.         //配置ADC3
  28.         ADC_InitStructure.ADC_Resolution=ADC_Resolution_12b;//分辨率12位
  29.         ADC_InitStructure.ADC_ScanConvMode=DISABLE;//关闭扫描模式
  30.         ADC_InitStructure.ADC_ContinuousConvMode=ENABLE;//开启连续转换 CR2
  31.         ADC_InitStructure.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_None;//不采用边沿触发
  32.         ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//右对齐
  33.         ADC_InitStructure.ADC_NbrOfConversion=1;//采样通道1个
  34.         ADC_Init(ADC1,&ADC_InitStructure);
  35.        
  36.         ADC_Init(ADC2,&ADC_InitStructure);

  37.         ADC_Init(ADC3,&ADC_InitStructure);
  38.        
  39.         //始能ADC       
  40.         ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_480Cycles ); //配置通道优先级 SMPR2,SQR3
  41.         ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 1, ADC_SampleTime_480Cycles ); //配置通道优先级 SMPR2,SQR3
  42.         ADC_RegularChannelConfig(ADC3, ADC_Channel_1, 1, ADC_SampleTime_480Cycles ); //配置通道优先级 SMPR2,SQR3
  43.        
  44.         ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);
  45.        
  46.         ADC_Cmd(ADC1, ENABLE);
  47.         ADC_Cmd(ADC2, ENABLE);
  48.         ADC_Cmd(ADC3, ENABLE);

  49.        
  50.         ADC_SoftwareStartConv(ADC1);
  51.         ADC_SoftwareStartConv(ADC2);
  52.         ADC_SoftwareStartConv(ADC3);
  53.        

  54.        
  55. }
复制代码
  1. <span style="background-color: rgb(255, 255, 255);">
  2. </span>
复制代码

复制代码
以上就是代码部分

捕获.PNG
收藏 评论12 发布时间:2018-5-24 22:43

举报

12个回答
lyl5530330 回答时间:2018-5-24 22:46:32
DMA的不知道为啥没显示,我补充一下:
  1. #include "dma.h"
  2. #include "sys.h"

  3. void MYDMA_DMA_DIR_PeripheralToMemoryConfig(DMA_Stream_TypeDef *DMA_Streamx,u32 chanlx,u32 par,u32 memory,u16 ndtr)//(数据流,通道,外设基地址,存储器基地址,传输量,不管是多少位的,传输量只是数据的个数,这里设置为数组的长度)
  4. {
  5.                 DMA_InitTypeDef  DMA_InitStructure;
  6.        
  7.         if((u32)DMA_Streamx>(u32)DMA2)//得到当前stream是属于DMA2还是DMA1
  8.         {
  9.           RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//DMA2时钟使能
  10.                
  11.         }else
  12.         {
  13.           RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);//DMA1时钟使能
  14.         }
  15.   DMA_DeInit(DMA_Streamx);
  16.         while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE){}//等待DMA可配置
  17.                
  18.                  /* 配置 DMA Stream */
  19.   DMA_InitStructure.DMA_Channel = chanlx;  //通道选择
  20.   DMA_InitStructure.DMA_PeripheralBaseAddr = par;//DMA外设地址,S0PAR
  21.   DMA_InitStructure.DMA_Memory0BaseAddr = memory;//DMA 存储器地址 S0M0AR
  22.   DMA_InitStructure.DMA_DIR =DMA_DIR_PeripheralToMemory ;//外设到存储器
  23.   DMA_InitStructure.DMA_BufferSize = ndtr;//数据传输量 ,NDTR
  24.   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设非增量模式,S0CR
  25.   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//存储器增量模式,S0CR
  26.   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  27.   DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord;
  28.   DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;// 循环模式,S0CR
  29.   DMA_InitStructure.DMA_Priority = DMA_Priority_High;//高优先级,S0CR
  30.   DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  31.   DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  32.   DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//存储器突发单次传输
  33.   DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//外设突发单次传输
  34.   DMA_Init(DMA_Streamx, &DMA_InitStructure);//初始化DMA Stream
  35.         DMA_Cmd(DMA_Streamx, ENABLE);
  36.          
  37. }



复制代码

wenyangzeng 回答时间:2018-5-25 07:22:49
本帖最后由 wenyangzeng 于 2018-5-25 16:25 编辑

1、楼主在主循环里不停地发送数据,如果ADC未转换结束,则可能会发送错误的数据。
2、只使用1个ADC,为何要打开3个ADC(ADC1、ADC2、ADC3)且使能三重交替模式?
3、DMA配置貌似未配置完整。ST官方代码可以参考:
ADC_DMA.rar (15.8 KB, 下载次数: 21)

评分

参与人数 1蝴蝶豆 +4 收起 理由
zero99 + 4

查看全部评分

MrJiu 回答时间:2018-5-25 09:48:28
直接使用官方的hal库,然后用cube配置岂不是更加好

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

wolfgang2015 回答时间:2018-5-25 10:03:35
1、ADC参考电压没对导致结果偏大
2、先不要测变化量,先要测个归零量,稳定量,避免因采样的方式带来的误差
3、直流电平最好选择电池,开关电源有波纹,并不是想象的那么平;
4、幅度大于波纹,看看是否采样过快或过慢,造成数据不准
5、3个ADC都送一个DMA, 但DAM设置用的是 DMA_PeripheralInc = DMA_PeripheralInc_Disable

这与 “如果DMA选用的通道(CHx)有多个外设连接,需要使用外设递增模式:DMA_PeripheralInc_Enable;” 不同。

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

西边的云彩 回答时间:2018-5-25 10:38:54
正好需要,感谢
lyl5530330 回答时间:2018-5-25 14:15:10
wenyangzeng 发表于 2018-5-25 07:22
1、楼主在主循环里不停地发送数据,如果ADC未转换结束,则可能会发送错误的数据。
2、只使用1个ADC,为何要 ...

谢谢,您发的这个附件我下载下来是空的。。。。
我以为三个ADC都要打开转换所以就打开三个ADC软件转换了。
那这个循环里面该怎么写呢?有没有一个函数是开启/关闭从ADC-CDR寄存器的DMA传输的呢,就像ADC_DMACmd(ADC3,DISABLE);在使用串口传输的时候就不让DMA取数了
lyl5530330 回答时间:2018-5-25 14:15:36
MrJiu 发表于 2018-5-25 09:48
直接使用官方的hal库,然后用cube配置岂不是更加好

怎么用啊。。新手表示用不来
lyl5530330 回答时间:2018-5-25 14:16:20
wolfgang2015 发表于 2018-5-25 10:03
1、ADC参考电压没对导致结果偏大
2、先不要测变化量,先要测个归零量,稳定量,避免因采样的方式带来的误差 ...

嗯嗯,我改用一下外设递增的模式试一下
lyl5530330 回答时间:2018-5-25 14:17:20
本帖最后由 lyl5530330 于 2018-5-25 14:19 编辑
wolfgang2015 发表于 2018-5-25 10:03
1、ADC参考电压没对导致结果偏大
2、先不要测变化量,先要测个归零量,稳定量,避免因采样的方式带来的误差 ...

但是三个ADC转换的数据都是存在ADC-CDR寄存器中的呀,这个也需要递增吗,如果改成外设递增的话那么传出来的数就全是0了
12下一页

所属标签

相似问题

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