在上一篇文章中说了STM8的ADC连续采样模式,为了提高采样的精度和速率,STM8单片机还提供了带缓存的连续采样模式,也就是说ADC会连续采集8个数据,放在缓存中,读取数据时可以一次从缓存中读取8个数据,这样就可以通过8个数据数据计算平均值,使得采样的结果更加准确。

下面看一下官方文档中的对缓存模式的介绍。

  通过文档中可以看出,要开启缓存模式,只需要将ADC_CR3寄存器中的COUNT为DBUF设置为1,就可以开启缓存模式了。
  当开启缓存模式后,采样的结果将不会存放在ADC_DR寄存器中,而是会将结果依次存放在ADC_DB0R寄存器到ADCDB7R寄存器,连续读取8次数据,存储在这8个寄存器中。读取数据的时候,依次从这8个寄存器中读取就行。

下面直接通过代码来实现带缓存功能的连续采样模式:

#include "adc.h"
#include "main.h"u16  DATAH = 0;                          //ADC转换值高8位
u16  DATAL = 0;                          //ADC转换值低8位
_Bool ADC_flag = 0;                     //ADC转换成功标志//AD通道引脚初始化
void ADC_GPIO_Init( void )
{PD_DDR &= ~( 1 << 3 );              //PD3 设置为输入      电流PD_CR1 &= ~( 1 << 3 );              //PD3 设置为悬空输入
}
/*
ch 为单片机ADC通道
通过置位ADC_CR1寄存器的ADON位来开启ADC。当第一次置位ADON时,ADC从低功耗模式唤醒。
为了启动转换必须第二次使用写指令来置位ADON位。
在转换结束时,ADC会保持在上电状态,用户只需要置位ADON位一次来启动下一次转换。
转换完成后,转换数据存储在ADC_DR寄存器中,EOC(转换结束)标志被置位,如果EOCIE被置位将产生一个中断
ADC输入通道初始化入口参数表示通道选择
*/
void ADC_CH_Init( u8 ch )
{char l = 0;ADC_CR1  = 0x00;                    //fADC = fMASTER/2, 8Mhz  单次转换,禁止转换ADC_CR1 |= ( 1 << 1 );              //开启连续转换模式ADC_CSR  = ch;                      //控制状态寄存器 选择要 AD输入通道  如:PD2(AIN3)ADC_CR2  = 0x00;                    //默认左对齐 读数据时先读高在读低ADC_TDRL = ( 1 << ch );             //禁止相应通道 施密特触发功能 1左移ch+1位ADC_CR1 |= 0x01;                    //使能ADC并开始转换//ADC_CSR |= 0x20;                    //EOCIE 使能转换结束中断  EOC中断使能ADC_CR3 |= ( 1 << 7 );              //数据缓存使能for( l = 0; l < 100; l++ );         //延时,保证ADC模块的上电完成 至少7usADC_CR1 = ADC_CR1 | 0x01;           //再次将CR1寄存器的最低位置1 使能ADC 并开始转换
}u16 databuf[8] = {0};
//采集PD2电压值
u16 ReadVol_CH3( void )
{u16 voltage = 0;while( ( ADC_CSR & 0x80 ) == 0 );      //等待转换结束if( ADC_CSR & 0x80 ){ADC_CSR &= 0x7F;/*使能缓存模式后,数据会存储在 ADC_DB0R ---- ADC_DB7R 寄存器中如果使能了扫描模式那么这几个寄存器存储的就是对应通道的数据如果没有使能扫描模式,那么这几个通道就存储的是连续转换的结果这里没有使用扫描模式,所以缓存器中存储的都是当前通道连续读取的数据*/DATAH = ADC_DB0RH;                    // 读出ADC结果的高8位DATAL = ADC_DB0RL;                    // 读出ADC结果的低8位voltage = ( DATAH << 2 ) + DATAL ;    //得到十位精度的数据  0--1024databuf[0] = voltage;DATAH = ADC_DB1RH;DATAL = ADC_DB1RL;voltage = ( DATAH << 2 ) + DATAL ;databuf[1] = voltage;DATAH = ADC_DB2RH;DATAL = ADC_DB2RL;voltage = ( DATAH << 2 ) + DATAL ;databuf[2] = voltage;DATAH = ADC_DB3RH;DATAL = ADC_DB3RL;voltage = ( DATAH << 2 ) + DATAL ;databuf[3] = voltage;DATAH = ADC_DB4RH;DATAL = ADC_DB4RL;voltage = ( DATAH << 2 ) + DATAL ;databuf[4] = voltage;DATAH = ADC_DB5RH;DATAL = ADC_DB5RL;voltage = ( DATAH << 2 ) + DATAL ;databuf[5] = voltage;DATAH = ADC_DB6RH;DATAL = ADC_DB6RL;voltage = ( DATAH << 2 ) + DATAL ;databuf[6] = voltage;DATAH = ADC_DB7RH;DATAL = ADC_DB7RL;voltage = ( DATAH << 2 ) + DATAL ;databuf[7] = voltage;}return voltage;
}

