STM8L051之通过ADC1与DMA读取内部参考电压

发布者:JoyfulSunflower最新更新时间:2019-12-14 来源: eefocus关键字:STM8L051  ADC1  DMA  内部参考电压 手机看文章 扫描二维码
随时随地手机看文章

stm8L051芯片内部的参考电压与电源电压有一定的关系


这在芯片供电电压变化的情况下,测量外部ADC电压输入提供一个确定的参考电压。这里提前厘清下:该内部参考电压VREFINT 并非ADC 的参考电压,ADC 的参考电压依然是VDD。即使VDD 有所波动,这个VREFINT 电压恒定不变,对于ADC 电路而言,它只是个测试点。 


对于某固定的ADC 参考电压情况下,所有被测电压点的AD转换值与该点电压值保持同一比例关系,换句话说,对于ADC参考电压固定情况下,各点的电压与ADC值与成线性关系。下面图形是芯片分别在3个不同参考电压的示意图,这里参考电压接VDD。下面三根斜线分别是VDD 为2.8V、3.2V、3.6V 时的AD转换曲线示意图。那根黄色垂直虚线是表示内部VREFINT电压(1.22V)所在的位置。 

这里写图片描述

图片以及部分文字是引用网友的原话,如果需要我备注的请给我提醒一下) 

刚开始的时候我是直接操作寄存器,但无奈怎样读测不准,计算值同实际电源电压差别比较大,后来不得已才用库函数试试。效果还可以,能测量电源的电压,当然stm8L芯片内部已经有一个出厂时写好的校准值,程序中可以读取,这里我只用手册中(技术手册中比编 

程手册说的详细一点),的典型值1.224V。下面是相关的代码(参考固件库的adc与dma例程):

#include "adc.h"

#include "led.h"

uint16_t Buffer[BUFFER_SIZE]  = {0};

uint32_t Verfin = 0;//电源电压*1000

void ADC_Config(void)

{

  /* Enable ADC1 clock */

  CLK_PeripheralClockConfig(CLK_Peripheral_ADC1, ENABLE);

/* Initialize and configure ADC1 */

  ADC_Init(ADC1, ADC_ConversionMode_Single, ADC_Resolution_12Bit, ADC_Prescaler_1);

  ADC_SamplingTimeConfig(ADC1, ADC_Group_SlowChannels, ADC_SamplingTime_24Cycles);

  ADC_SamplingTimeConfig(ADC1, ADC_Group_FastChannels, ADC_SamplingTime_24Cycles);


  /* Enable ADC1 */

  ADC_Cmd(ADC1, ENABLE);

  ADC_VrefintCmd(ENABLE);


  /* Enable ADC1 Channels 3 */

  ADC_ChannelCmd(ADC1, ADC_Channel_3, ENABLE); /* connected to Potentiometer RV */

  /* Enable ADC1 Channels 24 */

  ADC_ChannelCmd(ADC1, ADC_Channel_Vrefint, ENABLE); /* connected to ADC_Channel_Vrefint */


}

void DMA_Config(void)

{

   /* Enable DMA1 clock */

  CLK_PeripheralClockConfig(CLK_Peripheral_DMA1, ENABLE);

  /* Connect ADC to DMA channel 0 */

 SYSCFG_REMAPDMAChannelConfig(REMAP_DMA1Channel_ADC1ToChannel0);//ADC通道要remap

//BUFFER_SIZE

  DMA_Init(DMA1_Channel0, BUFFER_ADDRESS,

           ADC1_DR_ADDRESS,

           BUFFER_SIZE,

           DMA_DIR_PeripheralToMemory,

           DMA_Mode_Circular,

           DMA_MemoryIncMode_Inc,

           DMA_Priority_High,

           DMA_MemoryDataSize_HalfWord);

  /* DMA Channel0 enable */

  DMA_Cmd(DMA1_Channel0, ENABLE);

  /* Enable DMA1 channel0 Transfer complete interrupt */

  DMA_ITConfig(DMA1_Channel0, DMA_ITx_TC, ENABLE);   

  /* DMA enable */

  DMA_GlobalCmd(ENABLE);

  ADC_DMACmd(ADC1, ENABLE); 

}

/**

  * @brief DMA1 channel0 and channel1 Interrupt routine.

  * @param  None

  * @retval None

  */

INTERRUPT_HANDLER(DMA1_CHANNEL0_1_IRQHandler, 2)

