赞
踩
at24c16 有8块 256字节组成,共2K字节16K bit
I2C开始信号后,第一个字节为器件地址,由1010+3位块地址+1位读写标志组成, 3位块地址刚好可以表示 8个块, 所以一次写完256字节,换到下一下块的时候,要重新更改器件地址
共有三种写入模式:
字节写入模式: MODE脚可接高电平或低电平
多字节模式:MODE接高电平,一次最多写8个字节,24c16收到数据后,地址低4bit递增,当地址超出边界时,会回滚到本页的开头,相当于低4bit溢出了,而且写入时间加倍到20ms。
页写入模式:一次最多写入16字节。主机每发送一个字节,24c16收到确认,内部地址递增(仅限低4bit,所以1次可写16字节)。
写保护功能:
8个块(每个块256byte)中,高四个块是可以写保护的,防止误改。
从边界地址—到顶部0x07FF之间被保护,边界地址由PB1 PB0两个引脚电平和0x07FF这个字节确定。
PB0 PB1选择四个块,地址0x07FF里面的内容的高4bit选择行号,一个块里有16行,每行16字节。低4bit 必须是0。所以边界地址是以行为单位的。
写保护的顺序:
1、将要保护的数据写入内存的顶部,最多但不包括location7FFh
2、硬件选择PB0 PB1 电平
3、通过在地址指针(位置7FFh的4个MSB)中写入正确的底部边界地址并将位b2(保护标志)设置为“0”来设置保护。
注意:位置7FFh的低4bit必须写入0,然后当PRE引脚接高电平时,保护将起作用。
备注:只有当PRE为高电平,并且7FFH存储的地址的bit2位为0,保护才起作用。其它情况,7FFH可以作为普通存储单元。
/***************************************************************************** 函数名称 : readAT24C16 功能描述 :从at24c16读取数据 输入参数 : 要读的开始地址,读出来的数据存放到数组的指针,数据长度 返回参数 : hal_ok/hal_error 使用说明 : 无 *****************************************************************************/ HAL_StatusTypeDef readAT24C16(uint16_t addr,uint8_t *data, uint16_t len) { uint8_t rNum=0; uint16_t lenLeft=len; uint8_t deviceId; uint8_t *p=data; /*is the address overfolw*/ if(addr+len>E2PROM_SIZE) return HAL_ERROR; /*calculate the current read position to know how many word can read continully*/ rNum=16-addr & E2PROM_PAGE_MASK; if(rNum == 0) rNum=16; rNum = lenLeft>=rNum ? rNum : lenLeft;//剩余未读字节数如果大于rNum, 则读rNum个,如果小于rNum,则一次读完了 /*read the data from e2prom*/ while(lenLeft) { //这里计算页地址,当地址小于256时,右移8位会小于0,所以器件地址为基地址A1 //如果读取的地址大于256时,右移8位则不会小于0,所以器件地址为 基地址A1 | 3位页地址 deviceId=(addr>>8)<0 ? E2PROM_BASE_RID : (E2PROM_BASE_RID | (uint8_t)((addr>>7)&0x0E)); if(HAL_I2C_Mem_Read(&hi2c2,deviceId,addr&0x00FF,I2C_MEMADD_SIZE_8BIT,p,rNum, 20)!=HAL_OK) { printf("i2c read error\r\n"); continue; } addr+=rNum;//已经读了rNum个了,所以地址后移rNum个 lenLeft-=rNum;//剩余未读数据减少rNum个 p+=rNum; rNum=lenLeft>16? 16 : lenLeft;//如果剩余大于16个,则下次再读16个,如果小于,则一次读完 } return HAL_OK; }
上页的函数,会调用
HAL_I2C_Mem_Read(&hi2c2,deviceId,addr&0x00FF,I2C_MEMADD_SIZE_8BIT,p,rNum, 20)!
来读取16个字节。这个函数再调用下面的函数来读取
I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart)
读取的流程为:
设置CR1应答ACK-------产生START-------wait SB set -----发送器件地址-----wait ADDR set 表示地址发送完-----清除ADDR-----wait TXE set表示发送寄存器目前是空的---------发送子地址-------wait TXE set-------再次产生START------wait SB set ------发送器件地址-------wait ADDR set ------退回上一层。接收数据。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。