OpenEdv-开源电子网

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

stm32 adc多通道采集 使用dma 为什么只显示一个通道的值啊?

[复制链接]

4

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
52
金钱
52
注册时间
2012-9-16
在线时间
0 小时
发表于 2012-9-16 18:12:52 | 显示全部楼层 |阅读模式

请各位大侠帮忙看看啊   感谢.....
下面是我的程序部分:

adc的初始化设置:
void  Adc_Init(void)
{   
 //先初始化IO口
  RCC->APB2ENR|=1<<4;    //使能PORTC口时钟
 GPIOC->CRL&=0XFFF00000;//PC 0 1 2 3 4 anolog输入  
 RCC->APB2ENR|=1<<9;    //ADC1时钟使能  
 RCC->APB2RSTR|=1<<9;   //ADC1复位
 RCC->APB2RSTR&=~(1<<9);//复位结束    
 RCC->CFGR&=~(3<<14);   //分频因子清零 
 //SYSCLK/DIV2=12M ADC时钟设置为12M,ADC最大时钟不能超过14M!
 //否则将导致ADC准确度下降!
 RCC->CFGR|=2<<14;       

 ADC1->CR1&=0XF0FFFF;   //工作模式清零
 ADC1->CR1|=0<<16;      //独立工作模式 
 ADC1->CR1|=1<<8;       //扫描模式  
 ADC1->CR2|=1<<1;       //连续转换模式
 ADC1->CR2&=~(7<<17);
 ADC1->CR2|=1<<20;      //软件设置启动转换   
 ADC1->CR2|=7<<17;    //使用用外部触发(SWSTART)!!! 必须使用一个事件来触发
 
 ADC1->CR2&=~(1<<11);   //右对齐 
 ADC1->SQR1&=~(0XF<<20); 
 //ADC1->SQR3&=0X00000000;
 ADC1->SQR1&=4<<20;    //5个转换在规则序列中      
 //设置通道0~4的采样时间
 //ADC1->SQR3=0x0E6B16A;
 ADC1->SQR3|=0xa<<0;   //通道10为规则序列1
 ADC1->SQR3|=0xb<<5;   // 通道11为规则序列2
 ADC1->SQR3|=0xc<<10;  //  通道12为规则序列3
 ADC1->SQR3|=0xd<<15;  //  通道13为规则序列4
 ADC1->SQR3|=0xe<<20;  //  通道14为规则序列5
 ADC1->SMPR1&=0XFFFF0000;//通道10,11,12,13,14采样时间清空  
 ADC1->SMPR1|=7<<12;     //通道14  239.5周期,提高采样时间可以提高精确度 
 ADC1->SMPR1|=7<<9;      //通道13  239.5周期,提高采样时间可以提高精确度 
 ADC1->SMPR1|=7<<6;      //通道12  239.5周期,提高采样时间可以提高精确度 
 ADC1->SMPR1|=7<<3;      //通道11  239.5周期,提高采样时间可以提高精确度 
 ADC1->SMPR1|=7<<0;  //通道10  239.5周期,提高采样时间可以提高精确度
 ADC1->CR2|=1<<0;     //开启AD转换器 
 ADC1->CR2|=1<<3;        //使能复位校准 
 while(ADC1->CR2&1<<3);  //等待校准结束    
    //该位由软件设置并由硬件清除。在校准寄存器被初始化后该位将被清除。
 ADC1->CR2|=1<<8;        //开启ADC DMA转换   
 ADC1->CR2|=1<<2;        //开启AD校准   
 while(ADC1->CR2&1<<2);  //等待校准结束
 //该位由软件设置以开始校准,并在校准结束时由硬件清除
 ADC1->CR2|=1<<22; //启动规则转换通道
 ADC1->CR2|=1<<0;  //开启AD转换

}     
dma初始化设置:
void MYDMA_Config(DMA_Channel_TypeDef*DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{

 RCC->AHBENR|=1<<0;//开启DMA1时钟
 __nop();
 __nop();
 DMA_CHx->CPAR=cpar;   //DMA1 adc外设地址
 DMA_CHx->CMAR=cmar; //DMA1,存储器地址
 DMA1_MEM_LEN=cndtr;      //保存DMA传输数据量
 DMA_CHx->CNDTR=cndtr;    //DMA1,传输数据量
 DMA_CHx->CCR=0X00000000;//复位
 DMA_CHx->CCR|=1<<1;    //允许传输完中断
 DMA_CHx->CCR|=0<<4;  //从外设读取读据
 DMA_CHx->CCR|=1<<5;  //循环模式
 DMA_CHx->CCR|=0<<6;  //外设地址非增量模式
 DMA_CHx->CCR|=1<<7;  //存储器增量模式
 DMA_CHx->CCR|=1<<8;  //外设数据宽度为16位
 DMA_CHx->CCR|=1<<10; //存储器数据宽度16位
 DMA_CHx->CCR|=2<<12; //高等优先级
 DMA_CHx->CCR|=0<<14; //非存储器到存储器模式
 MY_NVIC_Init(1,3,DMA1_Channel1_IRQChannel ,2);      
}
//开启一次DMA传输
void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx)
{
    DMA_CHx->CCR&=~(1<<0);  //关闭DMA传输
 DMA_CHx->CNDTR=DMA1_MEM_LEN; //dma传输数据量
 DMA_CHx->CCR|=1<<0;          //开启DMA传输
}

