I2C读写EEPROM的MDK仿真(非模拟I2C)

 在学习STM32 I2C读写EEPROM的过程中,在编写完成I2C读写EEPROM程序时,在没有配套开发板的情况下,或者你的开发板没有类似支持I2C协议读写EEPROM的情况下,如何用KEIL5自带的仿真功能,对所写的应用程序进行仿真调试,验证其是否正确,具有现实意义。

MDK 的一个强大的功能就是提供软件仿真(注意:STM32F4 不支持软件仿真)。
在开始软件仿真之前,先检查一下配置是不是正确,在 IDE 里面点击在这里插入图片描述 ,确定 Target 选
项卡内容如图 4.1.1 所示(主要检查芯片型号和晶振频率,其他的一般默认就可以):在这里插入图片描述
图 4.1.1 Target 选项卡
确认了芯片以及外部晶振频率(8.0Mhz)之后,基本上就确定了 MDK5.14 软件仿真的硬
件环境了,接下来,我们再点击 Debug 选项卡,设置为如图 4.1.2 所示:

在这里插入图片描述
编写debug函数,这里我们参考的依据为MDK的帮助栏,查阅调试章节,这里,我们仿真USART与I2C读写EEPROM,I2C读写EEPROM的必要控制台命令,以及必要的虚拟寄存器,必要的内置函数,我分别作出说明。USART的命令仿真命不再做详细说明,只列出其控制命令,因为USART的仿真,网上已经很多。

首先,你要知道I2C的虚拟端口有哪些,在调试状态下,在控制台输入:DIR VTREG
这条命令现实所有虚拟端口,如下:
在这里插入图片描述
找到 I2C1_IN和I2C1_OUT,这就是I2C1设备虚拟端口,他们是I2C1设备与外界仿真唯一的联系通道,他们功能描述如下:

在这里插入图片描述
必要的WWATCH函数,以及RWATCH函数,MAP指令,用于分配一块存储单元,作为模拟EEPROM用。

你将要写的debug函数,本质上是在模拟一个可以支持I2C读写的EEPROM芯片,因此你将要写的debug函数必须遵守EEPROM芯片读写时序,即如下时序:

在这里插入图片描述
在这里插入图片描述

我这里我直接将控制命令和信号函数放进一个文件,命名为I2C_TEST.ini。
代码如下:
在这里插入图片描述
在这里插入图片描述
I2C_TEST,ini涉及的命令,以及内置函数,读者可查阅MDK的帮助栏,这里不再赘述。
编写I2C读写EEPROM的程序,可以参考野火,或者其他网上资料,这里也将不再赘述。这里仅仅将mian函数以及,仿真结果显示,证明完全可以通过自己编写的debug实现任何你想实现的芯片功能,不再受开发板硬件资源的限制。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
以下是仿真结果,通过虚拟串口打印出来,结果如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STC8单片机内部EEPROM KEIL工程文件源码: /* STC8 内部EEPROM测试 从手册717页上可以看出 STC8的 EEPROM空间为1k 地址在0000h-03ffh 地址也是1024的大小 次程序结合手册 编 大同小异 程序的主要目的是 先清楚地址0 到512 (一个扇区)的数据 然后取 清楚扇区的数据 如果清楚成功 则到的数据都为0xff 然后在向里入 1-ff 1-ff 512个这样的字节 然后在里面的字节 判断是否和入的一样 整个过程都是通过串口在不停的上传给电脑 重点强调 更新数据一定是要先擦除整个扇区 才能更新 这是和外部E2的比较大的区别 但是和flash的法差不多 要求 下载时 STC8 内部晶振为11.0592 电脑打开串口的波特率为9600 */ #include "stc8.h" #define u8 unsigned char #define u16 unsigned int #define CMD_IDLE 0 //空闲模式 #define CMD_READ 1 //IAP字节命令 #define CMD_PROGRAM 2 //IAP字节编程命令 #define CMD_ERASE 3 //IAP字节擦除命令 #define ENABLE_IAP 0X82 //if SYSCLK<20MHz //测试地址 #define IAP_ADDRESS 0X0000 //从手册上可以看出 STC15F2K60S2的EEPROM地址是0x0000- 0x03ff 正好是1k的地址空间 sbit led=P5^5; //P3.5口LED灯定义 //延时函数 void delay(u8 n) { while(n--); } //关闭IAP void IapIdle() { IAP_CONTR=0; //关闭IAP功能 IAP_CMD =0; //清除命令寄存器 IAP_TRIG =0; //清楚触发寄存器 IAP_ADDRH=0X80; //将地址设置到IAP区域 IAP_ADDRL=0; } //从ISP/IAP/EEPROM区域取一个字节 u8 IapReadByte(u16 addr) { u8 dat; //数据缓冲区 IAP_CONTR=ENABLE_IAP; //使能IAP 同时设置等待时间 IAP_CMD=CMD_READ; //设置IAP命令 IAP_ADDRL=addr; //设置IAP低地址 IAP_ADDRH=addr>>8; //设置IAP高地址 IAP_TRIG=0X5a; //触发命令(0x5a) 触摸命令以后 命令才会生效 手册713页 IAP_TRIG=0Xa5; //触发命令(0xa5) delay(10); //等待ISP/IAP/EEPROM操作完成 dat=IAP_DATA; //ISP/IAP/EEPROM数据 IapIdle(); //关闭IAP功能 return dat; //返回 } //一个字节数据到ISP/IAP/EEPROM区域 void IapProgramByte(u16 addr,u8 dat) { IAP_CONTR=ENABLE_IAP; //使能IAP 同时设置等待时间 IAP_CMD=CMD_PROGRAM; //设置IAP命令 IAP_ADDRL=addr; //设置IAP低地址 IAP_ADDRH=addr>>8; //设置IAP高地址 IAP_DATA=dat; //ISP/IAP/EEPROM数据 IAP_TRIG=0X5a; //触发命令(0x5a) 触摸命令以后 命令才会生效 手册713页 IAP_TRIG=0Xa5; //触发命令(0xa5) delay(10); //等待ISP/IAP/EEPROM操作完成 IapIdle(); //关闭IAP功能 } //扇区擦除 void IapEraseSector(u16 addr) { IAP_CONTR=ENABLE_IAP; //使能IAP 同时设置等待时间 IAP_CMD=CMD_ERASE; //设置IAP命令 IAP_ADDRL=addr; //设置IAP低地址 IAP_ADDR

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值