关于STM32F103C8T6的基础ADC_单通道_单次_软件触发-测量功能

让自己别忘了大学里学的东西,那么就把它记录下下来,效率会比忘记然后重新再去找资料再重头学高的多吐舌头


对于ADC的基础电压转换功能:


1.先是它的原理:

(1).adc是将模拟量转化成数字量的东西,对于单片机而言,它需要一个输入的基准电压,用于和待测的模拟电压做对比。


      (2).adc功能在单片机里面的流程是这样的:

              1. 单片机的AIN引脚接收到外部的待测S模拟电压量

               2.Adc功能将“输入的待测模拟电压量”和输入的基准电压做量化和离散化。(12位的精度)

               3. 然后单片机外设经过内部计算,输出一量化值M(假设输入的基准电压为3.3v,因为精度是12位,则3.3v被平均分成了4096

              4. 最后通过公式Output=M/4096*3.3  PS:”3.3”为假定的输入的基准电压


2.代码逻辑图:


3.代码实现:

main.c

#include <M_all.h>  

volatile float mm=0;                                //声明一个全局变量 浮点数类型的,            因为想在调试中看mm的值,但是如果是局部变量,(因为mm除了被输入数据以后,没有被输出数据运算,所以会被keil优化,也就是不会在内存设置储存空间),而全局变量可以设置存储空间

int main(void)
	{    		
		
		SystemInit();                                   
		//初始化系统时钟         自动配置成72Mhz
		
		ADC_DeInit(ADC1);                               
		//默认化ADC1
		
		adc_init();                                     
		//初始化ADC1
		
		while(1)
		{

			mm=Read_ADC_data(ADC1);                       
			//计算显示电压值
			
		}
		
	}

M_adc.c

#include <M_all.h>  

//------------------------------------------ADC校准函数(嵌在ADC_init函数内)-----------------------------------------------------//


void ADC_Reset(ADC_TypeDef* ADCx)
{
		
	ADC_ResetCalibration(ADCx);                                                           
	//复位校准寄存器             寄存器置1
	
	while(ADC_GetResetCalibrationStatus(ADCx));                                           
	//等待校准寄存器复位完成      寄存器置0

  ADC_StartCalibration(ADCx);                                                           
	//ADC校准                    寄存器置1
	
  while(ADC_GetCalibrationStatus(ADCx));                                                
	//等待校准完成                寄存器置0
	
}






//------------------------------------------ADC初始化函数-----------------------------------------------------//


void adc_init(void)
{
	
	ADC_InitTypeDef ADC_InitStructure;                                                    
	//结构体_ADC基础-声明   
	
	GPIO_InitTypeDef GPIO_InitStructure;                                                  
	//结构体_引脚基础-声明   
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE);           
	//时钟开启_GPIOA,ADC1
	
	
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;                                             
	//结构体_引脚-PA1
	
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                                     
	//结构体_引脚-引脚频率_50Mhz
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;                                         
	//结构体_引脚-引脚模式_模拟输入
	
	GPIO_Init(GPIOA, &GPIO_InitStructure);                                                
	//结构体_引脚_结束配置
	
	
	
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;                                    
	//结构体_ADC-总模式_独立模式

	ADC_InitStructure.ADC_ScanConvMode = DISABLE;                                         
	//结构体_ADC-是否扫描_单通道
	
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;                                   
	//结构体_ADC-是否连续_单次
	
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;                   
	//结构体_ADC-触发方式_软件触发
	
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;                                
	//结构体_ADC-对齐方式_右对齐
	
	ADC_InitStructure.ADC_NbrOfChannel = 1;                                               
	//结构体_ADC-通道个数_单通道
	
	ADC_Init(ADC1, &ADC_InitStructure);                                                   
	//结构体_ADC_结束配置
	
	
	
	//	RCC_ADCCLKConfig(RCC_PCLK2_Div2);                                                 
	//ADC1-时钟分频配置       PS:原始输入的ADC输入时钟是1/2的系统时钟
	
	ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_1Cycles5);            
	//配置内容和ADC外设的具体对接函数   (ADC端口 ,ADC通道 ,转换序号-第几个转换 ,转换的周期)     


	
	ADC_Cmd(ADC1,ENABLE);                                                                 
	//开关_ADC-总开关   
	
	
 	ADC_Reset(ADC1);                                                                      
	//ADC校准函数                                               
	                                                                                                                 

}





//------------------------------------------ADC运算读取数值函数-----------------------------------------------------//


float Read_ADC_data(ADC_TypeDef* ADCx)
{
	float kk=0;                                                                                                                                                                                                                                                                                                                                                               
	
	ADC_SoftwareStartConvCmd(ADCx,ENABLE);                                                
	//开关_ADC软件触发-开关    状态寄存器为0                                                                  
				
	while(!ADC_GetFlagStatus(ADCx,ADC_FLAG_EOC));                                         
	//等待转换结束             寄存器置1                                                                            
			
	kk=(3.3*(((float)ADC_GetConversionValue(ADCx)/4096)));                                
	//百分比值转化成电压值,    因为读取了数据寄存器,状态寄存器自动清0                                                                                    
	
	return kk;                                                                            
	//返回电压值                                          
	
}



M_all.h

#include <stm32f10x.h>  

#include <M_adc.h>  
PS:一开始,认为只要配置好,然后把使能打开就可以用了,结果发现不行,因为结构体配置的内容并没有涉及到引脚和配置内容的对应函数,所以在配置完以后 还需要添加一个对应函数"ADC_RegularChannelConfig",同时 要注意,这个函数里面的一个参数,第三个参数,RANK ,它是指该将通道设置为第几个顺序来转换电压值,(比如输入3,就是指这个通道作为第三个转换ad的顺序),在寄存器中,也就是指ADC_SQR寄存器.

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页