STC32G 比较器及其应用编程

一 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.h
  Designed by Bill Liu
  Version 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 P34
  O_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/disable
    BOOL 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.c
  Designed by Bill Liu
  Version 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;
    else
        CMPEXCFG &= 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;             //disable
    mStruct -> oPin = O_P34;
    mStruct -> pIntAble = 0; // INT disable 
    mStruct -> nIntAble = 0; // INT disable
    mStruct -> rInvAble  = 0;         // compare result invert disable
    mStruct -> aFilter = 1;      //0.1uS analog filter enable
    mStruct -> 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单片机比较器的常见用法及其编程

  1. 启动掉电保护

下面是STC官方提供的掉电保护启动电路

其原理是:将7805稳压前的电压经分压电阻分压到一个适当的值,送入比较器+(P3.7),与单片机内部的Bandgap电压(1.19V)比较,当分压低于内部1.19V电压时,触发比较中断,在中断函数中将重要的参数写入单片机内部EEPROM,或外部存储器,这对一些测试仪器等设备十分有用。注意:如果写入的数据较多,需要在容量为104的电容器前,二极管后,再并一个容量较大的延时供电电容器。下面就写一个来实现掉电保护的测试程序。

程序头文件:

/*main.h
  Designed by Bill Liu
  Version 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.c
  Designed by Bill Liu
  Version 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 flag
    CMP_InitDef(&mstuct);      //init comparator struct to defaut
    mstuct.nSource = NS_BAND;  //set bandgap voltage as comparator negative source 
    mstuct.nIntAble = 1;       // fall edge interrupt enbale
    CMP_StructInit(mstuct);    //init conparator by    mstruct
    CMP_ENABLE();              //comparator enable
    EA =1;                     //interrupt enable
    
    EEPROM_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("This a  Test Program!");
        Uart1_SendString("\r\n");
        Delayxms(1000);
    }
}
//End of main()

将程序编译后下载到单片机。重启后,打开STC-ISP中的串口调试助手,如果看到如下结果,说明掉电保护启动成功。

如果看到的是如下结果,说明你的输入分压不合适,或者延时供电电容太小。

b. 电池电量过低检测

其原理与掉电保护类似,这里不再重复

c.锂电池温度检测,过高报警

市面锂电池输出线有的有两条线,有的有三条线。有三条线的有温度监测功能,在多出的一条线与电池负(GND)之间串接了一个热敏电阻,一般是NTC,利用这个电阻,就可搭成一个分压电路,利用比较器,就可实现温度监测,防止温度过高。其原理实现与a相似,这里就不重复了。

d 比较器搭配三极管或MOS管还可实现PWM恒流恒压,由于该单片机本身就内置了PWM模块,一般不需要用比较器来实现PWM恒流恒压,这里就不再做详细介绍。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bill66

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值