TCA6416是一个I2C转16路IO的芯片,首先我们想一个输入输出端口(IO)至少要有3个寄存器控制把。
一路是方向,控制是输入还是输出。
一路是输出,控制输出0还是1.
一路是输入,读取引脚上的电平。
除了这三个必须寄存器之外,TCA6416还提供了一个极性转换的寄存器,我们不管这个寄存器,让它保持默认数值就可以。
下面是我写的代码,这里用的I2C接口也是我们上个BLOG提供的接口。
#define TCA6416_DEV_ADDR 0x40
#define I2C_WR 0 /* ???bit */
#define I2C_RD 1 /* ???bit */
static unsigned char reg_buff [8] = {0,0,0xff,0xff,0,0,0xff,0xff } ;
void tca6416_update_reg (unsigned char reg ){
unsigned short t ;
unsigned char r ;reg &=7 ;
while(1){r= i2c_CheckDevice(TCA6416_DEV_ADDR);if (r==0) break; }
i2c_start();
i2c_send_byte(TCA6416_DEV_ADDR | I2C_WR); t= i2c_WaitAck() ;if (t==1) return 0;
i2c_send_byte(reg ) ; t= i2c_WaitAck() ;if (t==1) return 0;
i2c_send_byte(reg_buff[reg ]) ; t= i2c_WaitAck() ;if (t==1) return 0;
i2c_stop();
}
void tca6416_wr_reg_bit ( unsigned char reg ,unsigned char bit ,unsigned char v ) {
unsigned char t ;
reg &=7 ;
t = reg_buff [reg] ;
if (v) t |= 1 << bit ;else t&=~(1<<bit) ;
if( t!=reg_buff[reg]) printf("Update reg%d from %02x to %02x \r\n",reg , reg_buff[reg ],t);
reg_buff[reg ]=t;
tca6416_update_reg(reg) ;
}
unsigned char tca6416_rd_reg_bit (unsigned char reg ,unsigned char bit ){
unsigned short t ; unsigned char r ;
while(1){r= i2c_CheckDevice(TCA6416_DEV_ADDR);if (r==0) break; }
i2c_start();
i2c_send_byte(TCA6416_DEV_ADDR | I2C_WR); t= i2c_WaitAck() ;if (t==1) return 0;
i2c_send_byte(reg ) ; t= i2c_WaitAck() ;if (t==1) return 0;
i2c_start();
i2c_send_byte(TCA6416_DEV_ADDR | I2C_RD); t= i2c_WaitAck() ;if (t==1) return 0;
r = i2c_ReadByte() ;
i2c_stop();
r &= 1<<bit ;
r = !!r ;
return r ;
}
void set_tca6416( unsigned char p,unsigned b, unsigned v){
p &= 1 ; b &= 0x7; v=!!v;
tca6416_wr_reg_bit( 2 + p , b,v ) ; // out
tca6416_wr_reg_bit( 6 + p , b,0 ) ; // dir
}
unsigned char get_tca6416( unsigned char p,unsigned b ){
unsigned char r ;
p &= 1 ;
b &= 0x7;
tca6416_wr_reg_bit( 6 + p , b,1 ) ; // dir
r = tca6416_rd_reg_bit(p,b);
r=!!r;
return r ;
}
这里最终对外的函数就只有set_tca6416和get_tca6416这两个,其中参数p代表port,取值范围是0或1,b代表bit位,取值范围是0-7。v取0或者1.
另外一个I2C物理总线上可以接2路TCA6416,使用时候要通过地址线分开,此时可以给这两个函数再加一个参数数进行区分。
1060

被折叠的 条评论
为什么被折叠?



