【STM32基础】第三篇、ADC的快速上手

目录

第一部分、关于ADC的基础知识

1、STM32ADC是多少位的?

2、STM32ADCADC参考电压为多少?

3、参考电压与ADC位数的转换关系

4、ADC通道对应的端口(来自野火的文档)

第二部分、直接上手的好用代码

1、adc.c文件

2、adc.h文件

3、main.h文件

第三部分、总结

第一部分、关于ADC的基础知识

1、STM32ADC是多少位的?

        STM32f103 系列有 3 个 ADC,精度都为 :12 位

2、STM32ADCADC参考电压为多少?

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

3、参考电压与ADC位数的转换关系

        由上知STM32的 ADC是 12 位的,而最大电压为 3.3V,那么3.3V被分成了2^12这么多份。因此,如果ADC得到数值为 X , 那么该X对应的模拟电压为 Y = (3.3 / 2^12)* X

4、ADC通道对应的端口(来自野火的文档)

        想要了解关于ADC的细节知识,可以去看《零死角玩转 STM32—基于野火 F103开发板》这本书,强烈推荐新手去看。

第二部分、直接上手的好用代码

1、adc.c文件

        这里把通道二和通道三给屏蔽 ,因为串口2的管脚刚好对应与PA2和PA3。

#include "adc.h"
#include "delay.h" 

void ADC_init(u8 ADC_CHx)
{    
	switch(ADC_CHx)
	{
		case ADC_CH0: RCC->APB2ENR|=1<<2; GPIOA->CRL&=0XFFFFFFF0; break;  //PA0
		case ADC_CH1: RCC->APB2ENR|=1<<2; GPIOA->CRL&=0XFFFFFF0F; break;  //PA1
//		case ADC_CH2: RCC->APB2ENR|=1<<2; GPIOA->CRL&=0XFFFFF0FF; break;//PA2
//		case ADC_CH3: RCC->APB2ENR|=1<<2; GPIOA->CRL&=0XFFFF0FFF; break;//PA3
		case ADC_CH4: RCC->APB2ENR|=1<<2; GPIOA->CRL&=0XFFF0FFFF; break;  //PA4
		case ADC_CH5: RCC->APB2ENR|=1<<2; GPIOA->CRL&=0XFF0FFFFF; break;  //PA5
		case ADC_CH6: RCC->APB2ENR|=1<<2; GPIOA->CRL&=0XF0FFFFFF; break;  //PA6
		case ADC_CH7: RCC->APB2ENR|=1<<2; GPIOA->CRL&=0X0FFFFFFF; break;  //PA7
		case ADC_CH8: RCC->APB2ENR|=1<<3; GPIOB->CRL&=0XFFFFFFF0; break;  //PB0
		case ADC_CH9: RCC->APB2ENR|=1<<3; GPIOB->CRL&=0XFFFFFF0F; break;  //PB1
		case ADC_CH10:RCC->APB2ENR|=1<<4; GPIOC->CRL&=0XFFFFFFF0; break;  //PC0
		case ADC_CH11:RCC->APB2ENR|=1<<4; GPIOC->CRL&=0XFFFFFF0F; break;  //PC1
		case ADC_CH12:RCC->APB2ENR|=1<<4; GPIOC->CRL&=0XFFFFF0FF; break;  //PC2
		case ADC_CH13:RCC->APB2ENR|=1<<4; GPIOC->CRL&=0XFFFF0FFF; break;  //PC3
		case ADC_CH14:RCC->APB2ENR|=1<<4; GPIOC->CRL&=0XFFF0FFFF; break;  //PC4
		case ADC_CH15:RCC->APB2ENR|=1<<4; GPIOC->CRL&=0XFF0FFFFF; break;  //PC5
	}
																																								//通道10/11设置			 
	RCC->APB2ENR|=1<<9;    																												//ADC1时钟使能	  
	RCC->APB2RSTR|=1<<9;   																												//ADC1复位
	RCC->APB2RSTR&=~(1<<9);																												//复位结束	    
	RCC->CFGR&=~(3<<14);  																												//分频因子清零	
																																							//否则将导致ADC准确度下降! 
	RCC->CFGR|=2<<14;      	 
	ADC1->CR1&=0XF0FFFF;   																												//工作模式清零
	ADC1->CR1|= 0<<16;
	ADC1->CR1|= ~(1<<8);
	ADC1->CR2|= 1<<20;
	ADC1->CR2&= ~(1<<1);
	ADC1->CR2|= 7<<17;
	ADC1->CR2&=~(1<<11); 
	ADC1->SMPR2&=~(7<<3);
	ADC1->SQR1&=~(0XF<<20);
	ADC1->SQR1|=0<<20;  
	ADC1->CR2|=1<<0;	
	ADC1->CR2|=1<<3;
	while(ADC1->CR2&(1<<3));
	ADC1->CR2|=1<<2;
	while(ADC1->CR2&(1<<2));
}				  

 /**
 * @brief   		得到ADC转换值函数
 * @code
 * // 得到ADC通道4值
 * Get_Adc(ADC_CH4);
 * @endcode
 * @param[in]   ADC_CHx ADC通道号:   值:ADC_CH0~ADC_CH15
 */
