关于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.3PS:”3.3”为假定的输入的基准电压
2.代码逻辑图:
代码实现:
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寄存器.
页:
[1]