• 已解决 73482 个问题
  • 已帮助 5993 位优秀工程师

用adc采样的波形周期性混乱

laoyaomao 2019-09-09 浏览量:1293
用da生成一组锯齿波在用ad采集。示波器上看还是好好的,把ad采到的数据放到matlab看就发现有周期性的混乱。均使用dma传输,中断同步。附上ad和da的代码,
  1. #include "sys.h"
  2. #include "math.h"
  3. #include "dac.h"
  4. #include "delay.h"
  5. #include "led.h"
  6. #define DAC_DHR12R1_ADDRESS 0x40007408

  7. u16 sawtooth[tableSize];// tableSize==250
  8. u16 led1=0;

  9. //锯齿波
  10. void sawtooth_Generation(void)
  11. {
  12.         u16 n;
  13.         for(n=0;n<tableSize;n++)
  14.         {
  15.                 sawtooth[n] = n*16;
  16.         }
  17. }

  18. void TIM6_Configuration(void)
  19. {
  20.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6 ENABLE);

  21.         TIM_PrescalerConfig(TIM6 83 TIM_PSCReloadMode_Update); //设置分频系数为83
  22.   TIM_SetAutoreload(TIM6 3); //设置自动重载寄存器值为3
  23.         TIM_SelectOutputTrigger(TIM6 TIM_TRGOSource_Update);
  24.         TIM_Cmd(TIM6 ENABLE);
  25. }

  26. void DacGPIO_Configuration(void)
  27. {
  28.         GPIO_InitTypeDef GPIO_InitStructure;//结构体
  29.   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA ENABLE);//使能GPIOA时钟
  30.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;//选定PA4
  31.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
  32.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  33.         GPIO_Init(GPIOA &GPIO_InitStructure);//GPIOA初始化
  34. }

  35. void DAC_DMA_Configuration(void)
  36. {
  37.         DAC_InitTypeDef  DAC_InitStructure;        //DAC结构体
  38.         DMA_InitTypeDef DMA_InitStructure; //DMA结构体
  39.         NVIC_InitTypeDef NVIC_InitStructure;

  40.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1 ENABLE);
  41.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC ENABLE);//使能DAC时钟

  42.         DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO;//使用触发功能
  43.         DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;//不用STM32自带的波形
  44.         DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;//设置不使用输出缓存
  45.         DAC_Init(DAC_Channel_1 &DAC_InitStructure);
  46.         //DMA1请求映射,DMA的数据流5和通道7为DAC1功能
  47.         DMA_DeInit(DMA1_Stream5);//设置数据流5
  48.         DMA_InitStructure.DMA_Channel = DMA_Channel_7;//设置通道7  
  49.         DMA_InitStructure.DMA_PeripheralbaseAddr = DAC_DHR12R1_ADDRESS;
  50.         DMA_InitStructure.DMA_Memory0baseAddr = (uint32_t)&sawtooth;//定义DMA外设基地址
  51.         DMA_InitStructure.DMA_BufferSize = tableSize; //设置DMA缓存大小
  52.         //外设数据宽度
  53.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  54.         DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord;
  55.         DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
  56.         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  57.         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

  58.         DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //设置为正常模式
  59.         DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  60.         DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
  61.         DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
  62.         DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  63.         DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  64.         DMA_Init(DMA1_Stream5 &DMA_InitStructure);
  65.         DMA_Cmd(DMA1_Stream5 ENABLE); //使能DMA1数据流5
  66.         DAC_Cmd(DAC_Channel_1 ENABLE); //使能DAC的通道1
  67.         //链接DAC通道和DMA通道
  68.         DAC_DMACmd(DAC_Channel_1 ENABLE);//使能DAC_DMA通道1

  69.         DMA_ITConfig(DMA1_Stream5DMA_IT_TCENABLE);//开启传输完成中断
  70.         NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream5_IRQn;
  71.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0X00;
  72.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0X00;
  73.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  74.         NVIC_Init(&NVIC_InitStructure);
  75. }

  76. void DMA1_Stream5_IRQHandler(void)
  77. {
  78.         if(DMA_GetFlagStatus(DMA1_Stream5DMA_FLAG_TCIF5)==SET) //传输完成标志
  79.                 {
  80.                         led1++;
  81.                         if(led1==100)
  82.                         {
  83.                                 LED1=!LED1;
  84.                                 led1=0;
  85.                         }
  86.                         ADC_SoftwareStartConv(ADC1); //启动一次ADC
  87.                         DMA_ClearFlag(DMA1_Stream5DMA_FLAG_TCIF5); //清除传输完成中断
  88.     }
  89. }

  90. void MYDAC_Init(void)
  91. {
  92.         sawtooth_Generation();
  93.         DacGPIO_Configuration();
  94.         TIM6_Configuration();
  95.         DAC_DMA_Configuration();
  96. }



  97. #include "adc.h"
  98. #include "delay.h"
  99. #include "usart.h"
  100. #include "led.h"
  101. #define len 1400

  102. u16 ADC_ConvertedValue[len];
  103. u16 save[len];
  104. u16 counter;
  105. u16 led=0;

  106. void ADC_DMA_Config(void)
  107. {
  108.         ADC_InitTypeDef ADC_InitStructure;
  109.         ADC_CommonInitTypeDef ADC_CommonInitStructure;
  110.         DMA_InitTypeDef DMA_InitStructure;
  111.         GPIO_InitTypeDef GPIO_InitStructure;
  112.         NVIC_InitTypeDef NVIC_InitStructure;

  113.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOA ENABLE);
  114.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 ENABLE);
  115.        
  116.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
  117.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  118.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  119.         GPIO_Init(GPIOA &GPIO_InitStructure);

  120.         ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; //独立模式
  121.         ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4; //4分频
  122.         ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1;
  123.         ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; //两次采样间隔5周期
  124.         ADC_CommonInit(&ADC_CommonInitStructure);

  125.         ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; //12位模式
  126.         ADC_InitStructure.ADC_ScanConvMode = DISABLE; //关闭扫描模式
  127.         ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //单次转换
  128.         ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //软件触发
  129.         ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //右对齐
  130.         ADC_InitStructure.ADC_NbrOfConversion = 1;
  131.         ADC_Init(ADC1 &ADC_InitStructure);

  132.         ADC_RegularChannelConfig(ADC1 ADC_Channel_5 1 ADC_SampleTime_3Cycles); //采样3周期
  133.         ADC_DMARequestAfterLastTransferCmd(ADC1 ENABLE);
  134.         ADC_DMACmd(ADC1 ENABLE);
  135.         ADC_Cmd(ADC1 ENABLE);

  136.         DMA_DeInit(DMA2_Stream0);
  137.         DMA_InitStructure.DMA_Channel = DMA_Channel_0; //选择通道0
  138.         DMA_InitStructure.DMA_PeripheralbaseAddr = ((u32)ADC1+0x4c); //外设基地址
  139.         DMA_InitStructure.DMA_Memory0baseAddr = (uint32_t)&ADC_ConvertedValue; //数据存放地址
  140.         DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; //设置外设到内存
  141.         DMA_InitStructure.DMA_BufferSize = len; //设置一次传输数据大小
  142.         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址不变
  143.         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址递增
  144.         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  145.         DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  146.         DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //设置为循环模式
  147.         DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //中等优先级
  148.         DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
  149.         DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  150.         DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  151.         DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  152.         DMA_Init(DMA2_Stream0 &DMA_InitStructure); //初始化
  153.         DMA_Cmd(DMA2_Stream0 ENABLE);

  154.         DMA_ITConfig(DMA2_Stream0DMA_IT_TCENABLE); //开启传输完成中断
  155.         NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
  156.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0X00;
  157.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0X01;
  158.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  159.         NVIC_Init(&NVIC_InitStructure);
  160. }

  161. void DMA2_Stream0_IRQHandler(void)
  162. {
  163.         if(DMA_GetFlagStatus(DMA2_Stream0DMA_FLAG_TCIF0)==SET) //传输完成标志
  164.                 {
  165.                         led++;
  166.                         if(led==100)
  167.                         {
  168.                                 LED0=!LED0;
  169.                                 led=0;
  170.                         }
  171.                         for(counter=0;counter<len;counter++)
  172.                         save[counter]=ADC_ConvertedValue[counter];
  173.                         DMA_ClearFlag(DMA2_Stream0DMA_FLAG_TCIF0); //清除传输完成中断
  174.     }
  175. }

m data-ke-onclick="copycode($('code_c3e'));">复制代码

板子是探索者f407。

0 0 收起

我来回答

上传资料:
选择文件 文件大小不超过15M(格式支持:doc、ppt、xls、pdf、zip、rar、txt)
所有亮答 数量:1
  • 建议你从如下几点查找:

    1、确定你DAC输出的波形为你想要的波形,用示波器查看。

    2、确定你的DAC输出的最大频率。

          根据你乃奎斯特采样定律,你的ADC采样频率需要大于你DAC的最大频率两倍,才能还原波形。

          一般实际上使用的是3-4倍。

相关问题

问题达人换一批

用adc采样的波形周期性混乱