STM8的ADC的五种工作模式

2023-11-19

STM8的ADC的五种工作模式

STM8的ADC是10位的逐次比较型模拟数字转换器,多达16个多功能的输入通道。拥有5种转换模式,转换结束可产生中断。

STM8 ADC的初始化顺序如下:

1、AD输入通道对应的IO设置为上拉输入;

2、配置AD参数,如:预分频系数、是否使用外部触发转换、是否使用施密特触发器、是否使用缓存以及是否使用扫描模式等;

3、开启ADC;

4、开启转换;

注意!开启ADC和开启转换实际上都是置位ADON。

然后就可以通过ADC_DR寄存器读取转换后的值。

 

l 单次模式:

在单次转换模式中,ADC仅在由ADC_CSR寄存器的CH[3:0]选定的通道上完成一次转换。该模式是在当CONT位为0时通过置位ADC_CR1寄存器的ADON位来启动的。

一旦转换完成,转换后的数据存储在ADC_DR寄存器中,EOC(转换结束)标志被置EOCIE 被置位将产生一个中断。

注意!初始化的时候只能选择一个通道。转换多个通道只能通过反复重新初始化或扫描模式!

示例程序:

void  adc_init(void)

{  

GPIO_Init(GPIOD,GPIO_PIN_3,GPIO_MODE_IN_PU_NO_IT);//AIN4 IO设置为上拉输入

  ADC1_PrescalerConfig(ADC1_PRESSEL_FCPU_D2);//预分频2

  ADC1_ExternalTriggerConfig(ADC1_EXTTRIG_TIM,DISABLE);//不使用外部触发

  ADC1_SchmittTriggerConfig(ADC1_SCHMITTTRIG_CHANNEL4,DISABLE);

  //禁止AIN2 AIN4的施密特触发器,降低IO静态功耗

  //PD5,PD6上的通道如果施密特方式禁用会导致串口无法收发数据!

  

ADC1_ConversionConfig(ADC1_CONVERSIONMODE_SINGLE,//单次转换

                        ADC1_CHANNEL_4,//只能选择一个通道!

                        ADC1_ALIGN_RIGHT);//右对齐

 ADC1_Cmd(ENABLE);//开启ADC

}

void main( void )

u16value=0;

  adc_init();

  while(1)

  {

ADC1_StartConversion();//开启一次转换一次

while(!ADC1_GetFlagStatus(ADC1_FLAG_EOC));//等待转换完成

    ADC1_ClearFlag(ADC1_FLAG_EOC);//软件清除

    value=(u16)ADC1_GetConversionValue();//从ADC_DR中读取ADC值

}

}

 

l 连续模式与带缓存的连续模式:

在连换模式中,ADC在完成一次转换后就立刻开始下一次的转换。当CONT位被置位时即将ADC设为连续模式,该模式是通过置位 ADC_CR1寄存器的 ADON 位来启动的。

如果缓冲功能没有被使能(ADC_CR3寄存器的DBUF位=0),那么转换结果数据保存在ADC_DR寄存器中同时 EOC 标志被置位。如果EOCIE 位已被置位时将产生一次中断。然后开始下一次转换。

如果缓存功能被使能(DBUF=1),那么某个选定通道上的8个或者10个连续的转换结果会填满数据缓存(此时填满的是同一个通道的数据!!扫描模式时才是不同通道的数据!),当缓存被填满时,EOC(转换结束)标志被置位,如果EOCIE位已被置位,则会产生一个中断,然后一个新的转换自动开始。如果某个数据缓存寄存器在被读走之前被覆盖,OVR标志将置1。

如果要停止连续转换,可以复位清零CONT位来停止转换或者复位清零ADON位来关闭ADC的电源。

示例程序(不带缓存):

void  adc_init(void)

