OpenEdv-开源电子网

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

请问,将例程中adc实验修改为多通道,如何读取ADC1->DR

[复制链接]

2

主题

11

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2014-7-13
在线时间
0 小时
发表于 2014-8-16 11:46:50 | 显示全部楼层 |阅读模式
5金钱
[mw_shl_code=c,true]void Adc_Init(void) { //先初始化IO口 RCC->APB2ENR|=1<<2; //使能PORTA口时钟 GPIOA->CRL&=0XFFF0000F;//PA1 anolog输入 //////////////////ttttttttttttttttttttttttttttttt //通道10/11设置 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; //非扫描模式 ttttttttttttttttttttttttttttttttttttttt ADC1->CR2&=1<<1; //单次转换模式 连续 ttttttttttttttttttttttttttttt ADC1->CR2&=~(7<<17); ADC1->CR2|=7<<17; //软件控制转换 ADC1->CR2|=1<<20; //使用用外部触发(SWSTART)!!! 必须使用一个事件来触发 ADC1->CR2&=~(1<<11); //右对齐 ADC1->SQR1&=~(0XF<<20); ADC1->SQR1|=2<<20; //4个转换在规则序列中 tttttttttttttttttttt ttttttttttt //设置通道1的采样时间 ADC1->SMPR2&=0x7ff8; //通道1,2,3,4采样时间清空 tttttttttttttttttttttttttttttt ADC1->SMPR2|=0x7ff8; //通道1,2,3,4 239.5周期,提高采样时间可以提高精确度 ADC1->CR2|=1<<0; //开启AD转换器 ADC1->CR2|=1<<3; //使能复位校准 while(ADC1->CR2&1<<3); //等待校准结束 //该位由软件设置并由硬件清除。在校准寄存器被初始化后该位将被清除。 ADC1->CR2|=1<<2; //开启AD校准 while(ADC1->CR2&1<<2); //等待校准结束 //该位由软件设置以开始校准,并在校准结束时由硬件清除 } [/mw_shl_code]

这是我的初始化代码,想打开通道1,2,3,4,

[mw_shl_code=c,true]//获得ADC值 //ch:通道值 0~16 //返回值:转换结果 u16 Get_Adc(u8 ch) { //设置转换序列 ADC1->SQR3&=0XFFFFFFE0;//规则序列1 通道ch ADC1->SQR3|=ch; ADC1->CR2|=1<<22; //启动规则转换通道 while(!(ADC1->SR&1<<1));//等待转换结束 return ADC1->DR; //返回adc值 } //获取通道ch的转换值,取times次,然后平均 //ch:通道编号 //times:获取次数 //返回值:通道ch的times次转换结果平均值 u16 Get_Adc_Average(u8 ch,u8 times) { u32 temp_val=0; u8 t; for(t=0;t<times;t++) { temp_val+=Get_Adc(ch); delay_ms(5); } return temp_val/times; } [/mw_shl_code]
但是《例说stm32》中读取转换结果是这样写的,要怎样改才能读取4个通道啊,
还有,我在网上搜索了一下其他人的解决办法,貌似大多数人都是用的库函数,看不懂,是不是我现在应该去学学库函数啊

最佳答案

查看完整内容[请看2#楼]

很简单啊,在ADC_Init函数里面,设置4个通道的IO为模拟输入,然后设置4个通道的采集时间. 设置1个通道在规则序列里面 然后每次读不通的通道就是了 第一次读通道1. 第二次读通道2. 第三次..... 以此类推.
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-8-16 11:46:51 | 显示全部楼层
很简单啊,在ADC_Init函数里面,设置4个通道的IO为模拟输入,然后设置4个通道的采集时间.
设置1个通道在规则序列里面
然后每次读不通的通道就是了
第一次读通道1.
第二次读通道2.
第三次.....
以此类推.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

2

主题

582

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2690
金钱
2690
注册时间
2014-5-23
在线时间
188 小时
发表于 2014-8-16 15:52:06 | 显示全部楼层
没有记错的话,使用多通道的时候必须能使用DMA来传输转换值。
回复

使用道具 举报

2

主题

582

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2690
金钱
2690
注册时间
2014-5-23
在线时间
188 小时
发表于 2014-8-16 15:54:23 | 显示全部楼层
不过看你的程序应该是每一次只打开一个通道
回复

使用道具 举报

20

主题

232

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
335
金钱
335
注册时间
2013-6-1
在线时间
0 小时
发表于 2014-8-16 20:15:31 | 显示全部楼层
库函数很简单啊...看寄存器的代码要每个寄存器一个一个去看,好累
回复

使用道具 举报

2

主题

11

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2014-7-13
在线时间
0 小时
 楼主| 发表于 2014-8-16 20:37:26 | 显示全部楼层
回复【2楼】awsawzj:
---------------------------------
哦,现在还没看到DMA,就是想试试自己学没学会ADC而已,去学了DMA在来看吧,谢了
回复

使用道具 举报

2

主题

11

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2014-7-13
在线时间
0 小时
 楼主| 发表于 2014-8-16 20:39:08 | 显示全部楼层
回复【3楼】awsawzj:
---------------------------------
额,就是说这个程序是每次只打开一个通道,要怎么改才能打开4个通道,并读取呢?
回复

使用道具 举报

2

主题

11

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2014-7-13
在线时间
0 小时
 楼主| 发表于 2014-8-16 20:41:12 | 显示全部楼层
回复【4楼】Scy:
---------------------------------
当初买mini板的时候配套的《例说stm32》只有寄存器版本的,而且我才刚学了51,所以就学寄存器了,现在再去看看库函数吧
回复

使用道具 举报

2

主题

582

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2690
金钱
2690
注册时间
2014-5-23
在线时间
188 小时
发表于 2014-8-16 21:17:27 | 显示全部楼层
void ADC_Configuration(void)
{
ADC_InitTypeDef ADC_InitStructure;
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
  ADC_DeInit(ADC1);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; 
ADC_InitStructure.ADC_ScanConvMode = ENABLE;       
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;    
ADC_InitStructure.ADC_NbrOfChannel = 3;                
ADC_Init(ADC1, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_55Cycles5);   
ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 2, ADC_SampleTime_55Cycles5);    
ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 3, ADC_SampleTime_55Cycles5);   
ADC_Cmd(ADC1, ENABLE);  
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
ADC_DMACmd(ADC1,ENABLE);
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
回复

使用道具 举报

2

主题

582

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2690
金钱
2690
注册时间
2014-5-23
在线时间
188 小时
发表于 2014-8-16 21:19:17 | 显示全部楼层
回复【8楼】awsawzj:
---------------------------------
void DMA_Configuration(void)
{
    /* 定义 DMA 初始化结构体 DMA_InitStructure */
    DMA_InitTypeDef DMA_InitStructure;
    
    /* 将 DMA1通道的寄存器重设为默认值  */
    DMA_DeInit(DMA1_Channel1);
    
    /*
    * 外设地址:adc寄存器;
    * 内存地址:(u32)ADnum;
    * 外设作为数据传输的来源;
    * DMA 缓存大小:BufferSize;
    * 外设地址寄存器不变?
    * 内存地址寄存器递增;
    * 外设数据宽度为 32 位;
    * 内存数据宽度为 32 位;
    * 设置DMA通道优先级为高;
    * DMA 通道设置为内存到内存传输;   
    */
    
    DMA_InitStructure.DMA_PeripheralBaseAddr =(u32) & ADC1->DR;
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADnum;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize =3;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);
    DMA_Cmd(DMA1_Channel1,ENABLE);

}
回复

使用道具 举报

2

主题

11

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2014-7-13
在线时间
0 小时
 楼主| 发表于 2014-8-16 23:33:08 | 显示全部楼层
额,今天晚上看了温度传感器一章刚好想到这个方法……一来看,正好和原子哥说的一样……
回复

使用道具 举报

2

主题

11

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2014-7-13
在线时间
0 小时
 楼主| 发表于 2014-8-16 23:35:02 | 显示全部楼层
回复【10楼】正点原子:
---------------------------------
不过,如果规则序列里边有多个通道,就只能用DMA吗?
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

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

使用道具 举报

9

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
92
金钱
92
注册时间
2015-6-7
在线时间
2 小时
发表于 2015-6-28 00:44:55 | 显示全部楼层
回复【10楼】正点原子:
---------------------------------

你好,原子哥,如果这样做的话,还可以使用DMA传输吗
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-6-28 10:42:46 | 显示全部楼层
回复【14楼】hxing:
---------------------------------
不能。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-20 20:00

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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