【STC8A8K64D4开发板】第2-9讲:比较器

news2024/10/1 9:43:47
    1. 学习目的
  1. 学习比较器的作用和原理。
  2. 掌握比较器的应用流程包括配置、启动以及中断服务函数的编写。
    1. 比较器原理

STC8A8K64D4单片机片内集成了比较器(Comparator),比较器有两个输入端IN+(正端输入端)和(负端输入端),可选择其中一个输入端作为参考点来比较,通常使用负端输入端(IN-)做为参考点,当正端输入端电压小于负端输入端时比较器输出低电平,反之输出高电平。

STC8A8K64D4的比较器原理框图如下图所示,主要包含输入选择、滤波配置以及输出控制和中断选择控制。

图1:比较器原理框图

  1. 选择输入端

输入端选择包含正端输入端选择和负端输入端选择,正端输入端可以配置为P3.7、P5.1、P5.1端口或者ADC的模拟输入通道。负端输入端可以配置为P3.6端口或者是内部BandGap经过OP后的REFV电压(内部固定比较电压)。

正端输入和负端输入是通过“比较器扩展配置寄存器(CMPEXCFG)”的CMPNS位和CMPPS[1:0]位配置,如下图所示。

比较器扩展配置寄存器(CMPEXCFG):

  1. CMPNS:比较器负端输入选择
  1. 0: P3.6。
  2. 1: 选择内部 BandGap 经过 OP 后的电压 REFV 作为比较器负极输入源 (芯片在出厂时,内部参考电压调整为 1.19V)。
  1. CMPPS[1:0]:比较器正端输入选择
  1. 00:P3.7。
  2. 01:P5.0。
  3. 10:P5.1。
  4. 11:ADCIN,此时必须打开ADC_CONTR寄存器中的ADC电源控制位ADC_POWER和ADC通道选择位ADC_CHS。
  1. 滤波配置

比较器内部有可程序控制的两级滤波:模拟滤波和数字滤波。模拟滤波可以过滤掉比较输入信号中的毛刺信号,数字滤波可以等待输入信号更加稳定后再进行比较。

模拟滤波和数字滤波通过“比较器控制寄存器2(CMPCR2)”的DISFLT位和LCDTY[5:0]位配置,如下图所示。

比较器控制寄存器2(CMPCR2):

  1. DISFLT:模拟滤波功能控制
  1. 0:使能0.1us模拟滤波功能。
  2. 1:关闭0.1us模拟滤波功能,可略微提高比较器的比较速度。
  1. LCDTY[5:0]:数字滤波功能控制

数字滤波功能即为数字信号去抖动功能。当比较结果发生上升沿或者下降沿变化时,比较器侦测变化后的信号必须维持 LCDTY 所设置的 CPU 时钟数不发生变化,才认为数据变化是有效的,否则将视同信号无变化。

注意: 当使能数字滤波功能后,芯片内部实际的等待时钟需额外增加两个状态机切换时间,即若LCDTY 设置为 0 时,为关闭数字滤波功能。若 LCDTY 设置为非 0 值 n(n=1~63)时,则实际的数字滤波时间为(n+2)个系统时钟。

  1. 输出控制

比较结果可以通过程序读取“比较器控制寄存器 1(CMPCR1)”寄存器的CMPRES位获取,也可以将配置CMPRES位将结果输出到P3.4或者P4.1端口上,如下图所示。

比较器控制寄存器1(CMPCR1):

  1. CMPRES:比较器的比较结果。此位为只读。
  1. 0:表示CMP+的电平低于CMP-的电平。
  2. 1:表示CMP+的电平高于CMP-的电平。

注意:CMPRES是经过数字滤波后的输出信号,而不是比较器的直接输出结果。

  1. CMPOE:比较器结果输出控制位
  1. 0:禁止比较器结果输出
  2. 1:使能比较器结果输出。比较器结果输出到 P3.4 或者 P4.1(由 P_SW2 中的 CMPO_S 进行设定)

比较器结果是输出到P3.4还是输出到P4.1由“外设端口切换控制寄存器2(P_SW2)”的CMPO_S位控制,如下所示。

  1. CMPO_S:比较器输出引脚选择位
  1. 0:比较结果输出到P3.4。
  2. 1:比较结果输出到P4.1。
  1. 中断控制

比较器通过配置“比较器控制寄存器1(CMPCR1)”的PIE位或NIE位开启中断,中断开启后,若中断产生,硬件置位比较器中断标志位CMPIF(该位必须软件清零)。

