STC8A8K64D4单片机片内集成了比较器(Comparator),比较器有两个输入端IN+(正端输入端)和(负端输入端),可选择其中一个输入端作为参考点来比较,通常使用负端输入端(IN-)做为参考点,当正端输入端电压小于负端输入端时比较器输出低电平,反之输出高电平。
STC8A8K64D4的比较器原理框图如下图所示,主要包含输入选择、滤波配置以及输出控制和中断选择控制。
图1:比较器原理框图
输入端选择包含正端输入端选择和负端输入端选择,正端输入端可以配置为P3.7、P5.1、P5.1端口或者ADC的模拟输入通道。负端输入端可以配置为P3.6端口或者是内部BandGap经过OP后的REFV电压(内部固定比较电压)。
正端输入和负端输入是通过“比较器扩展配置寄存器(CMPEXCFG)”的CMPNS位和CMPPS[1:0]位配置,如下图所示。
比较器扩展配置寄存器(CMPEXCFG):
比较器内部有可程序控制的两级滤波:模拟滤波和数字滤波。模拟滤波可以过滤掉比较输入信号中的毛刺信号,数字滤波可以等待输入信号更加稳定后再进行比较。
模拟滤波和数字滤波通过“比较器控制寄存器2(CMPCR2)”的DISFLT位和LCDTY[5:0]位配置,如下图所示。
比较器控制寄存器2(CMPCR2):
数字滤波功能即为数字信号去抖动功能。当比较结果发生上升沿或者下降沿变化时,比较器侦测变化后的信号必须维持 LCDTY 所设置的 CPU 时钟数不发生变化,才认为数据变化是有效的,否则将视同信号无变化。
注意: 当使能数字滤波功能后,芯片内部实际的等待时钟需额外增加两个状态机切换时间,即若LCDTY 设置为 0 时,为关闭数字滤波功能。若 LCDTY 设置为非 0 值 n(n=1~63)时,则实际的数字滤波时间为(n+2)个系统时钟。
比较结果可以通过程序读取“比较器控制寄存器 1(CMPCR1)”寄存器的CMPRES位获取,也可以将配置CMPRES位将结果输出到P3.4或者P4.1端口上,如下图所示。
比较器控制寄存器1(CMPCR1):
注意:CMPRES是经过数字滤波后的输出信号,而不是比较器的直接输出结果。
比较器结果是输出到P3.4还是输出到P4.1由“外设端口切换控制寄存器2(P_SW2)”的CMPO_S位控制,如下所示。
比较器通过配置“比较器控制寄存器1(CMPCR1)”的PIE位或NIE位开启中断,中断开启后,若中断产生,硬件置位比较器中断标志位CMPIF(该位必须软件清零)。
比较器控制寄存器1(CMPCR1):
比较器的应用步骤如下图所示,其中配置部分主要包含输入端配置、滤波器配置、输出和中断配置。配置完成之后,使能比较器,比较器即开始按照配置的参数工作。
图2:比较器应用流程
输入端通过“比较器控制寄存器1(CMPCR1)”的PIS位和NIS位配置,下面的代码配置了比较器的正向输入端为P3.7,反向输入端为P3.6。
代码清单:输入端配置
使用比较器的时候,通常会开启0.1us的模拟滤波功能,以消除输入信号中的毛刺信号,模拟滤波的开启和关闭代码如下。
代码清单:模拟滤波配置
数字滤波通过CMPCR2寄存器中的LCDTY[5:0]配置,LCDTY共有6位,因此取值范围是0~63。若LCDTY的值设置为0,则数字滤波关闭,若设置为1~63,则对应的实际数字滤波时间为:(LCDTY的值+2)个系统时钟。下面的代码设置了比较器结果经过 16个去抖时钟后输出。
代码清单:数字滤波配置
中断可以配置为:比较结果由0变成1时产生中断请求(上升沿)或比较结果由1变成0时产生中断请求(下降沿)。通常,我们会将他们都使能,这样当正向输入电压大于反向输入电压和正向输入电压小于反向输入电压时都可以触发中断,中断配置的代码如下。
代码清单:中断配置
将CMPCR1寄存器的CMPEN位置位即使能比较器的比较功能,清零则关闭比较器的比较功能,代码清单如下。
代码清单:中断配置
配置比较器的负端输入为:内部BandGap经过OP后的电压REFV(1.19V),正端输入为:P3.7。开启比较器的上升沿和下降沿中断,上升沿中断产生后点亮指示灯D1,下降沿中断产生后熄灭指示灯D1。
将P3.7用杜邦线连接到电位器抽头上,旋转电位器改变P3.7的输入电压,当P3.7的电压大于1.19V,产生上升沿中断,D1点亮。当P3.7的电压小于1.19V,产生下降沿中断,D1熄灭。
因为在“main.c”文件中使用了“cmp.c”文件中的函数,所以需要引用下面的头文件“cmp.h”。
代码清单:引用头文件
比较器初始化代码清单如下,包含配置输入端、模拟滤波和数字滤波以及开启中断。
代码清单:比较器初始化
4. 启动和停止比较器
比较器通过置位/清零“比较器控制寄存器1(CMPCR1)”的“CMPEN”位启动和停止,为了方便其他程序调用,我们将比较器启动和停止封装为函数,代码清单如下。
代码清单:比较器启动和停止
比较器中断服务函数里面读取“比较器控制寄存器1(CMPCR1)”的“CMPRES”位, “CMPRES”位为“1”表示P3.7的电压大于1.19V,点亮指示灯D1。“CMPRES”位为“0”表示P3.7的电压小于1.19V,熄灭指示灯D1。
代码清单:比较器中断服务函数
主函数中调用比较器初始化和启动函数,完成对比较器的初始化和启动。之后若P3.7的输入电压由低于1.19V增加到高于1.19V,会触发比较器中断,D1指示灯点亮,反之,D1指示灯熄灭。
代码清单:主函数
按照下图所示,短接指示灯D1的跳线帽,并用杜邦线将J29端子的P26连接到J27端子的ADC上,即将电位器抽头连接到比较器的正端输入,方便改变正端输入的电压。
图3:跳线帽短接
程序运行后,旋转电位器改变P3.7的输入电压,当P3.7的电压大于1.19V,产生上升沿中断,D1点亮。当P3.7的电压小于1.19V,产生下降沿中断,D1熄灭。