{  

GPIO_Init(GPIOD,GPIO_PIN_3,GPIO_MODE_IN_PU_NO_IT);//AIN4 IO设置为上拉输入

  ADC1_PrescalerConfig(ADC1_PRESSEL_FCPU_D2);//预分频2

  ADC1_ExternalTriggerConfig(ADC1_EXTTRIG_TIM,DISABLE);//不使用外部触发

  ADC1_SchmittTriggerConfig(ADC1_SCHMITTTRIG_CHANNEL4,DISABLE);

  //禁止AIN2 AIN4的施密特触发器,降低IO静态功耗

  //PD5,PD6上的通道如果施密特方式禁用会导致串口无法收发数据!

 

 ADC1_ConversionConfig(ADC1_CONVERSIONMODE_CONTINUOUS, //连续转换

                        ADC1_CHANNEL_4,//只能选择一个通道!

                        ADC1_ALIGN_RIGHT);//右对齐

 ADC1_Cmd(ENABLE);//开启ADC

 ADC1_StartConversion();//开启连续转换

}

void main( void )

u16value=0;

  adc_init();

  while(1)

  {

while(!ADC1_GetFlagStatus(ADC1_FLAG_EOC));//等待转换完成

    ADC1_ClearFlag(ADC1_FLAG_EOC);//软件清除

    value=(u16)ADC1_GetConversionValue();//从ADC_DR中读取ADC值

}

}

示例程序(带缓存):

void  adc_init(void)

{  

GPIO_Init(GPIOD,GPIO_PIN_3,GPIO_MODE_IN_PU_NO_IT);//AIN4 IO设置为上拉输入

  

ADC1_PrescalerConfig(ADC1_PRESSEL_FCPU_D2);//预分频2

  ADC1_ExternalTriggerConfig(ADC1_EXTTRIG_TIM,DISABLE);//不使用外部触发

  ADC1_SchmittTriggerConfig(ADC1_SCHMITTTRIG_CHANNEL4,DISABLE);

  //禁止AIN2 AIN4的施密特触发器,降低IO静态功耗

  //PD5,PD6上的通道如果施密特方式禁用会导致串口无法收发数据!

 

 ADC1_ConversionConfig(ADC1_CONVERSIONMODE_CONTINUOUS, //连续转换

                        ADC1_CHANNEL_4,//只能选择一个通道!

                        ADC1_ALIGN_RIGHT);//右对齐

 ADC1_Cmd(ENABLE);//开启ADC

 ADC1_StartConversion();//开启连续转换

ADC1_DataBufferCmd(ENABLE);//开启缓存

}

void main( void )

u16value=0;

  adc_init();

  while(1)

  {

while(!ADC1_GetFlagStatus(ADC1_FLAG_EOC));//等待转换完成

    ADC1_ClearFlag(ADC1_FLAG_EOC);//软件清除

    value=0;

for(u8 i=0;i<10;i++)//

    {

      value+=ADC1_GetBufferValue(i);//将10个缓存中的值求和

    }

    value=value/10;//求出ADC的平均值

}

}

注意,只有在连续转换模式下ADC_DB寄存器才能称之为缓存,此时存储的是同一个通道多次转换的值。在单次扫描和连续扫描模式下该寄存器被用来存放不同通道的转换值。

 

l 单次扫描模式:

该模式是用来转换从AIN0到AINn之间的一连串模拟通道,‘n’是在 ADC_CSR寄存器的CH[3:0]位中指定的通道编号(即CH[3:0]里配置第n个通道,就从通道0顺序递增逐个通道进行转换,直到第n个通道结束。例如,CH[3:0]里配置为AIN4,则对AIN0、AIN1、AIN2、AIN3、AIN4进行转换,其他通道不转换)。在扫描转换的过程中,序号 CH[3:0]位的值是被硬件自动更新的,它总保存当前正在被转换的通道编号。

单次转换模式可以在在SCAN 位被置位且CONT 位以被清零时通过置位 ADON 位来启动。

注意:当使用扫描模式时,不可以将AIN0到AINn之间通道对应的I/O口设为输出状态,因为ADC的多路选择器已经将这些I/O口的输出模块禁用了。

对于单次扫描模式,转换是从AIN0通道开始的,而且结果数据被存储在数据缓冲寄存器ADC_DBxR 中(例如,CH[3:0]里配置为AIN4,则ADC_DB0R存放AIN0的转换结果,ADC_DB1R存放AIN1的转换结果,以此类推。 ),当最后一个通道(通道‘n’)被转换完成后,EOC(转换结束)标志被置位,当EOCIE 位已被置位时将产生一个中断。

