目 录CONTENT

文章目录

NXP实战笔记(八):S32K3xx基于RTD-SDK在S32DS上配置LCU实现ABZ解码

moke
2024-07-10 / 0 评论 / 0 点赞 / 99 阅读 / 0 字

1、概述

        碰到光电编码器、磁编码器等,有时候传出来的位置信息为ABZ的方式,在S32K3里面通过TRGMUX、LCU、Emios结合的方式可以实现ABZ解码。

        官方推荐方式为

也有另外一种图示

        ABZ的是什么在前面的正交编码文章里面已经有了叙述,S32K芯片本身存在一定的缺陷,例如Z信号的接入,Z信号是每转动一个机械周期会发出一个脉冲,此时清除AB信号的脉冲计数值,防止累计误差,但是S32K3里面此功能并没有实现,需要通过外接emios触发边沿检测中断,在中断里面清除AB的计数器。

ABZ并显示如下

Trgmux的作用是功能路由

LCU进行真正的信号解析

Emios仅仅用来边沿计数或周期测量。

通常测量一段时间内的脉冲个数,叫做测频法,也就是M法

测量若干个脉冲的周期时间叫测周法,也就是T法

为了提高转速精度的测量,高速时候采用测频法,低速采用测周法。

        对LCU来说,正交信号的上升沿与下降沿到达emios的时候均会计数,也就是通过示波器测出来的A或者B上升沿的4倍才是脉冲数,正转A计数,反转B计数。以此A-B既可以测量位置,又可以测量旋转方向。

LCU实现原理

        从上图可以看出I0、I1作为ENC_PHA\B输入,经过LCU的LC模块做延时再输出其中下图的4倍,边沿也就是出来了,其实到emios的已经经过LCU处理后的了,只不过开发者无法监测而已。

2、SDK配置

2.1、IO配置

按照顺序,先把IO口与Trgnux连接起来

2.2、TRGMUX配置

使能TRGMUX

TRGMUX实例,针对S32K312这个只有一个。

将IO口路由到LCU,将IO输出到LCU

2.3、LCU配置

使能LCU模块,并开启LCU的同步与异步功能。

将解码功能放置在LCU1上

LCU的输入,从之前原理解析图里面可以看出,输入为I0\1、O0\1,所以下面的配置就逻辑清晰了

其中的Hardware input 与Mux Select分别表示如下图

LCU的输出

LUT的值,其实现在也不是特别明白,这个值的来源

2.4、Trgmux配置

 将LCU的输出路由到Emios通道实现边沿计数

2.5、Emios配置

2.6、代码实现

初始化

/*Init Io*/
Siul2_Port_Ip_Init(NUM_OF_CONFIGURED_PINS0, g_pin_mux_InitConfigArr0);
/*Init Trgmux*/
Trgmux_Ip_Init(&Trgmux_Ip_xTrgmuxInitPB);
    /* Initialize Lcu */
    Lcu_Ip_Init(&Lcu_Ip_xLcuInitPB);
    /* Initialize Emios0 */
    Emios_Mcl_Ip_Init(0U, &Emios_Mcl_Ip_0_Config_BOARD_INITPERIPHERALS);
mios_Icu_Ip_Init(0U, &eMios_Icu_Ip_0_Config_PB);
    Emios_Icu_Ip_EnableEdgeCount(0u, 5U);       /*A Phase*/
    Emios_Icu_Ip_EnableEdgeCount(0u, 6U);       /*B Phase*/
    /* Direct access register setting is needed due to missing feature in Configuration Tools. */
    /* It is a known issue and will be fix in the later RTD releases */
    IP_EMIOS_0->CH.UC[5].A = (uint32_t)0x1000U; /*0x1000 = 4096  this is main max count is 4096*/
    IP_EMIOS_0->CH.UC[6].A = (uint32_t)0x1000U;
    /* Assign eMIOS0_CH5 input to TRGMUX_OUT_36 */
    IP_SIUL2->IMCR[53] = SIUL2_IMCR_SSS(3U);             /*IMCR53  53 = 565%512 = 53 Reference S32K312_IOMUC.xlsx(S32K312_Input Muxing) */
    /* Assign eMIOS0_CH6 input to TRGMUX_OUT_37 */
    IP_SIUL2->IMCR[54] = SIUL2_IMCR_SSS(3U);             /*IMCR53  54 = 566%512 = 54 SIUL = System Integration Unit Lite2 (SIUL2)*/

    Lcu_Ip_SyncOutputValueType EncLcuEnable[6U];
    EncLcuEnable[0].LogicOutputId = LCU_LOGIC_OUTPUT_6;  /* Logic Instance 6  SDK configer ID  this is logic ID*/
    EncLcuEnable[0].Value = 1U;
    EncLcuEnable[1].LogicOutputId = LCU_LOGIC_OUTPUT_7;
    EncLcuEnable[1].Value = 1U;
    EncLcuEnable[2].LogicOutputId = LCU_LOGIC_OUTPUT_8;
    EncLcuEnable[2].Value = 1U;
    EncLcuEnable[3].LogicOutputId = LCU_LOGIC_OUTPUT_9;
    EncLcuEnable[3].Value = 1U;
    Lcu_Ip_SetSyncOutputEnable(EncLcuEnable, 4U);

执行代码

 counterCW   = (uint16_t)(Emios_Icu_Ip_GetEdgeNumbers(0U, 5U));     /* CW  counter */
 counterCCW  = (uint16_t)(Emios_Icu_Ip_GetEdgeNumbers(0U, 6U));     /* CCW counter */

清除计数值,在ICU里面已经有介绍,使用函数为

  Emios_Icu_Ip_ResetEdgeCount(0,5);   /*Clear A Edge Count*/
  Emios_Icu_Ip_ResetEdgeCount(0,6);   /*Clear B Edge Count*/

测试结果如下,边沿计数准确无误。

博主关闭了所有页面的评论