{

  /* In order to detect unexpected events during development,

     it is recommended to set a breakpoint on the following instruction.

  */

  /* Calculate Potentiometer RV voltage value*/

 // Voltage = (uint32_t)((uint32_t)Buffer[0] * //(uint32_t)ADC_RATIO) / 1000;


  /* Calculate BNC voltage value*/

   //(uint32_t)((uint32_t)Buffer[1] * 1225) / 1000;

  Verfin =  (uint32_t)1224*4096/Buffer[1];


  //GPIO_ToggleBits(GPIOB, GPIO_Pin_4);

  /* Clear IT Pending Bit */

  DMA_ClearITPendingBit(DMA1_IT_TC0);

}


上面时,c中的代码,。h中的如下:

ifndef __ADC_H

#define __ADC_H

#include "stm8l15x.h"

//#include "stm8l15x_it.h"

/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/

#define ADC1_DR_ADDRESS        ((uint16_t)0x5344)

#define BUFFER_SIZE            ((uint8_t) 0x02)

#define BUFFER_ADDRESS         ((uint16_t)(&Buffer))

extern uint16_t Buffer[BUFFER_SIZE];

/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/

void ADC_Config(void);

void DMA_Config(void);

#endif


下面是main中的代码:


#include "bsp.h"




int main( void )

{

  SysInit();//bsp文件中包含了系统,adc与dma的初始化

/* Enable Interrupts */

  enableInterrupts();

  ADC_SoftwareStartConv(ADC1);//START,necessary 启动adc转换

  while(1)

  {


  }

  return 0;

}

这里写图片描述

从调试窗口中看到,Verfin = 2498,实际万用表测的电压=2.49V,可见测量的数据还是挺准确的,另外在3点多V电源情况测的值也基本准确。


最后,由于stm8L051的内存空间比较小,还是希望能寄存器开发,这等待有空再参考库函数研究测量内部参考电压的寄存器操作吧。

关键字:STM8L051  ADC1  DMA  内部参考电压 引用地址:STM8L051之通过ADC1与DMA读取内部参考电压

上一篇:STM8L051F3基础功能:内部时钟;TIM2定时器;串口及printf
下一篇:STM8L051F3_02_EXTI应用

推荐阅读最新更新时间:2024-11-01 15:37

基于Windows98平台开发DMA高速数据采集系统
    摘要: 介绍基于Windows98平台的DMA虚拟设备驱动程序的开发,并给出了一个简单的DMA虚拟设备驱动程序的开发实例。     关键词: 直接存储器存取(DMA)方式 虚拟设备驱动程序(VxD)VtoolsD 直接存储器存取方式不仅具有高速度、高效率的特点,而且CPU资源占用少,因此在需要高速、批量交换数据的场合得到了广泛的应用。在DOS下编写DMA控制程序并不难,但要编制出精美实用的界面则是一件非常繁锁的工作,而且效果往往不佳。Windows自问世以来便以身采取的保护措施使得Windows与硬件直接接口时需要程序员编写专用的虚拟设备驱动程序。针对DMA的Windows虚拟设备驱动程序并不常见,因
