如何给eeprom写值(EEPROM编程和测试代码)
如何给eeprom写值(EEPROM编程和测试代码)void i2c_init(void) { /* 注册下面的I2C控制器 */ s3c2440_i2c_con_add(); /* 选择某款I2C控制器 */ select_i2c_controller("s3c2440"); /* 调用它的init函数 */ p_i2c_con_selected->init(); }select_i2c_controller("s3c2440")用于选择s3c2440的i2c控制器。p_i2c_con_selected->init()调用s3c2440的i2c控制器结构体中init初始化函数,初始化s3c2440的i2c控制器。2).执行do_write_at24cxx()函数用于往at24cxx设备中写入数据,do_write_at24cxx()函数的代码如下所示:void i2c_test(
来源:百问网_嵌入式Linux wiki_jz2440 新1期视频维基教程 (视频文字版)
作者:韦东山
本文字数:3087,阅读时长:3分钟
从设备程序,只涉及到两个函数分别是:从设备的写函数,从设备的读函数。下面下分析从设备的写函数,代码如下:
#define AT24CXX_ADDR 0x50
int at24cxx_write(unsigned int addr unsigned char *data int len)
{
i2c_msg msg;
int i;
int err;
unsigned char buf[2];
for (i = 0; i < len; i )
{
buf[0] = addr ;
buf[1] = data[i];
/* 构造i2c_msg */
msg.addr = AT24CXX_ADDR;
msg.lags = 0; /* write */
msg.len = 2;
msg.buf = buf;
msg.err = 0;
msg.cnt_transferred = -1;
/* 调用i2c_transfer */
err = i2c_transfer(&msg 1);
if (err)
return err;
}
return 0;
}
- #define AT24CXX_ADDR 0x50宏定义设备地址。
- 我们每次只写一个字节,所以我们需要构造出len个msg。
- 调用i2c接口函数,传输构造i2C_msg结构体,我们传输指针只需要传输四个字节,我们需要把以前的参数都改成传输指针的格式。
从设备读函数和写函数类似,读函数需要构造两个i2c_msg(每个i2c_msg只能表示一个传输方向) ,因为在读操作之前,需要把要读的地址告诉从设备。
代码如下:
int at24cxx_read(unsigned int addr unsigned char *data int len)
{
i2c_msg msg[2];
int err;
/* 构造i2c_msg */
msg[0].addr = AT24CXX_ADDR;
msg[0].lags = 0; /* write */
msg[0].len = 1;
msg[0].buf = &addr;
msg[0].err = 0;
msg[0].cnt_transferred = -1;
msg[1].addr = AT24CXX_ADDR;
msg[1].lags = 1; /* read */
msg[1].len = len;
msg[1].buf = data;
msg[1].err = 0;
msg[1].cnt_transferred = -1;
/* 调用i2c_transfer */
err = i2c_transfer(&msg 2);
if (err)
return err;
return 0;
}
I2c_test测试程序如下所示:
void i2c_test(void)
{
char c;
/* 初始化 */
i2c_init();
while (1)
{
/* 打印菜单 供我们选择测试内容 */
printf("[w] Write at24cxx\n\r");
printf("[r] Read at24cxx\n\r");
printf("[q] quit\n\r");
printf("Enter selection: ");
c = getchar();
printf("%c\n\r" c);
/* 测试内容:
* 3. 编写某个地址
* 4. 读某个地址
*/
switch (c)
{
case 'q':
case 'Q':
return;
break;
case 'w':
case 'W':
do_write_at24cxx();
break;
case 'r':
case 'R':
do_read_at24cxx();
break;
default:
break;
}
}
}
1).调用i2c_controller.c里面的 i2c_init()初始化函数,在这个函数中需要添加一些功能,i2c_init()代码如下所示:
void i2c_init(void)
{
/* 注册下面的I2C控制器 */
s3c2440_i2c_con_add();
/* 选择某款I2C控制器 */
select_i2c_controller("s3c2440");
/* 调用它的init函数 */
p_i2c_con_selected->init();
}
- select_i2c_controller("s3c2440")用于选择s3c2440的i2c控制器。
- p_i2c_con_selected->init()调用s3c2440的i2c控制器结构体中init初始化函数,初始化s3c2440的i2c控制器。
2).执行do_write_at24cxx()函数用于往at24cxx设备中写入数据,do_write_at24cxx()函数的代码如下所示:
{
unsigned int addr;
unsigned char str[100];
int err;
/* 获得地址 */
printf("Enter the address of sector to write: ");
addr = get_uint();
if (addr > 256)
{
printf("address > 256 error!\n\r");
return;
}
printf("Enter the string to write: ");
gets(str);
printf("writing ...\n\r");
err = at24cxx_write(addr str strlen(str) 1);
printf("at24cxx_write ret = %d\n\r" err);
}
- addr = get_uint()用于把输入的地址赋值给addr。
- gets(str)用于把输入的字符串存在str字符数组中。
- at24cxx_write(addr str strlen(str) 1)调用at24cxx_write函数把输入的数据str ,放在输入的地址addr中。
3).执行do_read_at24cxx()函数从at24cxx中读取数据,do_read_at24cxx()函数的代码如下所示:
void do_read_at24cxx(void)
{
unsigned int addr;
int i j;
unsigned char c;
unsigned char data[100];
unsigned char str[16];
int len;
int err;
int cnt = 0;
/* 获得地址 */
printf("Enter the address to read: ");
addr = get_uint();
if (addr > 256)
{
printf("address > 256 error!\n\r");
return;
}
/* 获得长度 */
printf("Enter the length to read: ");
len = get_int();
err = at24cxx_read(addr data len);
printf("at24cxx_read ret = %d\n\r" err);
printf("Data : \n\r");
/* 长度固定为64 */
for (i = 0; i < 4; i )
{
/* 每行打印16个数据 */
for (j = 0; j < 16; j )
{
/* 先打印数值 */
c = data[cnt ];
str[j] = c;
printf("x " c);
}
printf(" ; ");
for (j = 0; j < 16; j )
{
/* 后打印字符 */
if (str[j] < 0x20 || str[j] > 0x7e) /* 不可视字符 */
putchar('.');
else
putchar(str[j]);
}
printf("\n\r");
}
}
- 调用at24cxx_read(addr data len)函数,从addr地址中读取len长度的字节数据,放在data字符数组中,后面的代码就是把读取得到的数据,打印出来。
「新品首发」STM32MP157开发板火爆预售!首批仅300套