OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3077|回复: 4

我用ADC DMA进行三路数据采集,当单独每一路采集时数据正确,当我三路一起采集时,第一路数据正确,其他两路不正确求解答谢谢

[复制链接]

4

主题

12

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2016-4-9
在线时间
8 小时
发表于 2016-5-12 08:48:02 | 显示全部楼层 |阅读模式
13金钱
#include"stm32f0xx.h"
#include"led.h"
#include"key.h"
#include"extic.h"
#include"ad.h"
#define ADC1_DR_ADDRESS     0x40012440
//__IO uint16_t  RegularConvData_Tab[1];

__IO uint16_t  adc_dma_tab[3] = {0};
void ADC_Config()
{  
   ADC_InitTypeDef adc_init_structure;  
   GPIO_InitTypeDef  GPIO_InitStructure;  
  // RCC_ADCCLKConfig(RCC_ADCCLK_PCLK_Div4);   //设置ADC分频因子4   48M/4=12,ADC最大时间不能超过14M

   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);            //使能ADC时钟  
   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);//使能GPIOB
   ADC_DeInit(ADC1);                                               //复位ADC  

   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入引脚
   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//浮空
   GPIO_Init(GPIOA, &GPIO_InitStructure);
   

  //ADC_StructInit(&adc_init_structure);  
    adc_init_structure.ADC_ContinuousConvMode = ENABLE;            //连续转换模式  
    adc_init_structure.ADC_DataAlign = ADC_DataAlign_Right;         //采样数据右对齐  
   adc_init_structure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//软件触发
    adc_init_structure.ADC_Resolution = ADC_Resolution_12b;         //12位分辨率  
    adc_init_structure.ADC_ScanDirection = ADC_ScanDirection_Upward;//向上扫描0-18通道  
    ADC_Init(ADC1, &adc_init_structure);  
     
    ADC_ChannelConfig(ADC1, ADC_Channel_3 , ADC_SampleTime_7_5Cycles);   //配置采样通道,采样时间  
    ADC_ChannelConfig(ADC1, ADC_Channel_4 , ADC_SampleTime_7_5Cycles);   //配置采样通道,采样时间   
    ADC_ChannelConfig(ADC1, ADC_Channel_5 , ADC_SampleTime_7_5Cycles);   //配置采样通道,采样时间   
    ADC_OverrunModeCmd(ADC1, ENABLE);                               //使能数据覆盖模式  
   
    ADC_GetCalibrationFactor(ADC1);                                 //使能前校准ADC  
    ADC_Cmd(ADC1, ENABLE);                                          //使能ADC1  
    while(ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN) == RESET);         //等待ADC1使能完成  
  
  
    ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);           //配置DMA请求模式为循环模式  
    ADC_StartOfConversion(ADC1);                                    //开启一次转换(必须)  
  ADC_DMACmd(ADC1, ENABLE);                                       //使能ADC_DMA  
}  
  

  
void adc_dma_init()  
{  
    DMA_InitTypeDef dma_init_structure;  
    NVIC_InitTypeDef nvic_init_structure;  
  
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);              //使能DMA时钟  
  
    nvic_init_structure.NVIC_IRQChannel = DMA1_Channel1_IRQn;       //选择DMA1通道中断  
    nvic_init_structure.NVIC_IRQChannelCmd = ENABLE;                //中断使能  
    nvic_init_structure.NVIC_IRQChannelPriority = 1;                //优先级设为0  
    NVIC_Init(&nvic_init_structure);  
  
    DMA_DeInit(DMA1_Channel1);                                      //复位DMA1_channel1  
    DMA_StructInit(&dma_init_structure);                            //初始化DMA结构体  
  
    dma_init_structure.DMA_BufferSize = 3;            //DMA缓存数组大小设置  
    dma_init_structure.DMA_DIR = DMA_DIR_PeripheralSRC;             //DMA方向:外设作为数据源  
    dma_init_structure.DMA_M2M = DISABLE;                           //内存到内存禁用  
    dma_init_structure.DMA_MemoryBaseAddr = (uint32_t)adc_dma_tab;//;//缓存数据数组起始地址  
    dma_init_structure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//数据大小设置为Halfword  (16位)
    dma_init_structure.DMA_MemoryInc = DMA_MemoryInc_Enable;        //内存地址递增  
    dma_init_structure.DMA_Mode = DMA_Mode_Circular;                //DMA循环模式,即完成后重新开始覆盖  
    dma_init_structure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_ADDRESS;//取值的外设地址  
    dma_init_structure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外设取值大小设置为Halfword  
    dma_init_structure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址递增禁用  
    dma_init_structure.DMA_Priority = DMA_Priority_High;             //DMA优先级设置为高  
    DMA_Init(DMA1_Channel1, &dma_init_structure);  
  
    DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);                  //使能DMA中断  
    DMA_ClearITPendingBit(DMA_IT_TC);                                //清除一次DMA中断标志  
    DMA_Cmd(DMA1_Channel1, ENABLE);                                  //使能DMA1  
}  
下面是在中断读数
void EXTI0_1_IRQHandler(void)
{      
   
  if(EXTI_GetITStatus(EXTI_Line1)!=RESET)  //中断触发
{
   EXTI_ClearITPendingBit(EXTI_Line1);//退出中断时注意清除标志位  
  
    i++; //i++;//脉冲个数(一个脉冲大约有15ms)
    na1=a1;
   na2=a2;
   na3=a3;
    a1=0;
    a2=0;
    a3=0;
   }
     
}   

