stm32ADC值读取-

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

stm32ADC值读取-
void AD_Init(void)
(1)初始化DMA结构体变量
typedef struct
{
uint32_t DMA_PeripheralBaseAddr; /*!< Specifies the peripheral base address for DMAy Channelx. */
uint32_t DMA_MemoryBaseAddr; /*!< Specifies the memory base address for DMAy Channelx. */
uint32_t DMA_DIR; /*!< Specifies if the peripheral is the source or destination.This parameter can be a value of @ref
DMA_data_transfer_direction */
uint32_t 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. */
uint32_t DMA_PeripheralInc; /*!< Specifies whether the Peripheral address register is incremented or not.This parameter can be a value of @ref DMA_peripheral_incremented_mode */
uint32_t DMA_MemoryInc; /*!< Specifies whether the memory address register is incremented or not.This parameter can be a value of @ref DMA_memory_incremented_mode */
uint32_t DMA_PeripheralDataSize; /*!< Specifies the Peripheral data width.This parameter can be a value of @ref
DMA_peripheral_data_size */
uint32_t DMA_MemoryDataSize; /*!< Specifies the Memory data width.This parameter can be a value of @ref DMA_memory_data_size */
uint32_t DMA_Mode; /*!< Specifies the operation mode of the DMAy Channelx.This parameter can be a value of @ref
DMA_circular_normal_mode. @note: The circular buffer mode cannot be used if the memory-to-memodata transfer is configured on the selected Channel */
uint32_t DMA_Priority; /*!< Specifies the software priority for the DMAy Channelx.This parameter can be a value of @ref
DMA_priority_level */
uint32_t DMA_M2M; /*!< Specifies if the DMAy Channelx will be used in memory-to-memory transfer.This parameter can be a value of @ref DMA_memory_to_memory */
}DMA_InitTypeDef;
{
}
什么是DMA?其全称是:Direct Memory Access;根据ST公司提供的相关信息,DMA是STM32中⼀个独⽴与Cortex-M3内核的模块,有点类似与ADC、PWM、TIMER等模块;主要功能是通信“桥梁”的作⽤,可以将所有外设映射的寄存器“连接”起来,这样就可以⾼速问各寄存器,其传输不受CPU的⽀配,传输还是双向的;例如,从“表⾯”上看,它可以将flash中的数据与储存器中变量建⽴通讯,还可以将⼀外设的积存器或缓冲器与另外设的寄存器或缓冲器建⽴双向通讯,有点像把外设硬件之间⽤“导线”连接在⼀起了。

其间的通讯不占CPU资源,访问速度⾼,对于实时性强的应⽤将是⼀个很好的选择;就像我们⼈⼀样,我们平常习惯性的动作是不⽤经过⼤脑思考的,⽐如说眨眼睛,呼吸等。

DMA就是负责这些⼯作的,但它没⼈这么智能,需要将它设置好了它才会正常⼯作。

当然,对于实时性⾮常强的,建议还是采⽤专⽤的DSP芯⽚。

