当前位置:首页 > 单片机 > 单片机
[导读]stm32内部集成的ADC介绍一、参考电压的范围为/*2.4V≦ V ≦3.6V所以它的输入模拟电压范围0

stm32内部集成的ADC介绍
一、参考电压的范围为
/*2.4V≦ V ≦3.6V
所以它的输入模拟电压范围0 <= V <=V*/
二、需要测量负电压或测量的电压信号超出范围时,要先经过运算电路进行平移或利用电阻分压。
三、我采用的是51单片机上面的10k的电阻来模拟输入
四、规则通道和注入通道
/*所谓规则,那么就是按常理出牌的,我们可以称之为正常的通道,那么与之对应的是注入通道,就是
在规则通道正在转换的时候是可以被注入通道打断,转而去执行注入通道转换的,当注入通道转换完
成之后,才继续去进行规则通道里面的转换,TM32ADC的规则通道组最多包含16 个转换,而注入通道
组最多包含 4 个通道*/
五、初始化ADC这是必须的,比东有一个结构体来初始化这个ADC
1、首先确定从哪里输入我们的模拟量呢?
这里涉及到ADC通道的知识,每个ADC通道都对应着一个GPIO引脚端口
PC0对应的默认复用功能是ADC1、ADC2、ADC3的通道10
所以最开始应该配置GPIO,现在可以来做个猜测
2、配置GPIO