比较器控制寄存器1(CMPCR1)

  1. PIE:比较器上升沿中断使能位。
  1. 0:禁止比较器上升沿中断。
  2. 1:使能比较器上升沿中断,比较结果由0变成1时产生中断请求。
  1. NIE:比较器下降沿中断使能位。
  1. 0:禁止比较器下降沿中断。
  2. 1:使能比较器下降沿中断,比较结果由1变成0时产生中断请求。
  1. CMPIF:比较器中断标志位。当PIE或NIE被使能后,若产生相应的中断信号,硬件自动将CMPIF置1,并向CPU发出中断请求,此标志位必须用户软件清零。(注意:没有使能比较器中断时,硬件不会置位此中断标志,即使用查询方式访问比较器时,不能查询此中断标志)。
    1. 软件设计
      1. 比较器应用步骤

比较器的应用步骤如下图所示,其中配置部分主要包含输入端配置、滤波器配置、输出和中断配置。配置完成之后,使能比较器,比较器即开始按照配置的参数工作。

图2:比较器应用流程

  1. 配置输入端

输入端通过“比较器控制寄存器1(CMPCR1)”的PIS位和NIS位配置,下面的代码配置了比较器的正向输入端为P3.7,反向输入端为P3.6。

代码清单:输入端配置

  1. CMPCR1 &= ~0x08; //P3.7 为 CMP+输入脚  
  2. CMPCR1 |= 0x04;  //P3.6 为 CMP-输入脚  

  1. 配置滤波器

使用比较器的时候,通常会开启0.1us的模拟滤波功能,以消除输入信号中的毛刺信号,模拟滤波的开启和关闭代码如下。

代码清单:模拟滤波配置

  1. CMPCR2 &= ~0x40; //使能 0.1us 滤波  
  2. //CMPCR2 |= 0x40; //关闭 0.1us 滤波 

数字滤波通过CMPCR2寄存器中的LCDTY[5:0]配置,LCDTY共有6位,因此取值范围是0~63。若LCDTY的值设置为0,则数字滤波关闭,若设置为1~63,则对应的实际数字滤波时间为:(LCDTY的值+2)个系统时钟。下面的代码设置了比较器结果经过 16个去抖时钟后输出。

代码清单:数字滤波配置

  1. CMPCR2 = 0x0E;  //比较器结果经过 16个去抖时钟后输出  

  1. 配置中断

中断可以配置为:比较结果由0变成1时产生中断请求(上升沿)或比较结果由1变成0时产生中断请求(下降沿)。通常,我们会将他们都使能,这样当正向输入电压大于反向输入电压和正向输入电压小于反向输入电压时都可以触发中断,中断配置的代码如下。

代码清单:中断配置

  1. CMPCR1 |= 0x30;  //使能比较器边沿中断  
  2. // CMPCR1 &= ~0x20; //关闭比较器上升沿中断  
  3. // CMPCR1 |= 0x20; //使能比较器上升沿中断  
  4. // CMPCR1 &= ~0x10; //关闭比较器下降沿中断  
  5. // CMPCR1 |= 0x10; //使能比较器下降沿中断  
  • 注意:开启比较器中断的情况下,还需要开启总中断“EA=1”,比较器中断才能起作用。
  1. 使能比较器

将CMPCR1寄存器的CMPEN位置位即使能比较器的比较功能,清零则关闭比较器的比较功能,代码清单如下。

代码清单:中断配置

  1. CMPCR1 |= 0x80; //使能比较器的比较功能  
  2. CMPCR1 &= ~0x80; //关闭比较器的比较功能  
      1. 比较器实验
  • 注:本节的实验是在“实验2-6-1:串口1数据收发实验”的基础上修改,本节对应的实验源码是:“实验2-9-1:比较器实验”。
        1. 实验内容

配置比较器的负端输入为:内部BandGap经过OP后的电压REFV(1.19V),正端输入为:P3.7。开启比较器的上升沿和下降沿中断,上升沿中断产生后点亮指示灯D1,下降沿中断产生后熄灭指示灯D1。

将P3.7用杜邦线连接到电位器抽头上,旋转电位器改变P3.7的输入电压,当P3.7的电压大于1.19V,产生上升沿中断,D1点亮。当P3.7的电压小于1.19V,产生下降沿中断,D1熄灭。

        1. 代码编写
  1. 新建一个名称为“cmp.c”的文件及其头文件“cmp.h”并保存到工程的“Source”文件夹,并将“cmp.c”加入到Keil工程中的“SOURCE”组。
  2. 引用头文件