(2)初始化ADC结构体变量
typedef struct
{
uint32_t ADC_Mode; /*!< Configures the ADC to operate in independent or dual mode. This parameter can be a value of @ref ADC_mode */
FunctionalState 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 */
FunctionalState ADC_ContinuousConvMode; /*!< Specifies whether the conversion is performed in Continuous or Single mode.This parameter can be set to ENABLE or DISABLE. */
uint32_t ADC_ExternalTrigConv; /*!< Defines the external trigger used to start the analog to digital conversion of regular channels. This parameter can be a value of @ref ADC_external_trigger_sources_for_regular_channels_conversion */
uint32_t ADC_DataAlign; /*!< Specifies whether the ADC data alignment is left or right.This parameter can be a value of @ref ADC_data_align */
uint8_t ADC_NbrOfChannel; /*!< 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. */
}ADC_InitTypeDef;
}
(3)初始化GPIO结构体变量
(4)初始化外设GPIOC设置引脚(pin9、pin6、pin7),速度,模式:推挽输出
(5)初始化外设GPIOA设置引脚PIN11速度,模式:推挽输出
(6)初始化外设GPIOE设置引脚(pin2,pin4,pin5,pin6,pin7,pin9,pin12),速度,模式:推挽输出(7)清除指定的数据端⼝位(清除外设GPIOE的端⼝为pin5)
(8)初始化外设GPIOA设置引脚(pin0,pin1,pin5,pin6,pin7),模式:模拟输⼊
(9)初始化外设GPIOB设置引脚(pin0,,pin1),模式:模拟输⼊
(10)初始化外设GPIOC设置引脚(PIN0,PIN1,PIN2,pin3,pin4,pin5),模式:模拟输⼊
(11)DMA1通道1配置
①使通道1缺省
②设置DMA
DMA1外设基地址ADC1_DR_Address
DMA1内存基地址&ADC1ConvertedValue//////INT16U ADC1ConvertedValue[13] = {0}; //⽤于存放读取的AD值规定了外设是作为数据传输的来源
DMA1通道的DMA缓存⼤⼩为13
设定外设地址寄存器不增值
设定内存地址寄存器递增
设定了外设数据宽度DMA_PeripheralDataSize_HalfWord
//#define DMA_PeripheralDataSize_HalfWord ((uint32_t)0x00000100)
设定了外设数据宽度DMA_MemoryDataSize_HalfWord
//#define DMA_MemoryDataSize_HalfWord ((uint32_t)0x00000400)
设置了 CAN 的⼯作模式:⼯作在循环缓存模式
设定 DMA 通道 1 的软件优先级//⾼优先级
DMA 通道 1 没有设置为内存到内存传输
③根据上⾯设置初始化DMA1的通道1寄存器
(12)ADC1配置
①设置ADC1
设置 ADC1 ⼯作在独⽴
规定了模数转换⼯作在扫描模式(多通道)
规定了模数转换⼯作在连续
定义了转换由软件⽽不是外部触发启动
ADC 数据右对齐
规定了顺序进⾏规则转换的 ADC 通道的数⽬13
②根据 ADC_InitStruct 中指定的参数初始化外设 ADC1 的寄存器
(13)配置ADC1正规渠道
设置ADC1外设不同通道的采样顺序及采样时间
(14)使ADC的DMA请求
(15)使能ADC1
(16)重置指定的 ADC 的校准寄存器·
(17)获取 ADC 重置校准寄存器的状态
(18)开始指定 ADC 的校准状态
(19)获取指定 ADC 的校准程序
(20)使DMA1的通道1使能
(21)使能指定的 ADC 的软件转换启动功能(连续转换开始,ADC通过DMA⽅式不断的更新RAM区。


最后⼀步将ADC的值传⼊到之前申明的INT16U ADC1ConvertedValue[13] = {0}; //⽤于存放读取的AD值中。

#define ADC1_Chanel0 0
#define ADC1_Chanel1 1
#define ADC1_Chanel2 2
#define ADC1_Chanel3 3
#define ADC1_Chanel4 4
#define ADC1_Chanel5 5
#define ADC1_Chanel6 6
#define ADC1_Chanel7 7
#define ADC1_Chanel8 8
#define ADC1_Chanel9 9
#define ADC1_Chanel10 10
#define ADC1_Chanel11 11
#define ADC1_Chanel12 12
#define ADC1_Chanel13 13
#define ADC1_Chanel14 14
#define ADC1_Chanel15 15
#define ADC1_Chanel16 16
//====AD开启通道个数======================
#define ADC_ENB_NUM 1
#define ADC_CYC_Cycles5 ADC_SampleTime_55Cycles5 //设置AD转换速率
uint16_t AD_Value[ADC_ENB_NUM] ; //DMA存储数据的区域
#define ADC1_DR_Address ((uint32_t)0x4001244C) //ADC1数据寄存器的基地址
//*************************************
// 函数名称:ADC1_Config
// 函数功能:adc1 初始化配置
// ⼊⼝参数:⽆
// 出⼝参数:⽆
// 返回值:⽆
//***************************************/
void ADC1_Config(void)
{
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 , ENABLE); //使能ADC
/* DMA1 channel1 configuration ----------------------------------------------*/
RCC_ADCCLKConfig(RCC_PCLK2_Div6) ; //ADC时钟分频 72/6 = 12M
/* 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外部开关,关闭状态 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //对齐⽅式,ADC为12位中,右对齐⽅式 ADC_InitStructure.ADC_NbrOfChannel = ADC_ENB_NUM; //开启通道数,1个
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel9 configuration */
//ADC通道组,第9个通道采样顺序1,转换时间
ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 1, ADC_CYC_Cycles5);
// ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 2, ADC_SampleTime_55Cycles5);
ADC_DMACmd(ADC1, ENABLE); //ADC命令,使能
ADC_Cmd(ADC1, ENABLE); //开启ADC1
ADC_ResetCalibration(ADC1); //重新校准
while(ADC_GetResetCalibrationStatus(ADC1)); //等待重新校准完成
ADC_StartCalibration(ADC1); //开始校准
while(ADC_GetCalibrationStatus(ADC1)); //等待校准完成
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //连续转换开始,ADC通过DMA⽅式不断的更新RAM区。