可以从缓冲寄存器中读取各个通道的转换结果值。如果某个数据缓存寄存器在被读走之前被覆盖,OVR标志将置1。

在转换序列正在进行过程中不要清零SCAN位;单次扫描模式可通过清零ADON位来立即停止。为了开启一次新SCAN扫描转换,可以通过对ADC_CR1寄存器的EOC位清零和ADON位置位来实现。

示例程序:

void  adc_init(void)

{  

GPIO_Init(GPIOC,GPIO_PIN_4,GPIO_MODE_IN_PU_NO_IT);//AIN2 IO设置为上拉输入

  GPIO_Init(GPIOD,GPIO_PIN_3,GPIO_MODE_IN_PU_NO_IT);//AIN4 IO设置为上拉输入

 

ADC1_PrescalerConfig(ADC1_PRESSEL_FCPU_D2);//预分频2

  ADC1_ExternalTriggerConfig(ADC1_EXTTRIG_TIM,DISABLE);//不使用外部触发

  ADC1_SchmittTriggerConfig(ADC1_SCHMITTTRIG_CHANNEL4,DISABLE);

  //禁止AIN2 AIN4的施密特触发器,降低IO静态功耗

  //PD5,PD6上的通道如果施密特方式禁用会导致串口无法收发数据!

  

ADC1_ConversionConfig(ADC1_CONVERSIONMODE_SINGLE,//单次转换

                        ADC1_CHANNEL_4,//配置通道号最大的那个

                        ADC1_ALIGN_RIGHT);//右对齐

  ADC1_Cmd(ENABLE);//开启ADC

ADC1_ScanModeCmd(ENABLE);//开启扫描模式

}

void main( void )

u16value1=0;

u16value2=0;

  adc_init();

  while(1)

  {

ADC1_StartConversion();//开启一次转换

while(!ADC1_GetFlagStatus(ADC1_FLAG_EOC));//等待转换完成

    ADC1_ClearFlag(ADC1_FLAG_EOC);//软件清除

    value1=(u16)ADC1_GetBufferValue(ADC1_SCHMITTTRIG_CHANNEL2)//读取AIN2的值

value2=(u16)ADC1_GetBufferValue(ADC1_SCHMITTTRIG_CHANNEL4)//读取AIN4的值

}

}

 

l 连续扫描模式:

该模式和单次扫描模式相近,只是每一次在最后通道转换完成时,一次新的从通道0到通道n扫

描转换会自动开始。如果某个数据缓存寄存器在被读走之前被覆盖,OVR标志将置1。连续扫描模式是在当SCAN位和CONT位已被置时,通过置位ADON位来启动的。在转换序列正在进行过程中不要清零SCAN位。

连续扫描模式可以通过清零ADON位来立即停止。另外一种选择就是当转换过程中清除CONT位那么转换会在下一次的最后一个通道转换完成时停止。

注意:在扫描模式(连续扫描模式)中,不要使用位操作指令(BRES)去清除EOC标志位,这是因为该指令是对整个ADC_CSR寄存器的一个读-修改-写操作。从CH[3:0]寄存器中读取当前的通道编号和写回该寄存器,将会改变扫描系列的最后通道编号。在连续扫描模式中正确的清除EOC标志位的方法是 个RAM变量中载入一个字节到ADC_CSR寄存器,这样来清除EOC标志位同时还重新载入扫描系列新的最后通道编号。

笔者实验发现,位操作指令只在连续扫描模式中会清除CH[3:0]寄存器中的值,但并不影响其他值。因此将ADC_CSR中的值读出,再将CH[3:0]中原来通道号加入进去,最后重新写入ADC_CSR中即可。写法如下:

ADC1->CSR = (uint8_t)(ADC1->CSR &(~ADC1_FLAG_EOC)|ADC1_CHANNEL_n);

注:ADC1_CHANNEL_n表示扫描到那个通道结束。

示例程序:

void  adc_init(void)