因为在“main.c”文件中使用了“cmp.c”文件中的函数,所以需要引用下面的头文件“cmp.h”。

代码清单:引用头文件

  1. //引用比较器的头文件  
  2. #include    " cmp.h"  
  1. 比较器初始化

比较器初始化代码清单如下,包含配置输入端、模拟滤波和数字滤波以及开启中断。

代码清单:比较器初始化

  1. /********************************************************************************** 
  2. 功能描述:初始化比较器。正端输入:P3.7,负端输入:内部BandGap经过OP后的电压REFV(1.19V) 
  3.         :使能比较器上升沿和下降沿中断 
  4. 参    数:无 
  5. 返 回 值:无 
  6. ***********************************************************************************/  
  7. void cmp_init(void)       
  8. {  
  9.    P_SW2 |= 0x80;       //将EAXFR位置1,允许访问扩展RAM区特殊功能寄存器(XFR)  
  10.    CMPEXCFG = 0x00;   //先清零再配置  
  11.    CMPEXCFG |= 0x04;  //比较器负端输入:内部BandGap经过OP后的电压REFV(1.19V),正端输入:P3.7  
  12.    P_SW2 &= 0x7F;       //将EAXFR位置0,禁止访问XFR      
  13.    CMPCR2 = 0x00;     //先清零再配置  
  14.    CMPCR2 &= ~0x40;   //使能0.1us滤波  
  15.    CMPCR2 |= 0x12;    //比较器结果经过 20个去抖时钟后输出  
  16.    CMPCR1 = 0x00;     //先清零再配置  
  17.    CMPCR1 |= 0x30;    //使能比较器上升沿和下降沿中断  
  18.    CMPCR1 |= 0x02;    //使能比较器输出  
  19. }  

4. 启动和停止比较器

比较器通过置位/清零“比较器控制寄存器1(CMPCR1)”的“CMPEN”位启动和停止,为了方便其他程序调用,我们将比较器启动和停止封装为函数,代码清单如下。

代码清单:比较器启动和停止

  1. /********************************************************************************** 
  2.  * 描  述 : 使能比较器比较功能 
  3.  * 入  参 : 无 
  4.  * 返回值 : 无 
  5.  **********************************************************************************/  
  6. void cmp_start(void)      
  7. {  
  8.    CMPCR1 |= 0x80; //使能比较器的比较功能  
  9. }  
  10.   
  11. /********************************************************************************** 
  12.  * 描  述 : 关闭比较器比较功能 
  13.  * 入  参 : 无 
  14.  * 返回值 : 无 
  15.  **********************************************************************************/  
  16. void cmp_stop(void)   
  17. {  
  18.    CMPCR1 &= ~0x80; //关闭比较器的比较功能  
  19. }  
  1. 比较器中断服务函数

比较器中断服务函数里面读取“比较器控制寄存器1(CMPCR1)”的“CMPRES”位, “CMPRES”位为“1”表示P3.7的电压大于1.19V,点亮指示灯D1。“CMPRES”位为“0”表示P3.7的电压小于1.19V,熄灭指示灯D1。

代码清单:比较器中断服务函数

  1. /********************************************************************************** 
  2.  * 描  述 : 比较器中断服务函数 
  3.  * 入  参 : 无 
  4.  * 返回值 : 无 
  5.  **********************************************************************************/  
  6. void cmp_isr() interrupt 21  
  7. {  
  8.    CMPCR1 &= ~0x40;    //清中断标志  
  9.    if (CMPCR1 & 0x01)  //正向输入端电压高于反向输入端  
  10.    {  
  11.      led_on(LED_1);    //点亮指示灯D1  
  12.    }  
  13.    else                //正向输入端电压低于反向输入端  
  14.    {  
  15.      led_off(LED_1);   //熄灭指示灯D1  
  16.    }  
  17. }  
  1. 主函数

主函数中调用比较器初始化和启动函数,完成对比较器的初始化和启动。之后若P3.7的输入电压由低于1.19V增加到高于1.19V,会触发比较器中断,D1指示灯点亮,反之,D1指示灯熄灭。