GPIO_Mode = GPIO_Mode_AIN
GPIO_Pin = GPIO_Pin_10
GPIO_Speed = GPIO_Speed_50MHz
以上就是模拟输入
六、然后是配置ADC,也就是初始化ADC了,
找到这样一个结构体
ADC_InitTypeDef
结构体成员有{
FunctionalState ADC_ContinuousConvMode
uint32_t ADC_DataAlign
uint32_t ADC_ExternalTrigConv
uint32_t ADC_Mode
uint8_t ADC_NbrOfChannel
FunctionalState ADC_ScanConvMode
}
1、ADC_ContinuousConvMode的取值有
Specifies whether the conversion is performed in Continuous or Single mode.
This parameter can be set to ENABLE or DISABLE
此参数用来配置是否开启循环采集ENABLE or DISABLE
2、ADC_DataAlign明显意思是数据对齐,它的取值有
#define ADC_DataAlign_Left ((uint32_t)0x00000800)
#define ADC_DataAlign_Right ((uint32_t)0x00000000)
#define IS_ADC_DATA_ALIGN(ALIGN)
左对齐,右对齐。。
3、ADC_ExternalTrigConv外部中断触发方式?它的取值有
#define ADC_ExternalTrigConv_Ext_IT11_TIM8_TRGO ((uint32_t)0x000C0000)
#define ADC_ExternalTrigConv_None ((uint32_t)0x000E0000)
#define ADC_ExternalTrigConv_T1_CC1 ((uint32_t)0x00000000)
#define ADC_ExternalTrigConv_T1_CC2 ((uint32_t)0x00020000)
#define ADC_ExternalTrigConv_T1_CC3 ((uint32_t)0x00040000)
#define ADC_ExternalTrigConv_T2_CC2 ((uint32_t)0x00060000)
#define ADC_ExternalTrigConv_T2_CC3 ((uint32_t)0x00020000)
#define ADC_ExternalTrigConv_T3_CC1 ((uint32_t)0x00000000)
#define ADC_ExternalTrigConv_T3_TRGO ((uint32_t)0x00080000)
#define ADC_ExternalTrigConv_T4_CC4 ((uint32_t)0x000A0000)
#define ADC_ExternalTrigConv_T5_CC1 ((uint32_t)0x000A0000)
#define ADC_ExternalTrigConv_T5_CC3 ((uint32_t)0x000C0000)
#define ADC_ExternalTrigConv_T8_CC1 ((uint32_t)0x00060000)
#define ADC_ExternalTrigConv_T8_TRGO ((uint32_t)0x00080000)
触发方式很丰富,当然 ADC_ExternalTrigConv_None这就表示不采用外部中断方式触发(那么软件触发)
4、ADC_Mode ADC的模式?
Configures the ADC to operate in independent or dual mode.
This parameter can be a value of ADC_mode
它的取值有
#define ADC_Mode_AlterTrig ((uint32_t)0x00090000)
#define ADC_Mode_FastInterl ((uint32_t)0x00070000)
#define ADC_Mode_Independent ((uint32_t)0x00000000)
#define ADC_Mode_InjecSimult ((uint32_t)0x00050000)
#define ADC_Mode_InjecSimult_FastInterl ((uint32_t)0x00030000)
#define ADC_Mode_InjecSimult_SlowInterl ((uint32_t)0x00040000)
#define ADC_Mode_RegInjecSimult ((uint32_t)0x00010000)
#define ADC_Mode_RegSimult ((uint32_t)0x00060000)
#define ADC_Mode_RegSimult_AlterTrig ((uint32_t)0x00020000)
#define ADC_Mode_SlowInterl ((uint32_t)0x00080000)
貌似是有注入组、和规则组的概念,有些单词不是很熟悉,没关系那就先这样吧!用到了再来
5、ADC_NbrOfChannel采样通道?
明显一般采用的是是16个规则通道,那取值就是1--16
Specifies the number of ADC channels that will be converted using the sequencer for regular
channel group.This parameter must range from 1 to 16
6、ADC_ScanConvMode,字面意思不是很懂,看手册
Specifies whether the conversion is performed in Scan (multichannels) or Single (one channel)
mode. This parameter can be set to ENABLE or DISABLE
意思是当有多个通道的时候,使用扫描的方式,反之只有单个通道的是那么就是选择单通道了
那么取值就是ENABLE or DISABLE
至此结构成员分析完毕,下面来猜测一下,应该怎样赋值,声明:单通道采集,右对齐(方便存数据)
软件触发,通道采用10(使用PC0)
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None
ADC_InitStructure.ADC_Mode= ADC_Mode_Independent
ADC_InitStructure.ADC_NbrOfChannel = 11
ADC_InitStructure.ADC_ScanConvMode = DISABLE
下面来对照下,原始代码看看:
/* ADC1 configuration */
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 = 1;
ADC_Init(ADC1, &ADC_InitStructure);
显然错误还是比较多的,没关系,慢慢分析
1、因为是一个通道没必要扫描,所以第2个错了
2、通道数目理解错误。我以为那是指定的哪个通道,原来是number of channel
3、好的最后就是少了一个库函数的调用,这确实是缺乏这种意识呀!
七、既然是使用DMA来传送数据,那么下一步就开始初始化DMA吧!DMA的知识暂时不分析,那个得单独出来
我还是先来了解下DMA的变成思想吧!
1、STM32就是这样完美,每个模块都能有个结构体来组织它的一些参数配置,我甚至觉得它和uboot一样讨人喜欢
这只是我的愚见,也是这样一个结构体 DMA_InitTypeDef DMA_InitStructure;
跟着手册来吧
2、DMA_InitTypeDef{
uint32_t DMA_BufferSize
uint32_t DMA_DIR
uint32_t DMA_M2M
uint32_t DMA_MemoryBaseAddr
uint32_t DMA_MemoryDataSize
uint32_t DMA_MemoryInc
uint32_t DMA_Mode
uint32_t DMA_PeripheralBaseAddr
uint32_t DMA_PeripheralDataSize
uint32_t DMA_PeripheralInc
uint32_t DMA_Priority
}
3、DMA_BufferSize,明显就是数据的大小,看她是怎么描述的
Specifies the buffer size, in data unit, of the specified Channel. The data unit is equal to
the configuration set in DMA_PeripheralDataSize or DMA_MemoryDataSize members depending in
the transfer direction
可以得出DMA_PeripheralDataSize = DMA_MemoryDataSize = DMA_BufferSize
取值可以是
#define DMA_MemoryDataSize_Byte ((uint32_t)0x00000000)
#define DMA_MemoryDataSize_HalfWord ((uint32_t)0x00000400)
#define DMA_MemoryDataSize_Word ((uint32_t)0x00000800)
4、DMA_DIR字面意思不怎么明朗方向?看解释
Specifies if the peripheral is the source or destination. This parameter can be a value of
DMA_data_transfer_direction
数据源和目的源
取值
#define DMA_DIR_PeripheralDST ((uint32_t)0x00000010)
#define DMA_DIR_PeripheralSRC ((uint32_t)0x00000000
从存储器到外设或者从外设到存储器
5、DMA_M2M 这个可以猜测到,DMA的作用出了上面一个还有M to M的没有提及那么
#define DMA_M2M_Disable ((uint32_t)0x00000000)
#define DMA_M2M_Enable ((uint32_t)0x00004000)
可以这样设置了
6、DMA_MemoryBaseAddr、DMA_PeripheralBaseAddr
这两个可以一起看了,字面意思很清楚了,外设地址和存储器(变量)地址,这个得看你的地址了
7、DMA_MemoryInc、DMA_PeripheralInc看变量名不是很了解,中断触发么?看解释
Specifies whether the memory address register is incremented(adj.增加的) or not.
This parameter can be a value of DMA_memory_incremented_mode
地址增加?理解严重错误,那么就是地址递增的意思吧,那就是可以连续采集多个通道咯?继续分析
8、DMA_Mode:DMA的模式,他有什么模式呢?看解释
Specifies the operation mode of the DMAy Channelx.
This parameter can be a value of DMA_circular_normal_mode
还有一句:The circular buffer mode cannot be used if the memory-to-memory
data transfer is configured on the selected Channel
取值有
#define DMA_Mode_Circular ((uint32_t)0x00000020)
#define DMA_Mode_Normal ((uint32_t)0x00000000)
正常和循环模式,难道是轮采?先这样继续
9、DMA_Priority优先级这个就好理解了,不就是控制优先权么看解释以及取值
Specifies the software priority for the DMAy Channelx. This parameter can be
a value of DMA_priority_level
取值
#define DMA_Priority_High ((uint32_t)0x00002000)
#define DMA_Priority_Low ((uint32_t)0x00000000)
#define DMA_Priority_Medium ((uint32_t)0x00001000)
#define DMA_Priority_VeryHigh ((uint32_t)0x00003000
很明朗4个优先级
至此,分析完毕,尝试性猜测
1、DMA_InitStructure.DMA_BufferSize= 1
2、DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST
3、DMA_InitStructure.DMA_M2M = DMA_M2M_Disable
4、DMA_InitStructure.DMA_MemoryBaseAddr = 一个地址单元的变量单字节 可以使char型的
5、DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte
6、DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable 不需要地址增量
7、DMA_InitStructure.DMA_Mode = DMA_Mode_Circular 不停的采
8、DMA_InitStructure.DMA_PeripheralBaseAddr = 串口的地址?
9、DMA_InitStructure.DMA_PeripheralDataSize = DMA_MemoryDataSize_Byte
10、DMA_InitStructure.MA_PeripheralInc = DMA_PeripheralInc_Disable 同样的
11、DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh 给最高的
查看源代码
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
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);
貌似有点不妙的感觉
1、MA_InitStructure.DMA_DIR这个明显是作为数据源
2、DMA_MemoryDataSize_Byte和DMA_PeripheralDataSize_HalfWord有什么区别
百度里面我没有找到,先这样,等做完实验再验证
八、结构体成员初始化完毕之后,还有很多工作要做
1、 /* ADC1 regular channel11 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_55Cycles5);
配置规则通道11
2、 /* Enable DMA channel1 */
DMA_Cmd(DMA1_Channe10, ENABLE);
使能DMA通道
3、 /* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
使能ADC1的DMA控制器
4、 /* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
使能ADC1
5、 /* Enable ADC1 reset calibaration register */
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1));//复位校准


