我使用例程中的IIC程序,直接不改动例程,能在开发板上正常跑起来,但是,我现在要把数据写到EEPROM中去,如果使用例程中的读写函数:
i2c0WriteNByte(0xA0, ONE_BYTE_SUBA, 0x00, ucData, 10); /* 写数据操作 */
i2c0ReadNByte(0xA0, ONE_BYTE_SUBA, 0x00, ucData, 10); /* 读数据操作 */
那么,我该如何往EEPROM中的固定地址写数据呢?如果使用上面这两个函数,应该都是从0地址开始读写吧?
要怎样改才能使我能从EEPROM中的任意地址读取数据呢?
如下是实例代码中,关于IIC的部分:
/*********************************************************************************************************
** 全局变量
*********************************************************************************************************/
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--写操作
*/
void i2cDelay (INT32U ulTime)
{
INT32U i;
i = 0;
while (ulTime--) {
for (i = 0; i < 5000; i++);
}
}
/*********************************************************************************************************
** Function name: Wait_I2c_End
** Descriptions: 软件延时,提供给I2C总线等待超时使用
** input parameters: dly 延时参数,值越大,延时越久
** Output parameters: NONE
** Returned value: NONE
*********************************************************************************************************/
static INT8U Wait_I2c_End(INT32U dly)
{
INT32U i = 0;
if( I2C_end == 1 ) return (1);
for(; dly > 0; dly--)
for(i = 0; i<5000; i++)
{
if( I2C_end == 1 ) return (1);
}
return (0);
}
/*********************************************************************************************************
** Function name: Wait_I2c_Restart
** Descriptions: 等待I2C发送Restart
** input parameters: dly 延时参数,值越大,延时越久
** Output parameters: NONE
** Returned value: NONE
*********************************************************************************************************/
static INT8U Wait_I2c_Restart(INT32U dly)
{
INT32U i = 0;
for(; dly > 0; dly--) {
for(i = 0; i< 5000; i++) {
if( I2C_restart == 1 ) {
for(i = 0; i< 200; i++) {
}
return (1);
}
}
}
return (0);
}
/*********************************************************************************************************
** Function name: i2c0ClkEnable
** Descriptions: I2C时钟使能
** input parameters: none
** output parameters: none
** Returned value: none
** Created by: Li Xiang
** Created Date: 2012-12-14
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
*********************************************************************************************************/
__INLINE void i2c0ClkEnable(void)
{
SIM_SCGC4 |= SIM_SCGC4_I2C0_MASK;
}
/*********************************************************************************************************
** Function name: i2c0ClkDisable
** Descriptions: I2C时钟禁能
** input parameters: none
** output parameters: none
** Returned value: none
** Created by: Li Xiang
** Created Date: 2012-12-14
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
*********************************************************************************************************/
__INLINE void i2c0ClkDisable(void)
{
SIM_SCGC4 &= ~SIM_SCGC4_I2C0_MASK;
}
/*********************************************************************************************************
** Function name: i2c1ClkEnable
** Descriptions: I2C时钟使能
** input parameters: none
** output parameters: none
** Returned value: none
** Created by: Li Xiang
** Created Date: 2012-12-14
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
*********************************************************************************************************/
__INLINE void i2c1ClkEnable(void)
{
SIM_SCGC4 |= SIM_SCGC4_I2C1_MASK;
}
/*********************************************************************************************************
** Function name: i2c1ClkDisable
** Descriptions: I2C时钟禁能
** input parameters: none
** output parameters: none
** Returned value: none
** Created by: Li Xiang
** Created Date: 2012-12-14
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
*********************************************************************************************************/
__INLINE void i2c1ClkDisable(void)
{
SIM_SCGC4 &= ~SIM_SCGC4_I2C1_MASK;
}
/*********************************************************************************************************
** 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 0
PORT_ENABLE_CLK(MKL_PORTE);
IO_FUN_SEL(MKL_PORTE,24,5); /* SCL初始化 */
IO_FUN_SEL(MKL_PORTE,25,5); /* 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 1
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
) <= j) || ((GusSCLDivider - ulBaudRate) <= j) ){
break;
}
}
if (i != 64) {
break;
}
}
if (j == I2C0_BT_ERROR) {
printf("I2C0 BT SET ERROR
");
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));
}
/*********************************************************************************************************
** Function name: I2C0_IRQHandler
** 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 I2C0_IRQHandler(void)
{
if (I2C0_FLT & (1 << 6)) {
I2C_end = 1;
I2C0_FLT |= (1 << 6); /* 清零停止中断标志 */
I2C0_S |= (1 << 1); /* 清零中断标志 */
return; /* 中断返回 */
}
I2C0_S |= (1 << 1); /* 清零中断标志 */
#if (I2C0_MODE == I2C_MASTER)
switch (I2C_irq_status) {
case 0: /* 发送模式 */
if (I2C0_S & 0x01) { /* 应答检测 */
I2C_end = 1; /* 无应答,传输结束 */
I2C0_C1 &= ~(1 << 5); /* 发送STOP */
}
if (I2C_suba_num == TWO_BYTE_SUBA) { /* 两字节从机子地址处理 */
I2C0_D = ((I2C_suba >> 8) & 0xff);
I2C_suba_num --;
} else if (I2C_suba_num == ONE_BYTE_SUBA) { /* 单字节从机子地址处理 */
I2C0_D = (I2C_suba & 0xff);
I2C_suba_num --;
} else if (I2C_suba_num == NONE_SUBA) { /* 无从机子地址处理 */
if (I2C_sla_dir == 1) { /* 主机读操作处理 */
I2C0_C1 |= 1 << 2; /* 发送Restart */
I2C_suba_num --;
I2C_restart = 1; /* 重复起始信号标志置位 */
} else {
if (I2C_num > 0) { /* 发送数据 */
I2C0_D = *I2C_buf++;
I2C_num --;
} else {
I2C0_C1 &= ~(1 << 5); /* 发送STOP */
}
}
} else {
I2C0_C1 &= ~(1 << 4); /* 转为接收模式 */
I2C_irq_status = 1;
*I2C_buf = I2C0_D;
}
break;
case 1: /* 接收模式 */
I2C_num--;
if (I2C_num == 1) { /* 接收最后一个字节,返回NACK */
I2C0_C1 |= 1 << 3;
}
if (I2C_num == 0) { /* 接收完成,结束总线 */
I2C0_C1 &= ~(1 << 5); /* 发送STOP */
}
*I2C_buf++ = I2C0_D;
break;
default:
break;
}
#endif
#if (I2C0_MODE == I2C_SLAVER)
#endif
}
此帖出自小平头技术问答
一周热门 更多>