也许大家对比较器并不陌生,比较器类似与运算放大器(有部分运放可以用来做比较器),它有一对差分输入脚-Input/+input,一个输出脚。当-Input的输入电平比+input的输入电平低时,输出脚输出高电平;当-Input的输入电平比+input的输入电平高时,输出脚输出低电平。
STC15系列部分单片机内置了比较器功能,内置比较器原理与普通比较器一致,即可像普通比较器一样使用也可实现更为复杂的功能。+input的输入脚为P5.5或P2.0,-Input的输入脚为P5.4,输出脚为P1.2,也可将P5.5的输入与内部BandGap参考电压比较。与比较器相关的特殊功能寄存器如下:
从比较器的特殊功能寄存器可以看出,我们可以打开/关闭比较器、可以设置中断、可以将比较结果输出、可以将比较结果取反输出,甚至还可以实现对比较结果滤波滤除非稳定的跳变。
有了对比较器相关寄存器的了解就,可以写比较器得相关库函数。新建两个文件分别以stccomparator.h, stccomparator.c存入C51 Template文件夹下Library文件夹中。完成后的头文件如下:
/*stccomparator.h
Designed by Bill Liu
Version 0.0
Modified last by Bill Liu on 12/25/2021
*/
#ifndef __STCCOMPRATOR_H__
#define __STCCOMPRATOR_H__
#include "stc15w4k.h"
#include "mtype.h"
#include "stcint.h"
//*******************************************************
typedef enum
{
PI_SP55 = 0,
PI_SP20
}CMP_PISOURCE; // comparator positive input source
//*******************************************************
typedef enum
{
NI_SP54 = 0,
NI_SBGV
}CMP_NISOURCE; //comparator negtive input source
//******************************************************
typedef enum
{
INT_RN = 0, //Neg_edge interrupt enable
INT_RP //Pos_edge interrupt enable
}CMP_INTSOURCE; //comparator interrupt source
/***********************************************************
Function: CMP_OutEnable(BOOL mAble);
Return value: void
Discription: configure comparator out enable/disable
Example:
CMP_OutEnable(0); //comparator out disable
***********************************************************************/
void CMP_OutEnable(BOOL mAble);
/***********************************************************
Function: CMP_InvResEnable(BOOL mAble);
Return value: void
Discription: configure comparator invert result for outputing enable/disable
Example:
CMP_InvResEnable(0); //comparator invert result disable
***********************************************************************/
void CMP_InvResEnable(BOOL mAble);
/***********************************************************
Function: CMP_init(CMP_PISOURCE pIn,CMP_NISOURCE nIn, BOOL intAble, CMP_INTSOURCE intSource,BOOL outAble, BOOL InvAble, ui8 filterCycles);
Return value: void
Discription: init comparator
Example:
CMP_init(PI_SP55,NI_SP54, 1, INT_N, 1,0, 0);
***********************************************************************/
void CMP_init(CMP_PISOURCE pIn,CMP_NISOURCE nIn, BOOL intAble, CMP_INTSOURCE intSource,BOOL outAble, BOOL InvAble, ui8 filterCycles);
/***********************************************************
Function: CMP_Enable(BOOL mAble);
Return value: void
Discription: comparator enable/disable
Example:
CMP_Enable(1); // comparator enable
***********************************************************************/
void CMP_Enable(BOOL mAble);
/***********************************************************
Function: CMP_GetResult();
Return value: ui8
Discription: get comparator's result
Example:
ui8 tem = CMP_GetResult();
***********************************************************************/
ui8 CMP_GetResult();
#endif
完成后的源文件如下:
/*stccomparator.c
Designed by Bill Liu
Version 0.0
Modified last by Bill Liu on 12/25/2021
*/
#include "stccomparator.h"
/*stccomparator.c
Designed by Bill Liu
Version 0.0
Modified last by Bill Liu on 12/25/2021
*/
#include "stc15w4k.h"
#include "mtype.h"
#include "stcint.h"
//***********************************************************
void CMP_OutEnable(BOOL mAble)
{
if(mAble)
CMPCR1 |= 0x02;
else
CMPCR1 &= 0xFD;
}
//End of CMP_OutEnable(BOOL mAble)
//***********************************************************
void CMP_InvResEnable(BOOL mAble)
{
if(mAble)
CMPCR2 |= 0x80;
else
CMPCR2 &= 0x7F;
}
//End of CMP_InvResEnable(BOOL mAble)
//***********************************************************
void CMP_init(CMP_PISOURCE pIn,CMP_NISOURCE nIn, BOOL intAble, CMP_INTSOURCE intSource,BOOL outAble, BOOL InvAble, ui8 filterCycles)
{
STC_ClearCmpFlag();
if(pIn == PI_SP55)
CMPCR1 &= 0xF7;
else
CMPCR1 |= 0x08;
if(nIn == NI_SP54)
CMPCR1 &= 0xFB;
else
CMPCR1 |= 0x04;
STC_IntCmpInit(intAble, 0);
if(intSource == INT_RN)
CMPCR1 |= 0x10;
else
CMPCR1 |= 0x20;
if(outAble)
CMPCR1 |= 0x02;
else
CMPCR1 &= 0xFD;
if(InvAble)
CMPCR2 |= 0x80;
else
CMPCR2 &= 0x40;
CMPCR2 &= 0xC0;
CMPCR2 |= filterCycles;
}
//End of CMP_init(CMP_PISOURCE pIn,CMP_NISOURCE nIn, BOOL intAble, CMP_INTSOURCE intSource,BOOL outAble, BOOL InvAble, ui8 filterCycles)
//***********************************************************
void CMP_Enable(BOOL mAble)
{
if(mAble)
CMPCR1 |= 0x80;
else
CMPCR1 &= 0x40;
}
//End of CMP_Enable(BOOL mAble)
//***********************************************************
ui8 CMP_GetResult()
{
ui8 tem = CMPCR1 & 0x01;
return tem;
}
//End of CMP_GetResult()
单片机内置比较器,除了可以像普通比较器一样用法外,还有较多的用途,如用作停电检测,可将电源供电电压分压后做+input,与内部BandGap基准电压比较,当+input电压低于BandGap基准电压时触发中断,单片机将重要参数写入eeprom,以防重要数据丢失。内置比较器还可做外部中断扩展等。本文中的代码及相关库函数,已上传到CSDN,如下离线查看,可去下载,文件名为:
STC15 Comparator Library Source Code.rar。