您现在的位置是:首页 >技术教程 >STM32G4 比较器COMPx(寄存器开发)网站首页技术教程

STM32G4 比较器COMPx(寄存器开发)

Vice Versa XL 2024-07-09 18:01:02
简介STM32G4 比较器COMPx(寄存器开发)

STM内部的比较器是模拟量的比较器,其与APB2时钟同步,在RCC时钟控制器中没有COMx时钟使能标志位,其时钟的使能与复位与SYSCLK同步。

1. 特性

1.1 框图

模块框图

1.2 比较器输入信号SEL

比较器的输入端有正负极信号,正极INP通过INPSEL选择输入信号,负极通过INMSEL选择输入信号,其SEL引脚定义如下图表所示。

SEL定义

1.3 比较器滞回选择HYST

滞回英文 Hysteresis ,可以理解为施密特触发器,通过在CSR寄存器中配置HYST来选择滞回电压。

滞回电压配置

1.4 比较器的输出

根据框图可以看到,比较器的输出信号为VALUE。VALUE直接连接到 HRTIM(高分辨率定时器)外设;VALUE还通过POLARITY(CSR寄存器的POL配置)的极性选择(是否取反)连接到 COMPx_OUT(GPIO)EXTI总线TIMx定时器

1.5 LOCK机制

一旦将CSR寄存器的LOCK标志位置位,就不能清除LOCK标志位了,只有重新复位MCU才可清除。并且LOCK置位后,CSR寄存器变为只读,不能重新配置。

2. 编程

2.1 初始化步骤

  1. 使能SYSCLK时钟
  2. 初始化GPIO,将要使用到的comp引脚定义为模拟量模式(MODER=3)
  3. 配置CSR寄存器;使能比较器;锁定寄存器
  4. 配置中断

2.2 举例

下面以COMP1进行举例,分别使用PB1和PA4作为比较器输入的正负极,上下沿都产生中断。
测试代码如下。(已经提前打开GPIO、SYSCLK时钟)


#define MODER_IN												(0x00UL)	//输入
#define MODER_OUT												(0x01UL)	//输出
#define MODER_FUNC												(0x02UL)	//功能
#define MODER_ANA												(0x03UL)	//模拟
#define MODER_BIT												(0x03UL)	//

#define PUPDR_NO												(0x00UL)	//无上下拉
#define PUPDR_PU												(0x01UL)	//上拉
#define PUPDR_PD												(0x02UL)	//下拉
#define PUPDR_BIT												(0x03UL)	//


#define COMP_COMPx												COMP1
#define COMP_INP_GPIO											GPIOB
#define COMP_INP_PORT											1
#define COMP_INP_SEL											1 //<根据本文1.2的查表,PB1选择1
#define COMP_INM_GPIO											GPIOA
#define COMP_INM_PORT											4
#define COMP_INM_SEL											6 //<根据本文1.2的查表,PA4选择6

void COMP1_Init(void)
{
//步骤2:初始化GPIO,IO模式为模拟量
	COMP_INP_GPIO->MODER	&= ~(MODER_BIT	<< (COMP_INP_PORT << 1));
	COMP_INP_GPIO->MODER	|=  (MODER_ANA	<< (COMP_INP_PORT << 1));
	COMP_INP_GPIO->PUPDR	&= ~(PUPDR_BIT	<< (COMP_INP_PORT << 1));
	COMP_INP_GPIO->PUPDR	|=  (PUPDR_NO	<< (COMP_INP_PORT << 1));
	COMP_INM_GPIO->MODER	&= ~(MODER_BIT	<< (COMP_INM_PORT << 1));
	COMP_INM_GPIO->MODER	|=  (MODER_ANA	<< (COMP_INM_PORT << 1));
	COMP_INM_GPIO->PUPDR	&= ~(PUPDR_BIT	<< (COMP_INM_PORT << 1));
	COMP_INM_GPIO->PUPDR	|=  (PUPDR_NO	<< (COMP_INM_PORT << 1));

//步骤3:配置CSR寄存器;使能比较器;锁定寄存器
	COMP1->CSR = 0
				|COMP_CSR_LOCK						// 【1:寄存器只读】
				// COMP_CSR_VALUE					// 【只读,不经过机型选择器的value】
				// |COMP_CSR_SCALEN					// 【1:VREFINT分段使能(VREFINT/1/2/3有效)】
				// |COMP_CSR_BRGEN						// 【1:电阻桥使能】
				|(0 << COMP_CSR_BLANKING_Pos)		// 消隐信号选择   <暂时不用
				|(3 << COMP_CSR_HYST_Pos)			// 滞回电压选择
															// 0: No hysteresis 
															// 1: 10mV hysteresis 
															// 2: 20mv hysteresis 
															// 3: 30mV hysteresis <当前选择
															// 4: 40mV hysteresis
															// 5: 50mV hysteresis
															// 6: 60mV hysteresis
															// 7: 70mV hysteresis
				// |COMP_CSR_POLARITY					// 【1:极性反转】
				|(COMP_INP_SEL << COMP_CSR_INPSEL_Pos)			// 正极输入选择 <根据本文1.2的查表,PB1选择1
				|(COMP_INM_SEL << COMP_CSR_INMSEL_Pos)			// 负极输入选择 <根据本文1.2的查表,PA4选择6
				|COMP_CSR_EN						// 比较器使能
				;
//步骤4:配置中断

	EXTI->IMR1 |= BIT21;//COMP1 Output 中断屏蔽失效
	EXTI->RTSR1 |= BIT21;//COMP1 Output 上升沿触发
	EXTI->FTSR1 |= BIT21;//COMP1 Output 下降沿触发
}

上述配置中断部分的 BIT21,是通过手册查表 Table 98: EXTI lines connections 来的(手册Page449)。

在这里插入图片描述

根据上图可以看到,line21就是COMP1output总线。

EXTI的 RTSR1 、FTSR1 寄存器分别是上升沿使能、下降沿使能寄存器。

配置完毕初始化后,就可以在中断函数中等待比较中断了。中断内部举例代码如下。

void COMP1_2_3_IRQHandler(void)
{
	EXTI->PR1 |= BIT21;//清除中断挂起标志位
	if(COMP1->CSR & COMP_CSR_VALUE)
		GPIOC->BSRR |= BIT13;//LED点亮(测试使用)
	else
		GPIOC->BSRR |= (BIT13 << 16);//LED关闭(测试使用)
}

当正极大于负极(算上滞回电压),VALUE为0,即比较器输出0;(我测试是这个结果)
当正极小于负极(算上滞回电压),VALUE为1,即比较器输出1。
VALUE值可以在 COMPx->CSR寄存器中读取。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。