找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 26237|回复: 7
打印 上一主题 下一主题
收起左侧

STM8L的ADC之测量VDD电压详解 含例程

  [复制链接]
跳转到指定楼层
楼主
ID:140343 发表于 2016-10-10 00:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
STM8L内部含有一个12位的ADC,拥有25个输入通道,包括一个内部温度传感器,一个内部参考电压。



STM8L使用外部参考电压作为ADC参考电压,由于VDD,GND一般和ADC的外部参考电压引脚VREF+,VREF-连接在一起。所以VDD的电压就是ADC的参考电压,由于LDO供给MCU的电压有一定的偏差。所以使用ADC前需要知道VDD的电压为多少,对于十二位的ADC,VDD电压对应的转换出的数值为4096(2^12).

从第一张图中可以看到,STM8L内部还有一个内部参考电压,这个内部参考电压的电压值是可知的,且是精确的。由数据手册可知,内部参考电压为1.225V。

ADC选择内部参考电压作为测量通道,可以测量到内部电压的转化值Nadc。
此时,已经VDD的转化值4096,VREFINT电压值1.225V及对应的转化值Nadc。
这些值满足比例关系,VDD/4096=VREFINT/Nadc
VDD/4096 =1.225/Nadc
VDD=1.225*4096/Nadc

本文使用ADC的单次转换模式,每隔大约0.5S触发一次ADC转换。ADC转换的通道需要在ADC_SQR寄存器中选择。
ADC完成一次数据采集转化后,会进入中断。我们在中断中打一个断点,查看变量VDD_Value中的数据,可以看到此时数据为2976(电压值被扩大了1000倍),即VDD的电压为2.976V。.与实际用万用表测量的2.99V几乎一样。
  1. /****************************************************************************************

  2. *开发环境:IAR for stm8 v1.40.1

  3. *硬件平台:STM8L-DISCOVERY

  4. *功能说明:测量VDD电压,VDD的计算结果在ADC中断中,通过仿真,设置断点,可以在IAR中查看扩大1000被后的VDD电压数据VDD_Value

  5. *作    者:茗风

  6. ****************************************************************************************/

  7. #include"iostm8l152c6.h"

  8. #include"stdbool.h"

  9. #include"stdint.h"

  10. uint16_t VDD_Value=0;

  11. /******************************************************************************************************

  12. *  名    称:void delay_10ms(uint8_t x_ms)

  13. *  功    能:延时10ms

  14. *  入口参数:无

  15. *  出口参数:无

  16. *  说    明:

  17. *  范    例:无

  18. ******************************************************************************************************/

  19. void delay_100ms(void)

  20. {

  21.   uint8_t i,j;

  22.   for(i=0;i<255;i++)//2*255个指令周期

  23.     for(j=0;j<255;j++);//2*255个指令周期

  24.   //delay_10ms共消耗 x_ms*2*255+2*x_ms个指令周期  

  25.   //255*2*255+2*255=130610us=130ms

  26.   //此延时函数,延时时间为130ms

  27.   //16M/8/2=1M 一个指令周期为1us

  28. }

  29. /******************************************************************************************************

  30. *  名    称:void ADC_Init(void)

  31. *  功    能:初始化ADC

  32. *  入口参数:无

  33. *  出口参数:无

  34. *  说    明:ADC1的测量通道为内部参考电压,单次转换模式

  35. *  范    例:无

  36. ******************************************************************************************************/

  37. void ADC_Init(void)

  38. {   

  39.    CLK_PCKENR2_PCKEN20=1; //国际惯例,开启ADC1外设时钟

  40.    ADC1_TRIGR1_VREFINTON=1;//打开内部参考电压源

  41.    ADC1_CR1_ADON=1;  //wakes up the ADC from Power down mode.

  42.    ADC1_CR2_PRESC=1;//Select a sample time of 10 μs

  43. //   0: f(ADC_CLK) = CK

  44. //   1: f(ADC_CLK) = CK/2  //系统时钟此时为默认的16M/8=2M,这里分频后,fadc=2M/2=1M

  45.   

  46.    ADC1_SQR1_DMAOFF=1;    //关闭DMA,暂时不用


  47.    ADC1_CR3_SMTP2=0x06;//采样时间为24 ADC clock cycles,也就是24*1us=24us

  48. //000: 4 ADC clock cycles

  49. //001: 9 ADC clock cycles

  50. //010: 16 ADC clock cycles

  51. //011: 24 ADC clock cycles

  52. //100: 48 ADC clock cycles

  53. //101: 96 ADC clock cycles

  54. //110: 192 ADC clock cycles

  55. //111: 384 ADC clock cycles

  56.    

  57.    ADC1_SQR1_CHSEL_S28=1; //选择内部参考电压通道

  58.    

  59.    ADC1_CR1_EOCIE=1;

  60. }


  61. void main(void)

  62. {

  63.   ADC_Init();

  64.   asm("rim");               //enable interrupts

  65.   while(1)

  66.   {

  67.     delay_100ms();

  68.     ADC1_CR1_START=1;

  69.     delay_100ms();

  70.     delay_100ms();

  71.     delay_100ms();

  72.     delay_100ms();

  73.   }

  74. }

  75. /******************************************************************************************************

  76. * 名               称: ADC中断

  77. * 功         能: EOC事件处理函数

  78. * 入口           参数:无

  79. * 出口           参数:无

  80. * 说               明:

  81. * 范              例:无

  82. ******************************************************************************************************/

  83. #pragma vector=COMP_EF2_vector

  84. __interrupt void ADC1_ISR(void)

  85. {

  86.    static uint16_t temp=0;

  87.    PC_ODR_ODR7 ^=0x01;//输出低电平

  88.    ADC1_SR_EOC=0;

  89.    temp = ADC1_DRH;

  90.    temp = (temp<<8)+ADC1_DRL;

  91.    VDD_Value=(uint32_t)1225*4096/temp;//得到的数值单位为mv

  92.    asm("nop");

  93. }
复制代码




分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏5 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:100312 发表于 2017-8-24 20:22 | 只看该作者
这么好的东西咋没人点赞呢???怒赞,狂赞,超赞666
回复

使用道具 举报

板凳
ID:355067 发表于 2018-6-20 12:02 | 只看该作者

这么好的东西咋没人点赞呢???怒赞,狂赞,超赞666
回复

使用道具 举报

地板
ID:237362 发表于 2018-6-30 09:41 | 只看该作者
學習了
回复

使用道具 举报

5#
ID:106835 发表于 2018-11-15 15:25 | 只看该作者
学习了,正需要,mark
回复

使用道具 举报

6#
ID:171207 发表于 2018-11-29 11:56 | 只看该作者

好东西要学习
回复

使用道具 举报

7#
ID:18591 发表于 2019-2-15 22:59 | 只看该作者
棒棒棒
回复

使用道具 举报

8#
ID:723157 发表于 2020-5-15 15:24 | 只看该作者
教大家一起来点赞!  挺详细的的
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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