登录  | 立即注册

游客您好!登录后享受更多精彩

扫一扫,访问微社区

QQ登录

只需一步,快速开始

开启左侧

[寒假笔记] STM32 ADC数模转换 OLED屏幕使用

[复制链接]
发表于 2022-1-29 21:58:22 | 显示全部楼层 |阅读模式
学习笔记
学习科目: STM32ADC数模转换,OLED屏幕
学习安排: 学习如何使用STM32的数模转换和OLED屏幕
开始时间: 2022-01-28
结束时间: 2022-01-29
在开发过程中,我们有时需要得到某个引脚的电压值,通过改变电阻等方式,电压值不是恒定的,所以我们需要用的ADC转换来得到实时的电压值。
当需要采集外部信号时,外部信号多数为模拟信号,如电压、电流、温度、压力等,而单片机只能处理数字信号,这时便需要一个将模拟信号转换为数字信号的介质——模数转换器(ADC)。


模拟量转换为数字量:采样 保持 量化 编码



采样:将一个时间上连续变化的模拟量转换为时间上离散变化的模拟量;
保持:将采样的结果存储起来,直到下一次采样;
量化:将采样电平归化为与之接近的离散数字电平;
编码:将量化后的结果按照一定数制形式表示;

在编码中:将采样电平(模拟值)转换为数字值时,可通过直接比较型与间接比较型。
直接比较型:就是将输入模拟信号直接与标准的参考电压比较,从而得到数字量。常见的有并行ADC与逐次比较型ADC。

间接比较型:输入模拟量不是直接与参考电压比较,而是将二者变为中间的某种物理量在进行比较,然后将比较所得的结果进行数字编码。常见的有双积分ADC。

1.2 ADC转换原理
1) 逐次逼近型ADC

采用逐次逼近法的 AD 转换器是有一个比较器、DA 转换器、缓冲寄存器和控 制逻辑电路组成,如下图所示:



基本原理是:从高位到低位逐次试探比较,就像用天平秤物体,从重到轻逐 级增减砝码进行试探。逐次逼近法的转换过程是:初始化时将逐次逼近寄存器各 位清零,转换开始时,先将逐次逼近寄存器最高位置 1,送入 DA 转换器,经 DA 转换后生成的模拟量送入比较器,称为 U0,与送入比较器的待转换的模拟量 Ux 进行比较,若 U0<Ux,该位 1 被保留,否则被清除。然后再将逐次逼近寄存器次 高位置 1,将寄存器中新的数字量送 DA 转换器,输出的 U0 再与 Ux 比较,若 U0<Ux, 该位 1 被保留,否则被清除。重复此过程,直至逼近寄存器最低位。转换结束后, 将逐次逼近寄存器中的数字量送入缓冲寄存器,得到数字量的输出。逐次逼近的 操作过程是在一个控制电路的控制下进行的。



在STM32中,我们在使用adc时应在工程中添加adc的环境,然后配置我们需要的引脚初始化,然后再配置对应的ADC。




OLED

模拟量转换为数字量:采样 保持 量化 编码

采样:将一个时间上连续变化的模拟量转换为时间上离散变化的模拟量;
保持:将采样的结果存储起来,直到下一次采样;
量化:将采样电平归化为与之接近的离散数字电平;
编码:将量化后的结果按照一定数制形式表示;

在编码中:将采样电平(模拟值)转换为数字值时,可通过直接比较型与间接比较型。
直接比较型:就是将输入模拟信号直接与标准的参考电压比较,从而得到数字量。常见的有并行ADC与逐次比较型ADC。

间接比较型:输入模拟量不是直接与参考电压比较,而是将二者变为中间的某种物理量在进行比较,然后将比较所得的结果进行数字编码。常见的有双积分ADC。



我们不需要自己写OLED的头文件与源文件,我们应该学会站在前人的肩膀上,直接用已经写完的oled的程序就好了,但是我们需要根据自己的需要,在建模程序上完成自己所需要的字模或者照片。


.c文件

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

void ADC_init(void)
{
        GPIO_InitTypeDef GPIO_InitStruct;
        ADC_InitTypeDef ADC_InitStruct;
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE);
        RCC_ADCCLKConfig(RCC_PCLK2_Div6);
       
        GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AIN;
        GPIO_InitStruct.GPIO_Pin=GPIO_Pin_1;
        GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_Init(GPIOA,&GPIO_InitStruct);

        ADC_InitStruct.ADC_ContinuousConvMode=ENABLE;
        ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;
        ADC_InitStruct.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;
        ADC_InitStruct.ADC_Mode=ADC_Mode_Independent;
        ADC_InitStruct.ADC_NbrOfChannel=1;
        ADC_InitStruct.ADC_ScanConvMode=DISABLE;
        ADC_Init(ADC1,&ADC_InitStruct);

        ADC_Cmd(ADC1,ENABLE);
       
        ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_239Cycles5);

ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));

ADC_SoftwareStartConvCmd(ADC1,ENABLE);
}



.h文件

#ifndef  _ADC_H
#define  _ADC_H
#include "stdint.h"

void ADC_init(void);

#endif


好懒~~不想说~~~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表