目录
- 硬知识
- 比较器B介绍
- 比较器 B 的特点
- 比较器 B 的结构
- 模拟输入部分
- 比较部分
- 基准电压部分
- 低通滤波部分
- 比较器和普通运放的区别
- 比较器B测量电阻原理
- 利用比较器B实现电容触摸按键原理
- 比较器B控制寄存器
- COMP_B API (机翻)
- 介绍
- 处理初始化和输出的函数
- 参数
- 处理中断的函数
- 参数
- 处理COMP_B辅助特性的函数
- 参数
- 上机实战
- 整体代码
- 实验现象
平台:Code Composer Studio 10.3.1
MSP430F5529 LaunchPad™ Development Kit
(MSP‑EXP430F5529LP)
硬知识
比较器B介绍
比较器B模块包含多达16个通道的比较功能,具有以下特性:
反相和同相端输入多路复用器;
比较器输出可编程RC滤波器;
输出提供给定时器A捕获输入;
端口输入缓冲区程序控制;
中断能力;
可选参考电压发生器、电压滞后发生器;
外部参考电压输入;
超低功耗比较器模式;
中断驱动测量系统——支持低功耗运行。
比较器 B 的特点
比较器 B 模块可用于精确的斜率式模数转换,电压监控和外部模拟信号的监控。比较器 B 有如下特点:同相端和反相端均有输入复用器;比较器输出端具有软件选择的 RC 滤波器;比较器的输出可以作为定时器 A 的捕获输入;端口输入缓冲由软件控制;具有中断功能,并支持在低功耗模式响应;可选择的参考电压发生器,电压滞回发生器;可使用共享参考源作为参考电压;超低功耗比较模式。
比较器 B 的结构
比较器B的结构框图如下图所示。可以看出比较器 B 模块大概可以分为 5 个部分:模拟输入部分、核心部分、低通滤波部分、基准电压部分和比较器输出部分。
模拟输入部分
模拟输入部分通过CBIPSEL和SBIMSEL控制位控制模拟信号的输入,每个输入通道都是相对独立的,且都可以引入比较器B的“+”输入端或“-”输入端。通过CBSHORT控制位可以将比较器B的模拟信号输入短路。比较器B的输入端也可通过CBRSEL和CBEX控制位的配合引入内部基准电压生成器产生的参考电压。
通过相应寄存器的配置,比较器B可进行如下模拟电压信号的比较:
两个外部输入电压信号的比较;
每个外部输入电压信号与内部基准电压的比较。
比较部分
整个比较器 B 工作需将 CBCTL1 控制寄存器的 CBON 位置为 1,单片机上电复位时,此位为 0;CBCTL1 中的 CBEX 位控制输入方向。
基准电压部分
比较器B的基准电压部分的结构框图如图所示。
基准电压部分通过接入梯形电阻电路或内部共享电压来达到产生不同参考电压VREF的目的。如图所示,CBRSx控制位可选择参考电压的来源。若CBRSx为10,内部梯形电阻电路电压来自内部共享电压,内部共享电压可通过CBREFLx控制位产生1.5V、2.0V或2.5V电压。若CBRSx为01,内部梯形电阻电路电压来自VCC,可通过CBON实现参考电源的开关。若CBRSx为00或11,内部梯形电阻电路无电源可用,被禁止。若CBRSx为11,参考电压来自内部共享电压。当CBRSx不为11时,当CBMRVS为0且CBOUT为1时,参考电压来自VREF1;当CBMRVS和CBOUT均为0时,参考电压来自VREF0。当梯形电阻电路可用时,可通过CBREF1和CBREF0控制位对参考电压源进行分压,分压倍数可为1/5、2/5、3/5、4/5、1/4、3/4、1/3、2/3、1/2和1。CBMRVS控制位实现对控制VREF电压的来源信号的控制。若CBMRVS控制位为0,CBOUT控制VREF电压信号的来源;若CBMRVS控制位为1,CBMRVL控制位控制VREF电压信号的来源。
低通滤波部分
比较器B的输出可以选择使用或不使用内部RC滤波器。当CBF控制位设为1时,比较器输出信号经过RC滤波,反之,不使用RC滤波。
如果在比较器的输入端,模拟电压的电压差很小,那么比较器的输出会产生振荡。如图所示,当比较器“+”输入端的电压减少并越过“-”输入端参考比较电压时,若比较器输出没有经过内部滤波器的过滤,在电压穿越的时刻,比较器输出将会产生较大的振荡;若比较器输出经过内部滤波器的过滤,在电压穿越的时刻,比较器的输出振荡较小。
比较器和普通运放的区别
比较器就是一类特殊的运放。
(1) 一般情况,不要混用普通运放和比较器,那样很可能是用家具当劈柴烧。
(2) 比较器的压摆率比普通运放高,简单说,就是“快” 。 (3) 相比于比较器,普通运放内部有补偿电容,不易自激振荡。
(4) 输入端:普通运放正常工作时两输入端几乎没有压差,所以其输入端往往有电压嵌
位保护。比较器的输入端则没有,混用时应特别注意。
(5) 输出端:运放输出端一般是图腾柱输出,多数不能满幅输出。(轨至轨型除外)
比较器B测量电阻原理
利用比较器B测量电阻的电路示意图如图所示。被测电阻和一个标准参考电阻分别连接到两个GPIO端口,被测电阻可以是固定的,也可以是可变的,如温控电阻等。被测电阻和标准电阻的另外一端连接一个固定电容并接入比较器B的正输入端。比较器的负输入端接内部0.25VCC参考电压,比较器输出连接定时器A。
对被测电阻的测量过程为:
将Px.x引脚拉高,通过标准参考电阻Rref对电容进行充电;
将Px.x引脚拉低,通过标准参考电阻Rref对电容进行放电;
再将Px.x引脚拉高,通过标准参考电阻Rref对电容进行充电;
然后将Px.y引脚拉低,通过被测电阻Rmeas对电容进行放电。
如此往复,利用定时器A准确测量通过Rref和通过Rmeas对电容进行放电的时间,测量过程如图所示。
被测电阻的计算公式为
式中,Nmeas为电容通过被测电阻放电时定时器A的捕获计数值;Nref为电容通过标准参考电阻放电时定时器A的捕获计数值。
利用比较器B实现电容触摸按键原理
人体是具有一定电容的。当我们把PCB上的铜画成如图所示形式时,就做出了一个最基本的触摸感应按键。
上图中左边的图显示了一个基本的触摸按键,中间圆形阴影部分为铜(可以称为“按键”),在这按键中会引出一根导线与单片机相连,单片机通过这根导线来检测是否有按键“按下”(检测的方法将在后面介绍);外围的阴影部分也是铜,不过外围的这些铜是与GND大地相连的。在“按键”和外围的铜之间是空隙(可以称为空隙d)。图6.3.6中右边的图是左图的截面图,当没有手指接触时,只有一个电容Cp;当有手指接触时,“按键”通过手指就形成了电容Cf。由于两个电容是并联的,所以手指接触“按键”前后,总电容的变化率为C% = ((Cp+Cf)- Cp)/ Cp =Cf/Cp。
利用比较器B实现一个张弛振荡触摸按键的电路如图6.3.8所示。在输入端,比较器正输入端接内部参考电压,比较器负输入端接在电阻Rc与感应电容之间,CBOUT与TACLK相连。当感应电容CSENSOR两端没有电压时,通过比较器B的比较,CBOUT将输出高电平,之后通过Rc对感应电容进行充电。当感应电容两端的电压高于内部比较器“+”输入端的参考电压时,通过比较器B的比较,CBOUT将输出低电平,感应电容通过Rc放电。放电的过程中若感应电容两端的电压低于内部比较器“+”输入端的参考电压,CBOUT又输出高电平,通过Rc对感应电容放电,如此往复,比较器B的输出端CBOUT将输出具有一定频率的矩形波。该矩形波的频率可反映感应电容的充放电时间,进而可检测感应电容的变化,因此只需在固定时间内,利用定时器A作为频率计计算张弛振荡器的输出频率。如果在某一时刻输出频率有较大的变化的话,就说明电容值已经被改变,即按键被“按下”了。
基于张弛振荡器的电容触摸按键检测方法示意图如下图所示,当手指触摸到电容触摸按键以后,电容由C1变化至C2,张弛振荡器的输出频率会降低很多,然后利用定时器在门限时间内计算比较器B的输出频率,即可实现对感应电容的检测。
比较器B控制寄存器
比较器 B 的输出既可以输出到内部模块也可以输出到外部引脚,也可以用于产生中断。比较器 B 模块可以在比较器输出的上升沿或者下降沿产生中断,所用的边沿由 CBCTL1 的CBIES 选择。比较器 B 模块具有独立的中断向量,中断被响应后硬件会自动清除中断标志位 CBIFG。
COMP_B API (机翻)
介绍
COMP_B API提供了一组使用MSP430Ware COMP_B模块的函数。提供了初始化COMP_B模块、设置输入参考电压和管理COMP_B模块中断的功能。
COMP_B模块提供比较两个模拟信号的能力,并使用可使用软件和输出引脚来表示正端信号是否高于负端信号。COMP_B可以用来产生迟滞。可以使用16个不同的输入,也可以少至2个输入。COMP_B模块还可以控制REF模块来生成参考电压作为输入。
COMP_B模块可以产生多个中断。可以为输出时产生一个中断,或是输出分为上升或下降单独的中断。
COMP_B API被分成三组函数:
处理初始化和输出的函数,
处理中断的函数,
处理COMP_B辅助特性的函数。
处理初始化和输出的函数
Comp_B_init(uint16_t baseAddress, Comp_B_initParam ∗ param)
//初始化Comp B模块
Comp_B_configureReferenceVoltage(uint16_t baseAddress, Comp_B_configureReferenceVoltageParam ∗ param)
//在初始化过程中向选定的终端生成参考电压
Comp_B_selectReferenceVoltage(uint16_t baseAddress, uint16_t selectType, uint16_t selectVRef)
//修改比较器输出如何在VREFO或VREF1之间选择
Comp_B_enable(uint16_t baseAddress)
//打开Comp_B模块
Comp_B_disable(uint16_t baseAddress)
//关闭Comp_B模块
Comp_B_outputValue(uint16_t baseAddress)
//返回Comp B模块的输出值
参数
baseAddress
COMP_B_BASE
Comp_B_initParam
//*****************************************************************************
//
//! \brief Used in the Comp_B_init() function as the param parameter.
//
//*****************************************************************************
typedef struct Comp_B_initParam {//! Selects the input to the positive terminal.//! \n Valid values are://! - \b COMP_B_INPUT0 [Default]//! - \b COMP_B_INPUT1//! - \b COMP_B_INPUT2//! - \b COMP_B_INPUT3//! - \b COMP_B_INPUT4//! - \b COMP_B_INPUT5//! - \b COMP_B_INPUT6//! - \b COMP_B_INPUT7//! - \b COMP_B_INPUT8//! - \b COMP_B_INPUT9//! - \b COMP_B_INPUT10//! - \b COMP_B_INPUT11//! - \b COMP_B_INPUT12//! - \b COMP_B_INPUT13//! - \b COMP_B_INPUT14//! - \b COMP_B_INPUT15//! - \b COMP_B_VREFuint8_t positiveTerminalInput;//! Selects the input to the negative terminal.//! \n Valid values are://! - \b COMP_B_INPUT0 [Default]//! - \b COMP_B_INPUT1//! - \b COMP_B_INPUT2//! - \b COMP_B_INPUT3//! - \b COMP_B_INPUT4//! - \b COMP_B_INPUT5//! - \b COMP_B_INPUT6//! - \b COMP_B_INPUT7//! - \b COMP_B_INPUT8//! - \b COMP_B_INPUT9//! - \b COMP_B_INPUT10//! - \b COMP_B_INPUT11//! - \b COMP_B_INPUT12//! - \b COMP_B_INPUT13//! - \b COMP_B_INPUT14//! - \b COMP_B_INPUT15//! - \b COMP_B_VREFuint8_t negativeTerminalInput;//! Selects the power mode at which the Comp_B module will operate at.//! \n Valid values are://! - \b COMP_B_POWERMODE_HIGHSPEED [Default]//! - \b COMP_B_POWERMODE_NORMALMODE//! - \b COMP_B_POWERMODE_ULTRALOWPOWERuint16_t powerModeSelect;//! Controls the output filter delay state, which is either off or enabled//! with a specified delay level. This parameter is device specific and//! delay levels should be found in the device's datasheet.//! \n Valid values are://! - \b COMP_B_FILTEROUTPUT_OFF [Default]//! - \b COMP_B_FILTEROUTPUT_DLYLVL1//! - \b COMP_B_FILTEROUTPUT_DLYLVL2//! - \b COMP_B_FILTEROUTPUT_DLYLVL3//! - \b COMP_B_FILTEROUTPUT_DLYLVL4uint8_t outputFilterEnableAndDelayLevel;//! Controls if the output will be inverted or not//! \n Valid values are://! - \b COMP_B_NORMALOUTPUTPOLARITY [Default]//! - \b COMP_B_INVERTEDOUTPUTPOLARITYuint16_t invertedOutputPolarity;
} Comp_B_initParam;
Comp_B_configureReferenceVoltageParam
//*****************************************************************************
//
//! \brief Used in the Comp_B_configureReferenceVoltage() function as the param
//! parameter.
//
//*****************************************************************************
typedef struct Comp_B_configureReferenceVoltageParam {//! Decides the source and max amount of Voltage that can be used as a//! reference.//! \n Valid values are://! - \b COMP_B_VREFBASE_VCC//! - \b COMP_B_VREFBASE1_5V//! - \b COMP_B_VREFBASE2_0V//! - \b COMP_B_VREFBASE2_5Vuint16_t supplyVoltageReferenceBase;//! Is the numerator of the equation to generate the reference voltage for//! the lower limit reference voltage.uint16_t lowerLimitSupplyVoltageFractionOf32;//! Is the numerator of the equation to generate the reference voltage for//! the upper limit reference voltage.uint16_t upperLimitSupplyVoltageFractionOf32;//! is the reference accuracy setting of the Comp_B. Clocked is for low//! power/low accuracy.//! \n Valid values are://! - \b COMP_B_ACCURACY_STATIC//! - \b COMP_B_ACCURACY_CLOCKEDuint16_t referenceAccuracy;
} Comp_B_configureReferenceVoltageParam;
selectType
/*determines whether VREF instance is chosen automatically or manually Valid
values are:*/
COMP_B_VREF_AUTO_SELECT /* [Default] - VREF instance is chosen by comparator output state.*/
COMP_B_VREF_MANUAL_SELECT /*- VREF instance is chosen by user (CBCTL1. CBMRVL bit)
Modified bits are CBMRVS of CBCTL1 register.*/
selectVRef
/*selects VREF0 or VREF1. Only applicable if VREF instance is set up to be
chosen manually Valid values are:*/
COMP_B_SELECT_VREF0 /*[Default]*/
COMP_B_SELECT_VREF1
/*Modified bits are CBMRVL of CBCTL1 register*/
处理中断的函数
Comp_B_enableInterrupt(uint16_t baseAddress, uint16_t interruptMask)
//启用选择的Comp B中断源
Comp_B_disableInterrupt(uint16_t baseAddress, uint16_t interruptMask)
//禁用选择的Comp B中断源
Comp_B_clearInterrupt(uint16_t baseAddress, uint16_t interruptFlagMask)
//清除Comp_B中断标志
Comp_B_getInterruptStatus(uint16_t baseAddress, uint16_t interruptFlagMask)
//获取当前Comp B中断状态
Comp_B_setInterruptEdgeDirection(uint16_t baseAddress, uint16_t edgeDirection)
//设置将触发中断的边缘方向
Comp_B_toggleInterruptEdgeDirection(uint16_t baseAddress)
//反转将触发中断的边缘方向
参数
baseAddress
COMP_B_BASE
interruptMask
/*is the bit mask of the interrupt sources to be enabled. Mask value is the logical
OR of any of the following:*/
COMP_B_OUTPUT_INT /*- Output interrupt*/
COMP_B_OUTPUTINVERTED_INT /*- Output interrupt inverted polarity*/
/*Modified bits of CBINT register.*/
interruptFlagMask
/*is a bit mask of the interrupt sources to be cleared. Mask value is the
logical OR of any of the following:*/
COMP_B_OUTPUT_FLAG /*- Output interrupt*/
COMP_B_OUTPUTINVERTED_FLAG /*- Output interrupt inverted
polarity
Modified bits of CBINT register.*/
edgeDirection
/*determines which direction the edge would have to go to generate an interrupt
based on the non-inverted interrupt flag. Valid values are:*/
COMP_B_RISINGEDGE /*[Default] - sets the bit to generate an interrupt
when the output of the Comp_B falls from LOW to HIGH if the normal
interrupt bit is set(and HIGH to LOW if the inverted interrupt enable bit is
set).*/
COMP_B_FALLINGEDGE /*- sets the bit to generate an interrupt when
the output of the Comp_B rises from HIGH to LOW if the normal interrupt
bit is set(and LOW to HIGH if the inverted interrupt enable bit is set).
Modified bits are CBIES of CBCTL1 register.*/
处理COMP_B辅助特性的函数
Comp_B_shortInputs(uint16_t baseAddress)
//短路在初始化过程中选择的两个输入引脚
Comp_B_unshortInputs(uint16_t baseAddress)
//禁用初始化过程中选择的两个输入引脚的短路
Comp_B_disableInputBuffer(uint16_t baseAddress, uint8_t inputPort)
//禁用所选输入端口的输入缓冲区,以有效地允许模拟信号传递
Comp_B_enableInputBuffer(uint16_t baseAddress, uint8_t inputPort)
//使所选输入端口的输入缓冲区允许数字信号的通过
Comp_B_swapIO(uint16_t baseAddress)
//切换输入终端的位,同时也反转Comp_B的输出
参数
baseAddress
COMP_B_BASE
inputPort
//is the port in which the input buffer will be disabled. Valid values are:
COMP_B_INPUT0 //[Default]
COMP_B_INPUT1
COMP_B_INPUT2
COMP_B_INPUT3
COMP_B_INPUT4
COMP_B_INPUT5
COMP_B_INPUT6
COMP_B_INPUT7
COMP_B_INPUT8
COMP_B_INPUT9
COMP_B_INPUT10
COMP_B_INPUT11
COMP_B_INPUT12
COMP_B_INPUT13
COMP_B_INPUT14
COMP_B_INPUT15
COMP_B_VREF
//Modified bits are CBPDx of CBCTL3 register.
上机实战
P6.5 (CB5) 为输入,与内部产生的参考电压比较
正常模式,滤波器选延迟最短的
//Initialize the Comparator B module/** Base Address of Comparator B,* Pin CB5 to Positive(+) Terminal* Reference Voltage to Negative(-) Terminal* Normal Power Mode* Output Filter On with minimal delay* Non-Inverted Output Polarity*/Comp_B_initParam initParam = {0};initParam.positiveTerminalInput = COMP_B_INPUT5;initParam.negativeTerminalInput = COMP_B_VREF;initParam.powerModeSelect = COMP_B_POWERMODE_NORMALMODE;initParam.outputFilterEnableAndDelayLevel = COMP_B_FILTEROUTPUT_DLYLVL1;initParam.invertedOutputPolarity = COMP_B_NORMALOUTPUTPOLARITY;Comp_B_init(COMP_B_BASE, &initParam);
设下门槛为Vcc*(11/32) = 1.134375V, 上门槛为Vcc*(21/32) = 2.165625V
静态模式
//Set the reference voltage that is being supplied to the (-) terminal/** Base Address of Comparator B,* Reference Voltage = Vcc = 3.3V,* Lower Limit of Vcc*(11/32) = 1.134375V,* Upper Limit of Vcc*(21/32) = 2.165625V,* Static Mode Accuracy*/Comp_B_configureReferenceVoltageParam refVoltageParam = {0};refVoltageParam.supplyVoltageReferenceBase = COMP_B_VREFBASE_VCC;refVoltageParam.lowerLimitSupplyVoltageFractionOf32 = 11;refVoltageParam.upperLimitSupplyVoltageFractionOf32 = 21;refVoltageParam.referenceAccuracy = COMP_B_ACCURACY_STATIC;Comp_B_configureReferenceVoltage(COMP_B_BASE, &refVoltageParam);
启用比较器,复用P1.6为比较器输出
//Allow power to Comparator moduleComp_B_enable(COMP_B_BASE);GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P1,GPIO_PIN6);
整体代码
#include "driverlib.h"#define MCLK_IN_HZ 25000000#define delay_us(x) __delay_cycles((MCLK_IN_HZ/1000000*(x)))
#define delay_ms(x) __delay_cycles((MCLK_IN_HZ/1000*(x)))void SystemClock_Init(void)
{PMM_setVCore(PMM_CORE_LEVEL_3); //高主频工作需要较高的核心电压//XT1引脚复用GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN4);GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, GPIO_PIN5);//起振XT1UCS_turnOnLFXT1(UCS_XT1_DRIVE_3,UCS_XCAP_3);//XT2引脚复用GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN2);GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, GPIO_PIN3);//起振XT2UCS_turnOnXT2(UCS_XT2_DRIVE_4MHZ_8MHZ);//XT2作为FLL参考时钟,先8分频,再50倍频 4MHz / 8 * 50 = 25MHzUCS_initClockSignal(UCS_FLLREF, UCS_XT2CLK_SELECT, UCS_CLOCK_DIVIDER_8);UCS_initFLLSettle(25000, 50);//XT1作为ACLK时钟源 = 32768HzUCS_initClockSignal(UCS_ACLK, UCS_XT1CLK_SELECT, UCS_CLOCK_DIVIDER_1);//DCOCLK作为MCLK时钟源 = 25MHzUCS_initClockSignal(UCS_MCLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1);//DCOCLK作为SMCLK时钟源 = 25MHzUCS_initClockSignal(UCS_SMCLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1);//设置外部时钟源的频率,使得在调用UCS_getMCLK, UCS_getSMCLK 或 UCS_getACLK时可得到正确值UCS_setExternalClockSource(32768, 4000000);
}int main(void)
{WDT_A_hold(WDT_A_BASE);SystemClock_Init();//Initialize the Comparator B module/** Base Address of Comparator B,* Pin CB5 to Positive(+) Terminal* Reference Voltage to Negative(-) Terminal* Normal Power Mode* Output Filter On with minimal delay* Non-Inverted Output Polarity*/Comp_B_initParam initParam = {0};initParam.positiveTerminalInput = COMP_B_INPUT5;initParam.negativeTerminalInput = COMP_B_VREF;initParam.powerModeSelect = COMP_B_POWERMODE_NORMALMODE;initParam.outputFilterEnableAndDelayLevel = COMP_B_FILTEROUTPUT_DLYLVL1;initParam.invertedOutputPolarity = COMP_B_NORMALOUTPUTPOLARITY;Comp_B_init(COMP_B_BASE, &initParam);//Set the reference voltage that is being supplied to the (-) terminal/** Base Address of Comparator B,* Reference Voltage = Vcc = 3.3V,* Lower Limit of Vcc*(11/32) = 1.134375V,* Upper Limit of Vcc*(21/32) = 2.165625V,* Static Mode Accuracy*/Comp_B_configureReferenceVoltageParam refVoltageParam = {0};refVoltageParam.supplyVoltageReferenceBase = COMP_B_VREFBASE_VCC;refVoltageParam.lowerLimitSupplyVoltageFractionOf32 = 11;refVoltageParam.upperLimitSupplyVoltageFractionOf32 = 21;refVoltageParam.referenceAccuracy = COMP_B_ACCURACY_STATIC;Comp_B_configureReferenceVoltage(COMP_B_BASE, &refVoltageParam);//Allow power to Comparator moduleComp_B_enable(COMP_B_BASE);GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P1,GPIO_PIN6);__bis_SR_register(GIE);while(1){}
}
实验现象
用万用表测量P1.6输出电压,可观察到,当CB5输入电压高于上门槛电压时,P1.6输出3.3V,当CB5输入电压低于下门槛电压时,P1.6输出0V,当处于两者之间时,电压连续变化。