下面的是主程序部分:
int main(void)

 u16 R1=0;
    u16 R2=0;
 u16 R3=0;
    u16 R4=0;
 u16 R5=0;
 u16 table[10]={'0','1','2','3','4','5','6','7','8','9'};
 Stm32_Clock_Init(9);//系统时钟设置
 delay_init(72);     //延时初始化      
 uart_init(36,9600); //串口2初始化
 IIC_Init();   //IIc初始化
 key_init();         //按键初始化
 lcdport_init();     //lcd端口初始化
 LCDInit();    //lcd初始化
 Adc_Init();         //adc初始化       
 MYDMA_Config(DMA1_Channel1,(u32)&ADC1->DR ,(u32)&AD_Value,5200);  //初始化dma的设置,选择通道为dma1,外设地址为adc_dr,存贮器地址为adc_buf,数据长度为2
 MYDMA_Enable(DMA1_Channel1);//开启一次dma的传输

 while(1)
 { 
  //filter();//调用平均值函数
  //if(DMA1->ISR&(1<<1))
     //{
     R1=GetVolt(value1);//获取adc通道10的值
     DisplayListChar(0,0,"U:");
     DisplayOneChar(2,0,table[R1/1000]);
     DisplayOneChar(3,0,'.');
     DisplayOneChar(4,0,table[(R1%1000)/100]);
     DisplayOneChar(5,0,table[((R1%1000)%100)/10]);
     DisplayOneChar(6,0,table[((R1%1000)%100)%10]);

     R2=GetVolt( value2);//获取adc通道11的值
     DisplayListChar(8,0,"V:");
     DisplayOneChar(10,0,table[ R2/1000]);
     DisplayOneChar(11,0,'.');
     DisplayOneChar(12,0,table[(R2%1000)/100]);
     DisplayOneChar(13,0,table[((R2%1000)%100)/10]);
     DisplayOneChar(14,0,table[((R2%1000)%100)%10]);

     R3=GetVolt( value3);//获取adc通道12的值
     DisplayListChar(0,1,"W:");
     DisplayOneChar(2,1,table[R3/1000]);
     DisplayOneChar(3,1,'.');
     DisplayOneChar(4,1,table[(R3%1000)/100]);
     DisplayOneChar(5,1,table[((R3%1000)%100)/10]);
     DisplayOneChar(6,1,table[((R3%1000)%100)%10]);

     R4=GetVolt( value4);//获取adc通道13的值
     DisplayListChar(8,1,"D:");
     DisplayOneChar(10,1,table[R4/1000]);
     DisplayOneChar(11,1,'.');
     DisplayOneChar(12,1,table[(R4%1000)/100]);
     DisplayOneChar(13,1,table[((R4%1000)%100)/10]);
     DisplayOneChar(14,1,table[((R4%1000)%100)%10]);
     delay_ms(250);
     //DMA1->IFCR|=1<<1;//清除标志位
     //MYDMA_Enable(DMA1_Channel1);//再次开启DMA传输
   
 // }
   //DisplayListChar(0,0,"YUHONG TECH:"); 
 }

 

 

}
//获取ADC的值,将二进制换算为十进制
u16 GetVolt(u16 advalue)
{
 return (u16)(advalue*3300/4096);//所求结果扩大了1000倍,精确带小数点后三位
}

