打印
[其他ST产品]

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

[复制链接]
250|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
l63t89|  楼主 | 2023-5-29 23:31 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
对于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.代码逻辑图:



使用特权

评论回复
沙发
l63t89|  楼主 | 2023-5-29 23:31 | 只看该作者
代码实现:

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);                       
                        //计算显示电压值
                       
                }
               
        }

使用特权

评论回复
板凳
l63t89|  楼主 | 2023-5-29 23:32 | 只看该作者
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;                                                                           
        //返回电压值                                          
       
}

使用特权

评论回复
地板
l63t89|  楼主 | 2023-5-29 23:32 | 只看该作者
M_all.h
#include <stm32f10x.h>  

#include <M_adc.h>  

使用特权

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


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

88

主题

776

帖子

1

粉丝