// ADC_TempSensorVrefintCmd(ENABLE);
}
//*************************************
// 函数名称:DMA_Config_ADC1
// 函数功能:DMA 初始化配置
// ⼊⼝参数:⽆
// 出⼝参数:⽆
// 返回值:⽆
//***************************************/
void DMA_Config_ADC1(void)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA时钟
DMA_DeInit(DMA1_Channel1); //开启DMA1的第⼀通道
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; //DMA对应的外设基地址
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&AD_Value[0];//内存存储基地址⾃⼰开僻的数组
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//DMA的转换模式为SRC模式,由外设搬移到内存
DMA_InitStructure.DMA_BufferSize = Num_Adc_Chanel; //DMA缓存⼤⼩,N个
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //接收⼀次数据后,设备地址禁⽌后移
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //关闭接收⼀次数据后,⽬标内存地址后移
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //定义外设数据宽度为16位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //DMA搬移数据尺⼨,HalfWord就是为16位 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //转换模式,循环缓存模式。

DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA优先级⾼
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //M2M模式禁⽤
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
/* Enable DMA1 channel1 */
DMA_Cmd(DMA1_Channel1, ENABLE);
}
//===ADC GPIO 初始化=======
void ADC1_GPIOInit(void)
{
//-----------PB---------------------------------
//VR 端⼝ PB1
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //管脚1
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M时钟速度 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //输⼊模式 GPIO_Init(GPIOB, &GPIO_InitStructure);
}
//====实例应⽤=======
//ADC1初始化设置
ADC1_GPIOInit() ;
ADC1_Config() ;
DMA_Config_ADC1() ; //dma设置
//--主程序-----
void mian(void)
{
while(1)
{
while(!F_10MS);
F_10MS = 0 ;
Tmp = AD_Value[0] ; //在缓存区中读取AD结果
}
}
神通⼴⼤的各位互联⽹的⽹友们、⼤家早上中午晚上好好好、今早起来很准时的收到了两条10086的扣⽉租的信息、⼼痛不已、怀着这⼼情、⼜开始了STM32的研究、早上做了计算机控制的PID实验,⼜让我想起了飞思卡尔的电磁⼩车、、曾经的电感电压采集让我⼼碎的多少次、⼜让我开⼼了多少次、但已经成为过去、(软件和硬件都会影响),呵呵、估计有⼈已经猜到我接下来要介绍什么了、在你们⾯前、我已⽆秘密、额、其实标题也直接“表⽩”了、看到标题,别吓到哈、并不是要⽤英⽂写、⾄于原因是什么、请往下看:
好吧、⾔归正传:STM32的ADC模块,请允许我⽤如此通俗的语⾔:普通话来介绍STM32ADC模块的特⾊
1、1MHz转换速率、12位转换结果(12位、记住这个12位哈、因为2^12=4096 ,也请记住4096哈)
STM32F103系列:在56MHz时转换时间为:1µs
在72MHz时转换时间为:1.17µs
2、转换范围:0~3.6V (3.6v---->当你需要将采集的数据⽤电压来显⽰的话:设你采集的数据为:x[0~4095],此时的计算公式就为:(x / 4096) * 3.6))
3、ADC供电要求:2.4V~3.6 V(可千万别接到 5V 的⽯榴裙⼦底下呀)
4、ADC输⼊范围:VREF-≤ VIN ≤VREF+ (VREF+和VREF-只有LQFP100封装才有)
5、双重模式(带2个ADC的设备): 8种转换模式
6、最多有18个通道:16个外部通道
2个内部通道:连接到温度传感器和内部参考电压(VREFINT = 1.2V)
......(略,请看参考⼿册哈,由于篇幅,就不过多的列出来了、、说到略、让我想起了⽉光宝盒诸葛亮的:略懂略懂、、其实我也是略懂略懂⽽已、、)
12、DMA功能(仅ADC1有)
本博客⾥,由于篇幅、所以就以独⽴模式下的单次转换为例哈、打开参考⼿册可以看到这段话:
单次转换模式下,ADC只执⾏⼀次转换。

该模式既可通过设置ADC_CR2寄存器的ADON位(只适⽤于规则通道)启动也可通过外部触发启动(适⽤于规则通道或注⼊通道),这
时CONT位为0。

⼀旦选择通道的转换完成:
●如果⼀个规则通道被转换:─转换数据被储存在16位ADC_DR寄存器中─ EOC(转换结束)标志被设置─如果设置了EOCIE,则产⽣中断。

