热度 26
2014-6-27 16:02
12371 次阅读|
4 个评论
今天上午在做无线通信部分用到了小数据量的存储,临时写了一个小驱动,用起来还行。 /**********************************/ //作者:孙金刚 //时间:2013年7月4日 //功能:EEPROM 24CXX驱动。 //入口函数:WriteSet(0x00,0x0f); //在指定地址“0x00”中写入数据“0x0f” // P0=ReadSet(0x01); //从指定地址“0x01中读取数据 /**********************************/ #include #include #define SDA P1_3 //将串行数据总线SDA位定义在为P1.3引脚 #define SCL P1_7 //将串行时钟总线SDA位定义在为P1.7引脚 /***************************************************** 函数功能:延时1ms ***************************************************/ void delay1ms() { unsigned char i,j; for(i=0;i100;i++) for(j=0;j10;j++) { asm("NOP"); asm("NOP"); asm("NOP"); } } /***************************************************** 函数功能:延时若干毫秒 入口参数:n ***************************************************/ void delaynms(unsigned char n) { unsigned char i; for(i=0;i delay1ms(); } /*************************************************** 函数功能:开始数据传送 ***************************************************/ void start() // 开始位 { P1DIR |= 0x88; P1SEL = 0x77; SDA = 1; //SDA初始化为高电平“1” asm("NOP"); //等待一个机器周期 asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); SCL = 1; //开始数据传送时,要求SCL为高电平“1” asm("NOP"); //等待一个机器周期 asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); SDA = 0; //SDA的下降沿被认为是开始信号 asm("NOP"); //等待一个机器周期 asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); SCL = 0; //SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递) } /*************************************************** 函数功能:结束数据传送 ***************************************************/ void stop() // 停止位 { P1DIR |= 0x88; SDA = 0; //SDA初始化为低电平“0” _n asm("NOP"); //等待一个机器周期 asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); SCL = 1; //结束数据传送时,要求SCL为高电平“1” asm("NOP"); //等待一个机器周期 asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); SDA = 1; //SDA的上升沿被认为是结束信号 asm("NOP"); //等待一个机器周期 asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); SDA=0; SCL=0; } /*************************************************** 函数功能:从AT24Cxx读取数据 出口参数:x ***************************************************/ unsigned char ReadData() // 从AT24Cxx移入数据到MCU { P1DIR = ~0x08; unsigned char i; unsigned char x; //储存从AT24Cxx中读出的数据 for(i = 0; i 8; i++) { SCL = 1; //SCL置为高电平 x=1; //将x中的各二进位向左移一位 x|=(unsigned char)SDA; //将SDA上的数据通过按位“或“运算存入x中 SCL = 0; //在SCL的下降沿读出数据 } return(x); //将读取的数据返回 } /*************************************************** 函数功能:向AT24Cxx的当前地址写入数据 入口参数:y (储存待写入的数据) ***************************************************/ //在调用此数据写入函数前需首先调用开始函数start(),所以SCL=0 bool WriteCurrent(unsigned char y) { P1DIR |= 0x88; unsigned char i; bool ack_bit; //储存应答位 for(i = 0; i 8; i++) // 循环移入8个位 { SDA = (bool)(y0x80); //通过按位“与”运算将最高位数据送到S //因为传送时高位在前,低位在后 asm("NOP"); //等待一个机器周期 asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); SCL = 1; //在SCL的上升沿将数据写入AT24Cxx asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); SCL = 0; //将SCL重新置为低电平,以在SCL线形成传送数据所需的8个脉冲 y = 1; //将y中的各二进位向左移一位 } SDA = 1; // 发送设备(主机)应在时钟脉冲的高电平期间(SCL=1)释放SDA线, //以让SDA线转由接收设备(AT24Cxx)控制 asm("NOP"); //等待一个机器周期 asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); SCL = 1; //根据上述规定,SCL应为高电平 asm("NOP"); //等待一个机器周期 asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); ack_bit = SDA; //接受设备(AT24Cxx)向SDA送低电平,表示已经接收到一个字节 //若送高电平,表示没有接收到,传送异常 SCL = 0; //SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递) return ack_bit; // 返回AT24Cxx应答位 } /*************************************************** 函数功能:向AT24Cxx中的指定地址写入数据 入口参数:add (储存指定的地址);dat(储存待写入的数据) ***************************************************/ void WriteSet(unsigned char add, unsigned char dat) // 在指定地址addr处写入数据WriteCurrent { start(); //开始数据传递 WriteCurrent(OP_WRITE); //选择要操作的AT24Cxx芯片,并告知要对其写入数据 WriteCurrent(add); //写入指定地址 WriteCurrent(dat); //向当前地址(上面指定的地址)写入数据 stop(); //停止数据传递 delaynms(4); //1个字节的写入周期为1ms, 最好延时1ms以上 } /*************************************************** 函数功能:从AT24Cxx中的当前地址读取数据 出口参数:x (储存读出的数据) ***************************************************/ unsigned char ReadCurrent() { unsigned char x; start(); //开始数据传递 WriteCurrent(OP_READ); //选择要操作的AT24Cxx芯片,并告知要读其数据 x=ReadData(); //将读取的数据存入x stop(); //停止数据传递 return x; //返回读取的数据 } /*************************************************** 函数功能:从AT24Cxx中的指定地址读取数据 入口参数:set_addr 出口参数:x ***************************************************/ unsigned char ReadSet(unsigned char set_addr) // 在指定地址读取 { start(); //开始数据传递 WriteCurrent(OP_WRITE); //选择要操作的AT24Cxx芯片,并告知要对其写入数据 WriteCurrent(set_addr); //写入指定地址 return(ReadCurrent()); //从指定地址读出数据并返回 }