打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
[转]用LPC2103的I2C实现EEPROM?24C01的读写
[原创]用LPC2103的I2C实现EEPROM 24C01的读写
(2007-11-15 14:35:00)
分类: PHILIPS ARM LPC2XXX
标签: LPC2000  LPC2103  I2C  24C01  24C02 以前习惯用SPI的器件,现在I2C的器件越来越多,不得不学习一下来充充电了。
写了一个24C01的读写代码,开发环境是IAR的EWARM,MCU是LPC2103,大家可以对照24C01的时序图来写程序。
本来想用LPC2000的I2C中断的,不知道怎么回事,中断老是开不起来,只好死等了。
/*
程序功能:24C01读写程序
晶振12M,I2C0,100K
*/
#include <iolpc2103.h>
#include <intrinsics.h>
#define MEMWRITE 0XA0 //写命令
#define MEMREAD 0XA1 //读命令
#define STA (1<<5) //起始位
#define I2CEN (1<<6) //允许位
#define STO (1<<4)  //停止位
#define SI (1<<3) // 中断标志
#define AA (1<<2) // 响应标志
#define LASTBYTE 1 //最后字节标志
//i2c_buf1为发送缓冲区,i2c_buf2为接收缓冲区
unsigned char i2c_buf1[10]={1,2,3,4,5,6,7,8,9,10},i2c_buf2[10];
void i2cInit(void);//I2C初始化程序
void i2cStart(void);//I2C发送起始位
void i2cStop(void);//I2C发送停止位
void writeByte(unsigned char data);//写一个字节的数据到总线上
void writeAddr(unsigned char mode);//写 地址和方向标志 到总线上
void writeData(unsigned char data);//完整的写数据,包括开始,清除标志等操作
unsigned char readByte(unsigned char last);//读字节数据,返回读到的值
void writeMem(int page_start,int count_byte,unsigned char *message_out);//写存储器的整体操作
void readMem(int page_start,int count_byte,unsigned char *message_in);//读存储器的整体操作
void delayMs(int dly);//延时
int main(void)
{
i2cInit();//I2C初始化
writeMem(0,8,i2c_buf1);//从存储器的0地址开始写8个字节的数据
delayMs(1000);
readMem(7,10,i2c_buf2);//读存储器的1地址开始写5个字节的数据
while(1);
}
void i2cInit(void)
{
PINSEL0    = 0x50;  //Switch GPIO to I2C pins
I2C0SCLH   =15; //Set bit rate 12Mhz/VPBDIV+SCLH+SCLL = 12/4/(15+15) = 100Khz
I2C0SCLL   =15;
I2C0CONCLR  = 0XFF;
I2C0CONSET  = I2CEN;
}
//I2C发送起始位
void i2cStart(void)
{
I2C0CONSET=STA;
do{}while(I2C0STAT!=0x08);//等待起始条件发送完成
I2C0CONCLR=STA;
}
//I2C发送停止位
void i2cStop(void)
{
I2C0CONSET=STO;//启动发送stop位,STO位是自动清除的,不必判断是否结束
I2C0CONCLR=SI; //只能清除SI,如果同时清除STO会导致返回到初始化状态
}
//写一个字节的数据到I2CDAT中
void writeByte(unsigned char data)
{
I2C0DAT=data;
I2C0CONCLR=SI;//启动发送
}
//发送控制字,其中mode为 MEMWRITE 或 MEMREAD
void writeAddr(unsigned char mode)
{
writeByte(mode);
if(mode==MEMREAD)do{}while(I2C0STAT!=0x40);//如果发送的是读控制字(地址),等待从机响应
else
do{}while(I2C0STAT!=0x18);//如果发送的是写控制字(地址),等待从机响应
}
//写数据
void writeData(unsigned char data)
{
writeByte(data);
do{}while(I2C0STAT!=0x28);//0x28——已发送I2CDAT中的字节,已经接受ACK
}
//读数据
unsigned char readByte(unsigned char last)
{
if(last)//如果读的是最后一个字节,不需要发送应答位
{
I2C0CONCLR=AA;
I2C0CONCLR=SI;
do{}while(I2C0STAT!=0x58);//等待接收数据直接和非ACK
}
else
{  I2C0CONSET=AA;//发送一个应答位
I2C0CONCLR=SI;
do{}while(I2C0STAT!=0x50);//等待接收数据直接和ACK
}
return (I2C0DAT);
}
/*
写24C01
入口: page_start——起始地址,count_byte——需要写的字节数,
message_out——需要写入的数据缓冲区头指针
*/
void writeMem(int page_start,int count_byte,unsigned char *message_out)
{
int i;
i2cStart();//发送起始位
writeAddr(MEMWRITE);//发送写控制字
writeData(page_start);//发送写的起始地址
for(i=0;i<count_byte;i++,message_out++)//写数据
writeData(*message_out);
i2cStop();//发送停止位
}
/*
读24C01,模式——顺序读(SEQUENTIAL READ)
入口:page_start——读起始地址,count_byte——需要读的字节数,
message_in——读缓冲区头指针
出口:
*/
void readMem(int page_start,int count_byte,unsigned char *message_in)
{
int i;
//设置读指针
i2cStart();//发送起始位
writeAddr(MEMWRITE);//发送写控制字
writeData(page_start);//发送读的起始地址
i2cStop();//发送停止位
//开始读数据
i2cStart();//发送起始位
writeAddr(MEMREAD);//发送读控制字
for(i=0;i<count_byte;i++,message_in++)//接收数据
*message_in=readByte(!LASTBYTE);
*message_in=readByte(LASTBYTE);
i2cStop();//发送停止位
}
void delayMs(int dly)
{
int i;
for(;dly>0;dly--)
for(i=0;i<1000;i++);
}
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
lpc1788移植u
st7920
linux e2prom 驱动代码
74hc164驱动共阴数码管与共阳数码管
从长整型数据取字节
调试51+nrf905无线模块,可以保证稳定的收发,正在完善中。。 (www.ouravr...
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服