从零实现 IIC 、EEPROM

背景知识:

IIC是半双工,即同一时刻只能向一个方向发送数据。

IIC(inter-integrated circuit)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备。它是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据。在CPU与被控IC之间、IC与IC之间进行双向传送,高速IIC总线一般可达400kbps以上。

所用EEPROM是AT24C02,其容量为256个字节(也太少了吧,哪里够用啊!但是实验学习IIC已经足够),我们常用的是FRAM,其功能类似EEPROM,容量为8K字节。 硬件上可以直接替换EEPROM,也是采用IIC通信。


本次实验是用STM32F429的IO口模拟IIC,实现对EEPROM的控制,能够存入数据和读出数据。

为什么要用IO模拟不用MCU本身的IIC接口?ST为了规避PHILIPS IIC专利问题,将STM32的硬件IIC设计的比较复杂,而且稳定性也不怎么好,所以并不推荐使用。用软件模拟IIC,最大的好处就是方便移植,同一个代码兼容所有MCU,任何一个单片机只要有IO口都可以很快的移植,并不需要特定的IO口。而硬件IIC,则换一款MCU基本就得重新来一次,比较麻烦。

所以实验目的为:通过按键来写入数据、读出数据,并将要写入和已读出的数据显示在LCD上,查看是否一致。


cubemx:

将连接在EEPROM的两根线重命名,方便代码的移植。

从零实现 IIC 、EEPROM_第1张图片

cubemx部分就这么多,因为只有两根线啊!


生成代码

需要增加的文件为4个:myiic.c、myiic.h、eeprom.c、eeprom.h。这四个文件都是从原子的代码中拷贝过来的,我的目的是拿到一个新的项目,知道该如何快速实现效果,而非一个科研人员对底层的无限研究。所以这也是原子的立足意义所在,他让我们能够将精力放在各自领域的精细上,而非通用的底层上,术业有专攻,在此感谢。

myiic.c、myiic.h中都是可以通用的IIC通信协议,只要是用标准IIC的都可以用。eeprom.c也只是针对eeprom去调用myiic.c实现自身功能而已。

上面的文件有本人个人习惯的改动,比如说IO口的输出输入,我还是不习惯寄存器方式,改成了库函数。SDA管脚需要快速地在输入和输出模式下切换,如果是通过HAL_GPIO_Init设置GPIO的模式,那么由于速度太慢导致不满足铁电时序而失败,所以通过直接修改SDA所在GPIO的寄存器可实现快速切换GPIO模式,在推挽输出和输入模式之间切换,用库函数的方式会比寄存器方式要慢,因此我妥协了。

但是,并不是不可以根据库函数来改变IO口模式。只不过我没有进行稳定性测试,所以还是不要像下面那样做了。

还有一个需要注意的是:SDA读一个8位数据时,从最高位开始。写一个8位数据时,也是从最高位开始。

//main.c
        if(_u8KeyStatus[KEY1])
	{
		AT24CXX_Write(0, &h, 1);
		sprintf((char*)InLtdcBuff1, "Writed: %u\r\n",h);
		h++;
	}
	if(_u8KeyStatus[KEY2])
	{
		AT24CXX_Read(0, &h, 1);
		sprintf((char*)InLtdcBuff2, "Readed: %u\r\n",h);
	}
	

实验结果:

可以看出写入的和读出的一致。


结论:

还是那句话,实践出真知。

你可能感兴趣的:(嵌入式编程,存储类)