[嵌入式]
STM32之DMA讲解及配置过程,附带代码说明
DMA涉及概念讲解: ①:DMA即Direct Memory Access(直接存储器存取),是STM32特有的外设。大容量STM32产品集成了两个DMA,分别是DMA1和DMA2,。其中DMA1有7个通道,DMA2有5个通道,具体每个通道连接的外设可以参考STM32芯片的数据手册。 ②:通过DMA可以将数据在两个不同的地址之间进行传递,如存储器到外设寄存器,外设寄存器到存储器,也可以从存储器到存储器之间。 ③:当两个数据在不同的地址之间传递时,需要在程序配置中确定每次传输的字节数,确定是字节、半字还是字。 ④:DMA的每个通道优先级是可变的。以DMA1为例,它有7个通道,可以配置每个通道的优先级为很高、高、中,低
[单片机]
STM32G0开发笔记:多通道ADC与DMA的使用
使用Platformio平台的libopencm3开发框架来开发STM32G0,以下为多通道ADC与DMA的使用。 1 新建项目 建立adc_dma项目 在PIO的Home页面新建项目,项目名称adc_dma,选择开发板为 MonkeyPi_STM32_G070RB,开发框架选择libopencm3; 项目建立完成后在src目录下新建main.c主程序文件; 修改下载和调试方式,这里开发板使用的是DAPLink仿真器,因此修改platformio.ini文件如下: 1upload_protocol = cmsis-dap 2debug_tool = cmsis-dap 2 编写程序 2.1 ADC 设置 这里设置PA0、P
[单片机]
STM32G0开发笔记:多通道ADC与<font color='red'>DMA</font>的使用
kinetis的UART串口(DMA模式)
前面的例子中,串口的收发采用中断模式,虽然在一定程度上解放了CPU,但每个字节都要中断一次,在115200波特率下,约8.7uS就要中断一次,CPU仍然很累。直接存储器访问(DMA)方式可以进一步解放CPU,本例采用DAM方式实现每次100字节数据发送与接收。DMA处理发送是最有效的方法,因为程序明确知道有多少数据要发送,直接将数据存放数组的首地址和长度交给DMA即可由DAM连续发完这些数据,如果需要可以设置让DMA发完后产生中断。对于接收,用DMA的问题在于不知道接收多少个数,无法在收到数据后通知CPU。一般采用这样的做法:用DMA收下所有数据放到环形缓冲区里,但不产生中断。这样虽不能通知CPU何时收到了数据,但确可以收下所
[单片机]
kinetis的UART串口(<font color='red'>DMA</font>模式)
ADSP2106x中DMA的应用
   摘 要: 直接内存存取(DMA)是DSP芯片中用于快速数据交换的重要技术,对AD公司的浮点系列芯片ADSP2106x中的DMA的应用进行了详细介绍,并给出实际应用中的一些例子。     关键词: DMA 浮点系列芯片ADSP2106x     1 DMA概述     直接内存存取(DMA)对计算机系统是非常重要的。它可以使CPU在运行指令的同时,系统能实现从外部存储器或设备中存取数据,也可以在CPU不参与的情况下,由专用的DMA设备存取数据。     对于浮点DSP芯片来讲,DMA的作用更是重要。众所周知,DSP芯片主要是面向实时的信号处理,其核心的运算部件具有很高的运算速度,常以MFLOPS(每秒百万次浮点
[嵌入式]
定时器DMA Burst传输无法实现
有人使用STM32F4系列开发产品,程序运行过程中需要不时地对外输出一串驱动脉冲,并要求这几串脉冲的频率可变、占空比固定。他想到使用基于STM32定时器的DMA BURST传输。具体点说,他期望不时地通过TIM3的CH1输出一串频率可变、占空比固定的脉冲然后停下来。这个思路在原理上是没问题的,可是他在测试过程中发现怎么也折腾不出预期的效果。 他目前使用的芯片是STM32F401,虽有点老旧,但我查看了手册,确认该芯片的TIM3是支持基于TIMER事件实现TIME寄存器与内存间的DMABURST传输的。即每个TIMER事件可以申请多个DMA请求从而实现定时器寄存器与内存间的批量数据传输。要知某个STM32 TIMER是否支持上述
[单片机]
定时器<font color='red'>DMA</font> Burst传输无法实现
DMA+ADC单通道转换、多通道转换
在stm32中,使用ADC时往往采用DMA传输方式,由DMA把转换的数据传输到SRAM,再进行处理。 一、单通道转换 本章节选用ADC1进行配置实验: ADC通道与GPIO对应表: ADC结构体成员变量: typedef struct { uint32_t ADC_Mode; FunctionalState ADC_ScanConvMode; FunctionalState ADC_ContinuousConvMode; uint32_t ADC_ExternalTrigConv; uint32_t ADC_DataAlign; uint8_t ADC_NbrOfChannel; }ADC_Init
[单片机]
<font color='red'>DMA</font>+ADC单通道转换、多通道转换
STM32F429芯片带FIFO的DMA传输实现过程
STM32系列芯片都内置DMA外设,其中很多系列的DMA配备了FIFO。这里以STM32F429芯片及开发板为例,演示一下带FIFO的DMA传输实现过程。 大致情况是这样的,我用TIMER1通道1的比较事件触发DMA,将内存数据写进UART5的数据发送寄存器DR,并将UART5的TX/RX脚物理短接,同时开启UART5的DMA接收模式,即DMA将UART5接收到的数据写到指定的接收内存区。下面重点介绍UART5的DMA方式的接收过程。 首先使用STM32CubeMx完成基本配置。 下面是关于TIM1的相关配置,使用通道1的比较事件触发DMA,将内存数据写入UART的发送数据寄存器。为什么还要搞个定时器来触发,其中一个原因是
[单片机]
STM32F429芯片带FIFO的<font color='red'>DMA</font>传输实现过程
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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