51单片机实战教程(20 内置比较器)

       也许大家对比较器并不陌生,比较器类似与运算放大器(有部分运放可以用来做比较器),它有一对差分输入脚-Input/+input,一个输出脚。当-Input的输入电平比+input的输入电平低时,输出脚输出高电平;当-Input的输入电平比+input的输入电平高时,输出脚输出低电平。

        STC15系列部分单片机内置了比较器功能,内置比较器原理与普通比较器一致,即可像普通比较器一样使用也可实现更为复杂的功能。+input的输入脚为P5.5或P2.0,-Input的输入脚为P5.4,输出脚为P1.2,也可将P5.5的输入与内部BandGap参考电压比较。与比较器相关的特殊功能寄存器如下:

51单片机实战教程(20 内置比较器)

 51单片机实战教程(20 内置比较器)

51单片机实战教程(20 内置比较器)

       从比较器的特殊功能寄存器可以看出,我们可以打开/关闭比较器、可以设置中断、可以将比较结果输出、可以将比较结果取反输出,甚至还可以实现对比较结果滤波滤除非稳定的跳变。

       有了对比较器相关寄存器的了解就,可以写比较器得相关库函数。新建两个文件分别以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。

上一篇:Acwing 1096. 地牢大师(三维BFS)


下一篇:最近请求次数(TreeMap应用)