您的位置:首页 > 科技 > IT业 > 北京朝阳区疫情_设计素材网站免费大全最新_中国进入一级战备2023_推广合作

北京朝阳区疫情_设计素材网站免费大全最新_中国进入一级战备2023_推广合作

2024/12/23 11:31:53 来源:https://blog.csdn.net/cykaw2590/article/details/144197493  浏览:    关键词:北京朝阳区疫情_设计素材网站免费大全最新_中国进入一级战备2023_推广合作
北京朝阳区疫情_设计素材网站免费大全最新_中国进入一级战备2023_推广合作

ADC简介:

(主要用来测电压)

 1us转换时间(最大支持1MHZ的信号转换)

12位(0~4095)就是分辨率

通过ADC0809外挂芯片来理解STM32中的ADC

 地址锁存和译码是用来选择通路的,通过调节DAC(数字-模拟转换器)中的电压(通过改变SAR值来调节)使得比较器两端电压近似相等时的SAR值就是该模拟信号的值(一般采用二分法逼近,如果是12路的话,最多判断12次),EOC是转换结束信号,START是开始转换信号,要给个脉冲,CLOCK是ADC的时钟,VREF是参考电压。


 

STM32的ADC:

 

可以看到注入组和规则组的区别,规则组可以一次性接收16个信号数据,但是每次只能往寄存器里写入处理好的一个信号,所以要立马把寄存器里的值拿走(可以用DMA),而注入一次性可以接收4个信号数据,也可以一次性放入4个信号数据到寄存器

 

 这些相当于START(触发源选择触发的从模式或寄存器配置控制)

 

至于VREF(参考电压)和VDDA和VSSA ,STM32F103C8T6中已经将参考电压与单片机VDDA和VSSA相连了

相当于CLOCK

看门狗  

结构简图:

输入通道:

但是STM32F103C8T6只有10个外部输入通道 ,且没有ADC3和PC0~PC5

规则组的4钟转换模式:(单次就是每次都要触发,连续就是只需要触发一次,扫描就是一个一个从头到尾,非扫描就是只能看一个)

为了防止寄存器被覆盖,要及时使用DMA挪走数据,当扫描数量等于通道数目并完成转换后(通过配置)的时候产生EOC信号 

 

还有一个间断模式,就是在扫描的时候扫了几个后间断一下,要重新触发才能继续(了解即可)

 ——————————————————————————————————————————

规则组触发控制:

EXTI线11/TIM8_TRGO实践这一栏可以来自外部引脚也可以来自定时器内部信号,具体哪个通过AFIO重映射来决定

该ADC是12位的,转换结果是一个12位的二进制数,寄存器是16位,可以选择对齐方式,一般选择右对齐,因为读出来就是结果,左对齐的好处是可以裁剪分辨率,只取高8位舍弃掉后四位精度

转换时间:

 校准:

 在ADC初始化后加几条代码即可,无需知道如何校准

———————————————————————————————————————————

代码: 

单通道单次测量代码:

#include "stm32f10x.h"void AD_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;ADC_InitTypeDef ADC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);//打开ADC时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//打开GPIOA时钟RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADC时钟分频,选择6分频,72/6 = 12MHzGPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//ADC专用模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);//配置ADC1通道0放于序列1的位置,采样时间设为55.5个ADCCLK的周期ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//设置为单次模式ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//不使用外部触发源ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//配置ADC模式为独立模式(非双ADC模式)ADC_InitStructure.ADC_NbrOfChannel = 1;//指定在扫描模式会用到的通道数为1(可以不用)ADC_InitStructure.ADC_ScanConvMode = DISABLE;//设置为非扫描模式ADC_Init(ADC1,&ADC_InitStructure);ADC_Cmd(ADC1,ENABLE);//以下是校准的代码ADC_ResetCalibration(ADC1);while(ADC_GetResetCalibrationStatus(ADC1) == SET);ADC_StartCalibration(ADC1);while(ADC_GetCalibrationStatus(ADC1) == SET);}uint16_t AD_GetValue(void)
{ADC_SoftwareStartConvCmd(ADC1,ENABLE);//软件触发ADC1while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET);//等待转换完成EOC发出信号return ADC_GetConversionValue(ADC1);//返回寄存器里的值,读完EOC自动置0(RESET)
}

单通道连续测量代码:

void AD_continus_Init(void)//单通道连续扫描
{GPIO_InitTypeDef GPIO_InitStructure;ADC_InitTypeDef ADC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);//打开ADC时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//打开GPIOA时钟RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADC时钟分频,选择6分频,72/6 = 12MHzGPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//ADC专用模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);//配置ADC1通道0放于序列1的位置,采样时间设为55.5个ADCCLK的周期ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//设置为单次模式ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//不使用外部触发源ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//配置ADC模式为独立模式(非双ADC模式)ADC_InitStructure.ADC_NbrOfChannel = 1;//指定在扫描模式会用到的通道数为1(可以不用)ADC_InitStructure.ADC_ScanConvMode = DISABLE;//设置为非扫描模式ADC_Init(ADC1,&ADC_InitStructure);ADC_Cmd(ADC1,ENABLE);//以下是校准的代码ADC_ResetCalibration(ADC1);while(ADC_GetResetCalibrationStatus(ADC1) == SET);ADC_StartCalibration(ADC1);while(ADC_GetCalibrationStatus(ADC1) == SET);ADC_SoftwareStartConvCmd(ADC1,ENABLE);//只需软件触发ADC1一次即可,GetValue函数不需要再触发   
}
uint16_t AD_Continus_GetValue(void)
{//因为连续的会一直更新状态所以不用等待了return ADC_GetConversionValue(ADC1);//返回寄存器里的值,读完EOC自动置0(RESET)
}

多通道测量代码(使用单次非扫描模式,不用DMA方法实现):

void AD_Much_NoneDMA_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;ADC_InitTypeDef ADC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);//打开ADC时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//打开GPIOA时钟RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADC时钟分频,选择6分频,72/6 = 12MHzGPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//ADC专用模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);//配置ADC1通道0放于序列1的位置,采样时间设为55.5个ADCCLK的周期ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//设置为单次模式ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//不使用外部触发源ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//配置ADC模式为独立模式(非双ADC模式)ADC_InitStructure.ADC_NbrOfChannel = 1;//指定在扫描模式会用到的通道数为1(可以不用)ADC_InitStructure.ADC_ScanConvMode = DISABLE;//设置为非扫描模式ADC_Init(ADC1,&ADC_InitStructure);ADC_Cmd(ADC1,ENABLE);//以下是校准的代码ADC_ResetCalibration(ADC1);while(ADC_GetResetCalibrationStatus(ADC1) == SET);ADC_StartCalibration(ADC1);while(ADC_GetCalibrationStatus(ADC1) == SET);}
uint16_t AD_Much_NoneDMA_GetValue(uint8_t ADC_Channel)
{//想看哪个通道电压就放哪个进序号1中,然后单次非扫描转换ADC_RegularChannelConfig(ADC1,ADC_Channel,1,ADC_SampleTime_55Cycles5);ADC_SoftwareStartConvCmd(ADC1,ENABLE);//软件触发ADC1while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET);//等待转换完成EOC发出信号return ADC_GetConversionValue(ADC1);//返回寄存器里的值,读完EOC自动置0(RESET)
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com