本帖最后由 xld0932 于 2024-1-24 12:25 编辑
1.概述
电压比较器(Comparator,简称CMP)是将两个模拟电压进行比较,带有输出比较结果的外设模块。小华HC32F488系列MCU带有2组4个比较通道的比较器:CMP1/CMP2、CMP3/CMP4。这4个通道可以独立的进行电压比较,也可以组合使用。小华的HC32F488系列的比较器,除了带有最基本的电压比较功能,此外还带有窗口比较功能、输入扫描功能、窗口输出、外部引脚输出功能,对比较器的噪声还带有滤波设置。具体的功能描述可以参考UM手册中的电压比较器章节。
电压比较器应用还蛮广泛的,在电机的应用中直接起到了保证电路工作的安全参数范围内,不会因过压/过流导致硬件异常的风险;尤其是小华HC32F488的比较器还增加了窗口比较和窗口输出的功能,在我接触到的其它MCU中还真没遇到这个功能哄着……更是贴合实际的应用,点赞!
2.功能框图
3.示例程序
3.1.我们结合官网提供的例程,来熟悉一下窗口比较的功能,我们将连接PB1与JP1 PIN1(R3电位器输出)作为比较电压,芯片引脚PB1连接示波器查看输入比较电压,芯片引脚CMP4_OUT(PC13)连接示波器查看比较输出结果,通过调节R3变阻器改变输入比较电压值,通过示波器查看引脚PC13(CMP4_OUT)变化。当比较电压<1.3V,PC13输出低;当比较电压>2V,PC13输出低;当1.3V<比较电压<2V,PC13输出高。
3.2.示例代码
#define CMP_PERIP_CLK (FCG3_PERIPH_CMP3_4)
/* Define port and pin of CMP */
/* Window compare voltage PB1(CMP3_INP2+CMP4_INP2) */
#define WIN_POSITIVE_PORT (GPIO_PORT_B)
#define WIN_POSITIVE_PIN (GPIO_PIN_01)
/* CMP4_OUT */
#define CMP4_OUT_PORT (GPIO_PORT_C)
#define CMP4_OUT_PIN (GPIO_PIN_13)
#define CMP4_OUT_FUNC (GPIO_FUNC_2)
#define DAC_TEST_UNIT (CM_DAC)
#define DAC_PERIP_CLK (FCG3_PERIPH_DAC)
#define DAC_VOL_1P3V (0x1000U/33U*13U)
#define DAC_VOL_2V (0x1000U/33U*20U)
#define DAC_CHN1_PORT (GPIO_PORT_A)
#define DAC_CHN1_PIN (GPIO_PIN_06)
#define DAC_CHN2_PORT (GPIO_PORT_A)
#define DAC_CHN2_PIN (GPIO_PIN_07)
/**
* @brief LED Init
* @param None
* @retval None
*/
static void LED_Init(void)
{
stc_gpio_init_t stcGpioInit;
(void)GPIO_StructInit(&stcGpioInit);
stcGpioInit.u16PinState = PIN_STAT_RST;
stcGpioInit.u16PinDir = PIN_DIR_OUT;
(void)GPIO_Init(LED_G_PORT, LED_G_PIN, &stcGpioInit);
}
/**
* @brief Configure CMP.
* @param None
* @retval None
*/
static void CMP_Configuration(void)
{
stc_cmp_window_init_t stcWindowModeInit;
stc_gpio_init_t stcGpioInit;
/* Enable peripheral Clock */
FCG_Fcg3PeriphClockCmd(CMP_PERIP_CLK, ENABLE);
/* Port function configuration for CMP*/
(void)GPIO_StructInit(&stcGpioInit);
stcGpioInit.u16PinAttr = PIN_ATTR_ANALOG;
(void)GPIO_Init(DAC_CHN1_PORT, DAC_CHN1_PIN, &stcGpioInit);
(void)GPIO_Init(DAC_CHN2_PORT, DAC_CHN2_PIN, &stcGpioInit);
(void)GPIO_Init(WIN_POSITIVE_PORT, WIN_POSITIVE_PIN, &stcGpioInit);
GPIO_SetFunc(CMP4_OUT_PORT, CMP4_OUT_PIN, CMP4_OUT_FUNC);
/* Configuration for normal compare function */
(void)CMP_WindowStructInit(&stcWindowModeInit);
stcWindowModeInit.u16PositiveInput = CMP_WIN_POSITIVE_INP2; /* PB1 */
stcWindowModeInit.u16WinVolLow = CMP_WIN_LOW_INM3; /* DAO1 */
stcWindowModeInit.u16WinVolHigh = CMP_WIN_HIGH_INM4; /* DAO2 */
stcWindowModeInit.u16OutPolarity = CMP_OUT_INVT_OFF;
stcWindowModeInit.u16OutDetectEdge = CMP_DETECT_EDGS_BOTH;
stcWindowModeInit.u16OutFilter = CMP_OUT_FILTER_CLK_DIV32;
(void)CMP_WindowModeInit(CMP_WIN_CMP34, &stcWindowModeInit);
/* Enable CMP output */
CMP_CompareOutCmd(CM_CMP3, ENABLE);
CMP_CompareOutCmd(CM_CMP4, ENABLE);
/* Enable VCOUT */
CMP_PinVcoutCmd(CM_CMP4, ENABLE);
}
/**
* @brief Configure DAC.
* @param None
* @retval None
*/
static void DAC_Configuration(void)
{
stc_dac_init_t stcDacInit;
/* Enable peripheral Clock */
FCG_Fcg3PeriphClockCmd(DAC_PERIP_CLK, ENABLE);
DAC_DeInit(DAC_TEST_UNIT);
(void)DAC_StructInit(&stcDacInit);
(void)DAC_Init(DAC_TEST_UNIT, DAC_CH1, &stcDacInit);
(void)DAC_Init(DAC_TEST_UNIT, DAC_CH2, &stcDacInit);
/* Right alignment of data */
DAC_DataRegAlignConfig(DAC_TEST_UNIT, DAC_DATA_ALIGN_RIGHT);
/* Clear data register */
DAC_SetChData(DAC_TEST_UNIT, DAC_CH1, 0U);
DAC_SetChData(DAC_TEST_UNIT, DAC_CH2, 0U);
(void)DAC_AMPCmd(DAC_TEST_UNIT, DAC_CH1, ENABLE);
(void)DAC_AMPCmd(DAC_TEST_UNIT, DAC_CH2, ENABLE);
/* Output Enable */
DAC_StartDualCh(DAC_TEST_UNIT);
/* Write Data V = (Conversion Data / 4096) * VREFH */
DAC_SetChData(DAC_TEST_UNIT, DAC_CH1, DAC_VOL_1P3V);
DAC_SetChData(DAC_TEST_UNIT, DAC_CH2, DAC_VOL_2V);
}
/**
* @brief Main function of template project
* @param None
* @retval int32_t return value, if needed
*/
int32_t main(void)
{
/* Register write enable for some required peripherals. */
LL_PERIPH_WE(LL_PERIPH_ALL);
/* Initialize BSP system clock. */
BSP_CLK_Init();
/* Initializes UART for debug printing. Baudrate is 115200. */
DDL_PrintfInit(BSP_PRINTF_DEVICE, 115200UL, BSP_PRINTF_Preinit);
/* LED initialize */
LED_Init();
/* Configure DAC */
DAC_Configuration();
/* Configure CMP */
CMP_Configuration();
/* Register write protected for some required peripherals. */
LL_PERIPH_WP(LL_PERIPH_ALL);
stc_clock_freq_t stc_clock_freq;
CLK_GetClockFreq(&stc_clock_freq);
DDL_Printf("\r\n");
DDL_Printf("\r\nEV_F448_LQ80_Rev1.0 %s %s", __DATE__, __TIME__);
DDL_Printf("\r\nSYSCLK Frequency : %7.3f MHz", (double)stc_clock_freq.u32SysclkFreq / (double)1000000.0);
DDL_Printf("\r\nHCLK Frequency : %7.3f MHz", (double)stc_clock_freq.u32HclkFreq / (double)1000000.0);
DDL_Printf("\r\nPCLK0 Frequency : %7.3f MHz", (double)stc_clock_freq.u32Pclk0Freq / (double)1000000.0);
DDL_Printf("\r\nPCLK1 Frequency : %7.3f MHz", (double)stc_clock_freq.u32Pclk1Freq / (double)1000000.0);
DDL_Printf("\r\nPCLK2 Frequency : %7.3f MHz", (double)stc_clock_freq.u32Pclk2Freq / (double)1000000.0);
DDL_Printf("\r\nPCLK3 Frequency : %7.3f MHz", (double)stc_clock_freq.u32Pclk3Freq / (double)1000000.0);
DDL_Printf("\r\nPCLK4 Frequency : %7.3f MHz", (double)stc_clock_freq.u32Pclk4Freq / (double)1000000.0);
DDL_Printf("\r\nEXCLK Frequency : %7.3f MHz", (double)stc_clock_freq.u32ExclkFreq / (double)1000000.0);
DDL_Printf("\r\n");
for ( ;; )
{
LED_G_TOGGLE();
DDL_DelayMS(500);
}
}
3.3.测试环境
3.4.运行结果
如上图所示通道1和通道2是窗口电压、通道3是比较器电压、通道4是比较器输出电平状态,可以看到以比较器电压在窗口电压范围内时,比较器输出高电平,比较器电压大于或小于窗口电压时,比较器输出是低电平。
4.程序附件
替换HC32F448_DDL_Rev1.1.0\projects\ev_hc32f448_lqfp80目录下的template目录内容即可