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

    文章

    58

    浏览量

    12943
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    RK平台I2C开发:从硬件原理到实战排查

    在嵌入式开发中,I2C 总线是连接外设的 “桥梁”—— 小到传感器、EEPROM,大到 LCD 驱动器、音频芯片,都离不开它的控制。而瑞芯微(Rockchip)系列芯片作为主流嵌入式方案,其
    的头像 发表于 02-05 13:42 2695次阅读
    RK平台<b class='flag-5'>I2C</b>开发:从硬件原理到实战排查

    利用I2C接口采用轮询方式读写EEPROM芯片

    利用I2C接口,采用轮询方式读写EEPROM芯片 #define TESTI2C2 //I2C
    发表于 01-23 06:00

    RA MCU众测宝典 | I²C读取EEPROM

    I2C协议读取EEPROM数据。瑞萨嵌入式小百科将带着大家从I2C总线原理、EEPROM(AT24C02)特性,到FSP中
    的头像 发表于 01-13 18:05 8414次阅读
    RA MCU众测宝典 | <b class='flag-5'>I</b>²<b class='flag-5'>C</b>读取<b class='flag-5'>EEPROM</b>

    CW32单片机I2C接口读写EEPROM芯片

    一、概述 CW32L083 内部集成 2I2C 控制器,能按照设定的传输速率(标准,快速,高速)将需要发送的数据按照 I2C 规范串行发送到 I2C 总线上,或从总线上接收数据
    发表于 01-12 08:20

    基于FPGA的I2C控制模块设计

    I2C_WRITE_WDATA.v模块实现I2C写时序,I2C_Controller (I2C控制器)例化了I2C_WRITE_WDATA.
    的头像 发表于 12-26 09:48 6163次阅读
    基于FPGA的<b class='flag-5'>I2C</b>控制模块设计

    AS32X601的I2C模块操作EEPROM详解

    国科安芯推出的AS32X601系列MCU芯片内置的I2C模块提供了符合工业标准的两线串行制接口,可用于MCU和外部I2C设备的通讯。I2C
    的头像 发表于 12-21 21:39 1675次阅读
    AS32X601的<b class='flag-5'>I2C</b>模块操作<b class='flag-5'>EEPROM</b>详解

    CW32单片机I2C接口读写EEPROM芯片

    u8State = 0; uint8_t receivedflag = 0; //读取完成标志 6.主程序:利用I2C接口,采用中断方式读写EEPROM芯片(CW24
    发表于 12-09 07:43

    基于CW32 MCU的I2C接口优化稳定读写EEPROM关键技术

    CW32 MCU优化I2C接口,确保在与EEPROM芯片通信时的稳定性。内容涵盖以下几个关键技术点: I2C时序与频率调整:介绍如何根据EEPRO
    发表于 12-03 07:29

    基于芯源CW32F030 MCU的I2C通信及应用

    。 停止通信:发送停止信号,结束数据传输。 5. 实例代码:I2C读写EEPROM下面的代码展示了如何使用CW32F030 MCU通过I2C接口
    发表于 11-18 08:29

    深入剖析I2C协议

    I2C也是一种可以多主设备,多从设备的总线协议,通过地址索引,I2C可以使能所需从设备,I2C的出现主要是用来实现不同集成电路组件之间的控制功能,比如通过I2C协议,连接MCU与LC
    的头像 发表于 08-21 15:10 3960次阅读
    深入剖析<b class='flag-5'>I2C</b>协议

    【沁恒CH585开发板免费试用体验】I2C 读写EEPROM (三)

    */ I2C_Stop();/* 发送停止信号 */ return ucAck; } 注释很清楚,对照I2C的协议看就行。 接着就是实现AT2C02的读写操作
    发表于 08-05 22:25

    【沁恒CH585开发板免费试用体验】I2C 读写EEPROM (二)

    _GetFlagStatus(I2C_FLAG_BUSY) != RESET); } 主要配置I2C模式、低电平占空比、I2C寻址模式以及通信速率,最后使能I2C设备。 初始化完成后
    发表于 08-05 22:13

    【沁恒CH585开发板免费试用体验】I2C 读写EEPROM (一)

    I2C接口,并不需要用软件去模拟 SDA 和SCL 线的时序。 Figure 1‑3 主机写数据到从 Figure 1‑4 主机由从中读数据 图例: 数据由主机传输至从
    发表于 08-05 22:09

    高效率、6通道、白光LED驱动器,带I2C接口 skyworksinc

    电子发烧友网为你提供()高效率、6通道、白光LED驱动器,带I2C接口相关产品参数、数据手册,更有高效率、6通道、白光LED驱动器,带I2C接口的引脚图、接线图、封装手册、中文资料、英
    发表于 07-30 18:31
    高效率、6通道、白光LED驱动器,带<b class='flag-5'>I2C</b><b class='flag-5'>接口</b> skyworksinc

    简单了解I2C接口

    在电子电路的复杂世界里,各种电路模块设备需要相互通信才能协同工作 ,I2C接口就像是电路模块设备间的沟通桥梁,今天就带大家深入了解它。
    的头像 发表于 05-08 14:15 2844次阅读
    简单了解<b class='flag-5'>I2C</b><b class='flag-5'>接口</b>