在初始化中设置 ADC_CR1 |= ( 1 << 1 ); 也就是将ADC_CR1寄存器的第一位设置为1。

也就是使能了连续转换模式。

然后设置ADC_CR3 |= ( 1 << 7 ); 也就是将ADC_CR3寄存器的第7位设置为1.

也就是开启了ADC的数据缓存功能,当数据转换完成之后,ADC_CSR寄存器的EOC位会置1,此时如果程序判断到EOC位为1时,就可以去数据缓存寄存器读取数据了。也就是代码中ReadVol_CH3()函数实现的功能。

这里是通过查询标志位的方法读取数据,也可以通过中断的方式读取数据。

通过中断方式读取代码如下:

#include "adc.h"
#include "main.h"u16  DATAH = 0;                          //ADC转换值高8位
u16  DATAL = 0;                          //ADC转换值低8位
_Bool ADC_flag = 0;                     //ADC转换成功标志//AD通道引脚初始化
void ADC_GPIO_Init( void )
{PD_DDR &= ~( 1 << 3 );              //PD3 设置为输入      电流PD_CR1 &= ~( 1 << 3 );              //PD3 设置为悬空输入
}
/*
ch 为单片机ADC通道
通过置位ADC_CR1寄存器的ADON位来开启ADC。当第一次置位ADON时,ADC从低功耗模式唤醒。
为了启动转换必须第二次使用写指令来置位ADON位。
在转换结束时,ADC会保持在上电状态,用户只需要置位ADON位一次来启动下一次转换。
转换完成后,转换数据存储在ADC_DR寄存器中,EOC(转换结束)标志被置位,如果EOCIE被置位将产生一个中断
ADC输入通道初始化入口参数表示通道选择
*/
void ADC_CH_Init( u8 ch )
{char l = 0;ADC_CR1  = 0x00;                    //fADC = fMASTER/2, 8Mhz  单次转换,禁止转换ADC_CR1 |= ( 1 << 1 );              //开启连续转换模式ADC_CSR  = ch;                      //控制状态寄存器 选择要 AD输入通道  如:PD2(AIN3)ADC_CR2  = 0x00;                    //默认左对齐 读数据时先读高在读低ADC_TDRL = ( 1 << ch );             //禁止相应通道 施密特触发功能 1左移ch+1位ADC_CR1 |= 0x01;                    //使能ADC并开始转换ADC_CSR |= 0x20;                    //EOCIE 使能转换结束中断  EOC中断使能ADC_CR3 |= ( 1 << 7 );              //数据缓存使能for( l = 0; l < 100; l++ );         //延时,保证ADC模块的上电完成 至少7usADC_CR1 = ADC_CR1 | 0x01;           //再次将CR1寄存器的最低位置1 使能ADC 并开始转换
}u16 databuf[8] = {0};
//采集PD2电压值
u16 ReadVol_CH3( void )
{u16 voltage = 0;if( ADC_flag ){ADC_flag = 0;/*使能缓存模式后,数据会存储在 ADC_DB0R ---- ADC_DB7R 寄存器中如果使能了扫描模式那么这几个寄存器存储的就是对应通道的数据如果没有使能扫描模式,那么这几个通道就存储的是连续转换的结果这里没有使用扫描模式,所以缓存器中存储的都是当前通道连续读取的数据*/DATAH = ADC_DB0RH;                    // 读出ADC结果的高8位DATAL = ADC_DB0RL;                    // 读出ADC结果的低8位voltage = ( DATAH << 2 ) + DATAL ;    //得到十位精度的数据  0--1024databuf[0] = voltage;DATAH = ADC_DB1RH;DATAL = ADC_DB1RL;voltage = ( DATAH << 2 ) + DATAL ;databuf[1] = voltage;DATAH = ADC_DB2RH;DATAL = ADC_DB2RL;voltage = ( DATAH << 2 ) + DATAL ;databuf[2] = voltage;DATAH = ADC_DB3RH;DATAL = ADC_DB3RL;voltage = ( DATAH << 2 ) + DATAL ;databuf[3] = voltage;DATAH = ADC_DB4RH;DATAL = ADC_DB4RL;voltage = ( DATAH << 2 ) + DATAL ;databuf[4] = voltage;DATAH = ADC_DB5RH;DATAL = ADC_DB5RL;voltage = ( DATAH << 2 ) + DATAL ;databuf[5] = voltage;DATAH = ADC_DB6RH;DATAL = ADC_DB6RL;voltage = ( DATAH << 2 ) + DATAL ;databuf[6] = voltage;DATAH = ADC_DB7RH;DATAL = ADC_DB7RL;voltage = ( DATAH << 2 ) + DATAL ;databuf[7] = voltage;     }return voltage;
}//AD中断服务函数 中断号22
#pragma vector = 24                     // IAR中的中断号,要在STVD中的中断号上加2
__interrupt void ADC_Handle( void )
{ADC_CSR &= ~0x80;                   // 转换结束标志位清零  EOCADC_flag = 1;                       // ADC中断标志 置1
}

当数据采集完成后,就会产生一次中断,然后在中断中设置一个标志位,然后ReadVol_CH3()函数发现标志位置1后,就直接读取采样的数据。

STM8单片机ADC带缓存的连续采样模式相关推荐

  1. STM8 ADC转换模式-------带缓存的连续模式

    STM8单片机ADC支持5种转换模式:单次模式,连续模式,带缓存的连续模式,单次扫描模式,连续扫描模式. 连续和带缓存的连在连 换模式中,将ADC设为连续模式,该模式是通过置位 ADC_CR1寄存器的 ...

  2. STM8单片机ADC连续扫描模式

      当STM8单片机使用ADC功能读取多个通道的值时,可以使用连续模式,但是连续模式一次只能采样一个通道的值,那么如果要采样多个通道时怎么办呢?STM8提供了一个多通道连续采样扫描模式.也就是说多个通 ...

  3. STM8单片机ADC采样功能通过定时器触发

      在使用STM8单片机的ADC功能时,读取ADC数据时一般有两种方式,一种是通常不断地读取采样标志位,来判断ADC采样是否结束,一种是通过中断的方式来通知系统采样是否结束.   有时候采样ADC数据 ...

  4. STM8单片机 ADC模拟看门狗中文资料错误

      在调试stm8单片机的adc模拟看门狗功能时,不管怎么设置ADC_HTR和ADC_LTR寄存器的值,然后通过IAR软件单步调试时观察这两个寄存器的值都不对.   根据中文手册上看,高位寄存器存储的 ...

  5. STM8单片机ADC连续采样模式

     STM8S003单片机内部ADC为12位,A/D转换的各个通道可以执行单次和连续的转换模式.  单次转换模式的意思就是,ADC每次转换一次数据后,就会停止转换,如果还需要继续转换的话,就需要手动开启 ...

  6. STM8单片机ADC单次采样模式

     STM8S003单片机内部ADC为12位,A/D转换的各个通道可以执行单次和连续的转换模式.  单次转换模式的意思就是,ADC每次转换一次数据后,就会停止转换,如果还需要继续转换的话,就需要手动开启 ...

  7. STM8单片机ADC模拟看门狗功能实现

      看门狗的功能大家都知道,而这个模拟看门狗又是什么东西呢?   简单的说就是这个模拟看门狗可以实时监控ADC采样的数据,当采样的数据值小于设置的最小值或者大于设置的最大值时,单片机就会触发ADC中断 ...

  8. STM32F4系列探究1——三重ADC扫描连续采样+DMA双缓冲区存储

    文章目录 前言 一.STM32F4的ADC理论知识学习 1.基础知识 2.扫描模式与连续模式 3.单ADC模式下双缓存机制的实现 4.三重同步采样模式 二.由定时器触发的单缓冲区模式 1.时钟树配置 ...

  9. TI DSP 28335 ADC连续采样检测SPI控制的DAC输出 SCI串口232通信

    文章目录 前言 1 SCIA FIFO 串口通信配置 2 DAC 数模转换 配置 2.1 TLV5620芯片简介 2.2 TLV5620初始化函数 2.2 DAC 输出函数 3 ADC 模数转换 配置 ...

最新文章

  1. SNMP在windows linux router上的配置笔记
  2. 面向对象编程基础 (一)
  3. C++ 容易犯错误的模型
  4. 如何处理Angular依赖注入的错误消息: NullInjectorError No provider for EffectsRootModule!
  5. smartassembly 使用指南
  6. FPGA _Verilog HDL_8位加法计数器设计实验
  7. java beancomparator_xkbeancomparator
  8. 【转】No JVM could be found on your system解决方法
  9. 【GNN】大热下的 GNN 研究面临哪些“天花板”?未来的重点研究方向又在哪?...
  10. OJ:一道考察多态的题目
  11. Java集合框架的概念以及常用接口的介绍
  12. 孙鑫VC学习笔记:第十六讲 (二) 利用关键代码段实现线程间的同步
  13. 077 logging模块
  14. SwitchHost使用
  15. 【冒泡排序】c++实现冒泡排序代码
  16. creo视图管理器使用方法_5.3 视图管理-样式、截面
  17. leetcode 799. 香槟塔 (Champagne Tower)
  18. 移动端adaptive设置
  19. 【读书笔记】RevMiner:RevMiner: An Extractive Interface for Navigating Reviews on a Smartphone
  20. 3812 机器人走迷宫(枚举 + 全排列)

热门文章

  1. XWiki 4.4.1 发布,Java 的 Wiki 引擎
  2. db2 快速清除表中所以的数据
  3. 吃的苦中苦,方为人上人!
  4. secucrecrt配置文件导入和保存
  5. 如何实现多风格选择 样式实时切换?
  6. ExtJs4.1目录结构介绍和使用说明[转]
  7. SQL2008R2 收缩数据库问题 - 日志文件不变小
  8. Spring Cloud Eureka 2 (Eureka Server搭建服务注册中心)
  9. 匿名类型(C# 编程指南)
  10. WinSDK学习--Document/View结构