HC32F4不依赖中断的定时器外部计数模式,建议使用TIMA 的TRIG外部输入,以及正交编码计数模式,这两个都是外部计数,正交编码模式为正反向计数,计数器均为16位,测试使用 TIMA_3 电机编码器 正交编码器 TIMA_6_TRIG 外部计数器。
/*************************************************************************************************************************
* 函数 : void BSP_OuaEncoderInit(void)
* 功能 : 正交编码计数器初始化(TIMA_3)
* 参数 : 无
* 返回 : 无
* 依赖 : 底层宏定义
* 作者 : cp1300@139.com
* 时间 : 2022-10-20
* 最后修改时间 : 2022-10-20
* 说明 : 需要先初始化定时器
*************************************************************************************************************************/
void BSP_OuaEncoderInit(void)
{
static IRQn_Type INT_IRQ_n = INTC_MALLOC_INVALID_IRQn; //值允许0-31,超出的算无效值
Encoder_BottomHardwareIoInit(); //编码器IO初始化
SYS_DeviceClockEnable(DEV_TIMERA_3, TRUE); //使能timA_3时钟
TMRA3->BCSTR = 0; //关闭定时器
TMRA3->BCSTR = BIT1; //溢出后继续,锯齿波模式,向上计数,定时器关闭
TMRA3->ICONR = 0; //关闭所有匹配中断
TMRA3->ECONR = 0; //事件输出关闭
TMRA3->FCONR = 0; //关闭滤波
TMRA3->CNTER = 0x8000; //计数器值
TMRA3->PERAR = U16_MAX; //周期基准值-计数器到这个值就溢出
TMRA3->HCONR = 0; //硬件触发事件选择寄存器
TMRA3->HCUPR = BIT7; //TIMA_<t>_CLKB端口为高电平时, TIMA_<t>_CLKA端口上采样到下降沿 条件匹配时,硬件递加有效
TMRA3->HCDOR = BIT6; //TIMA_<t>_CLKB端口为高电平时, TIMA_<t>_CLKA端口上采样到上升沿 条件匹配时,硬件递减有效
//如果直接使用上溢出或者下溢出,可能存在竞争冲突,导致编码器值异常突变,此处使用2个比较寄存器,提前进行将编码器值复位,防止溢出
TMRA3->CMPAR[0] = 3000; //下比较直,大概提前一圈;
TMRA3->CMPAR[1] = 0xFFFF-3000; //上比较值,大概提前一圈;
TMRA3->ICONR = BIT0 | BIT1; //使能2个比较中断
if (INT_IRQ_n == INTC_MALLOC_INVALID_IRQn) //无效,没有申请
{
INT_IRQ_n = INTC_MallocIRQn(); //获取空闲的中断服务号(只支持0-31),如果返回Int032_IRQn则为无效
}
if (INT_IRQ_n != INTC_MALLOC_INVALID_IRQn) //申请成功了
{
INFO_S("TMRA3获取中断服务号:%d\r\n", INT_IRQ_n);
INTC_RegisterIRQHandler(INT_IRQ_n, SYS_INT_TMRA3_CMP, TMRA3_CMP_IRQHandler); //注册中断服务程序
INTC_IntEnable(INT_IRQ_n, TRUE); //中断线开关,只支持0-31中断线开关控制
NVIC_ClearPendingIRQ(INT_IRQ_n);
NVIC_SetPriority(INT_IRQ_n, 3);
NVIC_EnableIRQ(INT_IRQ_n);
}
else
{
ERROR_S("TMRA3获取中断服务号失败\r\n");
}
TMRA3->BCSTR |= BIT0; //启动定时器
}
/*************************************************************************************************************************
* 函数 : void BSP_OuaEncoderReset(void)
* 功能 : 正交编码计数器复位
* 参数 : 无
* 返回 : 无
* 依赖 : 底层宏定义
* 作者 : cp1300@139.com
* 时间 : 2022-10-22
* 最后修改时间 : 2022-10-22
* 说明 :
*************************************************************************************************************************/
void BSP_OuaEncoderReset(void)
{
TMRA3->BCSTR &= ~BIT0; //定时器关闭
TMRA3->CNTER = 0x8000;
sg_EncoderOverCount = 0;
TMRA3->BCSTR |= BIT0; //启动定时器
}
/*************************************************************************************************************************
* 函数 : int BSP_GetOuaEncoderCount(void)
* 功能 : 获取正交编码器值
* 参数 : 无
* 返回 : 编码器值
* 依赖 : 底层宏定义
* 作者 : cp1300@139.com
* 时间 : 2022-10-22
* 最后修改时间 : 2022-10-22
* 说明 : 可能存在竞争冲突,就是溢出的瞬间调用此值,但是可能性很低
*************************************************************************************************************************/
int BSP_GetOuaEncoderCount(void)
{
OS_CRITICAL_SR_VAL;
int temp;
int count;
OS_EnterCriticalSection(); //进入临界区
temp = TMRA3->CNTER;
count = sg_EncoderOverCount;
OS_LeaveCriticalSection(); //退出临界区
temp -= 0x8000;
count += temp;
return count;
}
/*************************************************************************************************************************
* 函数 : void BSP_OuaEncoderPowerDown(void)
* 功能 : 正交编码计数器掉电
* 参数 : 无
* 返回 : 无
* 依赖 : 底层宏定义
* 作者 : cp1300@139.com
* 时间 : 2023-01-04
* 最后修改时间 : 2023-01-04
* 说明 : 进入低功耗前,关闭定时器,降低功耗
*************************************************************************************************************************/
void BSP_OuaEncoderPowerDown(void)
{
TMRA3->BCSTR &= ~BIT0; //关闭定时器
SYS_DeviceClockEnable(DEV_TIMERA_3, FALSE); //关闭timA_3时钟
}
/*************************************************************************************************************************
* 函数 : void BSP_OuaEncoderPowerUp(void)
* 功能 : 正交编码计数器上电(需要先初始化)
* 参数 : 无
* 返回 : 无
* 依赖 : 底层宏定义
* 作者 : cp1300@139.com
* 时间 : 2023-01-04
* 最后修改时间 : 2023-01-04
* 说明 :
*************************************************************************************************************************/
void BSP_OuaEncoderPowerUp(void)
{
SYS_DeviceClockEnable(DEV_TIMERA_3, TRUE); //开启timA_3时钟
TMRA3->BCSTR |= BIT0; //开启定时器
}
//下面是外部计数
//TIMA6上溢出中断
static u32 sg_TIMA6_OverCount = 0; //TIMA6计数器溢出计数器
static void TMRA6_OVER_IRQHandler(void)
{
int temp;
if (TMRA6->BCSTR & BIT14) //上溢出
{
sg_TIMA6_OverCount += 65536;
INFO_S("TIMA6上溢出%d\r\n", sg_TIMA6_OverCount);
}
TMRA6->BCSTR &= ~BIT14; //清除状态标识
}
/*************************************************************************************************************************
* 函数 : void BSP_RotationInit(void)
* 功能 : 转动计数器初始化
* 参数 : 无
* 返回 : 无
* 依赖 : 底层宏定义
* 作者 : cp1300@139.com
* 时间 : 2022-12-30
* 最后修改时间 : 2022-12-30
* 说明 : PB15 TIMA6_TRIG FUN5 同步计数模式
* 注意:CPU在STOP模式下,HCLK会被关闭,导致TRIG计数失效
*************************************************************************************************************************/
void BSP_RotationInit(void)
{
static IRQn_Type INT_IRQ_n = INTC_MALLOC_INVALID_IRQn; //值允许0-31,超出的算无效值
u32 PCLK1_Speed;
u32 TimeClockDir;
SYS_DeviceClockEnable(DEV_TIMERA_6, TRUE); //使能TIMERA_6时钟
TMRA6->CNTER = 0; //计数器复位
TMRA6->BCSTR = BIT12 | (10 << 4) | BIT1; //定时器关闭,开启上溢出复位,锯齿波模式,向上计数
TMRA6->FCONR = (3 << 1) | BIT0; //TRIG输入滤波使能,使用PCLK/64 作为滤波基准时钟
TMRA6->HCUPR = BIT9; //TRIG端口采集到下降沿,硬件递增有效
HallRotation_IoInit(); //IO初始化
if (INT_IRQ_n == INTC_MALLOC_INVALID_IRQn) //无效,没有申请
{
INT_IRQ_n = INTC_MallocIRQn(); //获取空闲的中断服务号(只支持0-31),如果返回Int032_IRQn则为无效
}
if (INT_IRQ_n != INTC_MALLOC_INVALID_IRQn) //申请成功了
{
INFO_S("TMRA6获取中断服务号:%d\r\n", INT_IRQ_n);
INTC_RegisterIRQHandler(INT_IRQ_n, SYS_INT_TMRA6_OVF, TMRA6_OVER_IRQHandler); //注册中断服务程序
INTC_IntEnable(INT_IRQ_n, TRUE); //中断线开关,只支持0-31中断线开关控制
NVIC_ClearPendingIRQ(INT_IRQ_n);
NVIC_SetPriority(INT_IRQ_n, 4);
NVIC_EnableIRQ(INT_IRQ_n);
}
else
{
ERROR_S("TMRA6获取中断服务号失败\r\n");
}
TMRA6->BCSTR |= BIT0; //计数器启动
}
/*************************************************************************************************************************
* 函数 : void BSP_RotationPowerDown(void)
* 功能 : 转动计数器掉电(降低功耗)
* 参数 : 无
* 返回 : 无
* 依赖 : 底层宏定义
* 作者 : cp1300@139.com
* 时间 : 2022-01-04
* 最后修改时间 : 2022-01-04
* 说明 :
*************************************************************************************************************************/
void BSP_RotationPowerDown(void)
{
TMRA6->BCSTR &= ~BIT0; //关闭计数器
SYS_DeviceClockEnable(DEV_TIMERA_6, FALSE); //关闭TIMERA_6时钟
}
/*************************************************************************************************************************
* 函数 : void BSP_RotationPowerUp(void)
* 功能 : 转动计数器上电(需要先初始化)
* 参数 : 无
* 返回 : 无
* 依赖 : 底层宏定义
* 作者 : cp1300@139.com
* 时间 : 2022-01-04
* 最后修改时间 : 2022-01-04
* 说明 :
*************************************************************************************************************************/
void BSP_RotationPowerUp(void)
{
SYS_DeviceClockEnable(DEV_TIMERA_6, TRUE); //使能TIMERA_6时钟
TMRA6->BCSTR |= BIT0; //计数器启动
}
/*************************************************************************************************************************
* 函数 : u32 BSP_GetRotationCount(void)
* 功能 : 获取转动计数器值(1圈增加4次)
* 参数 : 无
* 返回 : 转动计数器值
* 依赖 : 底层宏定义
* 作者 : cp1300@139.com
* 时间 : 2022-12-30
* 最后修改时间 : 2022-12-30
* 说明 : 需要初始化TIMA6
*************************************************************************************************************************/
u32 BSP_GetRotationCount(void)
{
u32 count = sg_TIMA6_OverCount + TMRA6->CNTER;
return count;
}
/*************************************************************************************************************************
* 函数 : u32 BSP_ClearRotationCount(void)
* 功能 : 转动计数器值
* 参数 : 无
* 返回 : 转动计数器值
* 依赖 : 底层宏定义
* 作者 : cp1300@139.com
* 时间 : 2022-12-30
* 最后修改时间 : 2022-12-30
* 说明 : 需要初始化TIMA6
*************************************************************************************************************************/
void BSP_ClearRotationCount(void)
{
TMRA6->BCSTR &= ~BIT0; //计数器关闭
TMRA6->CNTER = 0; //计数器值复位
sg_TIMA6_OverCount = 0; //溢出计数值清零
TMRA6->BCSTR |= BIT0; //计数器启动
}
————————————————
版权声明:本文为CSDN博主「cp1300」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/cp1300/article/details/128968531
|