STM32学习笔记—ADC

1、adc简介

2、函数配置

3、代码

1、adc简介

  在ADC就是模数转换器,将模拟量转换成数字量,举个例子就是将电压转换位数字量,STM32拥有1-3个ADC(模数转换器),这些ADC可以独立使用,也可以采用双从模式(提高采样频率)STM32的ADC是12位逐次逼近的模拟数字转换器。它的每个adc有18个通道(ADC工作的时候只接一个通道),可以测量16个外部通道和2个内部信号源。各通道的ad可以单次转换、连续转换、扫描模式或者间断模式。这边我需要解释上面的几个模式:首先对于单通道来说,是不存在扫描模式的,这里的单次转换指的是就是你使能一次之后,那么adc本次转换完成之后就停止转换。连续模式是使能一次之后,一次转换结束之后,马上开始下一次转换。对于多通道来说,如果我们选择读取多个通道的值的时候,我们是需要选择扫描模式的,然后在扫描模式下单次转换是指一个通道转换结束之后就开始下一通道的转换,走一圈后停止。连续转换指的是一个通道转换结束之后,马上开始下一通道的转换,走一圈之后不停止,继续下一圈的转换。

在使用ADC的时候有一个东西需要注意,那就是STM32的ADC的最大转换速率为1MHZ,也就是转换时间为1us(在 ADCCLK=14M,采样周期 为 1.5 个 ADC 时钟下得到),不要让 ADC 的时钟超过 14M,否则将导致结果准确度下降。因为ADC1是挂在APB2时钟下面的,APB1的时钟为72MHZ,所以今天我们在选择分频系数的时候要大于5.14,所以今天的实验我们选择的分频系数为6。

在使用ADC的时候,还有一个知识点需要注意,那就是规则通道组和注入通道组。规则通道组相当于是正常执行的程序,注入通道组就相当于是一个中断,注入通道执行完之后才会回到正常程序继续执行。区分这两个分组是为了提高单片机的效率,这和中断的设定是一个道理,为了提高单片机处理事情的速率。

2、函数配置

这边主要讲一下ADC的初始化函数和读取ADC的函数

ADC函数的初始化:

1、开启我们的GPIO的时钟和ADC的时钟,这边我们使用的是A1和ADC1,这两个外设都挂在APB2的时钟下面。

2、开启时钟之后,我们需要设置 ADC1的分频系数,按照之前的解释这边选择分频系数为6。

3、初始化我们的IO口,这边选择IO的工作模式为模拟输入。

4、上面设置完成后,需要重初始化ADC1。这边我们调用的是ADC_DeInit(ADC1);

5、对ADC1的工作进行设置

//初始化adc
    ADC_InitTypesTructure.ADC_ContinuousConvMode=DISABLE;//不允许连续转换模式,即单次转换
    ADC_InitTypesTructure.ADC_DataAlign=ADC_DataAlign_Right;//12位的adc,存储在16位的数据寄存器中,所以这边选择右对齐
    ADC_InitTypesTructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//adc转换由软件启动而不是外部事件触发
    ADC_InitTypesTructure.ADC_Mode=ADC_Mode_Independent;//独立模式
    ADC_InitTypesTructure.ADC_NbrOfChannel=1;//进行转换的通道数是1;
    ADC_InitTypesTructure.ADC_ScanConvMode=DISABLE;//单通道模式
    ADC_Init(ADC1,&ADC_InitTypesTructure);
6、初始化ADC之后,我们需要对ADC进行使能然后校准

    
    ADC_Cmd(ADC1, ENABLE);    //使能指定的ADC1
    
    ADC_ResetCalibration(ADC1);    //使能复位校准  
     
    while(ADC_GetResetCalibrationStatus(ADC1));    //等待复位校准结束
    
    ADC_StartCalibration(ADC1);     //开启AD校准
 
    while(ADC_GetCalibrationStatus(ADC1));     //等待校准结束

下面说一下我们读取ADC的函数:

1、在读取ADC的值的时候,我们需要设定ADC的规则组通道规则,这边就是之前我说的,这通过调用下面的函数设置,哪个ADC、哪个通道、采样时间

ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );    //ADC1,ADC通道,设置转换的序列,采样时间为239.5周期