代码清单:主函数

  1. /************************************************************************** 
  2. 功能描述:主函数 
  3. 入口参数:无 
  4. 返回值:int类型 
  5.  *************************************************************************/  
  6. int main(void)  
  7. {  
  8.   P2M1 &= 0xBF;   P2M0 &= 0xBF;     //设置2.6为准双向口(LED1)  
  9.   P3M1 &= 0xFE;   P3M0 &= 0xFE;     //设置P3.0为准双向口(UART RxD)  
  10.   P3M1 &= 0xFD;   P3M0 |= 0x02;     //设置P3.1为推挽输出(UART TxD)  
  11.       
  12.   uart1_init();      //串口1初始化  
  13.   cmp_init();        //比较器初始化  
  14.   cmp_start();       //使能比较器  
  15.   EA = 1;            //使能总中断  
  16.       
  17.   printf("comparator example start! \r\n");  //串口输出程序启动信息  
  18.       
  19.   while(1)  
  20.   {  
  21.   }  
        1. 硬件连接

按照下图所示,短接指示灯D1的跳线帽,并用杜邦线将J29端子的P26连接到J27端子的ADC上,即将电位器抽头连接到比较器的正端输入,方便改变正端输入的电压。

图3:跳线帽短接

        1. 实验步骤
  1. 解压“…\第3部分:配套例程源码”目录下的压缩文件“实验2-9-1:比较器实验”,将解压后得到的文件夹拷贝到合适的目录,如“D\STC8”(这样做的目的是为了防止中文路径或者工程存放的路径过深导致打开工程出现问题)。
  2. 双击“…\comparator\project”目录下的工程文件“comparator.uvproj”。
  3. 点击编译按钮编译工程,编译成功后生成的HEX文件“comparator.hex”位于工程的“…\comparator\Project\Object”目录下。
  4. 打开STC-ISP软件下载程序,下载使用内部IRC时钟,IRC频率选择:24MHz。

程序运行后,旋转电位器改变P3.7的输入电压,当P3.7的电压大于1.19V,产生上升沿中断,D1点亮。当P3.7的电压小于1.19V,产生下降沿中断,D1熄灭。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1378445.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

代码随想录算法训练营第25天 | 216.组合总和III 17.电话号码的字母组合

目录 216.组合总和III 💡解题思路 回溯三部曲 💻实现代码 17.电话号码的字母组合 💡解题思路 # 数字和字母如何映射 # 回溯法来解决n个for循环的问题 💻实现代码 216.组合总和III 题目链接:216.组合总和III …

深度学习笔记(四)——TF2构建基础网络常用函数+简单ML分类网络实现

文中程序以Tensorflow-2.6.0为例 部分概念包含笔者个人理解,如有遗漏或错误,欢迎评论或私信指正。 截图和程序部分引用自北京大学机器学习公开课 TF2基础常用函数 1、张量处理类 强制数据类型转换: a1 tf.constant([1,2,3], dtypetf.floa…

鸿蒙开发环境搭建-高频环境问题解决

1.Node版本问题 由于SDK的部分工具依赖Node.js运行时,推荐使用配套API版本的Node.js,保证工程的兼容性。 匹配关系见下表: API LevelNode.js支持范围API Level≤914.x(≥14.19.1)、16.xAPI Level>914.x&#xff0…

软件测试之项目立项与需求评审

📢专注于分享软件测试干货内容,欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!📢软件测试面试题分享: 1000道软件测试面试题及答案📢软件测试实战项目分享: 纯接口项目-完…

ASP .net core微服务实战(杨中科)

背景: 主要是思考下,我们为什么要用微服务? 微服务我现在理解是:提供了我们一种模块化的手段,一个服务负责一种类型的业务,是一种面对复杂问题进行拆分的方式,但是也会引入一些中间件&#xf…

基于爬虫和Kettle的豆瓣电影的采集与预处理

一:爬虫 1、爬取的目标 将豆瓣电影网上的电影的基本信息,比如:电影名称、导演、电影类型、国家、上映年份、评分、评论人数爬取出来,并将爬取的结果放入csv文件中,方便存储。 2、网站结构 图1豆瓣网网站结构详…

Vue3:vue-cli项目创建及vue.config.js配置

一、node.js检测或安装: node -v node.js官方 二、vue-cli安装: npm install -g vue/cli # OR yarn global add vue/cli/*如果安装的时候报错,可以尝试一下方法 删除C:\Users**\AppData\Roaming下的npm和npm-cache文件夹 删除项目下的node…

Vue入门六(前端路由的概念与原理|Vue-router简单使用|登录跳转案例|scoped样式)

文章目录 前要:前端路由的概念与原理1)什么是路由2)SPA与前端路由3)什么是前端路由4)前端路由的工作方式 一、Vue-router简单使用1)什么是vue-router2) vue-router 安装和配置的步骤① 安装 vue-router 包②…