u16 Get_Adc(u8 ADC_CHx)   
{
																															//设置转换序列	  		 
	ADC1->SQR3&=0XFFFFFFE0;																			//规则序列1 通道ch
	ADC1->SQR3|=ADC_CHx;		  			    
	ADC1->CR2|=1<<22;       																		//启动规则转换通道 
	while(!(ADC1->SR&1<<1));																		//等待转换结束	 	   
	return ADC1->DR;																						//返回adc值	
}

 /**
 * @brief   		得到ADC转换平均值函数
 * @code
 * // 得到ADC通道4值,次数为20
 * Get_Adc_Average(ADC_CH4,20);
 * @endcode
 * @param[in]   ADC_CHx ADC通道号:   值:ADC_CH0~ADC_CH15
 * @param[in]   times  平均次数        
 */
u16 Get_Adc_Average(u8 ADC_CHx,u8 times)
{
	u32 temp_val=0;
	u8 t;
	for(t=0;t<times;t++)
	{
		temp_val+=Get_Adc(ADC_CHx);
		delay_ms(5);		
	}
	return temp_val/times;
} 

2、adc.h文件

#ifndef __ADC_H
#define __ADC_H

#include "stm32f10x.h"
#include "sys.h" 

/* ADC规则通道 端口定义 */
#define ADC_CH0   0       // PA0
#define ADC_CH1   1  			// PA1
//#define ADC_CH2   2  			// PA2
//#define ADC_CH3   3  			// PA3
#define ADC_CH4   4  			// PA4
#define ADC_CH5   5  			// PA5
#define ADC_CH6   6  			// PA6
#define ADC_CH7   7  			// PA7
#define ADC_CH8   8  			// PB0
#define ADC_CH9   9  			// PB1
#define ADC_CH10  10   		// PC0
#define ADC_CH11  11   		// PC1
#define ADC_CH12  12   		// PC2
#define ADC_CH13  13   		// PC3
#define ADC_CH14  14   		// PC4
#define ADC_CH15  15   		// PC5


//ADC1 API
void ADC_init(u8 ADC_CHx);
u16 Get_Adc(u8 ADC_CHx);
u16 Get_Adc_Average(u8 ADC_CHx,u8 times);


#endif

3、main.h文件

        注意:这里不是完整的main.c函数,主要是明白这个函数如何调用。

int main()
{
    /*ADC的采集值*/
    u16 ADC_Value;

    /*ADC初始化*/
    ADC_init(ADC_CH4);     //ADC1 通道四 PA4 初始化
    while(1)
    {
        ADC_Value = Get_Adc_Average(ADC_CH4, 20);
    }
}

第三部分、总结

        代码是我的朋友发给我,其实很多时候你不必要去明白ADC的驱动代码它到底怎么配置的,为什么这么配置,你只要明白它是一个工具,学会怎么用这个工具就可以了。然后在照葫芦画瓢弄明白哪些代码是用来更改的,就可以了。

        站在巨人的肩膀上,永远是最快的学习方法。

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大屁桃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值