一 STC32G系列单片机寄存器简介
STC32G系列单片机内部集成了一个比较器,其正极可以在P3.7、P5.0、P5.1、或者ADC的模拟输入通道间切换;而负极可以是P3.7或者内部BandGap经过OP的REF电压。通过配置分时复用可以实现多个比较器的应用。
STC32G系列单片机的比较器有模拟、数字两级可编程滤波。模拟滤波可消除信号毛刺。通过设置数字滤波的CPU时钟数,等信号稳定后再比较。
STC32G系列单片机的比较器的比较结果可以从寄存器中读出,也可让其在单片机的端口输出,如从P3.4或P4.l输出。 STC32G系列单片机的中断源中包含比较器中断,比较器的比较结果由0变1,或者由1变0,皆可产生中断请求,可在比较器控制寄存器1中设置。
STC32G系列单片机比较器的内部结构图如下:
STC32G系列单片机比较器输出脚选择控制位寄存器为P_SW2的B3位,如下:
与STC32G系列单片机比较器相关的寄存器共有3个如下:
控制寄存器1的各bit位的作用如下:
控制寄存器2的各bit位的作用如下:
比较器扩展配置寄存器各bit位的作用如下:
二 STC32G系列单片机比较器相关寄存器配置编程
要使用STC32G系列单片机内部集成比较器,就离不开对其相关寄存器配置操作编程。最好的办就是将常用的配置操作做成库函数,供以后使用时调用。下面是STC32G比较器库函数的头文件与源文件的示例。
头文件
/*STC32G_Comparator.hDesigned by Bill LiuVersion 0.0 Modified last by Bill Liu,07/12/2022
enum
STC32G_CMP_PSOURCE // comparator positive input source
STC32G_CMP_NSOURCE // comparator negtive source///struct//
STC32G_ComparatorDef///macro function/
CMP_OUTPINSELP34();
CMP_OUTPINSELP41();
CMP_ENABLE();
CMP_DISABLE();
CMP_CLEARFLAG();
CMP_PEDGEINTENABLE(); //compare result change to positive Int enable
CMP_PEDGEINTDISABLE(); //compare result change to positive Int disable
CMP_NEDGEINTENABLE(); //compare result change to negtive Int enable
CMP_NEDGEINTDISABLE(); //compare result change to negtive Int disable
CMP_RESULTOUENABLE();
CMP_RESULTOUDISABLE();
CMP_GETRESULT(res);
CMP_AFILTERENABLE(); //0.1uS analog filter enable
CMP_AFILTERDISABLE();
CMP_INVERTRESOUTENABLE();
CMP_INVERTRESOUTDISABLE();
CMP_NSOURCEP36(); //set P3.6 as coparator negative input source
CMP_NSOURCEINREF(); //set inner bandgap viltage as coparator negative input source
CMP_PSOURCEP37(); //set P3.7 as compraror positive input source
CMP_PSOURCEP50(); //set P5.0 as compraror positive input source
CMP_PSOURCEP51(); //set P5.1 as compraror positive input source
CMP_PSOURCEADCIN();Function
CMP_ConfiguDigFilter(ui8 nData); //configure digital filter data, return void
CMP_HysVoltageSel(ui8 mSel); //configure comparator DC input hysteresis voltage, return void
CMP_NSource(STC32G_CMP_NSOURCE mSel); //configure comparator negtive input source, return void
CMP_PSource(STC32G_CMP_PSOURCE mSel); //configure comparator negtive input source, return void
CMP_InitDef(STC32G_ComparatorDef* mStruct); // return void
CMP_StructInit(STC32G_ComparatorDef mStruct); //return void*/#ifndef __STC32G_COMPARATOR_H
#define __STC32G_COMPARATOR_H#include "config.h"
#include "mtype.h"
#include "STC32G.h"#define CMP_OUTPINSELP34() {CMPO_S = 0;}
#define CMP_OUTPINSELP41() {CMPO_S = 1;}
#define CMP_ENABLE() {CMPEN = 1;} //comparator enable(switch on)
#define CMP_DISABLE() {CMPEN = 0;} //comparator disable(switch off)
#define CMP_CLEARFLAG() {CMPIF = 0;}
#define CMP_PEDGEINTENABLE() {PIE = 1;} //compare result change to positive Int enable
#define CMP_PEDGEINTDISABLE() {PIE = 0;} //compare result change to positive Int disable
#define CMP_NEDGEINTENABLE() {NIE = 1;} //compare result change to negtive Int enable
#define CMP_NEDGEINTDISABLE() {NIE = 0;} //compare result change to negtive Int disable
#define CMP_RESULTOUDISABLE() {CMPOE = 0;}
#define CMP_RESULTOUENABLE() {CMPOE = 1;}
#define CMP_GETRESULT(res) {(res) = CMPRES;}
#define CMP_AFILTERENABLE() {DISFLT = 0;} //0.1uS analog filter enable
#define CMP_AFILTERDISABLE() {DISFLT = 1;} //0.1uS analog filter disable
#define CMP_INVERTRESOUTENABLE() {INVCMPO = 1;} //invert compare result out enable
#define CMP_INVERTRESOUTDISABLE() {INVCMPO = 0;} //invert compare result out disable
#define CMP_NSOURCEP36() {CMPEXCFG &= 0xFB;} //Negtive source is inner P36
#define CMP_NSOURCEINREF() {CMPEXCFG |= 0x04;} //Negtive source is inner Ref voltage
#define CMP_PSOURCEP37() {CMPEXCFG &=0xFC;} //positve source is P37
#define CMP_PSOURCEP50() {CMPEXCFG &= 0xFC; CMPEXCFG |= 0x01;}
#define CMP_PSOURCEP51() {CMPEXCFG &= 0xFC; CMPEXCFG |= 0x01;}
#define CMP_PSOURCEADCIN() {CMPEXCFG &= 0xFC; CMPEXCFG |= 0x03;}//*******************************************************
typedef enum
{PS_P37 = 0,PS_P50,PS_P51,PS_ADCIN
}STC32G_CMP_PSOURCE; // comparator positive input source//*******************************************************
typedef enum
{NS_P36 = 0,NS_BAND //inner bandgap reference voltage
}STC32G_CMP_NSOURCE; // comparator negtive source//*******************************************************
typedef enum
{O_P34 = 0, //compare result output at P34O_P41 //compare result output at P41
}STC32G_CMPO_PIN; // comparator output pin//*******************************************************
typedef struct
{STC32G_CMP_PSOURCE pSource;STC32G_CMP_NSOURCE nSource;BOOL outAble;STC32G_CMPO_PIN oPin;BOOL pIntAble;BOOL nIntAble;BOOL rInvAble; //invert compare result eanble/disableBOOL aFilter;ui8 dFilterCycles;ui8 dcInputHys; //DC input hysteresis valtage
}STC32G_ComparatorDef;/***********************************************************
Function: CMP_ConfiguDigFilter(ui8 nData);
Return value: void
nData: digital filter data,digital filter time: nData+2 system cycle times
Discription: configure digital filter data
Example:
CMMP_ConfiguDigFilter(0);
***********************************************************************/
void CMP_ConfiguDigFilter(ui8 nData);/***********************************************************
Function: CMP_HysVoltageSel(ui8 mSel);
Return value: void
mSel: selected hysteresis voltage,0: 0mV, 1: 10mV, 2: 20mV, 3: 30mV
Discription: configure comparator DC input hysteresis voltage
Example:
CMP_HysVoltageSel(0x01); //selected: 10mV
***********************************************************************/
void CMP_HysVoltageSel(ui8 mSel);/***********************************************************
Function: CMP_NSource(STC32G_CMP_NSOURCE mSel);
Return value: void
mSel: negtive input source
Discription: configure comparator negtive input source
Example:
CMP_NSource(0x00); //ngeive sourve:P36
***********************************************************************/
void CMP_NSource(STC32G_CMP_NSOURCE mSel);/***********************************************************
Function: CMP_PSource(STC32G_CMP_PSOURCE mSel);
Return value: void
mSel: positve input source
Discription: configure comparator negtive input source
Example:
CMP_PSource(0x00); //ngeive sourve:P36
***********************************************************************/
void CMP_PSource(STC32G_CMP_PSOURCE mSel);/***********************************************************
Function: CMP_InitDef(STC32G_CompareDef* mStruct);
Return value: void
mStruct: STC32G_CompareDef pointer variable
Discription: init comparator struct to default
Example:STC32G_CompareDef mSruct;CMP_InitDef(&mSruct); //init comparator struct to default
***********************************************************************/
void CMP_InitDef(STC32G_ComparatorDef* mStruct);/***********************************************************
Function: CMP_Init(STC32G_CompareDef mStruct);
Return value: void
mStruct: struct STC32G_CompareDef variable
Discription: configure comparator by mStruct
Example:STC32G_CompareDef mStruct;CMP_InitDef(&mSruct);mSruct.pSource = PS_P37;mSruct.nSource =NS_P36;CMP_Init(mStruct); //configure comparator by mStruct
***********************************************************************/
void CMP_Init(STC32G_ComparatorDef mStruct);#endif
源文件
/*STC32G_Comparator.cDesigned by Bill LiuVersion 0.0 Modified last by Bill Liu, 07/12/2022
*/#include "STC32G_Comparator.h"//***********************************************************************
void CMP_ConfiguDigFilter(ui8 nData)
{CMPCR2 &= 0xC0;CMPCR2 |= nData;
}
//End of CMP_ConfiguDigFilter(ui8 nData)//***********************************************************************/
void CMP_HysVoltageSel(ui8 mSel)
{//SysInit();CMPEXCFG &= 0x07;CMPEXCFG |= (mSel << 6);
}
//End of CMP_HysVoltageSel(ui8 mSel)//***********************************************************************
void CMP_NSource(STC32G_CMP_NSOURCE mSel)
{//SysInit();if(mSel)CMPEXCFG |= 0x01 << 2;elseCMPEXCFG &= 0xF3;}
//End of CMP_NSource(STC32G_CMP_NSOURCE mSel)//***********************************************************************/
void CMP_PSource(STC32G_CMP_PSOURCE mSel)
{//SysInit();CMPEXCFG &= 0xFC;CMPEXCFG |= mSel;
}
//End of CMP_PSource(STC32G_CMP_PSOURCE mSel)//***********************************************************
void CMP_InitDef(STC32G_ComparatorDef* mStruct)
{mStruct -> pSource = PS_P37;mStruct -> nSource = NS_P36;mStruct -> outAble = 0; //disablemStruct -> oPin = O_P34;mStruct -> pIntAble = 0; // INT disable mStruct -> nIntAble = 0; // INT disablemStruct -> rInvAble = 0; // compare result invert disablemStruct -> aFilter = 1; //0.1uS analog filter enablemStruct -> dFilterCycles = 0;mStruct -> dcInputHys = 0;
}
//End of CMP_InitDef(STC32G_CompareDef* mStruct)//***********************************************************************
void CMP_Init(STC32G_ComparatorDef mStruct)
{//SysInit();CMP_PSource(mStruct.pSource);CMP_NSource(mStruct.nSource);CMPOE = mStruct.outAble;CMPO_S = mStruct.oPin;PIE = mStruct.pIntAble;NIE = mStruct.nIntAble;INVCMPO = mStruct.rInvAble;DISFLT = mStruct.aFilter;CMP_ConfiguDigFilter(mStruct.dFilterCycles);CMP_HysVoltageSel(mStruct.dcInputHys);
}
//End of CMP_StructInit(STC32G_CompareDef mStruct)
三 STC32G单片机比较器的常见用法及其编程
启动掉电保护
下面是STC官方提供的掉电保护启动电路
其原理是:将7805稳压前的电压经分压电阻分压到一个适当的值,送入比较器+(P3.7),与单片机内部的Bandgap电压(1.19V)比较,当分压低于内部1.19V电压时,触发比较中断,在中断函数中将重要的参数写入单片机内部EEPROM,或外部存储器,这对一些测试仪器等设备十分有用。注意:如果写入的数据较多,需要在容量为104的电容器前,二极管后,再并一个容量较大的延时供电电容器。下面就写一个来实现掉电保护的测试程序。
程序头文件:
/*main.hDesigned by Bill LiuVersion 0.0 Modified last by Bill Liu ,03/25/2023
*/#ifndef __MAIN_H__
#define __MAIN_H__//#include "myport.h"
#include "mtype.h"
#include "config.h"
#include "STC32G_GPIO.h"
#include "STC32G_Delay.h"
#include "STC32G_UART.h"
#include "STC32G_EEPROM.h"
//#include "STC32G_PWM.h"
//#include "STC32G_ADC.h"
//#include "STC32G_EEPROM.H"
//#include "STC32G_SPI.h"
#include "STC32G_PWM.h"
//#include "STC32G_Timer.h"
#include "STC32G_comparator.h"STC32G_ComparatorDef mstuct;
#endif
源文件:
/*main.cDesigned by Bill LiuVersion 0.0 Modified last by Bill Liu, 03/25/2023
*/#include "main.h"ui8 str[30] = {0};
i16 t1 = 105;
i16 t2 = 115;
i16 t3 ,t4;void STC_CmpInt(void) interrupt 21 //comparator interrupt function
{EEPROM_SectorErase(0x0000);EEPROM_Write_nChar(0x0000,&t1,0x02);EEPROM_Write_nChar(0x0002,&t2,0x02);
}void main()
{SysInit();Uart1_Init(VBAUD_8BITS,G1, 0, 9600);CMP_CLEARFLAG(); //clear comparator INT flagCMP_InitDef(&mstuct); //init comparator struct to defautmstuct.nSource = NS_BAND; //set bandgap voltage as comparator negative source mstuct.nIntAble = 1; // fall edge interrupt enbaleCMP_StructInit(mstuct); //init conparator by mstructCMP_ENABLE(); //comparator enableEA =1; //interrupt enableEEPROM_Read_nChar(0x0000,&t3, 2);EEPROM_Read_nChar(0x0002,&t4, 2);while(1){ LongToString(t3,str); Uart1_SendString(str);Uart1_SendString("\r\n"); LongToString(t4,str); Uart1_SendString(str);Uart1_SendString("\r\n");Uart1_SendString(" ");Uart1_SendString("\r\n");Delayxms(1000);}
}
//End of main()
将程序编译后下载到单片机。重启后,打开STC-ISP中的串口调试助手,如果看到如下结果,说明掉电保护启动成功。
如果看到的是如下结果,说明你的输入分压不合适,或者延时供电电容太小。
b. 电池电量过低检测
其原理与掉电保护类似,这里不再重复
c.锂电池温度检测,过高报警
市面锂电池输出线有的有两条线,有的有三条线。有三条线的有温度监测功能,在多出的一条线与电池负(GND)之间串接了一个热敏电阻,一般是NTC,利用这个电阻,就可搭成一个分压电路,利用比较器,就可实现温度监测,防止温度过高。其原理实现与a相似,这里就不重复了。
d 比较器搭配三极管或MOS管还可实现PWM恒流恒压,由于该单片机本身就内置了PWM模块,一般不需要用比较器来实现PWM恒流恒压,这里就不再做详细介绍。