为什么企业容易陷入“自嗨式营销”,媒介盒子分析

互联网时代,各类信息都传播的非常快,同时信息技术的成熟也让许多企业可以监测广告效果,比如曝光、互动、转化等都可以通过数据体现,然而很多企业在营销过程中却发现,大部分的钱、精力、人力等都被浪费了。出现这种情况…

Android开发基础(三)

Android开发基础(三) 本篇将介绍Android权限管理。 Android权限管理 Android权限管理主要是为了保护用户的隐私和设备的安全性; 在Android系统中,应用在请求权限时必须进行明确的申请,根据权限的保护级别&#xff0…

C语言——(printf和scanf介绍)

一.printf 1.基本用法 printf()的作用是将参数文本输出的屏幕。如下; 2.占位符 printf()可以在输出文本中指定占位符 ,“占位符”,也就是这个位置可以用其他值代入。 如: …

Spring Cloud + Vue前后端分离-第12章 通用权限设计

源代码在GitHub - 629y/course: Spring Cloud Vue前后端分离-在线课程 Spring Cloud Vue前后端分离-第12章 通用权限设计 这一章我们不依赖第三方框架,我会从权限相关表的设计,到权限的配置,到权限的拦截,带大家一步一步的做出…

C语言基础语法跟练 day3

31、不使用累计乘法的基础上&#xff0c;通过移位运算&#xff08;<<&#xff09;实现2的n次方的计算。 #include <stdio.h> int main() {int i 0;scanf("%d",&i);printf("%d",1<<i);return 0; } 32、问题&#xff1a;一年约有 3.…

使用postman做接口测试(一)

如何执行HTTP接口测试。包括如下三步&#xff1a; 构造一条符合要求的HTTP请求消息&#xff1b;发给我&#xff0c;我给你回响应&#xff1b;你读取HTTP响应&#xff0c;检查响应内容是否正确。 今天我们就讲&#xff0c;如何使用postman发送符合要求的HTTP请求。 how-如何安…

完整的模型验证套路

读取图片 from PIL import Imageimg_path "../Yennefer_of_Vengerberg.jpg" image Image.open(img_path) print(image)转换成灰度图&#xff08;可选&#xff09; image image.convert(L) image.show()转换成RGB格式 image image.convert(RGB)因为png格式是四…

逆向分析爬取网页动态

本例子以爬取人民邮电出版社网页新书的信息为例 由于页面是动态的&#xff0c;信息会不停地更新&#xff0c;所以不同时间的爬取结果会不同。

Redis重点总结补充

Redis重点总结 1.redis分布式锁 2.redission实现分布式锁 注意&#xff1a;加锁、设置过期时间等操作都是基于lua脚本完成. redisson分布式锁&#xff0c;实现可重入&#xff08;前提是同一个线程下 3.redis主从集群 实现主从复制 ( Master-slave Replication)的工作原理 : …

Linux中关于echo命令详解

echo的作用 echo用于输出字符或字符串或者回显。 echo的参数说明 -n不换行输出内容-e解析转义字符-E不使用解析转义字符 使用 "-e" 参数拓展参数 \b删除前一个字符\c最后不加上换行号\f换页\n换行并将光标移动到行首\r光标移动到行首切不换行,如果\r后面还有字符,…

51-10 多模态论文串讲—ALBEF 论文精读

今天我们就来过一下多模态的串讲&#xff0c;其实之前&#xff0c;我们也讲了很多工作了&#xff0c;比如说CLIP&#xff0c;还有ViLT&#xff0c;以及CLIP的那么多后续工作。多模态学习在最近几年真的是异常的火爆&#xff0c;那除了普通的这种多模态学习&#xff0c;比如说视…

分块矩阵的定义、计算

目录 一、定义 二、分块矩阵的加减乘法 三、考点 一、定义 分块&#xff0c;顾名思义&#xff0c;将整个矩阵分成几部分&#xff0c;如下图所示 二、分块矩阵的加减乘法 三、考点 分块矩阵的考点不多&#xff0c;一般来说&#xff0c;有一种&#xff1a; 求分块矩阵的转置…