【Autosar】MCAL - DIO(NXP - S32K14x)

MCAL - DIO(NXP - S32K14x)

MCAL - 汇总

  • 配置工具:EB Tresos Studio
  • 芯片类型:S32K146

1. 概述

DIO模块提供接口读/写引脚的电平状态。

2. API

函数描述
Dio_ReadChannel读取通道电平状态
Dio_WriteChannel设置通道电平状态
Dio_ReadPort读取端口电平状态
Dio_WritePort设置端口电平状态
Dio_ReadChannelGroup读取通道组电平状态
Dio_WriteChannelGroup设置通道组电平状态
Dio_GetVersionInfo获取DIO模块版本号

3. 配置介绍

不管是端口通道通道组它的本质都只是配置引脚输出电平状态。

在这里插入图片描述

  • Port:端口
  • Channel:引脚
  • Channel Group:由同一端口中若干个连续引脚组成

DIO为以上3种都提供了对应的访问接口,个人认为这样的设计只是为了批量操作,比如我要一次性读出RTA中所有的引脚电平状态,调用Dio_ReadPort即可返回一个32位的数据,每一位代表对应的引脚电平状态。比如我要一次性读取同一个端口中指定的且连续的引脚,那可以调用Dio_ReadChannelGroup实现局部读取操作。

3.1 General

使能API

在这里插入图片描述

Dio Reverse Port Bits:翻转引脚

在这里插入图片描述

Dio Read Zero For Undefined Port Pins:未定义引脚电平状态读取返回为0

在这里插入图片描述

FUNC (Dio_PortLevelType, DIO_CODE) Dio_Gpio_ReadPort
(
    CONST(Dio_PortType, AUTOMATIC) PortId
)
{
    VAR(Dio_PortLevelType, AUTOMATIC) PortLevel = (Dio_PortLevelType) STD_LOW;

    /* @violates @ref Dio_Gpio_C_REF_2 Violates MISRA 2004 Rule 11.1, Cast from unsigned long to pointer.*/
    /* @violates @ref Dio_Gpio_C_REF_6 A cast should not be performed between a pointer type and an integral type. */
    PortLevel = (Dio_PortLevelType)((REG_READ32(GPIO_PDIR_ADDR32(PortId))));
#if (STD_ON == DIO_READZERO_UNDEFINEDPORTS)
    /* @violates @ref Dio_Gpio_C_REF_2 Violates MISRA 2004 Rule 11.1, Cast from unsigned long to pointer.*/
    /* @violates @ref Dio_Gpio_C_REF_6 A cast should not be performed between a pointer type and an integral type. */
    PortLevel =(Dio_PortLevelType)(PortLevel & Dio_aAvailablePinsForRead[PortId]);
#endif
#if (STD_ON == DIO_REVERSEPORTBITS)
    /* @violates @ref Dio_Gpio_C_REF_2 Violates MISRA 2004 Rule 11.1, Cast from unsigned long to pointer.*/
    /* @violates @ref Dio_Gpio_C_REF_6 A cast should not be performed between a pointer type and an integral type. */
    PortLevel = (Dio_PortLevelType)(Dio_Gpio_ReverseBits(PortLevel));
#endif

     return PortLevel;
}

3.2 DioPort

配置端口号,我用的是S32K146芯片,所以有5个端口:A(0)、B(1)、C(2)、D(3)、E(4)。

通过下面这段代码可以看到通过端口序号来计算出每个端口的起始地址:

/* @violates @ref Dio_Reg_eSys_Gpio_H_REF_1 Function-like macro defined */
#define GPIO_PDIR_ADDR32(port)  ((uint32)(GPIO_BASEADDR + GPIO_PDIR_OFFSET_ADDR32 + ((uint32)(port) * (uint32)0x40) ))

在这里插入图片描述

配置完以后可以在Dio_cfg.h中看到如下定义:

/* ---------- RTA ---------- */

/**
* @brief          Symbolic name for the port RTA.
*
*/
#define DioConf_DioPort_RTA  ((uint8)0x00U)

/* ---------- RTB ---------- */

/**
* @brief          Symbolic name for the port RTB.
*
*/
#define DioConf_DioPort_RTB  ((uint8)0x01U)

/* ---------- RTC ---------- */

/**
* @brief          Symbolic name for the port RTC.
*
*/
#define DioConf_DioPort_RTC  ((uint8)0x02U)

/* ---------- RTD ---------- */

/**
* @brief          Symbolic name for the port RTD.
*
*/
#define DioConf_DioPort_RTD  ((uint8)0x03U)

/* ---------- RTE ---------- */

/**
* @brief          Symbolic name for the port RTE.
*
*/
#define DioConf_DioPort_RTE  ((uint8)0x04U)

3.3 DioChannel

DioChannel中可以配置需要操作的引脚,如下图所示,我们在端口RTE下,配置了引脚3(RTE3):

在这里插入图片描述

配置完以后可以在Dio_cfg.h中看到如下定义,看到这个定义是不是似曾相识,在介绍Port模块的时候介绍过Pcr序号的计算方式,0x0083 = 131 = 4 * 32 + 3:

/** @violates @ref Dio_Cfg_H_REF_1 The used compilers use more than 31 chars for identifiers. */
#define  DioConf_DioChannel_out_put_test ((uint16)0x0083U)

3.4 DioChannelGroup

DioChannelGroup中我们可以配置通道组,如下所示,在RTE端口下,新建一个通道组

在这里插入图片描述
在这里插入图片描述

Dio Port Bit Number:通道个数

Dio Port Offset:起始通道号(偏移值)

Dio Port Mask:自动计算即可

如上图所示,我们的通道组配置范围是RTE2~RTE5。


参考资料:

S32K-RM.pdf - NXP

AUTOSAR_MCAL_DIO_UM[1].pdf - NXP

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值