XL6601系列ACMP模拟比较器使用

模拟比较器(ACMP)

实现一个简单的小功能,掉电检测,使用到了ACMP外设,认为学习东西后总得产出点什么,所以在此简单记录一下。

简介特性

模拟比较器模块(ACMP)提供一个用于比较两个模拟输入电压的电路。此比较器电路适用于在整个供电电压范围内操作(全摆幅操作);

  • 可在 2.7 V 至 5.5 V 的整个电源电压范围上操作
  • 片上 6 位分辨率 DAC,基准电压源可以选择 VDD 或内部带隙基准
  • 可配置迟滞(个人理解是)
  • 可在比较器输出上升沿、下降沿或者任何边沿时选择产生中断
  • 最多 4 个可选择比较器输入

实现

使用引脚复用外设ACMP0作为比较引脚,对此IO口电压进行比较,当引脚电压低于设定的对比值(DAC值),并在上升沿下降沿触发中断。

结构框图

结构框图

要想怎么实现的肯定要先理解结构框图了:

  1. 比较器输入端IN+ 6位DAC选择VDDA为基准与输入端IN- ACM0进行比较;
  2. 输出一路到外部输出,一路到ACO(返回比较器输出的当前值)寄存器;
  3. 将编译控制逻辑 ACMPMOD(确定中断触发器的触发模式)进行设置;
  4. 产生有效边沿后ACF产生中断标志位置位,触发中断;
  5. ACIE(中断使能)触发中断;

Demo

实例代码,一些理解写在了注释中


void Judge_Status(Return_Status flag)  
{    //正常执行就都会返回RET_STATE_OK,否则死循环
	if(flag != RET_STATE_OK)
	{
		while(1);
	}
}

/*********** ACMP配置初始化 ***************/
static void ACMP_Config(ACMP_Type *ACMPx)
{
	ACMP_InitTypeDef ACMP_Initstructure;	
	NVIC_InitTypeDef NVIC_InitStructure;

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 
	NVIC_InitStructure.NVIC_IRQChannel = (uint32_t)ACMP0_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 	
	NVIC_Init(&NVIC_InitStructure); 
	
	FUNC_Status = SIM_SCGC_Cmd(SIM_SCGC_ACMP0,ENABLE);		
	Judge_Status(FUNC_Status);    
	
	ACMP_Initstructure.ACMP_HystMode = ACMP_Hyst_20mv;                //ACMP选择了20mv的停滞
	ACMP_Initstructure.ACMP_IntTrigMode = ACMP_Int_FallorRiseEdge;    //上升沿下降沿均可触发中断        
	ACMP_Initstructure.ACMP_InputP = ACMP_Positive_EXT0;               //这里有个注意的,这是比较器输入IN+和IN-是反过来的,即为IN+为ACMP0,IN-为DAC输入       
	ACMP_Initstructure.ACMP_InputN = ACMP_Negative_DAC;               
	ACMP_Initstructure.ACMP_InputPin = ACMP_IN0;                       //以ACMP0为比较口
	ACMP_Initstructure.ACMP_DACEN = ENABLE;                            //使能
	ACMP_Initstructure.ACMP_DACRefVoltage = ACMP_DACRef_VDDA;          //以VDDA为基准
	ACMP_Initstructure.ACMP_DACValue =  0x1F;		                   //DAC电平选择 = Vin/64*(1+0x1f) = 5/64*(1+31) = 2.5(V)
    //比较电压,掉电触发下降沿中断,当ACMP复用IO口低于这个电压输出0或者1(设置(IN+,IN-)ACMP_InputN、ACMP_InputP,结构框图对应的比较器输入脚即可决定)

	FUNC_Status = ACMP_Init(ACMPx, &ACMP_Initstructure );	    //初始化ACMP	
	Judge_Status(FUNC_Status);
	FUNC_Status = ACMP_InterruptEn(ACMPx, ENABLE );	            //启用ACMP中断
	Judge_Status(FUNC_Status);
	FUNC_Status = ACMP_OutputPinEn(ACMPx, ENABLE );		        //输出引脚使能
	Judge_Status(FUNC_Status);
	FUNC_Status = ACMP_EnableCmd(ACMPx, ENABLE); 		        //ACMP模块使能
	Judge_Status(FUNC_Status);
}

/*********** 主函数 ***************/
int32_t main (void) 
{
	SYS_CLK_STATUS clk_state;
	clk_state = SystemSetFEI(ICS_IRC_50K, ICS_FLLFACTOR_1920);
	if(clk_state != SYS_CLK_OK)
	{
		while(1);
	}
	
	Systick_Init();
	ACMP_Config(ACMP0);
	FUNC_Status = GPIO_SetPinDir(GPIO_PTH5 ,GPIO_Direction_Output); 	//LED引脚配置为输出	
	Judge_Status(FUNC_Status);
	for(;;)
	{
		Delay_ms(1000);
	}	
}