void DMAChannel1_IRQHandler(void)//求函数的平均值
{
 u16 i;
 u32 sum[5]={0};
 ADC1->CR2&=~(1<<1);  //关闭连续转换
 for(i=0;i<250;i+=5)
 {
  sum[0]+= AD_Value[i+0];
  sum[1]+= AD_Value[i+1];
  sum[2]+= AD_Value[i+2];
  sum[3]+= AD_Value[i+3];
  sum[4]+= AD_Value[i+4];
 }

 value1=sum[0]/50;
 value2=sum[1]/50;
 value3=sum[2]/50;
 value4=sum[3]/50;
 value5=sum[4]/50;
 DMA1->IFCR |= 1<<1;  //清零通道完成中断标志位
 ADC1->CR2|=1<<1;     //启用连续转换
 ADC1->CR2|=1<<22;    //启动规则转换通道
}
显示部分是用1602显示的,其他几个通道的值和第一个通道的值一样......?
检查了好多遍都没用,不知道是不是dma传输的地址没有配置正确...

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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2012-9-16 21:23:18 | 显示全部楼层
论坛有例程:http://www.openedv.com/posts/list/1772.htm
供参考。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

4

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
52
金钱
52
注册时间
2012-9-16
在线时间
0 小时
 楼主| 发表于 2012-9-17 08:55:51 | 显示全部楼层
 谢谢!
回复 支持 反对

使用道具 举报

2

主题

15

帖子

0

精华

新手上路

积分
43
金钱
43
注册时间
2012-12-3
在线时间
0 小时
发表于 2012-12-3 23:29:01 | 显示全部楼层
回复【3楼】yuemanxilou:
---------------------------------
请问楼主解决了么?
回复 支持 反对

使用道具 举报

4

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
52
金钱
52
注册时间
2012-9-16
在线时间
0 小时
 楼主| 发表于 2012-12-6 11:44:50 | 显示全部楼层
回复【4楼】沐雨_枫林:
---------------------------------
嗯  解决了
回复 支持 反对

使用道具 举报

2

主题

15

帖子

0

精华

新手上路

积分
43
金钱
43
注册时间
2012-12-3
在线时间
0 小时
发表于 2012-12-9 21:07:32 | 显示全部楼层
回复【5楼】yuemanxilou:
---------------------------------
你的现在是几通道读取啊我的六通道读取正常当时加到7通道就不正常了能否把你的程序借我看看呢?
回复 支持 反对

使用道具 举报

12

主题

44

帖子

0

精华

初级会员

Rank: 2

积分
152
金钱
152
注册时间
2012-5-18
在线时间
12 小时
发表于 2013-6-20 16:49:34 | 显示全部楼层
请问什么原因呢
回复 支持 反对

使用道具 举报

4

主题

7

帖子

0

精华

新手上路

积分
43
金钱
43
注册时间
2014-3-14
在线时间
0 小时
发表于 2014-3-14 16:43:02 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
这个例程是几通道的ad采样?求助?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-3-14 23:12:27 | 显示全部楼层
回复【8楼】lucas:
---------------------------------
请看代码。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

8

主题

73

帖子

0

精华

初级会员

Rank: 2

积分
126
金钱
126
注册时间
2014-2-27
在线时间
0 小时
发表于 2014-6-10 21:10:25 | 显示全部楼层
楼主,我也碰到了这样的问题,你是怎么解决了????
文可提笔控萝莉,武能床头定人妻,进可欺身压正太,退能提臀迎众基
回复 支持 反对

使用道具 举报

4

主题

10

帖子

0

精华

初级会员

Rank: 2

积分
102
金钱
102
注册时间
2016-1-22
在线时间
27 小时
发表于 2016-7-10 16:41:41 | 显示全部楼层
怎么就解决的
回复 支持 反对

使用道具 举报

9

主题

48

帖子

0

精华

初级会员

Rank: 2

积分
98
金钱
98
注册时间
2018-2-11
在线时间
18 小时
发表于 2018-9-19 10:48:05 | 显示全部楼层
也遇到了这个问题!!!
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-19 20:34

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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