{  

GPIO_Init(GPIOC,GPIO_PIN_4,GPIO_MODE_IN_PU_NO_IT);//AIN2 IO设置为上拉输入

  GPIO_Init(GPIOD,GPIO_PIN_3,GPIO_MODE_IN_PU_NO_IT);//AIN4 IO设置为上拉输入

 

  ADC1_PrescalerConfig(ADC1_PRESSEL_FCPU_D2);//预分频2

  ADC1_ExternalTriggerConfig(ADC1_EXTTRIG_TIM,DISABLE);//不使用外部触发

  ADC1_SchmittTriggerConfig(ADC1_SCHMITTTRIG_CHANNEL4,DISABLE);

  //禁止AIN2 AIN4的施密特触发器,降低IO静态功耗

  //PD5,PD6上的通道如果施密特方式禁用会导致串口无法收发数据!

 

  ADC1_ConversionConfig(ADC1_CONVERSIONMODE_CONTINUOUS, //连续转换

                        ADC1_CHANNEL_4,//配置通道号最大的那个

                        ADC1_ALIGN_RIGHT);//右对齐

 ADC1_Cmd(ENABLE);//开启ADC

ADC1_ScanModeCmd(ENABLE);//开启扫描模式

 ADC1_StartConversion();//开启转换

}

void main( void )

u16value1=0;

u16value2=0;

  adc_init();

  while(1)

  {

while(!ADC1_GetFlagStatus(ADC1_FLAG_EOC));//等待转换完成

    ADC1->CSR = (uint8_t)(ADC1->CSR &(~ADC1_FLAG_EOC)|ADC1_CHANNEL_4);//软件清除

     value1=(u16)ADC1_GetBufferValue(ADC1_SCHMITTTRIG_CHANNEL2)//读取AIN2的值

value2=(u16)ADC1_GetBufferValue(ADC1_SCHMITTTRIG_CHANNEL4)//读取AIN4的值

}

}

 

至此,STM8的ADC的5种工作模式全部介绍完毕。总结一下学习经验就是仔细对照芯片手册编写程序,然后进行仿真调试,观察寄存器中的值的变化,从中领悟手册中的意思。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM8的ADC的五种工作模式 的相关文章

