STM32 ADC自我学习总结

发布者:数字冒险最新更新时间:2017-11-29 来源: eefocus关键字:STM32  ADC 手机看文章 扫描二维码
随时随地手机看文章

        记录一下STM32的ADC编程方法!

        前面已经学习了DMA,知道如何使用DMA去减小CPU的负担,这里的ADC转换也来使用DMA---这个也是STM32的ADC转换最常见的方式。


---第一步是---了解STM32的ADC对应的GPIO口----如下图---不用记住,可以查询,我是将它剪下来粘贴到书本的相应章节----!



---第二步是---配置相应ADC转换的GPIO口----这里使用PC0--PC1

static void ADC1_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);  //打开DMA1的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;  //模拟输入
GPIO_Init(GPIOC, &GPIO_InitStructure);
}

---第三步是---配置ADC的DMA----配置ADC通道等---

#define ADC1_DR_Address    ((u32)0x40012400+0x4c)  //外设地址
__IO uint16_t ADC_ConvertedValue[2];  //内存数组


static void ADC1_Mode_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
ADC_InitTypeDef ADC_InitStructure;

DMA_DeInit(DMA1_Channel1);  
//---------------ADC的DMA配置--------------------
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;  //ADC1地址---代表ADC1保存转换值的寄存器
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue;  //内存地址---用来保存DMA传输过来的ADC转换值----后面直接使用的变量地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  //外设为数据源
DMA_InitStructure.DMA_BufferSize = 2;  //传输总数据---2通道需要传输2个数据
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址固定
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址自增---总体表示始终从外设ADC1地址处取值---依次保存到连续的两个内存变量中---
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;  //外设传输数据单元---半字16位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;  //内存传输数据单元---半字16位
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  //循环模式---2个数据依次循环接收从外设ADC1传输过来的ADC值---
DMA_InitStructure.DMA_Priority = DMA_Priority_High;  //高优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //禁止内存传内存
DMA_Init(DMA1_Channel1, &DMA_InitStructure);

DMA_Cmd(DMA1_Channel1, ENABLE);  //再次打开DMA1

        //------------ADC模式配置------------------------
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;  //独立模式----还有很多模式---这个比较常见
ADC_InitStructure.ADC_ScanConvMode = ENABLE ;   //扫描模式---采集多通道使用----本程序采集2通道---所以扫描模式
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;  //连续转换模式---不难理解---就是不停地采集---一次接一次
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;  //不使用外部触发转换---触发分为外部触发---比如中断与定时器。软件触发---后面有专用函数
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;   //采集的数据右对齐---方便计算
ADC_InitStructure.ADC_NbrOfChannel = 2;  //总共需要转换的通道个数---这里2个
ADC_Init(ADC1, &ADC_InitStructure);

RCC_ADCCLKConfig(RCC_PCLK2_Div8);  //配置ADC转换时钟---PCLK2的8分频
        //下面这个函数比较重要----配置ADC的通道与采样周期---前面说的PC0与PC1对应的ADC通道分别是--10与11。采集周期也有几种。
ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2, ADC_SampleTime_55Cycles5);

ADC_DMACmd(ADC1, ENABLE);  //打开DMA1的ADC1
ADC_Cmd(ADC1, ENABLE);  //打开ADC1

ADC_ResetCalibration(ADC1);  //复位校准寄存器
while(ADC_GetResetCalibrationStatus(ADC1));  //等待校准寄存器复位完成

ADC_StartCalibration(ADC1);  //ADC校准
while(ADC_GetCalibrationStatus(ADC1));  //校准完成

ADC_SoftwareStartConvCmd(ADC1, ENABLE);  //软件触发转换
}

---第四部分是---在硬件上使用了一个通道切换芯片----CD4052----由PC2---PC3控制通道的选择CD4052切换控制GPIO配置----

void GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //推完输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}

---第五部分是---主函数-----

