您的位置:首页 > 其它

UglyMonste_Flying 丑八怪四轴——ADC电池电压采集

2017-07-25 11:15 351 查看
STM32的ADC模块是一个12位的逐次逼近型模拟数字转换器。他有18个通道,可测量16个外部和2个内部信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行。ADC的结果可以左对齐或右对齐方式储存在16位数据寄存器中

● ADC供电要求: 2.4V到3.6V

● ADC输入范围: VREF- ≤ VIN ≤ VREF+

●VSSA和VREF-接地,VREF+和VDDA接3.3V

●ADC的输入电压范围为0~3.3V



100脚型号以上的stm芯片,VREF+和VREF-是直接从引到了片外,而64脚和小于64脚的型号VREF+在芯片内部与VDDA的信号线相连,没有引到片外,所以VDDA上的电压就是ADC的基准参考电压VREF-在芯片内部与VSSA的信号线相连。(此处不明确,我在代码里面看到多的是使用了内部参考电压,而VDDA,VSSA是模拟电源)

但是如果需要的测量采集的电压大于基准电压3.3V呢,有以下几种办法:

1,高精度电阻分压后采集

2,运放电压压缩

3,基尔霍夫定律





硬件如图:



VBAT是模拟电压采集输入引脚,通过20K的电阻串联分压,采集3.7V的电池电压

1.配置GPIO的时钟,模拟输入模式

2.使能ADC时钟,复位,写入1结束复位。设置分频系数,为12M

3.CR1寄存器配置:设置ADC独立模式,非扫描模式

CR2寄存器配置:A/DConverter OFF,软件控制,使能外部事件转换,设置右对齐,使能温度传感器

4.SQR1设置:配置规则通道转换次数,1次。

5.SMPR2设置通道1,SMPR1设置通道16设置取样周期239.5

6.开启AD转换器,先复位校准,再校准

贴上代码:

static void ADC1_GPIO_Config(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

/* 打开GPIO和ADC、DMA部件的时钟 */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOB, ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //72M/6=12,ADC最大时间不能超过14M

/* 将GPIO配置为输入模式 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//设置端口为模拟输入
GPIO_Init(GPIOB, &GPIO_InitStructure);  //GPIO端口初始化


}

/[b]********************************************************************[/b]

函数原型: static void ADC1_Mode_Config(void)

功 能: ADC及DMA配置

[b]*********************************************************************[/b]/

static void ADC1_Mode_Config(void)

{

DMA_InitTypeDef DMA_InitStructure;

ADC_InitTypeDef ADC_InitStructure;

/* DMA 通道1 配置 */
DMA_DeInit(DMA1_Channel1);//将DMA的通道1寄存器重设为缺省值
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->DR;//DMA外设ADC基地址;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_Value;//DMA内存基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//内存作为数据传输的目的地
DMA_InitStructure.DMA_BufferSize = M;//DMA通道的DMA缓存的大小
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;//数据宽度为16位
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//工作在循环缓存模式
DMA_InitStructure.DMA_Priority = DMA_Priority_High;//DMA通道x拥有高优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//DMA通道x没有设置为内存到内存传输
DMA_Init(DMA1_Channel1, &DMA_InitStructure);//根据DMA_InitStruct中指定的参数初始化DMA的通道

/* 使能 DMA 通道1 */
DMA_Cmd(DMA1_Channel1, ENABLE);


//////////////////////////////////////////////////////////////////////////////////////////////

ADC_DeInit(ADC1); //将外设 ADC1 的全部寄存器重设为缺省值

ADC_TempSensorVrefintCmd(ENABLE);//使能内部参照电压(1.2V)

/* ADC1 配置 */

ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式 每个ADC独立工作

ADC_InitStructure.ADC_ScanConvMode = ENABLE;//使用扫描模式 scan位设置

ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//cont位设置 连续转换模式

ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//EXTSEL 选择启动规则通道组转换的外部事件 设置成有软件控制

ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据对齐 由软件置位和清楚 这里设置成右对齐

ADC_InitStructure.ADC_NbrOfChannel = M;//规则通道序列长度 这些位由软件定义在规则通道转换序列中的通道数目 1个转换 指定由多少个通道被转换

ADC_Init(ADC1, &ADC_InitStructure);

/* ADC1 采样顺序 配置*/
ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 1, ADC_SampleTime_239Cycles5);    //电源电压
ADC_RegularChannelConfig(ADC1, ADC_Channel_17,2, ADC_SampleTime_239Cycles5);    //内部参照电压(1.2V)

/* 使能 ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* 使能 ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* 复位 ADC1 的校准寄存器 */
ADC_ResetCalibration(ADC1);
/* 等待 ADC1 校准寄存器复位完成 */
while(ADC_GetResetCalibrationStatus(ADC1));
/* 开始 ADC1 校准 */
ADC_StartCalibration(ADC1);
/* 等待 ADC1 校准完成 */
while(ADC_GetCalibrationStatus(ADC1));
/* 使能指定的ADC1的软件转换启动功能 */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);


}

/[b]********************************************************************[/b]

函数原型: void ADC1_Init(void)

功 能: ADC1初始化

[b]*********************************************************************[/b]/

void ADC1_Init(void)

{

ADC1_GPIO_Config();

ADC1_Mode_Config();

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: