简介:
在之前的贴子,我们使用S32DS初始化配置适配了 S32K146 FreeRTOS 和 UART 的收发功能,我们在此工程的基础上继续添加I2C外设的配置。S32K146 的 I2C 是重要通信接口。支持主从模式,有标准、快速等传输速率。具备中断与 DMA 功能,可提高效率,支持 7 位和 10 位从设备地址本次试验我们使用主模式标准传输速率和7位地址的基本配置来验证I2C功能。
以下是S32K146 的 LPI2C的框图,从中可以看出master/slave 接口内部是独立的设计,以及设计的时钟域(Bus/External/Function)的作用范围,根据框图对内部设计可以有个概要的理解。
时钟配置
时钟源使用内部SIRC的8M 时钟源


PIN脚配置
按照上的I2C 接口设计配置 PTA2/PTA3 为I2C功能引脚
I2C参数配置

S32DS 配置好上述参数后生成代码,会生成如下I2C初始化配置结构体。
lpi2c_master_user_config_t lpi2c0_MasterConfig0 = {
.slaveAddress = 50U,
.is10bitAddr = false,
.operatingMode = LPI2C_STANDARD_MODE,
.baudRate = 100000UL,
.transferType = LPI2C_USING_INTERRUPTS,
.dmaChannel = 0U,
.masterCallback = NULL,
.callbackParam = NULL
};
lpi2c_slave_user_config_t lpi2c0_SlaveConfig0 = {
.slaveAddress = 50U,
.is10bitAddr = false,
.operatingMode = LPI2C_STANDARD_MODE,
.slaveListening = true,
.transferType = LPI2C_USING_INTERRUPTS,
.dmaChannel = 0U,
.slaveCallback = NULL,
.callbackParam = NULL
};I2C 功能测试
时钟,PIN脚, I2C 参数配置完成后,我们添加i2c 命令来嗅探总线上的I2C设备节点都有哪些,我们通过I2C总线读取0x00寄存器的I2C总线是否对该地址进行了响应来确认总线节点的数量,有应答则认为总线上对应的I2C地址上有I2C设备,添加如下测试代码。
#include "sdk_project_config.h"
#include <stdio.h>
#include "littleshell.h"
/********************************************************************************************************
* Private Variable Definitions *
*******************************************************************************************************/
static lpi2c_master_state_t lpi2cstatus;
/********************************************************************************************************
* Global Function Declarations *
*******************************************************************************************************/
void i2c_init(void)
{
status_t ret;
/* Init lpi2c master */
ret = LPI2C_DRV_MasterInit(INST_LPI2C0,&lpi2c0_MasterConfig0,&lpi2cstatus);
INT_SYS_SetPriority(LPI2C0_Master_IRQn,2);
if(ret != STATUS_SUCCESS)
{
printf("I2c init failed %x \r\n",ret);
}
}
/********************************************************************************************************
* Private Function Declarations *
*******************************************************************************************************/
static int i2c_probe(char addr)
{
static uint8_t data;
status_t retVal,retVal1;
/* Set i2c slave address */
LPI2C_DRV_MasterSetSlaveAddr(INST_LPI2C0,(uint16_t)addr,false);
data = 0x00;
retVal1 = LPI2C_DRV_MasterSendDataBlocking(INST_LPI2C0,&data,1,false,100);
retVal = LPI2C_DRV_MasterReceiveDataBlocking(INST_LPI2C0,&data,1,true,100);
return (retVal == STATUS_SUCCESS && retVal1 == STATUS_SUCCESS) ? 1 : 0 ;
}
static void i2c_scan(uint8_t start_addr, uint8_t stop_addr)
{
printf(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F");
uint8_t pos = start_addr <= 0xF? 0x00: start_addr & 0xF;
for(; pos < stop_addr; pos++)
{
if((pos & 0xF) == 0)
{
printf("\r\n%02X: ", pos);
}
if(pos < start_addr)
{
printf(" ");
continue;
}
if( i2c_probe(pos) == 1)
{
printf("%02X", pos);
}
else
{
printf("--");
}
printf(" ");
}
printf("\r\n");
}
unsigned int i2c(char argc,char *argv[])
{
i2c_scan(0x00,0x7f);
return 0;
}
LTSH_FUNCTION_EXPORT(i2c,"i2c rest cimmand");本地的硬件上I2C0挂载了4个外设,对应的7bit 地址分别为 0x20/0x21/0x32/0x08,在shell 上输入i2c 测试命令嗅探到的节点信息如下:
输出结果跟实际硬件环境保持一致,说明I2C总线工作状态正常,至此就基于S32DS完成了I2C总线的驱动适配。
我要赚赏金