/***********  ACMP中断调用函数 ***************/
static void ACMPx_IRQ_CallBack(ACMP_Type *ACMPx)
{
	uint8_t ACMP_Out = 0;
	FUNC_Status = ACMP_GetOutPutLogic(ACMPx, &ACMP_Out);  //获取比较器输出值	
	Judge_Status(FUNC_Status);    //根据上面配置信息,IN+电压小于IN-电压即为掉电
	if(ACMP_Out)  //输出为1,未掉电
	{
		FUNC_Status = GPIO_ClrPin(GPIO_PTH5);		
		Judge_Status(FUNC_Status);
	}
	else      //输出为0,确定掉电,因为配置IN-是DAC值
	{
        // 全局标志位置位,另写函数获取是否掉电,后续调用此函数写掉电后执行的操作
		FUNC_Status = GPIO_SetPin(GPIO_PTH5);		
		Judge_Status(FUNC_Status);
	}
	FUNC_Status = ACMP_ClearIntFlag(ACMPx);		//清除标志位
	Judge_Status(FUNC_Status);
}


/***********  ACMP0中断服务函数 ***************/
void ACMP0_IRQHandler(void)
{
	ACMPx_IRQ_CallBack(ACMP0);
}

官方解释

相关寄存器的描述已写出,以便更好阅读理解(阅读可更好理解ACMP的工作)。

功能说明

ACMP 模块就功能而言由两部分组成:数模转换器(DAC)和比较器(CMP)。

DAC 包括 64 级 DAC(数模转换器)和相关控制逻辑。通过置位 ACMP_C1[DACREF](DAC基准选择),DAC 可选择 VDDA 或片上带隙基准源这两个基准输入的其中之一作为 DAC 输入 Vin(这边选择的就是VDDA)。DAC 使能后,将ACMP_C1[DACVAL](DAC输入电平)中设置的数据转换为步进式模拟输出,然后馈入 ACMP 作为内部基准输入。输出电压范围为 Vin/64 到 Vin。步进大小为 Vin/64。

正输入与负输入

ACMP 可以实现正输入与负输入的模拟比较,然后提供一个数字输出和相关的中断。ACMP 的正负输入均可从四个通用输入中选择:三个外部基准输入和一个来自 DAC 输出的内部基准输入。
ACMP 的正输入由 ACMP_C0[ACPSEL](正输入选择)选定,其负输入由 ACMP_C0[ACNSEL](负输入选择)(Demo区注释已解释过)选定。可通过使用适当的值配置 ACMPC0 来比较 8 个输入的任何配对。

输出

通过置位 ACMP_CS[ACE](ACMP使能)使能 ACMP 之后,比较结果以数字输出呈现(1、0)。只要 ACMP_CS[ACMOD](中断边沿触发方式)中定义的有效边沿出现,ACMP_CS[ACF](中断标志位)的电平就会变为有效值。

输出标志

ACMP_CS[ACO](ACPC输出,比较后的结果)根据比较结果而改变,因此它可以用作一个跟踪标志,连续指示输入的电压变化。
如果选择芯片外部的基准输入作为 ACMP 的输入,那么必须置位对应的 ACMP_C2[ACIPE](是否允许对应的外部模拟输入,这边是允许DAC输入的,2.5V数字量转2.5V模拟量)位以使能来自焊盘接口的输入。如果需要将ACMP的输出置于外部引脚上(比较后的结果输出到引脚,这边不需要,只需得知是否掉电,其这个功能仅ACMP1支持),那么必须置位ACMP_CS[ACOPE](是否允许ACMP输出置于外部引脚上)位以使能焊盘逻辑的 ACMP 引脚功能。

中断

如果 ACMP_CS[ACMOD](中断边沿触发方式)定义的有效边沿出现时总线时钟可用,那么 ACMP_CS[ACF](中断标志位)的电平就会变为有效值。如果 ACMP_CS[ACIE](使能中断)置位,那么会发生 ACMP 中断事件。 ACMP_CS[ACF](中断标志位)位的电平将一直保持有效值,直到 ACMP 中断被软件清零。将 0 写入 ACMP_CS[ACF](中断标志位)位可清零该中断。

设置与操作

ACMP 两部分( DAC 和 CMP)的设置和操作可以独立进行。但是,如果 DAC 用作 CMP 的输入,那么在使能 ACMP 之前必须对 DAC 进行配置。
由于输入转换会导致 ACMP 输入上出现问题,因此用户应在启用 ACMP 之前完成输入选择,并且不能在启用 ACMP 时更改选择输入以避免意外输出。同样,更改 ACMP_C1[DACVAL](DAC输入电平,即为设置的2.5V)之后,DAC会有一定的设置延迟,因此用户应当在使能 DAC 之前完成 ACMP_C1[DACVAL](DAC输入电平)的设置。


posted @ 2024-01-15 12:51  Auroda_J  阅读(202)  评论(0编辑  收藏  举报