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

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  内部参考电压 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic482868.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

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

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

stm8L 触摸库使用教程
1、查看触摸库说明文档,根据需要选取芯片(主要支持几个键):STMTouch Driver User Manual一个channel为一个按钮,比如STM8L101F 就支持3个按钮,通过按钮扩充方式可以增加按钮,参照:增加触摸传感按钮数量指南.pdf2、下载对应的官方触摸库  STM8L_STMTouch_Lib_V1.1.0,将以下两个文件夹复制到自己的工程文件夹中3、选择跟自己项目相近的工程打开,比如我要做1-4个按钮的触摸灯,就选了STM8L101K3_Ex01打开:Projects——Examples——STM8L101K3_Ex01——EWSTM8(我用的是IAR)——Example.eww4、打开后Make
发表于 2020-01-16
stm8L 触摸库使用教程
stm8L051使用库建工程
先前直接寄存器开发,不过挺麻烦的,寄存器开发stm8s103直接对着英文技术手册写代码,现在换到了stm8L的又要回头看英文文档,开发效率个人感觉对于我这个新手来说还是很低的。现在在社区下载了一份固件,看看能不能建立一个用库的工程吧。(先前简单看过别人建工程的过程,由于对IAR不熟悉,不成功,现在也就是刚刚弄到没任何错误。)1 先下载一份工程固件stsw-stm8016,固件迟些发送到资源上面,也可以到stm32/stm8社区下载。 2 建立一个iar的工程 这里建立的工程如下(我已经弄好的):   备注:app文件放我们自己编写的BSP驱动,lib放固件,还有三个文件 
发表于 2020-01-15
stm8L051使用库建工程
STM8L051之蜂鸣器beep--库函数版(没有用TIM2校准LSI)
STM8L051的蜂鸣器引脚与swin调试口共用一个引脚,虽然使用了beep就不能使用调试功能(程序下载完成后,断开调试的swin,重启即可输出),但还是可以烧写程序到MCU中的。 (**注意**可以不用设置选项位即可使用beep功能)下面是库函数的代码:void BeepInit(){  // BEEP_LSClockToTIMConnectCmd(ENABLE);   CLK_PeripheralClockConfig(CLK_Peripheral_BEEP,ENABLE);  // BEEP_LSICalibrationConfig(38000);   
发表于 2020-01-15
STM8L051之ADC+DMA两通道数据采样错位问题
程序中使用ADC1采样一个外部输入,一个内部参考电压的电压,其中出现了两通道的数据错位问题,即有时数组第一个数与该数组第二个数据交换了,在网上找了很久都没神马结果,最后只能将ADC的连续转换模式设置成单次转换即ADC_Init(ADC1, ADC_ConversionMode_Continuous,   ADC_Resolution_12Bit, ADC_Prescaler_1);改成ADC_Init(ADC1, ADC_ConversionMode_Single,  ADC_Resolution_12Bit, ADC_Prescaler_1);在每次一组数据传 输完成产生一次DMA中断的时候再启动
发表于 2020-01-15
STM8L051 GPIO PC0 PC1无法上拉的问题
做一个温湿度,第一个样板调通以后,进行改版,为了减少PCB的面积,做得精巧一点,没经过验证,也没认真看书就去掉了GPIO上的2个上拉电阻,毕竟GPIO是有内部上拉电阻,结果真的中奖了,功能上不来了。正好是在PC0和PC1这两个IO上,然而正片IC就正好是这两个IO没有上拉功能,哈哈哈,又要改一版了,望引以为戒。
发表于 2020-01-15
STM8L051 GPIO PC0 PC1无法上拉的问题
STM8L051单片机,PWM配置
STM8L051单片机,PWM配置。文件.c 中代码如下所示#include <MYPWM.h>void MYPWM_Init(void)//PWM初始化{  GPIO_Init(GPIOB,GPIO_Pin_1,GPIO_Mode_Out_PP_High_Fast); //TIME3 ,CH1,PB1,快速推挽输出高电平  TIM3_DeInit();//定时器配置为缺省  CLK_PeripheralClockConfig(CLK_Peripheral_TIM3,ENABLE);      //TIME3时钟使能 
发表于 2020-01-15
小广播
何立民专栏 单片机及嵌入式宝典

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

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