2、然后软件使能我们的ADC开始工作,获取EOC(转换完成标志位)的状态,如果转换完成,我们就获取ADC的值并将这个值返回。

3、然后你可以根据返回的值进行处理。

3、代码

adc.c
void Adc_Init(void)
{
	GPIO_InitTypeDef GPIO_InitTypeStructure;
	ADC_InitTypeDef ADC_InitTypesTructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 ,ENABLE);
  //设置ADC1的时钟分频系数,并复位ADC1
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	//初始化引脚
	GPIO_InitTypeStructure.GPIO_Mode=GPIO_Mode_AIN;
	GPIO_InitTypeStructure.GPIO_Pin=GPIO_Pin_1;
	GPIO_InitTypeStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitTypeStructure);
	//设置ADC1的时钟分频系数,并复位ADC1
	ADC_DeInit(ADC1);
	
	//初始化adc
	ADC_InitTypesTructure.ADC_ContinuousConvMode=DISABLE;//不允许连续转换模式,即单次转换
	ADC_InitTypesTructure.ADC_DataAlign=ADC_DataAlign_Right;//12位的adc,存储在16位的数据寄存器中,所以这边选择右对齐
	ADC_InitTypesTructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//adc转换由软件启动而不是外部事件触发
	ADC_InitTypesTructure.ADC_Mode=ADC_Mode_Independent;//独立模式
	ADC_InitTypesTructure.ADC_NbrOfChannel=1;//进行转换的通道数是1;
	ADC_InitTypesTructure.ADC_ScanConvMode=DISABLE;//单通道模式
	ADC_Init(ADC1,&ADC_InitTypesTructure);
	//使能ADC并校准,这部分的代码直接拷过来就可以
		ADC_Cmd(ADC1, ENABLE);	//使能指定的ADC1
	
	ADC_ResetCalibration(ADC1);	//使能复位校准  
	 
	while(ADC_GetResetCalibrationStatus(ADC1));	//等待复位校准结束
	
	ADC_StartCalibration(ADC1);	 //开启AD校准
 
	while(ADC_GetCalibrationStatus(ADC1));	 //等待校准结束
 
//	ADC_SoftwareStartConvCmd(ADC1, ENABLE);		//使能指定的ADC1的软件转换启动功能

}

u16 Get_Adc(u8 ch)   
{
  	//设置指定ADC的规则组通道,一个序列,采样时间
	ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );	//ADC1,ADC通道,设置转换的顺序这边只有一个通道的转换,采样时间为239.5周期	  			    
  
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);		//使能指定的ADC1的软件转换启动功能	
	 
	while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束

	return ADC_GetConversionValue(ADC1);	//返回最近一次ADC1规则组的转换结果
}
//下面就是多次采样取均值
u16 Get_Adc_Average(u8 ch,u8 times)
{
	u32 temp_val=0;
	u8 i;
	for(i=0;i<times;i++)
	{
		temp_val+=Get_Adc(ch);
		delay_ms(5);
	}
	return temp_val/times;
}

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
对于巡线小车的学习笔记,可以参考以下内容: 1. 文件包括stm32部分源码,包含各个模块的使用。其中涉及到直流电机控制模块、pca9685舵机驱动器模块、mpu6050三轴角度驱动模块、ADC测电压等。 2. 平衡小车项目功能需求分析。对于平衡小车的整体框架及开发流程进行分析,包括环境数据采集进程、小车PID控制进程、菜单显示进程、交互进程、中断处理等。 3. 在选型手册中可以查看stm32的资源。例如,STM32F103ZET6拥有144个引脚、112个IO口(大部分IO口都耐5V,模拟通道除外)、512K FLASH和64k SRAM等。 综上所述,在学习巡线小车的过程中,可以参考stm32部分源码和各个模块的使用,了解平衡小车项目的功能需求分析和开发流程,以及了解选型手册中stm32的资源信息。这些内容将有助于你对巡线小车的学习和开发。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [电赛备战:基于stm32的多功能巡线避障小车](https://download.csdn.net/download/qq_32971095/88226743)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [stm32平衡小车学习记录1](https://blog.csdn.net/qq_60595797/article/details/126208318)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [【单片机学习笔记】(12):定时器中断、巡线小车各模块原理、stm32HAL库](https://blog.csdn.net/wenhaiii/article/details/120469472)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值