ADC

偶尔善良 提交于 2020-01-18 01:19:54

模拟–数字转换器

共3个独立ADC(ADC1、ADC2、ADC3)
12位分辨率
每个独立ADC有18个通道,16个是外部通道
ADC的通道并没有固定的引脚,可以根据自己随意选用。

转换结束、注入转换结束和发生模拟看门狗事件时产生中断

ADCCLK最大是14MHz。
转换时间=采样时间+12.5个时钟周期。采样时间通过寄存器来配置

有俩种模式:
注入模式和规则模式(没搞懂)
(也不需要搞懂,因为开发板只放了一个ADC设备)

函数:
typedef struct
{
uint32_t ADC_Mode; //模式,一般使用ADC_Mode_Independent表示使用一个ADC
FunctionalState ADC_ScanConvMode; //扫描模式
FunctionalState ADC_ContinuousConvMode; //连续转换模式
uint32_t ADC_ExternalTrigConv; //外部触发选择模式

uint32_t ADC_DataAlign; //对齐方式
uint8_t ADC_NbrOfChannel; //转换的通道
}ADC_InitTypeDef;

void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);//初始化ADC
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);//使能ADC
void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);//配置ADC为软件触发
void ADC_ExternalTrigConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);//配置ADC为外部触发
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);//ADC的规则通道配置
void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState);//ADC的DMA使能

void RCC_ADCCLKConfig(uint32_t RCC_PCLK2);//配置ADC的时钟

开发板中A/D输入电压调节电位器R37连接在M_PB0引脚,即GPIOB0.
查stm32f103rbt6参考手册,得知,PB0/ADC_IN8,即是第8通道。
且只有一个通道,因此也就不需要使用DMA。

步骤:
一、初始化
1.初始化GPIO
2.初始化ADC
3.配置ADC时钟,通道转换顺序和采样时间
4.使ADC完成后中断,配置中断,使能中断
5.使能ADC
6.校准ADC
7.软件触发ADC
二、中断服务函数或轮询函数

ADC设备:
在这里插入图片描述
就是一个滑动变阻器,一端3.3V电压,一段接地,M_PB0接到芯片上,读取电压转化的值。

adc.h

#ifndef	 _ADC_H
#define  _ADC_H

#include "stm32f10x.h"

void ADC_NVIC(void);
void ADC1_Init(void);
float Read_ADC(void);
void delay(int x);
#endif

adc.c

#include "adc.h"

void ADC1_Init()
{
	ADC_InitTypeDef ADC_InitStruct;
	GPIO_InitTypeDef GPIO_InitStruct;
//配置中断
	ADC_NVIC();

//GPIO配置
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AIN;//模拟输入
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);
//ADC配置
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	ADC_InitStruct.ADC_Mode	=  ADC_Mode_Independent;
	ADC_InitStruct.ADC_ScanConvMode	= DISABLE;
	ADC_InitStruct.ADC_ContinuousConvMode =	ENABLE;
	ADC_InitStruct.ADC_ExternalTrigConv	= ADC_ExternalTrigConv_None;//不使用外部触发
	ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
	ADC_InitStruct.ADC_NbrOfChannel	= 1;
	ADC_Init(ADC1,&ADC_InitStruct);

	RCC_ADCCLKConfig(RCC_PCLK2_Div8);
	ADC_RegularChannelConfig(ADC1,ADC_Channel_8,1,ADC_SampleTime_13Cycles5);
	//ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE);
	ADC_Cmd(ADC1,ENABLE);
	ADC_ResetCalibration(ADC1);
	ADC_StartCalibration(ADC1);
	while(ADC_GetCalibrationStatus(ADC1));
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);
	delay(10000000);
	ADC1->CR2 |= 0x02;

}
void delay(int x)
{
	while(x--)
	;
}
void ADC_NVIC()
{
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
	NVIC_InitStruct. NVIC_IRQChannel=ADC1_2_IRQn;
	NVIC_InitStruct. NVIC_IRQChannelPreemptionPriority=1;
	NVIC_InitStruct. NVIC_IRQChannelSubPriority	=1;
	NVIC_InitStruct. NVIC_IRQChannelCmd=ENABLE;
	NVIC_Init(&NVIC_InitStruct);
}
float Read_ADC(void)
{
	float ADC_VALUE;
	
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);
	
	while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换完成
	ADC_VALUE = ADC_GetConversionValue(ADC1)*3.30/0xfff;
	
	return ADC_VALUE;
}
  

主函数

#include "stm32f10x.h"
#include "uart.h"
#include "adc.h"

extern __IO uint16_t value;

int main()
{
	float fl_value;
	usrt_init();
	ADC1_Init();

	while(1)
	{
	//使用中断
	   fl_value=(float)value/4096*3.3;	   
	   fl_value = ADC_GetConversionValue(ADC1)*3.30/0xfff;
	   //fl_value=Read_ADC();//使用轮询
	   printf("0x%x\n%f  V\n",value,fl_value);
	   delay(10000000);
	}
}


中断服务函数:

__IO uint16_t value;

void ADC1_2_IRQHandler(void)
{
	if(ADC_GetITStatus(ADC1,ADC_IT_EOC)==SET)
	{
	 	value=ADC_GetConversionValue(ADC1);		
	}
	ADC_ClearITPendingBit(ADC1,ADC_IT_EOC);
}

使用通道传输数据:
(只需要在主函数调用初始化函数,然后读取value的值即可)

void DMA_ADC_Init(void)
{
	 DMA_InitTypeDef DMA_InitStruct;
	 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
	 DMA_InitStruct.DMA_PeripheralBaseAddr =(uint32_t)&(ADC1->DR);
	 DMA_InitStruct.DMA_MemoryBaseAddr=(uint32_t)&value;
	 DMA_InitStruct.DMA_DIR	=DMA_DIR_PeripheralSRC;
	 DMA_InitStruct.DMA_BufferSize=1;
	 DMA_InitStruct.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
	 DMA_InitStruct.DMA_MemoryInc= DMA_MemoryInc_Disable;
	 DMA_InitStruct.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;
	 DMA_InitStruct.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;
	 DMA_InitStruct.DMA_Mode= DMA_Mode_Circular;
	 DMA_InitStruct.DMA_Priority=DMA_Priority_High;
	 DMA_InitStruct.DMA_M2M= DMA_M2M_Disable;
	 DMA_Init(DMA1_Channel1,&DMA_InitStruct);
	 DMA_Cmd(DMA1_Channel1,ENABLE);

	 ADC_DMACmd(ADC1,ENABLE);
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!