当前位置:首页 > 单片机 > 单片机
[导读]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);//软件触发,这时候真正开始转换
硬件测试后,结果正确的!

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

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