今天帮一同事调试裸机下的EEprom,虽然是很小CASE,但是还是记录下,我们是基于SEP4020芯片的,该芯片上没有集成IIC控制器,因此我们分了两层,协议层和功能层。下面这个EEprom.c是功能层,可以适应8位数据地址,16位数据地址,以及AT24C16的地址组成(AT24c16的数据地址是11位高三位放在Devices_addr中,剩下8位为PAG中的偏移地址),函数参数传递的时候注意EEprom的地址大小。
EEprom.c
- #include "eeprom.h"
- #include "iic.h"
- #define DEV_ADDR 0xA0
- //#define I2C_FLAG_ADDR16
- #define AT_24C16
- //ReadAddr:开始读数的地址,注意读地址大小,比如atAT_24C16是:0~2408
- //返回值 :读到的数据
- u8 Eeprom_ReadOneByte(u16 ReadAddr)
- {
- u8 temp=0,temp1;
- u8 data_addr=0,dev_real;
-
- #ifdef AT_24C16
- data_addr=ReadAddr%256;
- temp = ReadAddr>>7;
- temp = temp &0x0E;
- dev_real = DEV_ADDR |temp;
- #else
- dev_real=DEV_ADDR;
- #endif
- IIC_Start();
- IIC_Send_Byte(dev_real); //发送读命令
- IIC_Wait_Ack();
-
- #ifdef I2C_FLAG_ADDR16
- IIC_Send_Byte(ReadAddr>>8);//发送高地址
- IIC_Wait_Ack();
- IIC_Send_Byte(ReadAddr%256); //发送低地址
- IIC_Wait_Ack();
- #else
- IIC_Send_Byte(data_addr);//发送读地址
- IIC_Wait_Ack();
- #endif
- IIC_Start();
- IIC_Send_Byte(dev_real | 1); //进入接收模式
- IIC_Wait_Ack();
- temp1=IIC_Read_Byte(0);
- IIC_Stop();//产生一个停止条件
- return temp1;
- }
- //WriteAddr :写入数据的目的地址 注意读地址大小,比如atAT_24C16是:0~2408
- //DataToWrite:要写入的数据
- /*
- 写入单个字节:
- 写入字节指令每次只能向芯片中的一个地址写入一个字节的数据。
- 首先发送开始位来通知芯片开始进行指令传输,
- 然后传送设置好的器件地址字节,R/W位应置0,
- 接着是分开传送十六位地址的高低字节,再传送要写入的数据,
- 最后发送停止位表示本次指令结束。
- 十六位地址的前3位忽略,所以可寻址的位数为13位,地址长度为213=8192,
- 正好为芯片资料上说的8K*8的结构,所以AT24C64可寻址的范围是0000-1FFFH。
- */
- void Eeprom_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
- {
- u8 temp=0,dev_real;
- u8 data_addr=0;
- #ifdef AT_24C16
- data_addr=WriteAddr%256;
- temp = WriteAddr>>7;
- temp = temp &0x0E;
- dev_real = DEV_ADDR |temp;
- #else
- dev_real=DEV_ADDR;
- #endif
- IIC_Start();
- IIC_Send_Byte(dev_real); //发送写命令
- IIC_Wait_Ack();
-
- #ifdef I2C_FLAG_ADDR16
- IIC_Send_Byte(WriteAddr>>8);//发送高地址
- IIC_Wait_Ack();
- IIC_Send_Byte(WriteAddr%256);//发送低地址
- IIC_Wait_Ack();
- #else
- IIC_Send_Byte(data_addr);//发送写入地址
- IIC_Wait_Ack();
- #endif
-
- IIC_Send_Byte(DataToWrite); //发送字节
- IIC_Wait_Ack();
- IIC_Stop();//产生一个停止条件
- delay_ms(10);
- }
- /*
- *read_addr:读取地址
- *buf:读取的数据放入buf中
- *len:读取数据长度
- */
- void eeprom_read_bytes(u16 read_addr, u8 *buf, u8 len)
- {
- u8 i = 0;
-
- for (i = 0; i < len; i++)
- buf[i] = Eeprom_ReadOneByte(read_addr + i);
- }
- /*
- *write_addr:写入地址
- *buf:写入的数据
- *len:写入数据长度
- */
- void eeprom_write_bytes(u16 write_addr, u8 *buf, u8 len)
- {
- u8 i = 0;
-
- for (i = 0; i < len; i++)
- Eeprom_WriteOneByte(write_addr + i, buf[i]);
- }
- /* 原始密码初始化 */
- void Eeprom_passwd_init()
- {
- u16 i ;
- u8 system_passwd[4] = {1, 2, 3, 4};
-
- /* eeprom地址 0~3 为系统密码存储地址 */
- for (i=1024; i < 1028; i++) {
- Eeprom_WriteOneByte(i, system_passwd[i-1024]);
- }
- }
IIC.c文件实现IIC协议的模拟层
阅读(3529) | 评论(0) | 转发(2) |