随机推荐

  • 【TCP/IP详解 卷一:协议】TCP的小结

    前言 TCP学习的综述 在学习TCP IP协议的大头 TCP协议 的过程中 遇到了很多机制和知识点 详解中更是用了足足8章的内容介绍它 TCP协议作为 应用层 和 网络层 中间的 传输层协议 既要为下面的网络层协议保证连接的可靠性 IP协议
  • 通过Jib将Springboot应用通过Docker部署

    一 安装Docker 1 更新Yum包 yum update 2 卸载旧版本 如果安装过旧版本的话 1 删除软件包 yum remove y docker docker client docker client latest docker
  • 【Espruino】NO.14 温湿度传感器DHT11

    http blog csdn net qwert1213131 article details 35828873 本文属于个人理解 能力有限 纰漏在所难免 还望指正 小鱼有点电
  • 环境变量是如何生效的——以Linux操作系统为例

    什么是环境变量 从我们学习Java开始 就经常接触一个东西 PATH 也叫环境变量 环境变量是操作系统提供给应用程序访问的简单 key value字符串 windows linux mac都有同样的概念 环境变量的作用 当我们拥有一个可执行
  • Git版本回退并强制推送到远端

    Git版本回退并强制推送到远端 本文参考廖雪峰的Git教程 前言 本文章解决问题的前提是本人不小心修改了本地代码仓库的最外层目录权限 不知道原权限是什么 导致本地git提示几十个文件被修改过 实际内容并未修改 可能是目录权限改变被git识别
  • C++ - 继承 一些 细节 - 组合 和 继承的区别

    前言 本篇博客基于 C 继承 chihiro1122的博客 CSDN博客 之上列出一些例子 如果有需要请看以上博客 继承的例子 例1 上述例子应该选择 C 首先不用说 p3肯定是指向 d 对象的开头的 p1 也是指向 d 对象的开头的 不同
  • 机器学习即服务:关于情感分析的10个应用场景和4个服务

    情感分析是什么 用户生成内容的爆炸式增长和档案材料的数字化创造了大量的数据集 其中包含了许多人对几乎每一个主题发表的观点 在某些情况下 该数据的生成是通过用户界面构造的 例如 在电子商务网站上处理客户评论相对容易 因为用户需要在产品评论的文
  • C++模板基础(六)

    类模板与成员函数模板 使用 template 关键字引入模板 template class B 类模板的声明与定义 翻译单元的一处定义原则 template
  • html5页面刷新时显示新数据,用ajax使网页不刷新就可以显示新数据

    用AjaxPro的 1 在引用中添加引用AjaxPro dll 我用的是这个 支持asp net 1 1 和asp net 2 0 2 web config中建立HttpHandler 3 新建一个类Demo 这个类里面提供了查询数据库和输
  • 怎么在html中复制粘贴图片,如何复制其他网页上的文章和图片

    首先 我们并不建议直接复制别人的内容 以免侵权 但是不排除在某些情况下 需要将其他网页上的内容完整的复制到你的网站中 比如 将自己的微博文章复制到自己的网站 大部分人都知道这个简单的方法 先选中目标文字按CTRL C快捷键 然后再网站后台文
  • AngularJS学习之全局API(应用程序编程接口)

    1 AngularJS全局API用于执行常见任务的Javascript函数集合 比较对象 迭代对象 转换对象 2 全局API函数使用angularJS对象进行访问 以下是通用API函数 angular lowercase 转换字符串为小写
  • Unity用Vuforia做AR实现脱卡效果

    有时在识别目标丢失后我们仍希望虚拟物体能够出现在摄像机前 或者到一个特定的位置 我们能对其进行操作 这就是脱卡功能 自带的脱卡功能应该是ExtendedTracking 允许模型在识别图丢失的时候还存在 位置不变 在丢失的时候的位置 这样也
  • 用Python实现火车票查询(含票价版)

    用Python实现火车票查询 含票价版 写在前面 网上关于用Python3编写火车查询脚本的版本众多 我在前人的基础上编写了自己的这个版本 我觉得的写的这个版本有以下几个特色 1 智能引导输入 我一直比较喜欢这种方式 如果直接做成GUI的图
  • 基于分位数回归的门控循环单元QRGRU时间序列区间预测。(主要应用于风速,负荷,功率)包含评价指标R2,MAE,MBE,区间覆盖率,区间平均宽度。

    清空环境变量 warning off 关闭报警信息 close all 关闭开启的图窗 clear 清空变量 clc 清空命令行 导入数据 时间序列的单列数据 result xlsread 数据集 xlsx 数据分析 num samples
  • Sublime Text配置anaconda环境

    Ref https blog csdn net pptde article details 110791950 spm 1001 2101 3001 6661 1 utm medium distribute pc relevant t0 n
  • docker创建CentOS云主机(docker实践)

    基于Ubuntu操作系统 从零开始构建一套docker虚拟化平台 docker的产物为 容器 docker构建容器 Nginx WEB docker启动虚拟机 创建CentOS云主机 同样是容器 对之前内容的总结熟悉 要求 CentOS 7
  • Android实现裁剪

    Android自定义View实现图片缩放旋转移动裁剪 灰信网 软件开发博客聚合 freesion com SuppressLint AppCompatCustomView public class CorpToView extends Im
  • java前后端传递日期类型不一致的转换问题

    今天在做学生信息的展示时发现展示的日期和数据库中日期不同 本来最开始是用SimpleDateFormat进行转换的 但是转换之后的是字符串类型的 与date类型对不上 所以就上网查了一下 发现可以用 DateTimeFormat和 Json
  • 牛顿法

    牛顿法被称为牛顿 拉夫逊 Newton Raphson 方法 牛顿在17世纪提出用来求解方程的根 假设点x 位函数f x 的根 则f x 0 将函数f x 在点处进行一阶泰勒展开有 假设点为函数f x 的根 则有 那么可以得到 牛顿法通过迭
  • STM8的ADC的五种工作模式

    STM8的ADC的五种工作模式 STM8的ADC是10位的逐次比较型模拟数字转换器 多达16个多功能的输入通道 拥有5种转换模式 转换结束可产生中断 STM8 ADC的初始化顺序如下 1 AD输入通道对应的IO设置为上拉输入 2 配置AD参