/****************************************************************************** * Shanghai ChipON Micro-Electronic Co.,Ltd * ****************************************************************************** * $File Name$ : kf32a156_qei.c * * $Author$ : ChipON AE/FAE Group * * $Data$ : 2021-07-08 * * $Chip Version : A02 * * $Hard Version : KF32A156-MINI-EVB_V1.2 * * $Description$ : This document provides functions related to * * quadrature coded pulse circuits (QEI) , including: * * + Quadrature coded pulse circuit(QEI) unitialization * * function * * + Quadrature coded pulse circuit(QEI) function * * configuration function * * + Quadrature coded pulse circuit(QEI) interrupt * * management function * ****************************************************************************** * Copyright (C) by Shanghai ChipON Micro-Electronic Co.,Ltd * * All rights reserved. * * * * This software is copyright protected and proprietary to * * Shanghai ChipON Micro-Electronic Co.,Ltd. * ****************************************************************************** * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * REVISON HISTORY * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Data Version Author Description * * ~~~~~~~~~~ ~~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * 2021-07-08 00.01.00 FAE Group Version 2.0 update * * * * * *****************************************************************************/ /****************************************************************************** ** Include Files ** ******************************************************************************/ #include "kf32a156_qei.h" #include "kf32a156_rst.h" #include "kf32a156_pclk.h" /******************************************************************************* ** (QEI) Module private definition ** *******************************************************************************/ /* QEIx_CTL0寄存器定时器功能初始化掩码 */ #define QEI_CTL0_TIMER_INIT_MASK (QEI_CTL0_TXDIR \ | QEI_CTL0_TXCS) /* QEIx_CTL0寄存器初始化掩码 */ #define QEI_CTL0_INIT_MASK (QEI_CTL0_INDRES \ | QEI_CTL0_TXDIROUT) /* QEIx_CTL1寄存器初始化掩码 */ #define QEI_CTL1_INIT_MASK (QEI_CTL1_QEICLK \ | QEI_CTL1_QEIOUT \ | QEI_CTL1_QEICK \ | QEI_CTL1_SWPAB) /** * ##### 正交编码脉冲电路(QEI)初始化函数 ##### */ /** * 描述 复位QEI外设,使能外设时钟。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * 返回 无。 */ void QEI_Reset (QEI_SFRmap* QEIx) { /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); if (QEIx == QEI0_SFR) { RST_CTL1_Peripheral_Reset_Enable(RST_CTL1_QEI0RST, TRUE); RST_CTL1_Peripheral_Reset_Enable(RST_CTL1_QEI0RST, FALSE); PCLK_CTL1_Peripheral_Clock_Enable(PCLK_CTL1_QEI0CLKEN, TRUE); } else if(QEIx == QEI1_SFR) { RST_CTL1_Peripheral_Reset_Enable(RST_CTL1_QEI1RST, TRUE); RST_CTL1_Peripheral_Reset_Enable(RST_CTL1_QEI1RST, FALSE); PCLK_CTL1_Peripheral_Clock_Enable(PCLK_CTL1_QEI1CLKEN, TRUE); } else { ; } } /** * 描述 QEI模块正交编码器初始化。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * qeiInitStruct: QEI模块正交编码器信息结构体。 * 返回 无。 */ void QEI_Configuration(QEI_SFRmap* QEIx, QEI_InitTypeDef* qeiInitStruct) { uint32_t tmpreg; /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); CHECK_RESTRICTION(CHECK_FUNCTIONAL_STATE(qeiInitStruct->m_IndexReset)); CHECK_RESTRICTION(CHECK_FUNCTIONAL_STATE(qeiInitStruct->m_DirectionEn)); CHECK_RESTRICTION(CHECK_QEI_SOURCE(qeiInitStruct->m_WorkClock)); CHECK_RESTRICTION(CHECK_FUNCTIONAL_STATE(qeiInitStruct->m_DigitalFilterEn)); CHECK_RESTRICTION(CHECK_QEI_DIGITAL_FILTER_CLK( \ qeiInitStruct->m_DigitalFilterPrescaler)); CHECK_RESTRICTION(CHECK_FUNCTIONAL_STATE(qeiInitStruct->m_SwapABEn)); /*---------------- 设置Tx_CNT寄存器 ----------------*/ QEIx->CNT = (uint32_t)qeiInitStruct->m_Counter; /*---------------- 设置PPx周期寄存器 ---------------*/ QEIx->PPX = (uint32_t)qeiInitStruct->m_Period; /*---------------- 设置Tx_PRSC预分频寄存器 ---------------*/ QEIx->PRSC = (uint32_t)qeiInitStruct->m_Prescaler; /*---------------- 设置QEIx_CTL1寄存器 ----------------*/ /* 根据结构体成员m_WorkClock,设置QEICLK位域 */ /* 根据结构体成员m_DigitalFilterEn,设置QEIOUT位域 */ /* 根据结构体成员m_DigitalFilterPrescaler,设置QEICK位域 */ /* 根据结构体成员m_SwapABEn,设置SWPAB位域 */ tmpreg = (qeiInitStruct->m_WorkClock) \ | (qeiInitStruct->m_DigitalFilterEn << QEI_CTL1_QEIOUT_POS) \ | (qeiInitStruct->m_DigitalFilterPrescaler) \ | (qeiInitStruct->m_SwapABEn << QEI_CTL1_SWPAB_POS); QEIx->CTL1 = SFR_Config (QEIx->CTL1, ~QEI_CTL1_INIT_MASK, tmpreg); /*---------------- 设置QEIx_CTL0寄存器 ----------------*/ /* 根据结构体成员m_IndexReset,设置INDRES位域 */ /* 根据结构体成员m_DirectionEn,设置TXDIROUT位域 */ tmpreg = (qeiInitStruct->m_IndexReset << QEI_CTL0_INDRES_POS) \ | (qeiInitStruct->m_DirectionEn << QEI_CTL0_TXDIROUT_POS); QEIx->CTL0 = SFR_Config (QEIx->CTL0, ~QEI_CTL0_INIT_MASK, tmpreg); } /** * 描述 QEI模块定时器初始化。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * qeiTimerInitStruct: QEI定时器(T7/T8)配置信息结构体指针。 * 返回 无。 */ void QEI_Timer_Configuration(QEI_SFRmap* QEIx, QEI_TimerTypeDef* qeiTimerInitStruct) { uint32_t tmpreg; /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); CHECK_RESTRICTION(CHECK_QEI_COUNT_DIRECT(qeiTimerInitStruct->m_CounterMode)); CHECK_RESTRICTION(CHECK_QEI_TIMER_SOURCE(qeiTimerInitStruct->m_ClockSource)); /*---------------- 设置Tx_CNT寄存器 ----------------*/ QEIx->CNT = (uint32_t)qeiTimerInitStruct->m_Counter; /*---------------- 设置PPx周期寄存器 ---------------*/ QEIx->PPX = (uint32_t)qeiTimerInitStruct->m_Period; /*---------------- 设置Tx预分频寄存器 --------------*/ QEIx->PRSC = (uint32_t)qeiTimerInitStruct->m_Prescaler; /*---------------- 设置QEIx_CTL0寄存器 ----------------*/ /* 根据结构体成员m_CounterMode,设置TXDIR位域 */ /* 根据结构体成员m_ClockSource,设置TXCS位域 */ tmpreg = (qeiTimerInitStruct->m_CounterMode) \ | (qeiTimerInitStruct->m_ClockSource); QEIx->CTL0 = SFR_Config (QEIx->CTL0, ~QEI_CTL0_TIMER_INIT_MASK, tmpreg); } /** * 描述 初始化QEI模块正交编码器信息结构体。 * 输入 qeiInitStruct: 指向待初始化的结构体指针。 * 返回 无。 */ void QEI_Struct_Init (QEI_InitTypeDef* qeiInitStruct) { /* 初始化 位置计数器复位使能 */ qeiInitStruct->m_IndexReset = FALSE; /* 初始化 位置计数器方向状态输出使能 */ qeiInitStruct->m_DirectionEn = FALSE; /* 初始化 QEI工作时钟 */ qeiInitStruct->m_WorkClock = QEI_SOURCE_SCLK; /* 初始化 QEI数字滤波器输出使能 */ qeiInitStruct->m_DigitalFilterEn = FALSE; /* 初始化 QEI数字滤波器时钟分频 */ qeiInitStruct->m_DigitalFilterPrescaler = QEI_DIGITAL_FILTER_CLK_DIV_1; /* 初始化 A相和B相输入交换使能 */ qeiInitStruct->m_SwapABEn = FALSE; /* 初始化 定时器计数值 */ qeiInitStruct->m_Counter = 0; /* 初始化 定时器周期值 */ qeiInitStruct->m_Period = 0; /* 初始化 定时器预分频 */ qeiInitStruct->m_Prescaler = 0; } /** * 描述 初始化QEI定时器配置信息结构体。 * 输入 qeiTimerInitStruct: 指向待初始化的结构体指针。 * 返回 无。 */ void QEI_Timer_Struct_Init (QEI_TimerTypeDef* qeiTimerInitStruct) { /* 初始化 定时器计数值 */ qeiTimerInitStruct->m_Counter = 0; /* 初始化 定时器周期值 */ qeiTimerInitStruct->m_Period = 0; /* 初始化 定时器预分频值 */ qeiTimerInitStruct->m_Prescaler = 0; /* 初始化 计数器方向 */ qeiTimerInitStruct->m_CounterMode = QEI_COUNT_DIRECT_REVERSE; /* 初始化 定时器时钟源选择 */ qeiTimerInitStruct->m_ClockSource = QEI_TIMER_SOURCE_SCLK; } /** * ##### 正交编码脉冲电路(QEI)初始化函数定义结束 ##### */ /** * ##### 正交编码脉冲电路(QEI)功能配置函数 ##### */ /** * 描述 配置正交编码器接口模式。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR和QEI1_SFR。 * PortMode: 正交编码器接口模式,取值范围为: * QEI_ENCODER_OFF: 正交编码器接口/定时器关闭 * QEI_GENERAL_PURPOSE_COUNTER: 使能计数方向/时钟可选的通用计数器模式 * QEI_X2_INDEX_PULSE_RESET: 使能正交编码器接口(x2模式),索引脉冲复位位置计数器 * QEI_X2_MATCH_RESET: 使能正交编码器接口(x2模式),匹配时复位位置计数器(PPX) * QEI_X4_INDEX_PULSE_RESET: 使能正交编码器接口(x4模式),索引脉冲复位位置计数器 * QEI_X4_MATCH_RESET: 使能正交编码器接口(x4模式),匹配时复位位置计数器(PPX) * 返回 无。 */ void QEI_Encoder_Mode_Config (QEI_SFRmap* QEIx, uint32_t PortMode) { uint32_t tmpreg; /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); CHECK_RESTRICTION(CHECK_QEI_PORT_MODE(PortMode)); /*---------------- 配置QEI_CTL0寄存器QEIMOD位 ----------------*/ tmpreg = PortMode << QEI_CTL0_QEIMOD0_POS; QEIx->CTL0 = SFR_Config (QEIx->CTL0, ~QEI_CTL0_QEIMOD, tmpreg); } /** * 描述 配置位置计数器复位使能。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * NewState: 位置计数器复位使能状态,取值为TRUE 或 FALSE。 * 返回 无。 */ void QEI_Location_Counter_Reset_Enable (QEI_SFRmap* QEIx, FunctionalState NewState) { /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); CHECK_RESTRICTION(CHECK_FUNCTIONAL_STATE(NewState)); /*---------------- 设置QEI_CTL0寄存器INDRES位 ----------------*/ if (NewState != FALSE) { /* 索引脉冲复位位置计数器 */ SFR_SET_BIT_ASM(QEIx->CTL0, QEI_CTL0_INDRES_POS); } else { /* 索引脉冲不复位位置计数器 */ SFR_CLR_BIT_ASM(QEIx->CTL0, QEI_CTL0_INDRES_POS); } } /** * 描述 配置QEI定时器时钟源。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * TimerClock: QEI定时器时钟源,取值范围为: * QEI_TIMER_SOURCE_SCLK: 内部时钟(SCLK) * QEI_TIMER_SOURCE_EXTERNAL_PIN_QEA: 来自QEAy引脚的外部时钟(下降沿触发计数) * 返回 无。 */ void QEI_Timer_Source_Clock_Config (QEI_SFRmap* QEIx, uint32_t TimerClock) { /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); CHECK_RESTRICTION(CHECK_QEI_TIMER_SOURCE(TimerClock)); /*---------------- 设置QEI_CTL0寄存器TXCS位 ----------------*/ if (TimerClock != QEI_TIMER_SOURCE_SCLK) { /* 来自QEAy引脚的外部时钟 */ SFR_SET_BIT_ASM(QEIx->CTL0, QEI_CTL0_TXCS_POS); } else { /* 内部时钟(SCLK) */ SFR_CLR_BIT_ASM(QEIx->CTL0, QEI_CTL0_TXCS_POS); } } /** * 描述 获取QEI索引引脚状态。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * 返回 1:索引引脚为高电平,0:索引引脚为低电平。 */ FlagStatus QEI_Get_Index_Pin_State (QEI_SFRmap* QEIx) { /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); /*---------------- 读取QEI_CTL0寄存器INDEX位 ----------------*/ if (QEIx->CTL0 & QEI_CTL0_INDEX) { /* 索引引脚为高电平 */ return SET; } else { /* 索引引脚为低电平 */ return RESET; } } /** * 描述 配置位置计数器方向状态输出使能。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * NewState: 位置计数器方向状态输出使能状态,取值为TRUE 或 FALSE。 * 返回 无。 */ void QEI_Location_Counter_Output_Enable (QEI_SFRmap* QEIx, FunctionalState NewState) { /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); CHECK_RESTRICTION(CHECK_FUNCTIONAL_STATE(NewState)); /*---------------- 设置QEI_CTL0寄存器TXDIROUT位 ----------------*/ if (NewState != FALSE) { /* 使能位置计数器方向状态输出 */ SFR_SET_BIT_ASM(QEIx->CTL0, QEI_CTL0_TXDIROUT_POS); } else { /* 禁止位置计数器方向状态输出 */ SFR_CLR_BIT_ASM(QEIx->CTL0, QEI_CTL0_TXDIROUT_POS); } } /** * 描述 配置QEI位置计数器方向状态。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * Direction: QEI位置计数器方向状态,取值范围为: * QEI_COUNT_DIRECT_REVERSE: 位置计数器方向为反向(-) * QEI_COUNT_DIRECT_FORWARD: 位置计数器方向为正向(+) * 返回 无。 */ void QEI_Location_Counter_Direction_Config (QEI_SFRmap* QEIx, uint32_t Direction) { /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); CHECK_RESTRICTION(CHECK_QEI_COUNT_DIRECT(Direction)); /*---------------- 设置QEI_CTL0寄存器TXDIR位 ----------------*/ if (Direction != QEI_COUNT_DIRECT_REVERSE) { /* 位置计数器方向为正向(+) */ SFR_SET_BIT_ASM(QEIx->CTL0, QEI_CTL0_TXDIR_POS); } else { /* 位置计数器方向为反向(-) */ SFR_CLR_BIT_ASM(QEIx->CTL0, QEI_CTL0_TXDIR_POS); } } /** * 描述 获取QEI位置计数器方向状态。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * 返回 1:位置计数器方向为正向(+),0:位置计数器方向为反向(-)。 */ FlagStatus QEI_Get_Location_Counter_Direction (QEI_SFRmap* QEIx) { /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); /*---------------- 读取QEI_CTL0寄存器TXDIR位 ----------------*/ if (QEIx->CTL0 & QEI_CTL0_TXDIR) { /* 位置计数器方向为正向(+) */ return SET; } else { /* 位置计数器方向为反向(-) */ return RESET; } } /** * 描述 配置低功耗 QEI 工作时钟。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * QEICLK: 低功耗 QEI 工作时钟,取值范围为: * QEI_CLK_INTLF: 选择INTLF作为低功耗QEI的工作时钟 * QEI_CLK_LP4M: 选择LP4M作为低功耗QEI的工作时钟 * 返回 无。 */ void QEI_LP_Source_Clock_Config(QEI_SFRmap* QEIx, uint32_t QEICLK) { uint32_t tmpreg; /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); CHECK_RESTRICTION(CHECK_LPQEI_CLK(QEICLK)); /*---------------- 配置QEI_CTL0寄存器LPCLK位 ----------------*/ tmpreg = QEICLK << QEI_CTL0_LPCLK_POS; QEIx->CTL0 = SFR_Config(QEIx->CTL0, ~QEI_CTL0_LPCLK, tmpreg); } /** * 描述 配置QEI工作时钟。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * PeripheralClock: QEI工作时钟,取值范围为: * QEI_SOURCE_SCLK: 工作时钟为SCLK * QEI_SOURCE_HFCLK: 工作时钟为HFCLK * QEI_SOURCE_LFCLK: 工作时钟为LFCLK * 返回 无。 */ void QEI_Source_Clock_Config (QEI_SFRmap* QEIx, uint32_t PeripheralClock) { /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); CHECK_RESTRICTION(CHECK_QEI_SOURCE(PeripheralClock)); /*---------------- 配置QEI_CTL1寄存器QEICLK位 ----------------*/ QEIx->CTL1 = SFR_Config (QEIx->CTL1, ~QEI_CTL1_QEICLK, PeripheralClock); } /** * 描述 配置数字滤波器输出使能。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * NewState: 数字滤波器输出使能状态,取值为TRUE 或 FALSE。 * 返回 无。 */ void QEI_Digital_Filter_Output_Enable (QEI_SFRmap* QEIx, FunctionalState NewState) { /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); CHECK_RESTRICTION(CHECK_FUNCTIONAL_STATE(NewState)); /*---------------- 配置QEI_CTL1寄存器QEIOUT位 ----------------*/ if (NewState != FALSE) { /* 使能QEAy/QEBy/INDXy引脚上的数字滤波器输出 */ SFR_SET_BIT_ASM(QEIx->CTL1, QEI_CTL1_QEIOUT_POS); } else { /* 禁止数字滤波器输出 */ SFR_CLR_BIT_ASM(QEIx->CTL1, QEI_CTL1_QEIOUT_POS); } } /** * 描述 配置QEI数字滤波器时钟分频。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * DigitalFilterClock: QEI数字滤波器时钟分频,对QEAy/QEBy/INDXy滤波时钟 * 进行分频,取值范围为: * QEI_DIGITAL_FILTER_CLK_DIV_1: 1:1分频 * QEI_DIGITAL_FILTER_CLK_DIV_2: 1:2分频 * QEI_DIGITAL_FILTER_CLK_DIV_4: 1:4分频 * QEI_DIGITAL_FILTER_CLK_DIV_16: 1:16分频 * QEI_DIGITAL_FILTER_CLK_DIV_32: 1:32分频 * QEI_DIGITAL_FILTER_CLK_DIV_64: 1:64分频 * QEI_DIGITAL_FILTER_CLK_DIV_128: 1:128分频 * QEI_DIGITAL_FILTER_CLK_DIV_256: 1:256分频 * 返回 无。 */ void QEI_Digital_Filter_Clock_Config (QEI_SFRmap* QEIx, uint32_t DigitalFilterClock) { /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); CHECK_RESTRICTION(CHECK_QEI_DIGITAL_FILTER_CLK(DigitalFilterClock)); /*---------------- 配置QEI_CTL1寄存器QEICK位 ----------------*/ QEIx->CTL1 = SFR_Config (QEIx->CTL1, ~QEI_CTL1_QEICK, DigitalFilterClock); } /** * 描述 配置A相和B相输入交换使能。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * NewState: A相和B相输入交换使能状态,取值为TRUE 或 FALSE。 * 返回 无。 */ void QEI_Swap_Phase_AB_Enable (QEI_SFRmap* QEIx, FunctionalState NewState) { /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); CHECK_RESTRICTION(CHECK_FUNCTIONAL_STATE(NewState)); /*---------------- 配置QEI_CTL1寄存器SWPAB位 ----------------*/ if (NewState != FALSE) { /* A相和B相输入交换 */ SFR_SET_BIT_ASM(QEIx->CTL1, QEI_CTL1_SWPAB_POS); } else { /* A相和B相输入不交换 */ SFR_CLR_BIT_ASM(QEIx->CTL1, QEI_CTL1_SWPAB_POS); } } /** * 描述 配置QEI 16位的Tx定时器。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * Counter: 16位的Tx定时器,取值为16位数值。 * 返回 无。 */ void QEI_Timer_Counter_Config (QEI_SFRmap* QEIx, uint16_t Counter) { uint32_t tmpreg; /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); /*---------------- 配置Tx_CNT寄存器TXCNT位 ----------------*/ tmpreg = Counter << QEI_TXCNT_TXCNT0_POS; QEIx->CNT = SFR_Config (QEIx->CNT, ~QEI_TXCNT_TXCNT, (uint32_t)tmpreg); } /** * 描述 获取QEI 16位的Tx定时器。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * 返回 16位的Tx定时器,取值为16位数值。 */ uint16_t QEI_Get_Timer_Counter (QEI_SFRmap* QEIx) { uint32_t tmpreg; /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); /*---------------- 读取Tx_CNT寄存器TXCNT位 ----------------*/ tmpreg = QEIx->CNT; return (uint16_t)tmpreg; } /** * 描述 配置QEI 16位的Tx周期寄存器。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * Period: 16位的Tx周期寄存器,取值为16位数值。 * 返回 无。 */ void QEI_Timer_Period_Config (QEI_SFRmap* QEIx, uint16_t Period) { uint32_t tmpreg; /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); /*---------------- 配置Tx_PPX寄存器PPX位 ----------------*/ tmpreg = Period << QEI_PPX_PPX0_POS; QEIx->PPX = SFR_Config (QEIx->PPX, ~QEI_PPX_PPX, (uint32_t)tmpreg); } /** * 描述 获取QEI 16位的Tx周期寄存器。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * 返回 16位的Tx周期寄存器,取值为16位数值。 */ uint16_t QEI_Get_Timer_Period (QEI_SFRmap* QEIx) { uint32_t tmpreg; /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); /*---------------- 读取Tx_PPX寄存器PPX位 ----------------*/ tmpreg = QEIx->PPX; return (uint16_t)tmpreg; } /** * 描述 配置QEI 16位的Tx预分频器。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * Prescaler: 16位的Tx预分频器,取值为16位数值。 * 返回 无。 */ void QEI_Timer_Prescaler_Config (QEI_SFRmap* QEIx, uint16_t Prescaler) { uint32_t tmpreg; /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); /*---------------- 配置Tx_PRSC寄存器TXPRSC位 ----------------*/ tmpreg = Prescaler << QEI_TXPRSC_TXPRSC0_POS; QEIx->PRSC = SFR_Config (QEIx->PRSC, ~QEI_TXPRSC_TXPRSC, (uint32_t)tmpreg); } /** * ##### 正交编码脉冲电路(QEI)功能配置函数定义结束 ##### */ /** * ##### 正交编码脉冲电路(QEI)中断管理函数 ##### */ /** * 描述 获取QEI中断标志。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * InterruptType: QEI中断事件,取值为下面提供的一个: * QEI_INT_COUNT_ERROR: 计数器Tx溢出中断事件 * QEI_INT_PHASE_ERROR: QEIy相位错误中断事件 * QEI_INT_TX_OVERFLOW: QEIy计数错误中断事件 * 返回 1:发生相应中断标志,0:未发生相应中断标志。 */ FlagStatus QEI_Get_INT_Flag (QEI_SFRmap* QEIx, uint32_t InterruptType) { uint32_t tmpreg; /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); CHECK_RESTRICTION(CHECK_QEI_INT_ONE_EVENT(InterruptType)); /*---------------- 读取QEI_CTL0寄存器对应位 ----------------*/ tmpreg = InterruptType << QEI_CTL0_CNTERRIF_POS; if (QEIx->CTL0 & tmpreg) { /* 发生相应中断标志 */ return SET; } else { /* 未发生相应中断标志 */ return RESET; } } /** * 描述 清除QEI中断标志。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * InterruptType: QEI中断事件,取值为下面的一个或多个组合: * QEI_INT_COUNT_ERROR: 计数器Tx溢出中断事件 * QEI_INT_PHASE_ERROR: QEIy相位错误中断事件 * QEI_INT_TX_OVERFLOW: QEIy计数错误中断事件 * 返回 : 清除QEI中断标志是否成功。 */ RetStatus QEI_Clear_INT_Flag (QEI_SFRmap* QEIx, uint32_t InterruptType) { uint32_t tmpreg; uint32_t tmpreg1; volatile uint32_t wait_flag=0x0000; /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); CHECK_RESTRICTION(CHECK_QEI_INT_EVENT(InterruptType)); /*---------------- 清除QEI_DIER寄存器对应位 ----------------*/ tmpreg1 = InterruptType << QEI_CTL0_CNTERRIF_POS; tmpreg = InterruptType << QEI_DIER_CNTERRIC_POS; QEIx->DIER |= tmpreg; while((QEIx->CTL0 & tmpreg1)&& (wait_flag != FLAG_TIMEOUT)) { wait_flag++; } QEIx->DIER &= ~tmpreg; if(wait_flag==FLAG_TIMEOUT) { return FAILURE; } return SUCCESS; } /** * 描述 配置QEI中断使能。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * InterruptType: QEI中断事件,取值为下面的一个或多个组合: * QEI_INT_COUNT_ERROR: 计数器Tx溢出中断事件 * QEI_INT_PHASE_ERROR: QEIy相位错误中断事件 * QEI_INT_TX_OVERFLOW: QEIy计数错误中断事件 * NewState: 中断使能状态,取值为TRUE 或 FALSE。 * 返回 无。 */ void QEI_Set_INT_Enable (QEI_SFRmap* QEIx,uint32_t InterruptType, FunctionalState NewState) { uint32_t tmpreg; /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); CHECK_RESTRICTION(CHECK_QEI_INT_EVENT(InterruptType)); CHECK_RESTRICTION(CHECK_FUNCTIONAL_STATE(NewState)); /*---------------- 配置QEI_DIER寄存器对应位 ----------------*/ tmpreg = InterruptType << QEI_DIER_CNTERRIE_POS; if (NewState != FALSE) { /* 使能中断 */ QEIx->DIER |= tmpreg; } else { /* 禁止中断 */ QEIx->DIER &= ~tmpreg; } } /** * 描述 获取计数器Tx溢出中断标志。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * 返回 1:Tx发生向上或者向下溢出,0:Tx未发生向上或者向下溢出。 */ FlagStatus QEI_Get_Counter_Overflow_INT_Flag (QEI_SFRmap* QEIx) { /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); /*---------------- 读取QEI_CTL0寄存器TXIF位 ----------------*/ if (QEIx->CTL0 & QEI_CTL0_TXIF) { /* Tx发生向上或者向下溢出 */ return SET; } else { /* Tx未发生向上或者向下溢出 */ return RESET; } } /** * 描述 获取QEI相位错误中断标志。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * 返回 1:QEI相位出现错误,0:QEI相位未出现错误。 */ FlagStatus QEI_Get_Phase_Error_INT_Flag (QEI_SFRmap* QEIx) { /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); /*---------------- 读取QEI_CTL0寄存器PHEIF位 ----------------*/ if (QEIx->CTL0 & QEI_CTL0_PHEIF) { /* QEI相位出现错误 */ return SET; } else { /* QEI相位未出现错误 */ return RESET; } } /** * 描述 获取QEI计数错误中断标志。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * 返回 1:QEI计数出现错误,0:QEI计数未出现错误。 */ FlagStatus QEI_Get_Count_Error_INT_Flag (QEI_SFRmap* QEIx) { /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); /*---------------- 读取QEI_CTL0寄存器PHEIF位 ----------------*/ if (QEIx->CTL0 & QEI_CTL0_CNTERRIF) { /* QEI计数出现错误 */ return SET; } else { /* QEI计数未出现错误 */ return RESET; } } /** * 描述 清除QEI Tx溢出中断标志。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * 返回 :清除QEI Tx溢出中断标志是否成功状态。 */ RetStatus QEI_Clear_Timer_Overflow_INT_Flag (QEI_SFRmap* QEIx) { volatile uint32_t wait_flag=0x0000; /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); /*-------------------- 设置QEI_DIER寄存器TXIC位 --------------------*/ SFR_SET_BIT_ASM(QEIx->DIER, QEI_DIER_TXIC_POS); while((QEIx->CTL0 & QEI_CTL0_TXIF)&& (wait_flag != FLAG_TIMEOUT)) { wait_flag++; } SFR_CLR_BIT_ASM(QEIx->DIER, QEI_DIER_TXIC_POS); if(wait_flag==FLAG_TIMEOUT) { return FAILURE; } return SUCCESS; } /** * 描述 清除QEI相位错误中断标志。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * 返回: 清除QEI相位错误中断标志是否成功状态。 */ RetStatus QEI_Clear_Phase_Error_INT_Flag (QEI_SFRmap* QEIx) { volatile uint32_t wait_flag=0x0000; /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); /*-------------------- 设置QEI_DIER寄存器PHEIC位 --------------------*/ SFR_SET_BIT_ASM(QEIx->DIER, QEI_DIER_PHEIC_POS); while((QEIx->CTL0 & QEI_CTL0_PHEIF)&& (wait_flag != FLAG_TIMEOUT)) { wait_flag++; } SFR_CLR_BIT_ASM(QEIx->DIER, QEI_DIER_PHEIC_POS); if(wait_flag==FLAG_TIMEOUT) { return FAILURE; } return SUCCESS; } /** * 描述 清除QEI计数错误中断标志。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * 返回:清除QEI计数错误中断标志是否成功状态。 */ RetStatus QEI_Clear_Counter_Error_INT_Flag (QEI_SFRmap* QEIx) { volatile uint32_t wait_flag=0x0000; /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); /*-------------------- 设置QEI_DIER寄存器CNTERRIC位 --------------------*/ SFR_SET_BIT_ASM(QEIx->DIER, QEI_DIER_CNTERRIC_POS); while((QEIx->CTL0 & QEI_CTL0_CNTERRIF)&& (wait_flag != FLAG_TIMEOUT)) { wait_flag++; } SFR_CLR_BIT_ASM(QEIx->DIER, QEI_DIER_CNTERRIC_POS); if(wait_flag==FLAG_TIMEOUT) { return FAILURE; } return SUCCESS; } /** * 描述 配置QEI Tx溢出中断使能。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * NewState: Tx溢出中断使能状态,取值为TRUE 或 FALSE。 * 返回 无。 */ void QEI_Timer_Overflow_INT_Enable (QEI_SFRmap* QEIx, FunctionalState NewState) { /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); CHECK_RESTRICTION(CHECK_FUNCTIONAL_STATE(NewState)); /*---------------- 配置QEI_DIER寄存器TXIE位 ----------------*/ if (NewState != FALSE) { /* 使能计数器Tx溢出中断 */ SFR_SET_BIT_ASM(QEIx->DIER, QEI_DIER_TXIE_POS); } else { /* 禁止计数器Tx溢出中断 */ SFR_CLR_BIT_ASM(QEIx->DIER, QEI_DIER_TXIE_POS); } } /** * 描述 配置QEI相位错误中断使能。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * NewState:相位错误中断使能状态,取值为TRUE 或 FALSE。 * 返回 无。 */ void QEI_Phase_Error_INT_Enable (QEI_SFRmap* QEIx, FunctionalState NewState) { /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); CHECK_RESTRICTION(CHECK_FUNCTIONAL_STATE(NewState)); /*---------------- 配置QEI_DIER寄存器PHEIE位 ----------------*/ if (NewState != FALSE) { /* 使能QEIy相位错误中断 */ SFR_SET_BIT_ASM(QEIx->DIER, QEI_DIER_PHEIE_POS); } else { /* 禁止QEIy相位错误中断 */ SFR_CLR_BIT_ASM(QEIx->DIER, QEI_DIER_PHEIE_POS); } } /** * 描述 配置QEI计数错误中断使能。 * 输入 QEIx: 指向QEI内存结构的指针,取值为QEI0_SFR。 * NewState:计数错误中断使能状态,取值为TRUE 或 FALSE。 * 返回 无。 */ void QEI_Counter_Error_INT_Enable (QEI_SFRmap* QEIx, FunctionalState NewState) { /* 参数校验 */ CHECK_RESTRICTION(CHECK_QEI_ALL_PERIPH(QEIx)); CHECK_RESTRICTION(CHECK_FUNCTIONAL_STATE(NewState)); /*---------------- 配置QEI_DIER寄存器CNTERRIE位 ----------------*/ if (NewState != FALSE) { /* 使能QEIy计数错误中断 */ SFR_SET_BIT_ASM(QEIx->DIER, QEI_DIER_CNTERRIE_POS); } else { /* 禁止QEIy计数错误中断 */ SFR_CLR_BIT_ASM(QEIx->DIER, QEI_DIER_CNTERRIE_POS); } } /** * ##### 正交编码脉冲电路(QEI)中断管理函数定义结束 ##### */