STM32F103学习笔记(6.2)——ADC规则_软件触发

使用ADC1规则通道,单次、非扫描转换,独立模式,外部触发(软件触发),右对齐

一、时钟使能和引脚初始化

//时钟使能
RCC->APB2ENR |= (1<<2);     //GPIOA时钟使能
GPIOA->CRL &= 0XFF0FFFFF;	//PA5模拟输入

	
RCC->APB2ENR |= (1<<9);		//ADC1时钟使能
RCC->APB2RSTR|=1<<9;   		//ADC1复位
RCC->APB2RSTR&=~(1<<9);		//复位结束	    
RCC->CFGR &= ~(3<<14);		//清零
RCC->CFGR |= 2<<14;			//PCLK2 6分频后得12Mhz

 查询手册可以知道,将引脚设置为模拟输入,这里用PA5,通道5作为例子。

要注意的是,ADC1的最大输入时钟是14Mhz,将主频设置为72Mhz之后,APB2的时钟频率也是72Mhz,那就需要6分频得到12Mhz作为时钟输入。

STM32F103学习笔记(6.2)——ADC规则_软件触发_第1张图片

二、ADC配置

//配置ADC,独立,单次,非扫描,外部触发,右对齐,规则
ADC1->CR1&=0XF0FFFF;   //工作模式清零,设置成了独立模式
ADC1->CR1&=~(1<<8);    //关闭扫描模式	
	
ADC1->CR2&=~(1<<1);    //单次转换模式
ADC1->CR2 &=~(7<<12);	//清零
ADC1->CR2 |= 7<<17;		//软件控制,SWSTART
ADC1->CR2 |= 1<<20;		//使用外部事件启动转换
ADC1->CR2&=~(1<<11);   	//右对齐
	
	
ADC1->SQR1 &= ~(0xf<<20);	//1个转换
ADC1->SQR3 |= (5<<0);		//第一个转换,通道5 

ADC1->SMPR2&=~(7<<15);  //通道5采样时间清空	  
ADC1->SMPR2 |= 7<<15;	//通道5,239.5周期
	
ADC1->CR2|=1<<0;	   	//开启AD转换器

三、ADC校准

ADC校准是为了提高精度,上电不校准也是没有问题的。

//校准
ADC1->CR2 |= (1<<3);	//复位校准
while(ADC1->CR2&1<<3); //等待校准结束
ADC1->CR2 |= (1<<2);	//A/D校准
while(ADC1->CR2&1<<2);  //等待校准结束

四、获取启动转换

写一个函数,手动开启转换,等待转换结束并返回结果。

uint16_t ADC1_GetAC()
{
	ADC1->CR2 |= (1<<22);	//手动开始转换,注入
	while(!(ADC1->SR&1<<1));//等待转换结束,JEOC标志位
	ADC1->SR&=~(1<<1);		//清除标志位
	return ADC1->DR;
}

综上,完整代码如下:

#include "stm32f10x.h" 
#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "stdio.h"

void ADC_Init(void)
{
	//时钟使能
	RCC->APB2ENR |= (1<<2);
	GPIOA->CRL &= 0XFF0FFFFF;	//PA5模拟输入

	
	RCC->APB2ENR |= (1<<9);		//ADC1时钟使能
	RCC->APB2RSTR|=1<<9;   		//ADC1复位
	RCC->APB2RSTR&=~(1<<9);		//复位结束	    
	RCC->CFGR &= ~(3<<14);		//清零
	RCC->CFGR |= 2<<14;			//PCLK2 6分频后得12Mhz
	
	
	//配置ADC,独立,单次,非扫描,外部触发,右对齐,规则
	ADC1->CR1&=0XF0FFFF;   //工作模式清零,设置成了独立模式
	ADC1->CR1&=~(1<<8);    //关闭扫描模式	
	
	ADC1->CR2&=~(1<<1);    //单次转换模式
	ADC1->CR2 &=~(7<<12);	//清零
	ADC1->CR2 |= 7<<17;		//软件控制,SWSTART
	ADC1->CR2 |= 1<<20;		//使用外部事件启动转换
	ADC1->CR2&=~(1<<11);   	//右对齐
	
	
	ADC1->SQR1 &= ~(0xf<<20);	//1个转换
	ADC1->SQR3 |= (5<<0);		//第一个转换,通道5 
	
	ADC1->SMPR2&=~(7<<15);  //通道5采样时间清空	  
 	ADC1->SMPR2 |= 7<<15;	//通道5,239.5周期
	
	ADC1->CR2|=1<<0;	   	//开启AD转换器
	//校准
	ADC1->CR2 |= (1<<3);	//复位校准
	while(ADC1->CR2&1<<3); //等待校准结束
	ADC1->CR2 |= (1<<2);	//A/D校准
	while(ADC1->CR2&1<<2);  //等待校准结束

}	

uint16_t ADC1_GetAC()
{
	ADC1->CR2 |= (1<<22);	//手动开始转换,注入
	while(!(ADC1->SR&1<<1));//等待转换结束,JEOC标志位
	ADC1->SR&=~(1<<1);		//清除标志位
	return ADC1->DR;
}

int main(void)
{			
	float ac;
	
	Stm32_Clock_Init(9);
	delay_init(72);
	uart_init(72,9600);
	ADC_Init();
	
	
  	while(1)
	{
		ac = ((float)ADC1_GetAC()/0xfff)*3.3;
		printf("第5通道:%f",ac);
		delay_ms(300);
		
	}	 
} 




你可能感兴趣的:(STM32F103学习笔记,stm32,学习,单片机)