/* Start ADC1 calibaration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));//校准

/* Start ADC1 Software Conversion */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);//软件触发,这时候真正开始转换
硬件测试后,结果正确的!

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

stm32f103zet6是一种嵌入式-微控制器的集成电路(IC),是由ST公司开发的STM32F1系列的其中一种,芯体尺寸是32位,速度是72MHz,程序存储器容量是256KB,程序存储器类型是FLASH,RAM容量是...

关键字: stm32f103zet6 datasheet 引脚图

从我们的直观感受来说,DMA并不是一个复杂的东西,要做的事情也很单纯直白。因此Linux kernel对它的抽象和实现,也应该简洁、易懂才是。不过现实却不甚乐观(个人感觉),Linux kernel dmaengine...

关键字: Linux dma

  吉利dma项目进展   为进一步扩大市场份额和开拓大客户市场,吉利汽车拟在梅山岛新建整车生产工业园,本项目总用地面积约1888亩,项目位于宁波市北仑区东南海滨的梅山岛。地块北侧为七星

关键字: dma 吉利

  吉利品牌包含BMA乘用车在内的三大项目此前已宣布落户成都,预计整车总产能将达60万台。近日网通社从成都市发改委获悉,吉利正推进成都BMA/PMA、宁波梅山DMA基地建设项目,未来将投产多款吉

关键字: dma 吉利

什么是8位微控制器STM8L050?它有什么作用?2019年1月16日 - 意法半导体推出了全新的8位微控制器STM8L050的推出,以提升低成本、低功耗8位微控制器(MCU)的功能集成度。作为超高能效的STM8L系列的...

关键字: dma MCU stm8l050

这是一篇指导驱动工程师如何使用DMA API的文档。

关键字: CPU dma

本文从计算机组成原理的层面详细介绍了DMA,以及Linux网络子系统的DMA机制是如何实现的。

关键字: dma Linux 编程

你知道嵌入式驱动程序关于设计层面的技术吗?无论学习什么都有需要掌握的要点与窍门,本文我们一起深入了解关于嵌入式驱动程序关于设计层面的窍门。每一个嵌入式应用软件都会在某些时候访问最底层的固件和进行一些硬件控制。 驱动的设计...

关键字: dma 嵌入式设计 usart驱动程序

今天,我将带您了解Linux内存管理。 对于精通CURD的学生,内存管理似乎离我们还很远,但是尽管这一知识点并不热门(据估计,很多人在学习后不会再使用它),但这无疑是基础。 虽然学完后没有看到即时的效果,但是它将对您将来...

关键字: dma Linux zone
关闭
关闭