找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2057|回复: 0
打印 上一主题 下一主题
收起左侧

STM32 ADC多通道连续采集 +DMA 寄存器版本程序问题

[复制链接]
跳转到指定楼层
楼主
ID:788840 发表于 2020-6-29 14:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
2黑币
//这是部分代码,刚刚帖子不全,这是下面的代码部分,
//ADC多通道连续采集,采用DMA模式,寄存器版本写的程序。但是结果却是只能初始化时候传递一个数据,本来应该采集50次的,只采集一次,用串口显示结果是0.38,这是一次采集的电压除以50的结果,也就是说DMA只传递了一个数据,找了很久无果,请教大家!!!

  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "LED.h"
  4. #include "usart.h"

  5. #define N  50
  6. #define M  3

  7. void filter(void);
  8. void ADC_Init(void);                                 //ADC通道初始化
  9. void DMA_Init(DMA_Channel_TypeDef*DMA_CHx);//配置DMA1_CHx

  10. vu16 ADC_Value[N][M];//用来存放ADC转换结果,也是DMA的目标地址 define a N line and M row
  11. u16 filterADC[M];//用来存放平均值
  12. int main(void)
  13. {
  14.     float V1;
  15.         float V2;
  16.         float V3;
  17.         
  18.          Stm32_Clock_Init(9);        //系统时钟设置
  19.         delay_init(72);                            //延时初始化
  20.     uart_init(72,115200);
  21.         LED_Init();                                  //初始化与LED连接的硬件接口

  22.         ADC_Init();
  23.     DMA_Init(DMA1_Channel1);
  24.                
  25.         while(1)
  26.         {               
  27.                
  28.                 delay_ms(10);
  29.                         filter();
  30.                                        
  31.                 V1=filterADC[0]*3.3/4095;printf("V1=%f\r\n",V1);
  32.                                 V2=filterADC[1]*3.3/4095;printf("V2=%f\r\n",V2);
  33.                                 V3=filterADC[2]*3.3/4095;printf("V3=%f\r\n\r\n\r\n",V3);

  34.                            delay_ms(500);
  35.                            LED0=!LED0;               
  36.         
  37.         }                                                                                                                                                                                                                                                                                                                                                            
  38. }
  39. void filter(void)
  40. {
  41.         vu32 sum=0;                //必须初始化为0,否则初值将保持上次调用值。
  42.         vu8 i=0,j=0;
  43.         for(i=0;i<M;i++)                //M row
  44.         {
  45.                 for(j=0;j<N;j++)        //N line
  46.                 {
  47.                         sum+=ADC_Value[j][i];
  48.                 }
  49.                 filterADC[i]=sum/N;
  50.                 sum=0;
  51.         }        
  52. }

  53.            
  54. //初始化ADC1
  55. //以规则通道为例
  56. //开启ADC1通道1 ADC1通道2 ADC1通道3        开启连续扫描模式         使能DMA                                                                                                                           

  57. void  ADC_Init(void)
  58. {   
  59.         //先初始化IO口

  60.          RCC->APB2ENR|=1<<2;    //使能PORTA口时钟
  61.     RCC->APB2ENR|=1<<9;    //ADC1时钟使能

  62.         RCC->CFGR&=~(3<<14);   //分频因子清零        
  63.         //SYSCLK/DIV2=12M ADC时钟设置为12M,ADC最大时钟不能超过14M!
  64.         //否则将导致ADC准确度下降!
  65.         RCC->CFGR|=2<<14;   //ADC 分频系数为6 adcclock为12M         
  66.         GPIOA->CRL&=0XFFFF000F;//PA1 PA2 PA3 anolog输入

  67.         RCC->APB2RSTR|=1<<9;   //ADC1复位
  68.         RCC->APB2RSTR&=~(1<<9);//复位结束
  69.                   
  70.         ADC1->CR1&=0XF0FFFF;   //工作模式清零
  71.         ADC1->CR1|=0<<16;      //独立工作模式
  72.         ADC1->CR1&=1<<8;    //扫描模式        
  73.         ADC1->CR2&=1<<1;    //连续转换模式
  74.         ADC1->CR2&=~(7<<17);           
  75.         ADC1->CR2|=7<<17;           //不使用外部触发模式  
  76.         ADC1->CR2&=~(1<<11);   //右对齐        
  77.     ADC1->SQR1&=0xFF0FFFFF;
  78.         ADC1->SQR1|=2<<20;     //3个转换在规则序列中 也就是只转换规则序列1~3

  79.     ADC1->SMPR2&=~(7<<(3*1));   //通道1采样时间清空         
  80.          ADC1->SMPR2|=7<<(3*1); //通道1  239.5周期,提高采样时间可以提高精确度
  81.     ADC1->SQR3&=~(0X0000001F<<(5*0));//规则序列1 ADC1通道1
  82.         ADC1->SQR3|=1<<(5*0);        

  83.     ADC1->SMPR2&=~(7<<(3*2));   //通道2采样时间清空         
  84.          ADC1->SMPR2|=7<<(3*2); //通道2  239.5周期,提高采样时间可以提高精确度
  85.     ADC1->SQR3&=~(0X0000001F<<(5*1));//规则序列1 ADC1通道1
  86.         ADC1->SQR3|=2<<(5*1);        

  87.     ADC1->SMPR2&=~(7<<(3*3));   //通道3采样时间清空         
  88.          ADC1->SMPR2|=7<<(3*3); //通道3  239.5周期,提高采样时间可以提高精确度
  89.     ADC1->SQR3&=~(0X0000001F<<(5*2));//规则序列1 ADC1通道1
  90.         ADC1->SQR3|=3<<(5*2);

  91.     ADC1->CR2|=1<<8;        //使能DMA
  92.     ADC1->CR2|=1<<0;           //开启AD转换器         

  93.     ADC1->CR2|=1<<3;       //使能复位校准  
  94.         while(ADC1->CR2&1<<3); //等待复位结束                          
  95.     //该位由软件设置并由硬件清除。在校准寄存器被初始化后该位将被清除。                  
  96.         ADC1->CR2|=1<<2;        //开启AD校准           
  97.         while(ADC1->CR2&1<<2);  //等待校准结束
  98.         //该位由软件设置以开始校准,并在校准结束时由硬件清除        

  99.         ADC1->CR2|=1<<20;      //使用SWSTART触发         必须使用一个事件来触发
  100.         ADC1->CR2|=1<<22;       //启动规则转换通道         
  101. }                                 
  102.                     
  103. //DMA1的各通道配置
  104. //这里的传输形式是固定的,这点要根据不同的情况来修改
  105. //从存储器->外设模式/16位数据宽度/存储器增量模式
  106. //DMA_CHx:DMA通道CHx
  107. //cpar:外设地址
  108. //cmar:存储器地址
  109. //cndtr:数据传输量  
  110. void DMA_Init(DMA_Channel_TypeDef*DMA_CHx)
  111. {
  112.         RCC->AHBENR|=1<<0;                        //开启DMA1时钟
  113.         delay_ms(5);                                //等待DMA时钟稳定
  114.     DMA_CHx->CCR&=~0x0001;
  115.     DMA_CHx->CCR=0;
  116.         DMA_CHx->CPAR=0;                  
  117.         DMA_CHx->CMAR=0;         
  118.         DMA_CHx->CNDTR=0;                    
  119.         DMA1->IFCR=0x0000000F;
  120.         
  121.         DMA_CHx->CPAR=(u32)&ADC1->DR; //DMA1 外设地址
  122.         DMA_CHx->CMAR=(u32)&ADC_Value; //DMA1,存储器地址
  123.         DMA_CHx->CNDTR=N*M;                //DMA1,传输数据量

  124.         DMA_CHx->CCR|=0<<4;                  //从外设读 DIR数据传输方向
  125.         DMA_CHx->CCR|=1<<5;                  //循环模式 CIRC=1
  126.         DMA_CHx->CCR|=0<<6;                 //外设地址非增量模式
  127.         DMA_CHx->CCR|=1<<7;                  //存储器增量模式
  128.         DMA_CHx->CCR|=1<<8;                  //外设数据宽度为16位
  129.         DMA_CHx->CCR|=1<<10;                 //存储器数据宽度16位
  130.         DMA_CHx->CCR|=3<<12;                 //高优先级
  131.         DMA_CHx->CCR|=0<<14;            //非存储器到存储器模式                          

  132.     DMA_CHx->CCR|=1<<0;          //开启DMA传输

  133. }
复制代码


多通道ADC检测+DMA(寄存器版本正在调试).7z

88.92 KB, 下载次数: 14

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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