前言
在某宝花五块钱买了这个IO扩展模块,结果卖家不提供资料,在踩了各种坑之后,终于成功的驱动了我的跑马灯。
硬件准备
1 .STM32F103C8T6;
2. PCF8574T成品模块;
补充说明
PCF8574T由软件IIC方式驱动,IIC有一个地址的问题。
PCF8574T地址控制位是 0 1 0 0 A2 A1 A0 0 (PCF8574AT前四位是0111)
其中A2,A1,A0会制作成拨码开关,由用户自由控制地址。因此,一个IIC接口,可以同时控制8个PCF8574T,非常实用。
我将拨码开关全部接到GND,所以IIC地址是0x40。(某宝坑我是0x27,幸亏看了芯片手册)
程序设计
一般IIC驱动都包括以下流程:
IIC_Start();
IIC_Send_Byte(addr);
IIC_Send_Byte(data);
IIC_Stop();
但是对于PCF8574T,还要增加应答位IIC_Wait_Ack();
所以整体的设计思路是:
IIC_Start();
IIC_Send_Byte(0x40);//A2A1A0都接地时,地址为0x40
IIC_Wait_Ack();
IIC_Send_Byte(data);//要发送的8位数据,对芯片P7-P0控制
IIC_Wait_Ack();
IIC_Stop();
上述函数的展开
//产生IIC起始信号
void IIC_Start(void)
{
SDA_OUT(); //sda线输出
IIC_SDA=1;
IIC_SCL=1;
delay_us(4);
IIC_SDA=0;//START:when CLK is high,DATA change form high to low
delay_us(4);
IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
}
//IIC发送一个字节
void IIC_Send_Byte(u8 txd)
{
u8 t;
SDA_OUT();
IIC_SCL=0;//拉低时钟开始数据传输
for(t=0;t<8;t++)
{
IIC_SDA=(txd&0x80)>>7;
txd<<=1;
delay_us(2); //对TEA5767这三个延时都是必须的
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
delay_us(2);
}
}
//等待应答信号到来
//返回值:1-失败 ; 0-成功
u8 IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
SDA_IN(); //SDA设置为输入
IIC_SDA=1;delay_us(1);
IIC_SCL=1;delay_us(1);
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL=0;//时钟输出0
return 0;
}
总结
最终点亮了小灯,还是激动了一下下。