●如果⼀个注⼊通道被转换:─转换数据被储存在16位的ADC_DRJ1寄存器中─ JEOC(注⼊转换结束)标志被设置─如果设置
了JEOCIE位,则产⽣中断。

然后ADC停⽌。

此图形象的表明了其背后那不为⼈知的秘密转换关系。

虽然单凭看⽂字就能想象出来、但是、有图⽚是不是更加形象呢对于以上的寄存器、在此我稍微提提:免得寄存器⼤神们产⽣怨⽓:好不容易等到你讲我⽼⼤ADC,却不把我这些背后的勤劳者给导出来
好了,那就恕⼩弟容禀:
1、ADC状态寄存器(ADC_SR)
2、ADC控制寄存器1(ADC_CR1)
3、ADC控制寄存器2(ADC_CR2)
EXTSEL[2:0]:选择启动规则通道组转换的外部事件 (External event select for regular group)
ALIGN:数据对齐 (Data alignment)
RSTCAL:复位校准 (Reset calibration)
CAL:A/D校准 (A/D Calibration)
CONT:连续转换 (Continuous conversion)
ADON:开/关A/D转换器 (A/D converter ON / OFF)
4、ADC采样时间寄存器1(ADC_SMPR1)
SMPx[2:0]:选择通道x的采样时间 (Channel x Sample time selection)
5、ADC规则序列寄存器1(ADC_SQR1)
L[3:0]:规则通道序列长度 (Regular channel sequence length)
SQ1[4:0]:规则序列中的第1个转换 (1st conversion in regular sequence)(ADC规则序列寄存器3(ADC_SQR3))
6、ADC规则数据寄存器(ADC_DR)
DATA[15:0]:规则转换的数据 (Regular data)
(由于寄存器过于多,我们就不在这⼀⼀列举了哈、、因为我主要是⽤库,所以寄存器相关的位都不具体介绍了哈、请⼤家参照中⽂⼿册)在这⾥,向⼤家介绍下:数据对齐:
ALIGN位⽤于设置对齐⽅式:右或左;
对于注⼊通道,转换结果是减去偏移量的值,可以为⼀个负数,在右对齐时扩展位位符号位。

那我们现在要怎么来实现呢??这个问题、相信⼤家在看了那么多的寄存器之后急迫想要知道的吧、、前⾯的只是个热⾝、、接下来步骤如下:
1、开启ADC1的时钟,由于ADC1是在PA1上,所以同时也要打开PA的时钟,并进⾏相关的配置、对于这个配置,要把PA1设置成模拟输⼊,为什么呢??⼤家打开中⽂参考⼿册可以看到
啊哈、、这下⼦清楚了吧、
2、复位ADC1,(本⼈觉得没必要、为什么,待会我会跟你说,留下悬念先),设置ADC1的分频因⼦,(记住,这⾥的ADC的时钟不能超
过14MHZ),⽽且其采样周期长点会好点,
ADCCLK---最快可达14MHz, 时钟来⾃经过分频器的PCLK2(2、4、6、8分频)
整个转换时间 = 采样时间 + 12.5个周期(固定时间)
在14MHz和采样时间位1.5周期时 è 转换时间:1µs (14个周期 cycles)
当ADCCLK=14MHz和1.5周期的采样时间:
TCONV = 1.5 + 12.5 = 14周期 = 14×(1 / (14 × 1000000)) = 1µs
其采样周期⼀览表:
涉及到采样周期、这⾥来看看转换序列:
最多达16个转换通道且可以采样不同的顺序排列,不同的采样时间和过采样的可能性。

例如:- 转换通道:1、2、8、4、7、3、11
- 不同的采样时间;
- Oversampling of channel 7。

3、初始化ADC1的参数、设置ADC1的⼯作模式和规则序列的相关信息;
⼤家通过打开"stm32f10.adc.h"可以看到:
typedef struct
{
uint32_t ADC_Mode; //设置ADC模式-->独⽴模式
FunctionalState ADC_ScanConvMode; //设置是否开启扫描模式 --->否
FunctionalState ADC_ContinuousConvMode; //设置是否开启连续转换模式 ---->否
uint32_t ADC_ExternalTrigConv; //设置启动规则转换组转换模式---->软件触发
uint32_t ADC_DataAlign; //设置数据对齐⽅式----->右对齐
uint8_t ADC_NbrOfChannel; //设置规则序列的长度---->顺序进⾏规则转换的ADC通道数⽬1
}ADC_InitTypeDef;
4、使能ADC并校准
注:在设置完了以上信息后,使能AD转换器,执⾏复位校准和AD校准(这两步校准⼀定要,否则数据将不准)
还有记住,每次进⾏校准之后都要等待校准结束,但是通过什么⽅式知道校准结束呢?
这⾥是通过获取校准状态来判断是否校准结束,相关的库函数请看代码
分别的库函数请看待会的代码。

