我用的是FRDM-K25Z_demo例程,但是一直无法调通AT24c256的使用,AT24C256与1MHz I2C总线兼容,以下是我的主要配置(PTE18和19为SCL和SDA):
/*********************************************************************************************************
** 全局变量
*********************************************************************************************************/
const INT16U GusSCLDivider[64] = {
20, 22, 24, 26, 28, 30, 34, 40, 28, 32, 36, 40, 44, 48, 56, 68, 48, 56, 64, 72, 80, 88, 104, 128,
80, 96, 112, 128, 144, 160, 192, 240, 160, 192, 224, 256, 288, 320, 384, 480, 320, 384, 448, 512,
576, 640, 768, 960, 640, 768, 896, 1024, 1152, 1280, 1536, 1920, 1280, 1536, 1792, 2048, 2304,
2560, 3072, 3840};
/*
* 用于进行I2C通讯的全局变量
*/
volatile INT8U I2C_sla; /* I2C器件从地址 */
volatile INT32U I2C_suba; /* I2C器件内子地址 */
volatile INT8U I2C_suba_num; /* I2C子地址长度 */
volatile INT8U *I2C_buf; /* 数据缓冲区指针 */
volatile INT32U I2C_num; /* 要读取/写入的数据个数 */
volatile INT8U I2C_end; /* I2C总线结束标志 */
volatile INT8U I2C_restart; /* I2C总线结重复起始标? */
static INT8U I2C_irq_status; /* I2C中断读写操作控制 */
/* 1--读模式 */
/* 0--写模式 */
volatile INT8U I2C_sla_dir; /* 从机控制
* 1--读取操作
* 0--写操作
*/
/*********************************************************************************************************
** Function name: i2c0Init
** Descriptions: I2C初始化
** input parameters: none
** output parameters: none
** Returned value: none
** Created by: Li Xiang
** Created Date: 2012-12-14
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
*********************************************************************************************************/
void i2c0Init(void)
{
INT32U ulBaudRate = 0;
INT32U i = 0;
INT32U j = 0;
#if 1
PORT_ENABLE_CLK(MKL_PORTE);
IO_FUN_SEL(MKL_PORTE,18,4); /* SCL初始化 */
IO_FUN_SEL(MKL_PORTE,19,4); /* SDA初始化 */
#endif
#if 0
PORT_ENABLE_CLK(MKL_PORTB);
IO_FUN_SEL(MKL_PORTB,0,2); /* SCL初始化 */
IO_FUN_SEL(MKL_PORTB,1,2); /* SDA初始化 */
#endif
#if 0
PORT_ENABLE_CLK(MKL_PORTB);
IO_FUN_SEL(MKL_PORTB,2,2); /* SCL初始化 */
IO_FUN_SEL(MKL_PORTB,3,2); /* SDA初始化 */
#endif
#if 0
PORT_ENABLE_CLK(MKL_PORTC);
IO_FUN_SEL(MKL_PORTC,8,2); /* SCL初始化 */
IO_FUN_SEL(MKL_PORTC,9,2); /* SDA初始化 */
#endif
i2c0ClkEnable(); /* 打开I2C0时钟 */
#if (I2C0_MODE == I2C_MASTER)
ulBaudRate = SystemBusClock / (I2C0_BAUD_RATE << I2C0_MUL); /* 计算SCL divider */
for(j = 0; j < I2C0_BT_ERROR; j++) {
for(i = 0; i < 64; i++) {
if(((ulBaudRate - GusSCLDivider[i]) <= j) || ((GusSCLDivider[i] - ulBaudRate) <= j) ){
break;
}
}
if (i != 64) {
break;
}
}
if (j == I2C0_BT_ERROR) {
printf("I2C0 BT SET ERROR\r\n");
while(1);
}
I2C0_F = (I2C0_MUL << 6) | i; /* 配置波特率 */
I2C0_C1 |= (1 << 5); /* 选择主机模式 */
#endif
#if (I2C0_MODE == I2C_SLAVER)
I2C0_C1 |= (1 << 7)| /* 响应地址 */
(I2C0_SLAVER_ADDRESS_MODE << 6)| /* 从机地址类型定义 */
(I2C0_SLAVER_ADR_MATCH << 3)| /* 地址匹配设置 */
((I2C0_SLAVER_ADR >> 8) & 7UL); /* 高位地址设置 */
I2C0_A1 = I2C0_SLAVER_ADR; /* 从机地址定义 */
I2C0_RA = I2C0_RANGE_SLAVER_ADR;
// I2C0_C1 &= ~(1 << 5); /* 选择从机模式 */
#endif
// I2C0_C1 |= (1 << 5); /* 发送起始位与停止位 */
// I2C0_C1 &= ~(1 << 5); /* 初始化总线 */
I2C0_S |= (1 << 1)| /* 清除标志 */
(1 << 4);
I2C0_FLT |= 1 << 6;
I2C0_C1 |= (1 << 7)| /* 使能I2C0 */
(1 << 6); /* 使能IRQ */
I2C0_FLT |= 1 << 5; /* 使能停止中断 */
NVIC_EnableIRQ(I2C0_IRQn);
NVIC_SetPriority(I2C0_IRQn,3); /* 用户自己定义 */
}
/*********************************************************************************************************
** Function name: i2c0SendByte
** Descriptions: I2C0发送单字节函数
** input parameters: sla:从机地址 dat:数据缓冲区指针
** output parameters: none
** Returned value: none
** Created by: Li Xiang
** Created Date: 2012-12-14
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
*********************************************************************************************************/
INT8U i2c0SendByte(INT8U sla, INT8U *dat)
{
I2C_sla = sla; /* 写操作的器件地址 */
I2C_buf = dat; /* 待发送的数据缓冲区指针 */
I2C_num = 1; /* 发送1字节数据 */
I2C_suba_num = 0; /* 无子地址 */
I2C_sla_dir = 0; /* 写操作 */
I2C_irq_status = 0; /* 写模式 */
I2C_end = 0;
I2C0_C1 |= (1 << 5); /* 发送起始位,主模式 */
I2C0_D = I2C_sla & 0xFE; /* 将写地址写入数据寄存器 */
I2C0_C1 |= (1 << 4); /* 发送模式 */
return( Wait_I2c_End(20));
}
/*********************************************************************************************************
** Function name: i2c0WriteNByte
** Descriptions: I2C0发送多字节函数
** input parameters: sla:从机地址 suba_type: 子地址类型
** suba:子地址 s:数据缓冲区指针 num:数据长度
** output parameters: none
** Returned value: none
** Created by: Li Xiang
** Created Date: 2012-12-14
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
*********************************************************************************************************/
INT8U i2c0WriteNByte(INT8U sla, INT8U suba_type, INT32U suba, INT8U *s, INT32U num)
{
I2C_sla = sla; /* 写操作的器件地址 */
I2C_suba = suba; /* 子地址类型 */
I2C_num = num; /* 发送n字节数据 */
I2C_suba_num = suba_type; /* 子地址类型 */
I2C_buf = s; /* 待发送的数据缓冲区指针 */
I2C_sla_dir = 0; /* 写操作 */
I2C_irq_status = 0; /* 写模式 */
I2C_end = 0;
I2C_restart = 0;
I2C0_C1 |= (1 << 5); /* 发送起始位,主模式 */
I2C0_C1 |= (1 << 4); /* 发送模式 */
I2C0_D = I2C_sla & 0xFE; /* 将写地址写入数据寄存器 */
return( Wait_I2c_End(20));
}
/*********************************************************************************************************
** Function name: i2c0ReadNByte
** Descriptions: I2C0接收多字节函数
** input parameters: sla:从机地址 suba_type: 子地址类型
** suba:子地址 s:接收数据缓冲区指针 num:数据长度
** output parameters: none
** Returned value: none
** Created by: Li Xiang
** Created Date: 2012-12-14
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
*********************************************************************************************************/
INT8U i2c0ReadNByte(INT8U sla, INT8U suba_type, INT32U suba, INT8U *s, INT32U num)
{
I2C_sla = sla; /* 写操作的器件地址 */
I2C_suba = suba; /* 子地址类型 */
I2C_num = num; /* 发送n字节数据 */
I2C_suba_num = suba_type; /* 子地址类型 */
I2C_buf = s; /* 接收数据缓冲区指针 */
I2C_sla_dir = 1; /* 写操作 */
I2C_irq_status = 0; /* 写模式 */
I2C_end = 0;
I2C_restart = 0;
I2C0_C1 |= (1 << 5); /* 发送起始位,主模式 */
I2C0_C1 |= (1 << 4); /* 发送模式 */
I2C0_D = I2C_sla & 0xFE; /* 将写地址写入数据寄存器 */
Wait_I2c_Restart(20);
I2C0_D = (I2C_sla & 0xFE) + 1; /* 将读地址写入数据寄存器 */
return( Wait_I2c_End(20));
}
|