extern __IO uint16_t ADC_ConvertedValue[2];  //声明外部变量
uint16_t My_ADC[2];  //求平均值

int main(void)
{
u8 i,led=0x01;

USART1_Config();


ADC1_GPIO_Config();
ADC1_Mode_Config();


while (1)
{
My_ADC[0]=0;
My_ADC[1]=0;


for(i=0;i<10;i++)  
{
                        My_ADC[0]+=ADC_ConvertedValue[0];
My_ADC[1]+=ADC_ConvertedValue[1];
               }
My_ADC[0]=My_ADC[0]/10;   //采集10次求平均值
My_ADC[1]=My_ADC[1]/10;

ADC_ConvertedValueLocal =(float) My_ADC[0]/4096*3.3;   //转换为电压值

printf("\r\n The current AD---0 value = 0x%04X \n", My_ADC[0]); 
printf("The current AD---0 value = %f V \n",ADC_ConvertedValueLocal); 

ADC_ConvertedValueLocal =(float) My_ADC[1]/4096*3.3; 

printf("The current AD---1 value = 0x%04X \n", My_ADC[1]); 
printf("The current AD---1 value = %f V \n",ADC_ConvertedValueLocal);  
}
}


关键字:STM32  ADC 引用地址:STM32 ADC自我学习总结

上一篇:STM32 DMA 自我学习 简单总结
下一篇:LPC2114的I2C总线介绍

推荐阅读最新更新时间:2024-03-16 15:47

