24C02的秘密 电子说
何为4线、5线、8线的24C02 ?
在市场上面我们常常会听到4线、5线、8线的24C02,这里我跟大家解释一下:
1、所谓的4线24C02:其实就是芯片内部母体只打了4种功能线到塑封金属引脚上。分别是VDD、GND、SDA、SCLK。对于这种芯片的打线方式,芯片的设备地址选择脚A0A1A2和芯片写保护脚WP脚在母体上面都固定接地了,当然还有一种情况就是原厂为了省成本在芯片设计的时候就把这部分的电路简化掉了,所以母体上面根本就没有这4个脚的PAD。这种打线的芯片是没有器件地址选择和写保护功能的。
2、所谓的5线24C02:其实就是芯片内部母体只打了5种功能线到塑封金属引脚上。分别是GND、SDA、SCLK、WP、VDD、。对于这种芯片的打线方式,芯片的设备地址选择脚A0A1A2脚在母体上面都固定接地了,当然还有一种情况就是原厂为了省成本在芯片设计的时候就把这部分的电路简化掉了,所以母体上面根本就没有这3个脚的PAD。这种打线的芯片是没有器件地址选择功能,但是有芯片写保护功能。
3、所谓的8线24C02:其实就是芯片内部母体打了8种功能线到塑封金属引脚。分别是A0A1A2GNDSDASCLKWPVDD。对于这种芯片的打线方式,24C02的器件地址选择跟写保护功能都具备,是功能完全的24C02。
24C02都是以8字节为一页划分的么?
作为24C02的使用者,曾几何时在我们上大学的时候,学习51单片机编程用的开发板上面的就有24C02,因此教程实验里面就有用软件模拟I2C总线对24C02进行读写操作,那时候的24C02数据手册基本清一色都是一个存储单元可以保存8位数据,8个存储单元为一页的存储结构。直到后面参加工作以后,发现市场上面有的厂家的24C02别具特色,芯片内部的结构是以一个存储单元可以保存8位数据,16个存储单元为一页。其实这两种存储结构的芯片总容量是一样的,单个存储单元也是一样的,唯一不同的地方就是页的划分不一样,8个存储单元为一页的芯片内部总共是32页,而16个存储单元为一页的芯片内部有16页。因此这两种芯片的24C02进行页存取数据的时候会有点差异。
如何选择适合自己的24C02?
1、首先要确定你的产品应用是不是需要多个I2C接口设备,因为这里牵涉到多个设备地址会不会冲突的问题。
2、另外就是确定芯片是否需要写保护功能。
3、还有就是考虑一下在对24c02进行读取数据时,是按8字节一页来操作还是按16字节一页来操作的。
另外就是不同厂家的24C02芯片替代也可以跟进上面的3条来确定。我就有遇到过客户的板子上面用的是打4线的24C02,后面客户缺货拿我们的芯片替代上一家的芯片,并且把芯片全部贴到板子上面后,发现在生产测试的时候板子上面所有的24C02都不能正常读写数据。后来我拿到客户的PCBA板看了一下,才知道客户的应用电路是按打4线的24C02来设计的,他们的应用电路是将WP引脚悬空的。用打5线或者8线的24C02是没有办法使用的,因为5线或者8线的24c02的WP脚是有功能的,所以在写保护功能不用的时候WP脚必须接地,不能悬空或者接VDD上面。因此作为硬件工程师在设计电路的时候,一定要考虑电路兼容性的问题。很多时候采购对不同厂家的芯片的不同细节不清楚,她们只知道型号一样以为功能也一样,所以容易导致出问题。
软件模式I2C协议读取24C02 C语言(STM32)和汇编语音(九齐MCU)
C语言
u8 eepromFlag[16];
void at24c02PortInit(void)
{
GPIOB_ModeCfg(EEP_SDA_PORT_NUM, GPIO_ModeOut_PP_5mA);
GPIOB_ModeCfg(EEP_SCL_PORT_NUM, GPIO_ModeOut_PP_5mA);
AT_SDA_H;
AT_SCL_H;
}
void at24c02_Delay(void)
{
uint16_t i;
for (i=0; i<40; i++);
}
void at24c02Start(void)
{
AT_SDA_H;
at24c02_Delay();
AT_SCL_H ;
at24c02_Delay();
AT_SDA_L;
at24c02_Delay();
AT_SCL_L ;
at24c02_Delay();
}
/*---------------------*/
void at24c02Stop(void)
{
AT_SDA_L;
at24c02_Delay();
AT_SCL_H ;
at24c02_Delay();
at24c02_Delay();
AT_SDA_H;
at24c02_Delay();
}
u8 at24c02WriteByte(u8 dat)
{
u8 mask;
for (mask=0x80; mask!=0; mask>>=1)
{
AT_SCL_L;
if ((mask&dat) == 0){
AT_SDA_L;
}
else {
AT_SDA_H;
}
at24c02_Delay();
AT_SCL_H;
at24c02_Delay();
}
AT_SCL_L;
AT_SDA_H;
at24c02_Delay();
AT_SCL_H;
at24c02_Delay();
mask = AT_SDA_IN;
AT_SCL_L;
return mask;
}
u8 at24c02ReadByte(void)
{
u8 mask;
u8 byte;
byte = 0;
for (mask=0x80; mask!=0; mask>>=1){
AT_SCL_L;
AT_SDA_H;
at24c02_Delay();
AT_SCL_H;
at24c02_Delay();
if(AT_SDA_IN != 0){
byte |= mask;
}
}
return byte;
}
static void at24c02ACK(void)
{
AT_SCL_L;
AT_SDA_L;
at24c02_Delay();
AT_SCL_H;
at24c02_Delay();
AT_SCL_L;
}
static void at24c02NAK(void)
{
AT_SCL_L;
AT_SDA_H;
at24c02_Delay();
AT_SCL_H;
at24c02_Delay();
AT_SCL_L;
}
u8 at24c02ReadACK(void)
{
u8 byte;
byte = at24c02ReadByte();
at24c02ACK();
return byte;
}
u8 at24c02ReadNAK(void)
{
u8 byte;
byte = at24c02ReadByte();
at24c02NAK();
return byte;
}
void at24c02WriteDat(u8 WriteAddr,u8 dat)
{
if (at24c02WaitThenStart(0xa0) != 0) {
return;
}
if (at24c02WriteByte(WriteAddr) != 0) {
at24c02Stop();
return;
}
if(at24c02WriteByte(dat) != 0) {
at24c02Stop();
return;
}
at24c02Stop();
delay_ms(30);
}
u8 at24c02ReadDat(u8 WriteAddr)
{
u8 dat;
if (at24c02WaitThenStart(0xa0) != 0) {
return 0;
}
if (at24c02WriteByte(WriteAddr) != 0) {
at24c02Stop();
return 0;
}
at24c02Start();
if (at24c02WriteByte(0xa1) != 0) {
at24c02Stop();
return 0;
}
dat = at24c02ReadNAK();
at24c02Stop();
delay_ms(5);
return dat;
}
void at24c02WriteBuf(u8 WriteAddr,u8 *buf,u8 num)
{
u8 cnt;
cnt = num;
if (at24c02WaitThenStart(0xa0) != 0) {
return;
}
if (at24c02WriteByte(WriteAddr) != 0) {
at24c02Stop();
return;
}
while (cnt>0) {
if(at24c02WriteByte(*buf) != 0) {
at24c02Stop();
return;
}
buf++;
cnt--;
}
at24c02Stop();
delay_ms(30);
}
void at24c02ReadBuf(u8 WriteAddr,u8 *buf,u8 num)
{
u8 cnt;
cnt = num;
if (at24c02WaitThenStart(0xa0) != 0) {
return;
}
if (at24c02WriteByte(WriteAddr) != 0) {
at24c02Stop();
return;
}
at24c02Start();
if (at24c02WriteByte(0xa1) != 0) {
at24c02Stop();
return;
}
while (cnt > 1) {
*buf = at24c02ReadACK();
buf++;
cnt--;
}
if (cnt == 1) {
*buf = at24c02ReadNAK();
}
at24c02Stop();
delay_ms(10);
}
汇编语音:
; ============================ WWW.idchip.com =============================================
; 该测试程序可以测试24C02芯片
; I2C SDA 是PB4 ->芯片3脚
; i2C CLK 是PB5 ->芯片2脚
; PB1->LED_R 读写错误指示灯
; PB0->LED_G 读写完成指示灯
; PB2->LED_B 读写操作中指示灯
;//读或者写存储芯片过程中亮蓝灯,如果中间发生错误或者读出来的数据跟写进去的数据不一样报错亮红灯
;//正常成功写入24C16 完成后,蓝灯跟绿灯同时亮
;//正常成功读24C16数据完成后,注意读的过程中会跟写入的数据进行比较,如果错误则亮红灯并退出读操作
;//全部读出数据并验证跟写入的数据一样,蓝灯会灭,直亮绿灯
; File: main.asm
;--------------------------------------------------------------------------
#include AT8A513F.H ; The Header File for AT8A513F
;--------------- Variable Defination --------------------------------------
;--------------------------------------------------------------------------
;//
temp0 EQU 10H;//H'0010'
temp1 EQU 11H;H'0011'
ACC_BUF EQU 12H;//H'0012'
PFLAG_BUF EQU 13H;H'0013'
wait_cnt equ 14H;//
FLAG1 equ 15H
KEY_CNT equ 16H
KEY_LONG_CNT equ 17H
delay_10ms_cnt EQU 18H;//
I2C_QJ_BLOCK_TEMP EQU 19H
block_adder_cnt EQU 1AH
block_cnt_temp EQU 1BH
page_cnt_temp EQU 1CH
I2C_QJ_BLOCK_R_TEMP EQU 1DH
page_st_adder EQU 20H ;//页读的首地址
;block_adder_cnt equ 31H ;//块地址
page_adder_cnt equ 21H
;unit_adder_cnt equ 22H ;//单元地址
write_data_cnt equ 23H ;//写入的数据
read_data_cnt equ 24H ;//
I2C_WDT EQU 25H
I2C_REV EQU 26H;H'0026'
DELAY_3S EQU 27H;H'0027'
POW_LED EQU 28H;H'0028'
DELAY_COUNT EQU 29H;H'0029'
;//===================================
FLAG0 EQU 2AH;H'0029'
EEPROM_DATA EQU 2BH;H'002A'
TEST_REV EQU 2CH;H'002B'
page_rw_byte EQU 2DH;//页读写的字节数目 ;、、8字节还是16字节
page_tab_cnt EQU 2EH;//
block_adder_cnt_temp EQU 2FH;//
;//===========================================
;//====================测试说明=============================
#define CODE_3S_MATCH FLAG0,0
#define IR_DET_F FLAG0,1
#define Error_Flag FLAG0,2
#define DELAY_F FLAG0,3
#define LAMP_OFF_F FLAG0,4
#define LED_STATE_F FLAG0,5
#define key_ok_flag FLAG0,6;//
#define KEY_UP_FLAG FLAG0,7
#define KEY_LONG_FLAG FLAG1,0;///
#define run_flag FLAG1,1;//
#define pwm_up_flag FLAG1,2;//
#define key_flag FLAG1,3;//
#define start_write_flag FLAG1,4;//
#define start_read_flag FLAG1,5;//
;//=================注意240248163264的区别==========================================
;#define C_02_FLAG FLAG1,0 ;//02每页是8字节 C02 C04 C08 C16 C32 C64
;#define C_04_FLAG FLAG1,1 ;//04每页是16字节 A0 A0 NC NC NC A0 A0
;#define C_08_FLAG FLAG1,2 ;//08每页是16字节 A1 A1 A1 NC NC A1 A1
;#define C_16_FLAG FLAG1,3 ;//16每页是16字节 A2 A2 A2 A2 NC A2 A2
#define C32_64_FLAG FLAG1,4 ;//32每页是32字节
;//#define C_64_FLAG FLAG1,5;//64每页是32字节
;//================存储结构================================================================
;// 器件 容量 总页数 字节/页 字地址长度
;// 24C02 2K 32 8 8 ;;16字节一页的芯片只是页存取改一下即可
;// 24C04 4K 32 16 9 ;;器件地址bit1 为字地址位高1位
;// 24C08 8K 64 16 10;;器件地址bit1、bit2为字地址位高2位
;// 24C16 16K 128 16 11;;器件地址bit1、bit2、bit3位为地址位高3位
;// 24C32 32K 128 32 12;//需要写入2个字节的地址
;// 24C64 64K 256 32 13;//需要写入2个字节的地址
;//===========================综合上述了解================================================================
;//在0-255单元,如果随机读写,24C024816 的读写程序是一样的。 但是C32C64的话注意要读写地址都要2个字节
;//另外就是在0-255这个地址如果进行页读写操作,注意他们每页的字节数就可以了。
;//=======================================================================================================
#define I2C_WADR 0xa0
#define I2C_READ 0xa1
#define WR_ADD0 0x01
#define WR_ADD1 0x00;//
#define R 1
#define A 0
;//====================================
#define KEY_ADJ PORTB,3 ;//
#define I2C_SDA PORTB,4
#define I2C_CLK PORTB,5
#define LED_G PORTB,0;//绿表示准确完成读写
#define LED_B PORTB,2;//红色表示读写错误
#define LED_R PORTB,1;//蓝色表示在读写过程中
;//====================================
org 0x000
Lgoto main
org 0x008
Lgoto int_time
;=========================================
int_time:
retie
;//=======================================
main:
LCALL ClearAllRAM;//
LCALL system_init;//
MOVIA 200 ;//
LCALL delayxms ;//
BCR LED_R
bCr LED_B
BSR LED_G
MOVIA 200 ;//
LCALL delayxms ;//
BCR LED_G
BSR LED_B
MOVIA 200 ;//
LCALL delayxms ;//
bcr LED_B ;//
;//==========================================
main_loop:
BTRSS key_flag ;//
LGOTO delay_10ms_fun;//delay_cnt_loop;//
BCR key_flag ;//
LCALL KEY_ADJ_FUN;//
delay_cnt_loop:
btrss key_ok_flag
lgoto delay_10ms_fun;//main_loop
bcr key_ok_flag;//
btrsc start_write_flag;//
lgoto write_c16_data_loop;
btrsc start_read_flag;//
lgoto read_c16_data_loop ;//
delay_10ms_fun:
movia 0x01
LCALL delayxms ;//
INCR delay_10ms_cnt,r
movia 10
subar delay_10ms_cnt,a
btrss STATUS,2
LGOTO main_loop ;//loop
clrr delay_10ms_cnt;
bsr key_flag;//
lgoto main_loop ;//
write_c16_data_loop:
BCR LED_G
BCR LED_R
BSR LED_B ;//
LCALL page_write_data ;//写数据的前亮蓝灯,写入过程中失败亮红的
BTRSC ERROR_flag
lgoto delay_10ms_fun;//main_loop
BSR LED_G ;//写入完成蓝灯跟绿灯同时亮
lgoto delay_10ms_fun;// main_loop ;//
;//=========================================;//
read_c16_data_loop:
BCR LED_G
BCR LED_R
BSR LED_B ;// 读数据前亮蓝灯
LCALL page_read_data
btrsc ERROR_flag;//读数据过程中失败亮红灯
lgoto delay_10ms_fun
BCR LED_B;//
bsr LED_G;//读出校验成功只量绿灯
lgoto main_loop
;//============================================;//
KEY_ADJ_FUN:
btrsc KEY_ADJ
LGOTO KEY_UP_UP
BTRSC KEY_UP_FLAG
LGOTO KEY_EXIT;//
INCR KEY_CNT,R
movia 0x02
subar KEY_CNT,A
BTRSS STATUS,2
LGOTO KEY_EXIT;
CLRR KEY_CNT
BSR KEY_UP_FLAG;//
BCR KEY_LONG_FLAG;//
LGOTO KEY_EXIT;
KEY_UP_UP:
BTRSS KEY_UP_FLAG;//
LGOTO KEY_EXIT;
BTRSC start_write_flag
lgoto SET_READ_FLAG
bsr key_ok_flag
bcr LED_R
BCR LED_B
BCR LED_G
bsr start_write_flag
bcr start_read_flag
bcr KEY_UP_FLAG
CLRR KEY_CNT
lgoto KEY_EXIT
SET_READ_FLAG:
bcr LED_R
BCR LED_B
BCR LED_G
bsr key_ok_flag
bcr start_write_flag
bsr start_read_flag
bcr KEY_UP_FLAG
CLRR KEY_CNT
KEY_EXIT:
RET
;===============================================//
ClearAllRAM:
MOVIA 0x2f ;; Clear Bank0 RAM 0x11-0x3f RAM数量
MOVAR 10H;clrr_ram_cnt
MOVIA 0x11 ;//RAM 地址
MOVAR FSR
L_Clear_Next_Byte:
CLRR INDF
INCR FSR, R
DECRSZ 10H,R ;//clrr_ram_cnt, R
LGOTO L_Clear_Next_Byte
CLRR FSR
clrr 10H
ret
;//============================================//
system_init:
movia 0x01 ;//
movar PORTB ;//
MOVIA 0x08 ;//0000 8 1为输入 0为输出 P11输入上拉 P13输入下拉
IOST IOSTB ;//配置PB4输入,PB2为PWM PB1 PB0 PB3 PB5输出
MOVIA 0x37 ;//1100 0111
MOVAR BPHCON ;//上拉寄存器 0使能 1禁止 PB0-PB5 P14使能上拉
MOVIA 0xff ;// 下拉电阻是bit7-bit4
MOVAR BPLCON ;//下拉寄存器 0使能 1禁止 PB0-PB3 P13使能下拉
MOVIA 0x00 ;//
IOST BODCON ;//开漏配置 0禁止 1使能
clrr BWUCON ;//
movia 0x00 ;//
IOST PCON1 ;//关闭定时器0 bit0:T0EN bit6:LVDOUT bit7:GIE
MOVIA 0x08 ;//bit3:低电压复位 bit5:低电压检测使能 bit7:看门狗使能
movar PCON ;//
BSR LED_R
bcr LED_B
BCR LED_G
ret
;//=================================================
TIME1_init:
movia 0x02 ;//
SFUN T1CR1;//
movia 0x08 ;//bit3 ->1 关闭预分频器 0->打开预分频器
SFUN T1CR2;//bit0-bit2 预分频器 000->2 分频 001->4分频
movia 100 ;// 37*0.25
SFUN TMR1 ;//
movia 0 ;//
SFUN PWM1DUTY;//
movia 0x83 ;//
SFUN T1CR1;//
RET
delayxms:
MOVAR DELAY_COUNT
DY_LOOP0:
MOVIA 240
MOVAR temp0
DY_LOOP1:
NOP
DECRSZ temp0,R
Lgoto DY_LOOP1
DECRSZ DELAY_COUNT,R
Lgoto DY_LOOP0
ret
;//======================================
delayus:
NOP
NOP
NOP
NOP
NOP
NOP
ret;
;=========================================
i2c_stat:
BCR I2C_CLK
BCR I2C_SDA
LCALL delayus
BSR I2C_SDA
LCALL delayus
BSR I2C_CLK
LCALL delayus
BCR I2C_SDA
LCALL delayus
BCR I2C_CLK
LCALL delayus
ret
;=========================================
i2c_stop:
BCR I2C_CLK
BCR I2C_SDA
LCALL delayus
BSR I2C_CLK
LCALL delayus
BSR I2C_SDA
LCALL delayus
BCR I2C_CLK
ret
;================应答回复一个低电平=========================
i2c_ack:
IOSTR IOSTB
ANDIA 0x2f;//P14 设置为输出
IOST IOSTB;//
lCALL delayus
BCR I2C_SDA
LCALL delayus
BSR I2C_CLK
LCALL delayus
BCR I2C_CLK
LCALL delayus
;BSR I2C_SDA
;LCALL delayus
ret
;=================非应答给一个高电平========================
i2c_noack:
IOSTR IOSTB
ANDIA 0x2f;//P14 设置为输出
IOST IOSTB;//
LCALL delayus
BSR I2C_SDA
LCALL delayus
BSR I2C_CLK
LCALL delayus
BCR I2C_CLK
LCALL delayus
ret
;===========================================
i2c_write_byte:
MOVAR temp1
MOVIA 0x08
MOVAR temp0
W_LOOP:
RLR temp1,R ;//
BTRSC STATUS,0;//
Lgoto w_h
w_l:
BCR I2C_SDA
LCALL delayus
BSR I2C_CLK
LCALL delayus
BCR I2C_CLK
LCALL delayus
DECRSZ temp0,R
Lgoto W_LOOP
Lgoto w_ack
w_h:
BSR I2C_SDA
LCALL delayus
BSR I2C_CLK
LCALL delayus
BCR I2C_CLK
LCALL delayus
DECRSZ temp0,R
Lgoto W_LOOP
w_ack:
BCR Error_Flag;//错为标志=====
IOSTR IOSTB ;//
IORIA 0x10 ;//
IOST IOSTB ;//P14设置为输入
NOP
NOP
BSR I2C_CLK
movia 200 ;//
movar wait_cnt;
wait_ack_l:
BTRSS I2C_SDA
LGOTO WRITE_OK ;///
LCALL delayus ;///
DECRSZ wait_cnt,r;//
LGOTO wait_ack_l;//
BSR Error_Flag;//
BSR LED_R ;// 接收不到应答信号;//
bcr LED_B ;//
WRITE_OK:
NOP ;//新增加
BCR I2C_CLK ;//新增加
;//================================
NOP
NOP
IOSTR IOSTB ;//
ANDIA 0x2F ;//P15设置为输出 0010 1111 1是输入 0是输出
IOST IOSTB ;//
BCR I2C_SDA
NOP
NOP
ret
;===============================================
i2c_read_byte:
CLRR I2C_REV
MOVIA 0x08
MOVAR temp0
IOSTR IOSTB ;//
IORIA 0x10 ;//
IOST IOSTB ;//P15设置为输入
LCALL delayus
R_LOOP:
LCALL delayus
BSR I2C_CLK
LCALL delayus
BTRSC I2C_SDA
LGOTO R_H
NOP
NOP
BCR I2C_CLK
BCR STATUS,0;//C
RLR I2C_REV,R
DECRSZ temp0,R
Lgoto R_LOOP
Lgoto R_RETURN
R_H:
NOP
NOP
BCR I2C_CLK
BSR STATUS,0;//C
RLR I2C_REV,R
DECRSZ temp0,R
lgoto R_LOOP
NOP ;//
;/LCALL i2c_ack ;//回复一个应答信号;、、
R_RETURN:
LCALL i2c_ack
ret
;====================写任意一个单元地址数据========================
i2c_write_data:
LCALL i2c_stat;//
MOVIA I2C_WADR;// 器件地址
LCALL i2c_write_byte
LCALL delayus
;//MOVR ADR_BUF,A
movia WR_ADD0
LCALL i2c_write_byte;//单元地址
LCALL delayus
BTRSS C32_64_FLAG;//注意C32/C64要写2个字节地址
LGOTO W_DATA_LOOP
movia WR_ADD1;//
LCALL i2c_write_byte;//单元地址
LCALL delayus
W_DATA_LOOP:
MOVR I2C_WDT,A
LCALL i2c_write_byte
LCALL delayus
LCALL delayus
;//=============写周期===========
LCALL i2c_stop
MOVIA 30
LCALL delayxms
ret
;=====================读任意一个单元地址数据==========================
i2c_read_data:
LCALL i2c_stat;//
MOVIA I2C_WADR;//器件地址
LCALL i2c_write_byte;
btrsc Error_Flag
LGOTO eixt_read_data
LCALL delayus
LCALL delayus
MOVIA WR_ADD0 ;//
LCALL i2c_write_byte;//
LCALL delayus ;//
BTRSS C32_64_FLAG ;//============C32 C64
LGOTO R_DATA_LOOP ;//
MOVIA WR_ADD1
LCALL i2c_write_byte
LCAll delayus
;//=============================
R_DATA_LOOP:
LCALL i2c_stat
MOVIA I2C_READ
LCALL i2c_write_byte;//写
LCALL delayus
;//==============================
LCALL i2c_read_byte
LCALL delayus
eixt_read_data:
LCALL i2c_stop ;//随机读的话,读一个单元发停止信号,如果是页读的话,不用发.
ret
;//================页写======================================
;//=================传递3个参数 块地址 在器件地址的 bit1-bit3
;//=================页地址16字节为一页
page_write_data:
clrr write_data_cnt ;//写入的数据从0-255
clrr page_adder_cnt ;//页首地址
clrr block_adder_cnt;//块首地址
movia 32;//16 ;//16页
movar page_cnt_temp ;//
movia 0x01
movar block_cnt_temp ;//8个数据块
movia 0xa0 ;//
movar I2C_QJ_BLOCK_TEMP;//
write_page_loop:
LCALL i2c_stat;//
MOVR I2C_QJ_BLOCK_TEMP,A;//I2C_WADR;//0xa0 器件地址
LCALL i2c_write_byte
LCALL delayus
;//=======================================
movr page_adder_cnt,a;// 从00地址开始
LCALL i2c_write_byte ;//单元地址
LCALL delayus ;//
;//======================================
movia 8;//16 ;//16个字节为一页
movar page_rw_byte ;//页写数据的数量为16字节
WPAGE_DATA_LOOP:
movr write_data_cnt,a;// 要写入的数据
LCALL i2c_write_byte ;//
LCALL delayus
LCALL delayus
incr write_data_cnt,r;//
decrsz page_rw_byte,r ;//字节计数器减一
lgoto WPAGE_DATA_LOOP ;//
CLRR page_rw_byte ;//
LCALL delayus ;//
LCALL delayus ;//完成16字节的数据写入
;//=======写周期======== ;//
LCALL i2c_stop ;//
MOVIA 10 ;//
LCALL delayxms ;//
;//=======================================================
decrsz page_cnt_temp,r ;//
lgoto page_adder_incr_loop;/// 写完16页
movia 32;//16 ;//16页
movar page_cnt_temp ;//
clrr write_data_cnt ;//
decrsz block_cnt_temp,r ;//
lgoto block_adder_incr_loop;//
ret ;//
page_adder_incr_loop:
movr page_adder_cnt,a ;//
addia 0x08
movar page_adder_cnt ;//
lgoto write_page_loop
block_adder_incr_loop:
incr block_adder_cnt,r;//
bcr STATUS,0
RLR block_adder_cnt,a
; movar block_adder_cnt_temp
addia 0xa0;//I2C_WADR
MOVAR I2C_QJ_BLOCK_TEMP ;;//这里面的bit3-bit1 是芯片的块地址
lgoto write_page_loop ;//写下一个块
;//================页读===============================================================================
page_read_data:
clrr write_data_cnt ;//写入的数据从0-255
clrr page_adder_cnt ;//页首地址
clrr block_adder_cnt;//块首地址
movia 32;//16 ;//16页
movar page_cnt_temp ;//
movia 0x01
movar block_cnt_temp ;//8个数据块
movia 0xa0 ;//
movar I2C_QJ_BLOCK_TEMP;//
movia 0xa1
movar I2C_QJ_BLOCK_R_TEMP
; movia 0x40 ;//对一页的首地址单页测试
; movar page_adder_cnt ;//
;//=========================================================
read_page_loop:
LCALL i2c_stat;//
MOVR I2C_QJ_BLOCK_TEMP,A;//0xa0;//I2C_WADR;//写入器件地址
LCALL i2c_write_byte;
btrsc Error_Flag
LGOTO eixt_read_data
LCALL delayus
LCALL delayus
MOVR page_adder_cnt,A;//0x20;//WR_ADD0;//写入单元地址或者页首地址
LCALL i2c_write_byte;//
LCALL delayus ;//
;//=============================
RPAGE_LOOP:
LCALL i2c_stat ;//
MOVR I2C_QJ_BLOCK_R_TEMP,A;//0xa1 ;I2C_READ ;//
LCALL i2c_write_byte;//写入对器件读操作指令
LCALL delayus ;//
movia 8;//16;//;//16 写8个字节或者16个字节
movar page_rw_byte ;//页写数据的数量为16字节
; movia 0x30 ;//缓存数据的单元首地址 0x30-0x3f 为缓存单元块
; movar FSR ;//
; CLRR INDF ;//
RPAGE_DATE_LOOP:
LCALL i2c_read_byte ;//
movr I2C_REV,a ;//
subar write_data_cnt,a;//比较读出来的数据跟写入的数据是否一样,注意首地址读写要对的上
btrss STATUS,2
LGOTO exit_read_loop
; movar INDF
; INCR FSR,R
INCR write_data_cnt,r;//
DECRSZ page_rw_byte,R ;//
lgoto RPAGE_DATE_LOOP;//比较完一页数据
LCALL delayus
LCALL delayus
LCALL i2c_stop ;//随机读的话,读一个单元发停止信号,如果是页读的话,不用发.
decrsz page_cnt_temp,r ;//
lgoto R_page_adder_incr_loop;/// 读完16页 也就是一块数据
movia 32;//16 ;//1块有16页
movar page_cnt_temp ;//
clrr write_data_cnt ;//
decrsz block_cnt_temp,r ;//
lgoto W_block_adder_incr_loop;//
ret ;//
R_page_adder_incr_loop:
movr page_adder_cnt,a ;//
addia 0x08;//0x10
movar page_adder_cnt ;//读下一页,页地址要加16 16字节为一页
lgoto read_page_loop ;//
W_block_adder_incr_loop:
incr block_adder_cnt,r;//
bcr STATUS,0
RLR block_adder_cnt,A
movar block_adder_cnt_temp
addia 0xa0;//I2C_WADR bit0 = 0表示对器件写入数据
MOVAR I2C_QJ_BLOCK_TEMP ;;//这里面的bit3-bit1 是芯片的块地址
movr block_adder_cnt_temp,a
addia 0xa1 ;//bit0 = 1表示对器件读数据
movar I2C_QJ_BLOCK_R_TEMP;//
lgoto read_page_loop ;//写下一个块
;//==================================================================
exit_read_loop:
bcr LED_R
BCR LED_B
BCR LED_G
ret
;//============================================
end
审核编辑 黄昊宇
全部0条评论
快来发表一下你的评论吧 !