从零实现 IIC 、拓展IO口芯片PCF8574T

前言:

ST的IIC因为专利问题十分不好用,所以我们需要用GPIO来模拟IIC,IIC一共两根线,SDA、SCL。那么也能看出来,是半双工通讯方式。

本次实验主要是使用PCF8574T,它是一个专门用于拓展IO口的芯片,用IIC控制。最多支持一条IIC总线上挂8个PCF8574T芯片。每个芯片支持8个IO口,也就是两根IIC线控制64个IO口。其实还有一根INT中断线,专门通知MCU,拓展的IO口中有改变电平状态的。


从零实现 IIC 、拓展IO口芯片PCF8574T_第1张图片

介绍下芯片的管脚功能:

A0~A2为地址线,前面不是说了一根IIC总线上最多只能支持8个芯片吗,其实就是最大支持8个地址。这三根线就是设置芯片地址用的,板子上A0~A2都接GND,那么这个芯片的ID就是0x00。若都接VCC,那么ID为0x07。

p0~p7为拓展的IO口,可以被控制电平状态,也可以获取电平状态。

INT为中断管脚,是一个输出管脚,接MCU输入模式的IO口。这个管脚是非常重要和有趣的!它的默认电平状态为高,当PCF8574T上电时会记录p0~p7的电平,若有外界改变时会拉低INT(由MCU控制改变电平状态的时候并不会触发INT)。在这个时候,若外界再次改变则INT又会为高。也就是说,电平改变与否是跟上电状态时的电平比较,而通过读取一遍PCF8574T的数据,则可以刷新这个记录的初始值。此时,INT从低变为高。所以,我们每当获取到INT为低时,一定要读一遍值!INT就会为高了(这是PCF8574T再被读值的时候自动刷新了INT),这样就可以接收到下一次的改变了。

举个例子:

p4上电状态为1,此时INT为1。若我让p4接0,那么INT会为0。再次让p4为1,则INT会变回1。若在p4为0时、INT为0时,读一下值,那么p4仍未0,INT为1了。下一次p4变为1,INT会变为0。

p4上电状态为0,此时INT为1。若我让p4接1,那么INT会为0。再次让p4为0,则INT会变回1。若在p4为0时、INT为0时,不读值,而去发送改变p0的值,那么p4仍未0,INT为1了。下一次p4变为1,INT仍旧为1不会再被触发了,这个时候再去读PCF8574T的值也没有用了,INT会始终为1。

关系图我画出图来方便理解:

由此可以看出,INT是十分重要的,

SCL、SDA是IIC的时钟线和数据线。

Vss、VDD是电源地和电源正。


配置cubemx

cubemx配置部分是将SCL(PH4)、SDA(PH5)配置为推挽输出,INT接的PB12配置为输入模式。没什么好截图的了


代码生成

代码部分,其实就是上一个实验STM32 IIC实验:cubemx EEPROM的拓展,PCF8574T的驱动调用myiic.c。

实验目的:通过KEY0改变PCF8574T的p0来打开和关闭蜂鸣器(硬件相连),通过更改p4来触发INT(可以通过接地),然后在循环中获取INT为低时改变LED1的状态。

	if(_u8KeyStatus[KEY1])
	{
		_u8BeepStatus = !_u8BeepStatus;
		PCF8574_WriteBit(BEEP_IO, _u8BeepStatus);
	}
	//若PCF8574_INT的管脚为低电平则表示有中断发生,需要读一个字节
	if(PCF8574_INT() == GPIO_PIN_RESET)
	{
		if(PCF8574_ReadBit(EX_IO))
		{
			LED_Off(1);				//若EX_IO为高电平,则关LED1(默认状态,因为EX_IO被硬件拉高)
		}
		else
		{
			LED_On(1);				//若EX_IO为低电平,则开LED1
		}
	}

实验效果:如实验目的一样,能够成功。

结论:

实践出真知,多质疑权威,多找逻辑漏洞,在探寻的时候就能学到很多东西。

你可能感兴趣的:(基础嵌入式编程,调试经验)