(请⽤⽐较⽼外的⽅式去看,也就是⽤英语啦,为什么呢?请看下⽂)
5、读取AD的值
当然,这⾥说读取AD值并不是那么的简单,以上我们只是准备好了AD,还没有设置相关的规则序列通道,采样顺序,以及采样周期,设置完之后启动AD转换就⾏了、然后才直接读取哈、、
相关的库函数请看代码、
void Adc_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable ADC1 and GPIOA clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//12MHZ
/* Configure PA.1 (ADC Channel) as analog input -------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//ADC_DeInit(ADC1);//在这⾥复位被我注释掉了、⾄于为什么,我待会会说
/* ADC1 configuration ------------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//这⾥对应上⾯所讲的配置,在这⾥就不给出注释了
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* Enable ADC1 *///知道我为啥要在上⾯提醒⼤家要⽤⽼外的⽅式来看了吧、因为这⾥的注释都是⽤英⽂的
//请不要以为我装逼,我这样做是有原因的、、原因我待会会说、你也会明⽩我最初的标题为何那样写
ADC_Cmd(ADC1, ENABLE);
/* Enable ADC1 reset calibration register */
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1));
/* Start ADC1 calibration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));
}
u16 Get_val(u8 ch)
{
u16 DataValue; //⼜是英⽂注释、、啊哈 /* ADC1 regular channel14 configuration */ ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5);
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
/* Test if the ADC1 EOC flag is set or not */
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
//FlagStatus Status;
//Status = ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC);
//while(!Status);---->这样做实现不了、请注意
/*Returns the ADC1 Master data value of the last converted channel*/
DataValue = ADC_GetConversionValue(ADC1);
return DataValue;
}
u16 ADC_Get_aveg(u8 ch,u8 n)
{
u32 ad_sum = 0;
u8 i;
for(i=0;i<n;i++)
{
ad_sum += Get_val(ch);
delay_ms(5);
}
return (ad_sum / n);
}
adcx=ADC_Get_aveg(ADC_Channel_1,10);//获取AD数值(0~4095)
temp=(float)adcx*(3.3/4096);//获取相应的电压值
到了这⼀步,我们已经完成了AD采集数据的任务、接下来,有⼈可能有时候会觉得很纳闷,为什么有些⼈知道要完成特定的功能,它的步骤是怎么样的、为什么我就不知道??这个问题嘛、、接下来我讲的希望能稍微帮你,也希望你能好好的借鉴、步骤⼩技巧:其实也没啥的、⼤家知道下载库的⽂件的时候,⾥⾯都有包含每个模块的例⼦和⼀个模版、拿ADC这个模块来举例:
点击main.c可以看到神奇的⼀幕:
⼤家仔细看看,可以发现在官⽅给的历程中的步骤⾥并没有复位ADC的函数,个⼈觉得所以没有必要去复位当然复位也不是什么坏事哈、看你个⼈、、看到这、应该明⽩了我前⾯的说法了吧、还有、⼤家应该也注意到了、都是英⽂的注释、、所以看到这⼤家也清楚了,前⾯不是我装逼、、所以呢、其实英语对于我们来说还是很重要的、、那有⼈问,时钟的分频因⼦呢?怎么没有设置??不急哈、、请看:
对于分频因⼦的设置,也在这个函数⾥:⽽这个RCC_Configuration()在最开始已经使⽤了、、
所以⼤家要好好利⽤官⽅给的历程、说到这、你猜我词穷了吗?
答案是否定的、、我还有话要说:
做⼀件事要有⼀个⽬的、、才不会显得⾃⼰做的很空泛、、我写博客也⼀样、、我想让我⾃⼰理清思路、也希望⾃⼰在写的过程中能领悟到⾃⼰在学的时候没领悟到的知识点、、也希望能帮到跟我有⼀样困惑的⼈、、我把我不懂的理解后写下来、我也知道会有⼈跟我⼀样遇到同样不懂的地⽅、、所以这就是我的⽬的哈、、希望能帮到你们、、尽管不认识你们、、啊哈、、初学者、难免有出错、、所以、写错或理解错的请帮我指出来、⾂不甚感激,今当远离,零表涕零,不知所⾔、、。

相关文档
最新文档