S32K312 IIC DMA配置

本文详细介绍了如何在S32K312平台上使用DMA方式配置IIC通信,以减少中断,并提供了一个示例,包括Pins配置、时钟设置和LPI2C以及DMA_IP模块的初始化过程,以实现对ICM42670从设备的数据传输。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        本文主要描述S32K312使用DMA方式进行IIC通信的配置。在工程中,尽可能减少非必要的中断,然而,官方例程中给的demo,是使用LPI2C_USING_INTERRUPTS方式的。因此,本文记录了IIC的DMA方式配置过程。

        1、Pins配置

使用PTD13和PTD14作为LPI2C_0的SDA和SCL。

        2、 时钟使用默认的40MHz。

        3、外设需添加Lpi2c和Dma_Ip。

其中,Dma_Ip的配置如图所示:

Lpi2c的配置如图所示:

main.c文件

#include "Mcal.h"
#include "Clock_Ip.h"
#include "Lpi2c_Ip.h"
#include "Siul2_Port_Ip.h"

volatile int exit_code = 0;
/* User includes */
#define I2C_MASTER   0U
#define I2C_SYNC_TIMEOUT ( 10*100)

uint8 rxBuffer[16] = {0x00, };
uint8 txBuffer[4] = {0x75, 0x00, };

/*!
  \brief The main function for the project.
  \details The startup initialization sequence is the following:
 * - startup asm routine
 * - main()
*/
int main(void)
{
    /* Write your code here */
	Lpi2c_Ip_StatusType status;
	/* Init clock  */
	Clock_Ip_Init(&Clock_Ip_aClockConfig[0]);

	/* Init Pins */
	Siul2_Port_Ip_Init(NUM_OF_CONFIGURED_PINS0, g_pin_mux_InitConfigArr0);
	/* Init master module */
	Lpi2c_Ip_MasterInit(I2C_MASTER, &I2c_Lpi2cMasterChannel0_BOARD_InitPeripherals);

	Lpi2c_Ip_MasterSetSlaveAddr(I2C_MASTER, 0x69, false);
	/* Send data non-blocking */
	status = Lpi2c_Ip_MasterSendDataBlocking(I2C_MASTER, txBuffer, 1, false, I2C_SYNC_TIMEOUT);
	if (LPI2C_IP_SUCCESS_STATUS != status)
	{
		return -1;
	}

	status = Lpi2c_Ip_MasterReceiveDataBlocking(I2C_MASTER, rxBuffer, 1, true, I2C_SYNC_TIMEOUT);
	if (LPI2C_IP_SUCCESS_STATUS != status)
	{
		return -1;
	}

    for(;;)
    {
        if(exit_code != 0)
        {
            break;
        }
    }
    return exit_code;
}

测试中,我使用的从设备是icm42670,slave地址是0x69,发送0x75来获取型号。返回1字节0x67。

### S32K312 IIC (I²C) 读写操作指南 #### 使用DMA方式进行IIC通信的配置概述 对于S32K312微控制器,在进行IIC(I²C)总线上的数据传输时,可以采用DMA方式来优化性能并减少CPU占用率。这种方式能够有效降低因频繁处理中断而带来的开销[^2]。 #### 初始化设置 为了实现高效的IIC读写功能,初始化阶段至关重要。这包括但不限于: - 配置IIC模块的工作模式; - 设置波特率以匹配目标设备的要求; - 启用DMA通道并与指定的IIC端口关联; ```c // 假设已经完成了基本硬件资源分配和时钟使能 LPI2C_Type *base = LPI2C0; // 根据实际使用的外设选择合适的基地址 lpi2c_master_config_t masterConfig; /* 获取默认配置 */ LPI2C_MasterGetDefaultConfig(&masterConfig); /* 自定义配置参数 */ masterConfig.baudRate_Bps = 100000U; ... /* 应用自定义配置到选定的IIC接口 */ LPI2C_MasterInit(base, &masterConfig, GetFreq()); /* DMA相关初始化省略... */ ``` #### 数据发送函数设计 当准备向从机发送数据时,构建一个专门用于写入操作的功能显得尤为必要。此过程中需注意起始条件、停止条件以及应答信号的管理。 ```c status_t LPI2C_MasterTransferSend(LPI2C_Type *base, uint8_t deviceAddress, const uint8_t *txBuff, size_t txSize) { lpi2c_master_transfer_t transfer; /* 构建传输结构体 */ memset(&transfer, 0, sizeof(transfer)); transfer.flags = kLPI2C_TransferStartFlag | kLPI2C_TransferStopFlag; transfer.slaveAddress = deviceAddress << 1; transfer.direction = kLPI2C_Write; transfer.subaddress = 0; transfer.subaddressSize = 0; transfer.data = txBuff; transfer.dataSize = txSize; return LPI2C_MasterTransferNonBlocking(base, &handle, &transfer); } ``` #### 接收来自从机的数据 同样地,接收数据也需要精心规划。考虑到可能存在的多种情况——比如只读取固定长度的消息或是直到遇到特定终止符为止——灵活调整代码逻辑就变得非常重要了。 ```c status_t LPI2C_MasterTransferReceive(LPI2C_Type *base, uint8_t deviceAddress, uint8_t *rxBuff, size_t rxSize) { lpi2c_master_transfer_t transfer; /* 构建传输结构体 */ memset(&transfer, 0, sizeof(transfer)); transfer.flags = kLPI2C_TransferStartFlag | kLPI2C_TransferStopFlag; transfer.slaveAddress = deviceAddress << 1; transfer.direction = kLPI2C_Read; transfer.subaddress = 0; transfer.subaddressSize = 0; transfer.data = rxBuff; transfer.dataSize = rxSize; return LPI2C_MasterTransferNonBlocking(base, &handle, &transfer); } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值