MSP430 ADC12采样分析
AD部分主要配置ADC12模块的时钟、参考源、采样通道、采样模式、存储和采样保持。 我就一个部分一个部分来 第一个是ADC12模块的时钟,这个是模块运行时的时钟,跟采样定时器是两个概念,曾经我有一段时间被迷惑住了。这个由ADC12CTL1里面的ADC12SSEL和ADC12DIV配置,可以选择ADC12OSC/ACLK/SMCLK/MCLK,TI例程里面好像都是选择的ADC12OSC,这个是5MHZ,不过频率容易受外界影响而改变。这个部分配置好了就得到了ADC12CLK。 第二个参考源,这个部分可以用单片机的参考模块控制,也可以用ADC12模块控制,REFCTL0 &= ~REFMSTR;这句就是设置ADC模块直
[单片机]
MSP430 <font color='red'>ADC</font>12采样分析
STM32入门系列-使用C语言封装寄存器
前面介绍了存储器映射、寄存器和寄存器映射,这些都是为了介绍使用 C语言封装寄存器做铺垫。这里我们通过一个实例来对 C 语言封装寄存器进行介绍。 具体实例:控制 GPIOC 端口的第 0 管脚输出一个低电平。首先我们需要知道GPIOC 端口外设是挂接在哪个总线上的,然后根据总线基地址和本身的偏移地址得到 GPIOC 外设基地址,最后通过这个外设基地址得到里面各种寄存器基地址。 总线和外设基地址封装 根据寄存器的概念,我们可以使用 C 语言中的宏定义对寄存器进行定义。具体代码如下: //定义外设基地址 #define PERIPH_BASE ((unsigned int)0x40000000) 1) //定义 APB2 总线基地址
[单片机]
STM32开发笔记23: 使用__weak修饰符
单片机型号:STM32L053R8T6 在 HAL 库中,很多回调函数前面使用__weak 修饰符。 weak 顾名思义是“弱”的意思,所以如果函数名称前面加上__weak 修饰符,我们一般称这个函数为“弱函数”。 加上了__weak 修饰符的函数,用户可以在用户文件中重新定义一个同名函数,最终编译器编译的时候,会选择用户定义的函数,如果用户没有重新定义这个函数, 那么编译器就会执行__weak 声明的函数,并且编译器不会报错。 举个例子: 我们打开工程模板,找到并打开文件stm32f4xx_hal.c 文件,里面定义了一个函数 HAL_MspInit,定义如下: __weak void HAL_MspInit(v
[单片机]
移植STM32固件库用于HID双向通信
USB的应用中HID类是比较常见的方式。通过修改STM32 USB固件库V4.0的JOYSTICK应用,我们实现一个双向USB通信。 一、移植 使用STM32源程序为点亮LED灯程序。 首先将USB固件库中有用的函数复制到源函数中,建立LIB文件夹其中放入USB2.0协议函数 建立CFG文件夹放入USB应用函数 将两个文件夹都放到源工程目录下将文件添加进来,设置好,配置好KEIL软件设置。 二、修改文件 1、首先修改platform_config.h函数。 该文件是对于多种芯片对于USB库的支持。我们使用STM32F103ZET6芯片,所以只保留与之相关的ID项,与USB_DISCONNECT线(PG11)的配
[单片机]
STM32】串口通信基本原理(超基础、详细版)
STM32F1xx官方资料: 《STM32中文参考手册V10》-第25章通用同步异步收发器(USART) 通信接口背景知识 设备之间通信的方式 一般情况下,设备之间的通信方式可以分成并行通信和串行通信两种。它们的区别是: 并、串行通信的区别 并行通信 串行通信 传输原理 数据各个位同时传输 数据按位顺序传输 优点 速度快 占用引脚资源少 缺点 占用引脚资源多 速度相对较慢 串行通信的分类 1、按照数据传送方向,分为: 单工:数据传输只支持数据在一个方向上传输; 半双工:允许数据在两个方向上传输。但是,在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信;它不需要独立的接收端和发送端,两
[单片机]
【<font color='red'>STM32</font>】串口通信基本原理(超基础、详细版)
串行输出的12位模数转换器MAX1286–MAX1289
MAX1286–MAX1289是串行输出的12位模拟-数字转换器(ADC),具有成本低、功耗小的特点,采用小型8引脚SOT23封装和8引脚TDFN封装。MAX1286/MAX1288采用+5V单电源供电,MAX1287/MAX1289采用+3V单电源供电。这些器件具备逐次逼近ADC,自动关断,快速唤醒(1.4µs)的功能和一个高速3线接口。在150ksps最大采样速率下功耗仅为0.5mW (VDD = +2.7V)。在较低的采样速率下,转换间隙的AutoShutdown™ (0.2µA)特性能够减小功率消耗。MAX1286/MAX1287提供双通道单端工作模式,接受输入信号范围为0到基准VREF。MAX1288/MAX1289接受
[模拟电子]
串行输出的12位<font color='red'>模数转换器</font>MAX1286–MAX1289
Proteus仿真STM32实现--DS18B20和LCD1602显示
proteus仿真stm32103r6,实现18B20温度值在1602上显示,可测量正负温度。程序及仿真工程已上传附件,利用proteus仿真18b20温度为0和-0.1时返回值均为零,新手上路,请多指教。使用proteus8.8版本进行仿真。 原理图 时序 原理图 单片机部分程序如下: #include stm32f10x.h #include bsp-lcd1602.h #include delay.h #include sys.h #include ds18b20.h #include stdio.h #include math.h short tem,tem1; u8 a,b,c,t
[单片机]
Proteus仿真<font color='red'>STM32</font>实现--DS18B20和LCD1602显示
stm32单片机待机模式的设计
一 待机模式简介 在stm32的低功耗模式中,待机模式可以实现系统的最低功耗,在这种模式下,只需要2uA左右的电流。 三 待机唤醒程序分析 实验现象: 将程序下载到开发板上后,LED灯会不断地亮灭,当按下KEY2键超过3s时,LED灯灭,标志着单片机进入待机模式,再按下KEY1键,这时唤醒单片机,LED又开始不断地亮灭亮灭。 程序中用到的一些宏定义 #definemacEXTI_GPIO_CLK(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO) #definemacEXTI_GPIO_PORTGPIOC #definemacEXTI_GPIO_PINGPIO_Pin_13 #definem
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved