0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

应广单片机系列——用I2C接口读写EEPROM

聚丰开发 2018-10-17 15:43 次阅读

注:本文是作者以前发表在其个人博客,现在发布到电子发烧友专栏


本例是用针对标准I2C接口EEPROM存储器24C02进行读写操作,只要对例程做适当修改,就可以用到大部分控制I2C接口设备的场合。

应广单片机软件I2C接口例程(MASTER模式)

本例仅供参考,欢迎指正程序中的问题

//-----------------------------------------
.chip p201cs14a
//{{PADAUK_CODE_OPTION
.Code_OptionBootupSlow// 1024 ILRC
.Code_OptionLVD2.79V// Maximum performance = 4 MIPS
.Code_OptionSecurityEnable// Security 3/4 words Enable
//}}PADAUK_CODE_OPTION


//定义I2C接口
I2C_SDAequpa.7
I2C_SCLequpa.6
I2C_SDA_DIRequpac.7
I2C_SCL_DIRequpac.6
I2C_LONG_DLYequ50
I2C_SHORT_DLYequ20
I2C_SDA_HIGHequset1I2C_SDA
I2C_SDA_LOWequset0I2C_SDA
I2C_SCL_HIGHequset1I2C_SCL
I2C_SCL_LOWequset0I2C_SCL
I2C_SDA_OUTPUTequset1I2C_SDA_DIR
I2C_SDA_INPUTequset0I2C_SDA_DIR
I2C_SCL_OUTPUTequset1I2C_SCL_DIR
I2C_SCL_INPUTequset0I2C_SCL_DIR


//定义I2C变量
bytei2c_rw_addr//读写地址
bytei2c_rw_byte//读写数据
bytei2c_rw_cmd//读写的器件地址
bytei2c_rw_temp//读写过程中间变量
bytei2c_rw_cnt//读写过程中间变量

//
byteXms
bytems_cnt

//
bytetest_addr
bytetest_data

.romadr0x000
gotomain0
gotomain1

.romadr0x010
isr_entry:
pushaf
intrq = 0
popaf
reti


//----------------------------
//产生START信号
//----------------------------
i2c_start:
I2C_SDA_OUTPUT
I2C_SCL_OUTPUT
I2C_SDA_HIGH
delayI2C_LONG_DLY
I2C_SCL_HIGH
delayI2C_LONG_DLY
I2C_SDA_LOW
delayI2C_LONG_DLY
I2C_SCL_LOW
delayI2C_LONG_DLY
ret

//----------------------------
//产生STOP信号
//----------------------------
i2c_stop:
I2C_SCL_LOW
delayI2C_LONG_DLY
I2C_SDA_LOW
delayI2C_LONG_DLY
I2C_SCL_HIGH
delayI2C_LONG_DLY
I2C_SDA_HIGH
delayI2C_LONG_DLY
//
I2C_SCL_INPUT
I2C_SDA_INPUT
ret


//----------------------------
//检查SALVE ACK信号
//----------------------------
i2c_slave_ack:
//don't check ACK
I2C_SDA_INPUT
delayI2C_SHORT_DLY
I2C_SCL_HIGH
delayI2C_SHORT_DLY
I2C_SCL_LOW
delayI2C_SHORT_DLY
I2C_SDA_OUTPUT
I2C_SDA_LOW
delayI2C_SHORT_DLY
ret

//----------------------------
//输出MASTER ACK信号
//----------------------------
i2c_master_ack:
I2C_SDA_OUTPUT
I2C_SDA_LOW
delayI2C_SHORT_DLY
I2C_SCL_HIGH
delayI2C_SHORT_DLY
I2C_SCL_LOW
delayI2C_SHORT_DLY
ret

//----------------------------
//输出MASTER NACK信号
//----------------------------
i2c_master_nack:
I2C_SDA_OUTPUT
I2C_SDA_HIGH
delayI2C_SHORT_DLY
I2C_SCL_HIGH
delayI2C_SHORT_DLY
I2C_SCL_LOW
delayI2C_SHORT_DLY
ret


//------------------------------
//写一个字节
//Input: i2c_rw_temp
//Used: i2c_rw_cnt
//------------------------------
i2c_write_8bit:
i2c_rw_cnt = 8
i2c_write_8bit_loop:
slci2c_rw_temp
swapcI2C_SDA
delayI2C_SHORT_DLY
I2C_SCL_HIGH
delayI2C_SHORT_DLY
I2C_SCL_LOW
delayI2C_SHORT_DLY
dzsni2c_rw_cnt
gotoi2c_write_8bit_loop
ret

//------------------------------
//读一个字节
//Used: i2c_rw_cnt
//Output: i2c_rw_temp
//------------------------------
i2c_read_8bit:
i2c_rw_temp = 0
i2c_rw_cnt = 8
delayI2C_SHORT_DLY
i2c_read_8bit_loop:
I2C_SCL_HIGH
delayI2C_SHORT_DLY
swapcI2C_SDA
slci2c_rw_temp
I2C_SCL_LOW
delayI2C_SHORT_DLY
dzsni2c_rw_cnt
gotoi2c_read_8bit_loop
ret

//------------------------------
//Input: i2c_rw_addr
// i2c_rw_cmd
//Used: i2c_rw_cnt
// i2c_rw_temp
//Output: i2c_rw_byte
//------------------------------
i2c_read_byte:
//start
calli2c_start

//write device address(write)
i2c_rw_temp = i2c_rw_cmd
calli2c_write_8bit

//slave ack
calli2c_slave_ack

//write register address
i2c_rw_temp = i2c_rw_addr
calli2c_write_8bit

//slave ack
//don't check ACK
calli2c_slave_ack

//start repeat
calli2c_start

//write device address(read)
i2c_rw_temp = i2c_rw_cmd
i2c_rw_temp.0 = 1
calli2c_write_8bit

//slave ack
//don't check ACK
I2C_SDA_INPUT
delayI2C_SHORT_DLY
I2C_SCL_HIGH
delayI2C_SHORT_DLY
I2C_SCL_LOW
delayI2C_SHORT_DLY//这里为特殊情况I2C_SDA不用转为输出

//read data
i2c_rw_temp = 0
calli2c_read_8bit
i2c_rw_byte = i2c_rw_temp//store data

//master nack
calli2c_master_nack

//stop
calli2c_stop

//retune
delayI2C_LONG_DLY
wdreset
ret

//------------------------------
//Input: i2c_rw_addr
// i2c_rw_byte
// i2c_rw_cmd
//Used: i2c_rw_cnt
// i2c_rw_temp
//------------------------------
i2c_write_byte:
//start
calli2c_start

//write device address
i2c_rw_temp = i2c_rw_cmd
calli2c_write_8bit

//slave ack
//don't check ACK
calli2c_slave_ack

//write register address
i2c_rw_temp = i2c_rw_addr
calli2c_write_8bit

//slave ack
//don't check ACK
calli2c_slave_ack

//write data
i2c_rw_temp = i2c_rw_byte
calli2c_write_8bit

//slave ack
//don't check ACK
calli2c_slave_ack

//stop
calli2c_stop

//retune
delayI2C_LONG_DLY
wdreset
ret

EEPROM_RW_CMDequ0xA0
//------------------------------
//函数名: eeprom_read_byte
//Input: i2c_rw_addr
//Used: i2c_rw_cnt
// i2c_rw_temp
//Output: i2c_rw_byte
//------------------------------
eeprom_read_byte:
i2c_rw_cmd = EEPROM_RW_CMD
gotoi2c_read_byte//注意这里用的是跳转
//------------------------------
//函数名: eeprom_write_byte
//Input: i2c_rw_addr
// i2c_rw_byte
//Used: i2c_rw_cnt
// i2c_rw_temp
//注意: 调用完后需要等待一段时间以保证写操作完成
//------------------------------
eeprom_write_byte:
i2c_rw_cmd = EEPROM_RW_CMD
gotoi2c_write_byte//注意这里用的是跳转

//----------------------------------------
//input: ms
//该函数以4M频率为基准时钟实现延时
//----------------------------------------
delayXms:
while(Xms)
{
wdreset
ms_cnt = 20
while(ms_cnt)
{
delay195
ms_cnt--
}
Xms--
}
ret

main0:
.ADJUST_OTP_IHRCR8MIPS// IHRC/2 = 8MIPS, WatchDog Disable, RAM 0,1 temporary be used
sp = 0x30

disgint
inten = 0


pa = 0b0000_0000
paph = 0b1101_0000
pac = 0b0000_0001
pb = 0b0000_0000
pbph = 0b0000_0000
pbc = 0b1111_1111

I2C_SDA_INPUT
I2C_SCL_INPUT

delay200

mova,0b100_11_111
movt16m,a

clkmd.1 = 1//enable watch dog
wdreset


Xms = 100
calldelayXms

test_data = 0
test_addr = 0

main0_loop:
wdreset

//写E2EPROM
i2c_rw_addr = test_addr
i2c_rw_byte = test_data
calleeprom_write_byte

//调用EEPROM写操作函数后要等待一段时间,以保证数据写操作完成
Xms = 20
calldelayXms

//读E2EPROM
i2c_rw_addr = test_addr
calleeprom_read_byte
if(i2c_rw_byte != test_data)
{
//读回的数据比较出错,判断为读写E2PROM出错
nop
}

test_addr ++
test_data --

gotomain0_loop

//----------------FPPA1-------------------
main1:
sp = 52
main1_loop:
gotomain1_loop

本例代码是从实际程序中移植而来,已编译,未做最终调试


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单机片
    +关注

    关注

    0

    文章

    50

    浏览量

    11733
收藏 人收藏

    评论

    相关推荐

    tvl320aic32完成通话的功能,单片机i2s接口发送的数据aic32接收不到怎么解决?

    我们正用tvl320aic32于我们的设备内完成通话的功能,stm32f103的单片机控制,现在已经可以i2c正确的写入与读取aic32的寄存器值,但是在使用
    发表于 11-06 08:16

    51单片机STC8H8K64U通过RA8889/RA8876如何控制彩屏 I2C源码下载

    51单片机STC8H8K64U驱动彩屏,控制器采用瑞佑RA8889. 使用软件模拟I2C方式通信,驱动大屏显示。
    的头像 发表于 11-01 11:02 364次阅读
    51<b class='flag-5'>单片机</b>STC8H8K64U通过RA8889/RA8876如何控制彩屏 <b class='flag-5'>I2C</b>源码下载

    使用C2000 I2C模块连接EEPROM

    电子发烧友网站提供《使用C2000 I2C模块连接EEPROM.pdf》资料免费下载
    发表于 08-27 09:53 0次下载
    使用<b class='flag-5'>C</b>2000 <b class='flag-5'>I2C</b>模块连接<b class='flag-5'>EEPROM</b>

    CYUSB3014通过I2C EEPROM启动时,收到了I2C EEPROM编程失败的错误信息怎么解决?

    我使用的是 CYUSB3014。 在通过 I2C EEPROM 启动时,我收到了 I2C EEPROM 编程失败的错误信息 当我尝试使用 RAM 时,编程成功。 PMODE 引脚连接至
    发表于 07-11 06:12

    如何通过cyusb3014的i2c操作界面操作ads1119的i2c接口

    我使用 cyusb3014 作为 i2c 设备的主机,并使用 ads1119 采集电压。 我需要使用 i2c 操作相关指令。 例子中提供的示例只显示了读写步骤,即 dev_ Addr+reg_
    发表于 05-23 07:30

    利用软件模拟i2c读写EEPROM,超过256个字节就读写不了了的原因?如何处理?

    利用野火的软件模拟i2c读写EEPROMEEPROM的芯片型号为AT24C512,读写256个
    发表于 03-20 06:42

    STM32F103利用软件模拟I2C读写EEPROM,超过385个字节就读写不了的原因?

    在STM32F103的芯片中,利用软件模拟I2C读写EEPROM,在使用页写入的方式进行读写时,能够读写385个字节,(
    发表于 03-19 07:45

    stm32f4软件模拟I2C读写EEPROM无器件响应是什么原因造成的?

    利用STM32F4软件模拟I2C读写EEPROM时,在检测I2C总线设备时,在等待应答阶段,CPU读取SDA线口状态值为1(GPIO_ReadInputDataBit(GPIOB,GP
    发表于 03-19 06:36

    什么是I2C协议 I2C总线的控制逻辑

    在实际使用过程中,I2C比较容易出现的一个问题就是死锁 ,死锁在I2C中主要表现为:I2C死锁时表现为SCL为高,SDA一直为低。
    发表于 03-12 09:17 976次阅读
    什么是<b class='flag-5'>I2C</b>协议 <b class='flag-5'>I2C</b>总线的控制逻辑

    i2c接口由哪几根线组成 i2c接口可以接哪些器件

    I2C接口的线路可以适应不同的系统需求和器件规格,因此具体的线路配置可能会有所不同。但通常来说,时钟线(SCL)和数据线(SDA)是I2C接口的核心线路。
    的头像 发表于 03-05 16:55 3674次阅读
    <b class='flag-5'>i2c</b><b class='flag-5'>接口</b>由哪几根线组成 <b class='flag-5'>i2c</b><b class='flag-5'>接口</b>可以接哪些器件

    CX3 I2C启动失败的原因?怎么解决?

    有一款定制的 CX3 控制板(CYUSB3065 芯片)使用 I2C EEPROM(ST M24M02)连接 OV5460 摄像。 该测试使用了 FX3 SDK1.3.4 的常规 &
    发表于 02-23 06:53

    什么是I2C接口?什么是I3C接口I2CI3C的区别

    I2C接口是一种串行通信协议,全称为Inter-Integrated Circuit,即集成电路间总线。它是一种双向、两线制(SCL和SDA)的串行通信接口,主要用于连接微控制器和其他外围设备,如传感器、存储器、显示器等。
    的头像 发表于 02-17 14:39 5662次阅读
    什么是<b class='flag-5'>I2C</b><b class='flag-5'>接口</b>?什么是<b class='flag-5'>I3C</b><b class='flag-5'>接口</b>?<b class='flag-5'>I2C</b>与<b class='flag-5'>I3C</b>的区别

    LTC2471的I2C接口没有ACK应答是怎么回事?

    LTC2471的接口部分如图所示: 其中SCL和SDA直接与PIC16F1947单片机I2C接口的SCL和SDA相连。VDD电压5V。
    发表于 01-05 11:44

    XV4001BC车载SPI/I2C输出接口的数字输出

    XV4001BC车载SPI/I2C输出接口的数字输出,可实现角速度输出和温度传感器输出,满足汽车导航和通讯系统的要求。SPI / I2C 输出
    发表于 01-02 16:33 0次下载

    i2c接口和spi接口区别

    I2C(Inter-Integrated Circuit)和SPI(Serial Peripheral Interface)都是用于设备间通信的串行接口标准。它们在很多方面有着相似之处,但也有一些
    的头像 发表于 12-25 15:02 3836次阅读