//DMA中断函数                  
void  DMA1_Channel1_IRQHandler()
{  
   if(DMA_GetITStatus(DMA_IT_TC))                      //判断DMA传输完成中断  
    {  
    DMA_ClearITPendingBit(DMA_IT_TC);                   //清除DMA中断标志位  
  
    a++;
   
   PL1=L1L2=L2L3=L3;
    if(adc_dma_tab[0]>500) L1=1;   //0.5v=620
   if(adc_dma_tab[0]<260) L1=0;                     //0.2v=248.
   
    if(PL1==1)
    {
      if( PL1!=L1)
     {
    a1++;   
     }  
    }
      
   if(adc_dma_tab[1]>500) L2=1;          //0.5v=620
  
   if(adc_dma_tab[1]<260) L2=0;                     //0.2v=248.
   
    if(PL2==1)
    {
      if( PL2!=L2)
     {
    a2++;   
     }  
   }
   if(adc_dma_tab[2]>500) L3=1;          //0.5v=620
  
   if(adc_dma_tab[2]<260) L3=0;                     //0.2v=248.
   
    if(PL3==1)
    {
      if( PL3!=L3)
     {
    a3++;   
     }  
    }
     
}
}
下面是主函数
int main(void)
{
  

    LED_Init();//led初始化
    ADC_Config();//初始化
    EXIT_Init();//中断初始化
   
    adc_dma_init();   
      
while(1)
{     
   
}
}


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

4

主题

12

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2016-4-9
在线时间
8 小时
 楼主| 发表于 2016-5-12 08:52:47 | 显示全部楼层
别沉啊。自己先顶。跪求大神解答
回复

使用道具 举报

13

主题

201

帖子

0

精华

高级会员

Rank: 4

积分
671
金钱
671
注册时间
2015-4-26
在线时间
173 小时
发表于 2016-5-12 09:14:01 | 显示全部楼层
http://www.openedv.com/thread-27827-1-1.html参考一个这里面的解决方案
回复

使用道具 举报

4

主题

12

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2016-4-9
在线时间
8 小时
 楼主| 发表于 2016-5-12 09:35:35 | 显示全部楼层
康仔呦 发表于 2016-5-12 09:14
http://www.openedv.com/thread-27827-1-1.html参考一个这里面的解决方案

多谢,我这个帖子早就看过了,我要用DMA中断去读数。这个帖子和我的不一样。求大神指点。
回复

使用道具 举报

0

主题

4

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2015-9-23
在线时间
10 小时
发表于 2016-5-12 12:09:24 | 显示全部楼层
大神啊,顶一个
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-7 00:05

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表