#include "PCA9555.h"
|
|
uint8_t pca9555writedata_config[10];//ÔÝ´æ¼Ä´æÆ÷ËùÓÐÅäÖõÄÊý×é
|
uint8_t pca9555writedata_output[10];
|
void IIC_gpio_pca_init(void)
|
{
|
io_pin_mux_set(SDA_PIN, IO_FUNC0);
|
io_pin_mux_set(SCL_PIN, IO_FUNC0);
|
|
gpio_pin_set_dir(SDA_PIN , GPIO_DIR_OUT, 1);
|
// io_open_drain_set(SDA_PIN, 1);
|
io_pull_set(SDA_PIN , IO_PULL_UP, IO_PULL_UP_LEVEL2);//Êä³ö¸ß×è̬
|
|
gpio_pin_set_dir(SCL_PIN , GPIO_DIR_OUT, 1);
|
//io_open_drain_set(SCL_PIN, 1);
|
io_pull_set(SCL_PIN , IO_HIGH_Z, IO_PULL_UP_NONE);
|
}
|
|
void IIC2_pca_Start(void)
|
{
|
// IIC2_SDA_OUT(); //sdaÏßÊä³ö
|
SDA_1;
|
delay_us(10);
|
SCL_1;
|
delay_us(10);
|
SDA_0;//START:when CLK is high,DATA change form high to low
|
delay_us(10);
|
}
|
void IIC_pca_Ready(void)
|
{
|
|
SCL_1;
|
delay_us(10);
|
SDA_1;
|
delay_us(10);
|
}
|
//²úÉúIICÍ£Ö¹ÐźÅ
|
void IIC2_pca_Stop(void)
|
{
|
|
SDA_0;//STOP:when CLK is high DATA change form low to high
|
|
delay_us(10);
|
SCL_1;
|
delay_us(10);
|
SDA_1;//·¢ËÍI2C×ÜÏß½áÊøÐźÅ
|
delay_us(10);
|
}
|
//µÈ´ýÓ¦´ðÐźŵ½À´
|
//·µ»ØÖµ£º1£¬½ÓÊÕÓ¦´ðʧ°Ü
|
// 0£¬½ÓÊÕÓ¦´ð³É¹¦
|
uint8_t IIC2_Wait_pca_Ack(void)
|
{
|
uint8_t ucErrTime=0;
|
// IIC2_SDA_IN();
|
gpio_pin_set_dir(SDA_PIN , GPIO_DIR_IN, 1); //SDAÉèÖÃΪÊäÈëµÈ´ý½ÓÊն˵ÄÓ¦´ðÐźÅ
|
SDA_1;
|
delay_us(6);
|
SCL_1;
|
delay_us(6);
|
|
while(IIC2_READ_SDA)
|
{
|
ucErrTime++;
|
if(ucErrTime>250)
|
{
|
IIC2_pca_Stop();
|
return 1;
|
}
|
}
|
gpio_pin_set_dir(SDA_PIN , GPIO_DIR_OUT, 1);
|
SCL_0;//ʱÖÓÊä³ö0
|
return 0;
|
|
}
|
//²úÉúACKÓ¦´ð
|
void IIC2_pca_send_Ack(void)
|
{
|
SDA_0;
|
delay_us(10);
|
SCL_1;//¶ÁÈ¡SDAµçƽΪµÍÔòÓÐÓ¦´ð
|
delay_us(10);
|
SCL_0;
|
}
|
//²»²úÉúACKÓ¦´ð
|
void IIC2_pca_send_NAck(void)
|
{
|
SDA_1;
|
delay_us(10);
|
SCL_1;//¶ÁÈ¡SDAµçƽΪ¸ßÔòÎÞÓ¦´ðÐźÅ
|
delay_us(10);
|
SCL_0;
|
}
|
//IIC·¢ËÍÒ»¸ö×Ö½Ú,WRITE
|
//·µ»Ø´Ó»úÓÐÎÞÓ¦´ð
|
//1£¬ÓÐÓ¦´ð
|
//0£¬ÎÞÓ¦´ð
|
void IIC2_Send_pca_Byte(uint8_t txd)
|
{
|
uint8_t t;
|
// IIC2_SDA_OUT();
|
SCL_0;//ÀµÍʱÖÓ¿ªÊ¼Êý¾Ý´«Êä
|
for(t=0; t<8; t++)
|
{
|
if((txd&0x80)>>7)
|
{
|
SDA_1;
|
}
|
else
|
{
|
SDA_0;
|
}
|
txd <<= 1;
|
delay_us(10);
|
SCL_1;
|
delay_us(10);
|
SCL_0;
|
delay_us(10);
|
}
|
SDA_1;//ÐÂÔösdaÀ¸ß
|
delay_us(10);
|
}
|
|
//¶Á1¸ö×Ö½Ú£¬ack=1ʱ£¬·¢ËÍACK£¬ack=0£¬·¢ËÍnACK,²»ÊÇÒ»ÑùµÄ
|
uint8_t IIC2_Read_pca_Byte(unsigned char ack)
|
{
|
unsigned char i,receive=0;
|
// IIC2_SDA_IN();//SDAÉèÖÃΪÊäÈë
|
for(i=0; i<8; i++ )
|
{
|
SCL_0;
|
delay_us(10);
|
SCL_1;
|
receive<<=1;
|
if(IIC2_READ_SDA)receive++;
|
delay_us(5);
|
}
|
if (!ack)
|
IIC2_pca_send_NAck();//·¢ËÍnACK
|
else
|
IIC2_pca_send_Ack(); //·¢ËÍACK
|
return receive;
|
}
|
|
|
/*********************************************************
|
//дpca9555µÚ¶þ²ãÇý¶¯£¬¿É¸¨ÖúÂß¼²»ÆÆ»µ×îµ×²ãÇý¶¯
|
addr оƬµØÖ·£¬0x40±íʾµÚÒ»¸öоƬµØÖ·
|
low_byte дÈëоƬµÄǰ°ËλÊý¾Ý
|
high_byte дÈëоƬµÄǰºóλÊý¾Ý
|
*********************************************************/
|
//дpca9555µÚÒ»²ã£¬×îµ×²ãÇý¶¯
|
void IIC_Write_Pca9555(unsigned char addr,unsigned char reg_addr,unsigned char low_byte,unsigned char high_byte)
|
{
|
IIC2_pca_Start();
|
IIC2_Send_pca_Byte(addr & 0xfe);
|
IIC2_Wait_pca_Ack();
|
IIC2_Send_pca_Byte(reg_addr);
|
IIC2_Wait_pca_Ack();
|
IIC2_Send_pca_Byte(low_byte);
|
IIC2_Wait_pca_Ack();
|
IIC2_Send_pca_Byte(high_byte);
|
IIC2_Wait_pca_Ack();
|
IIC2_pca_Stop();
|
}
|
|
void IIC_Read_Pca9555(uint8_t addr,uint8_t reg_addr,uint8_t* pBuffer,uint16_t num)
|
{
|
IIC2_pca_Start();
|
IIC2_Send_pca_Byte(addr & 0xfe);
|
IIC2_Wait_pca_Ack();
|
IIC2_Send_pca_Byte(reg_addr);
|
IIC2_Wait_pca_Ack();
|
|
IIC2_pca_Start();
|
IIC2_Send_pca_Byte(addr | 0x01);
|
IIC2_Wait_pca_Ack();
|
while (num)
|
{
|
*pBuffer = IIC2_Read_pca_Byte(1);
|
if (num == 1)
|
{
|
IIC2_pca_send_NAck();
|
}
|
else
|
{
|
IIC2_pca_send_Ack();
|
}
|
pBuffer++;
|
num--;
|
}
|
IIC2_pca_Stop();
|
}
|
|
/*дpca9555µÚ¶þ²ãÇý¶¯£¬¿É¸¨ÖúÂß¼²»ÆÆ»µ×îµ×²ãÇý¶¯,¸Ãº¯ÊýĬÈÏÅäÖÃÊä³ö¼Ä´æÆ÷
|
addr оƬµØÖ·£¬0x40±íʾµÚÒ»¸öоƬµØÖ·
|
data_L дÈëоƬµÄǰ°ËλÊý¾Ý
|
data_H дÈëоƬµÄǰºóλÊý¾Ý
|
*/
|
void PCA9555_write_output_port_data(unsigned char addr,unsigned char data_L,unsigned char data_H)
|
{
|
IIC_Write_Pca9555(addr,PCA9555_REG_OUT0,data_L,data_H);// PCA9555_REG_OUT0 Êä³ö¼Ä´æÆ÷0µØÖ·
|
pca9555writedata_output[0]= data_L;//±£´æ¸Ã´ÎÉèÖÃÊý¾Ý
|
pca9555writedata_output[0]= data_H;
|
}
|
|
/*дpca9555µÚ¶þ²ãÇý¶¯£¬¿É¸¨ÖúÂß¼²»ÆÆ»µ×îµ×²ãÇý¶¯,¸Ãº¯ÊýĬÈÏÅäÖÃÊä³ö¼Ä´æÆ÷
|
addr оƬµØÖ·£¬0x40±íʾµÚÒ»¸öоƬµØÖ·
|
data_L дÈëоƬµÄǰ°ËλÊý¾Ý
|
data_H дÈëоƬµÄǰºóλÊý¾Ý
|
*/
|
void PCA9555_write_config_port_data(unsigned char addr,unsigned char data_L,unsigned char data_H)
|
{
|
IIC_Write_Pca9555(addr,PCA9555_REG_CFG0,data_L,data_H);// PCA9555_REG_OUT0 Êä³ö¼Ä´æÆ÷0µØÖ·
|
pca9555writedata_config[0]= data_L;//±£´æ¸Ã´ÎÉèÖÃÊý¾Ý
|
pca9555writedata_config[0]= data_H;
|
}
|
|
/*¶Ápca9555µÚ¶þ²ãÇý¶¯£¬¿É¸¨ÖúÂß¼²»ÆÆ»µ×îµ×²ãÇý¶¯
|
addr оƬµØÖ·£¬0x40±íʾµÚÒ»¸öоƬµØÖ·
|
pBuffer ¶Á³öоƬµÄÊý¾Ý 2¸ö¼Ä´æÆ÷µÄgpioµçƽ
|
*/
|
void PCA9555_readdata(unsigned char addr,unsigned char* pBuffer)
|
{
|
IIC_Read_Pca9555(addr,PCA9555_REG_IN0,pBuffer,2);//2Ϊ¶Á³öоƬÊý¾Ý×éÊý£¬9555Ϊ2×é,È«²¿¶Á³ö
|
}
|
///*ÅäÖÃоƬµÄ¶ÔÓ¦¹Ü½ÅÊäÈëÊä³ö¹¦ÄÜ
|
// addr оƬµØÖ·£¬0x40±íʾµÚÒ»¸öоƬµØÖ·
|
// data_L дÈëоƬµÄǰ°ËλÊý¾Ý 1¸ß×迹ÊäÈë 0Êä³ö ÊäÈë¼Ä´æÆ÷ĬÈÏÉÏÀ
|
// data_H дÈëоƬµÄǰºóλÊý¾Ý
|
//*/
|
//void PCA9555_config_gpio(unsigned char addr,unsigned char data_L,unsigned char data_H)
|
//{
|
// IIC_Write_Pca9555(addr,PCA9555_REG_CFG0,data_L,data_H);// PCA9555_REG_OUT0 Êä³ö¼Ä´æÆ÷0µØÖ·
|
//}
|
|
|
/*ÉèÖÃËùÓÐÊä³ö
|
value ¿ØÖƵÄIOÊä³ö״̬ 0£ºÈ«²¿Êä³öµÍ 1£ºÈ«²¿Êä³ö¸ß
|
½öÏÞÊä³öģʽ
|
*/
|
void PCA9555_Set_All_Output(unsigned char value)
|
{
|
int i;
|
for(i=0;i<4;i++){
|
if(value==0)
|
pca9555writedata_output[i]=0;
|
else
|
pca9555writedata_output[i]=0xff;
|
}
|
PCA9555_write_output_port_data(PCA9555_DEVICE_ADDR,pca9555writedata_output[0],pca9555writedata_output[1]);//È«²¿Êä³öΪ1»ò0
|
//¶àоƬ
|
//PCA9555_writedata(PCA9555_REG_OUT0,pca9555writedata[2],pca9555writedata[3]);
|
}
|
/*ÉèÖõÚÒ»¸öоƬijһͨµÀIO¸ßµÍÊä³ö½öÏÞÊä³ö
|
num ¿ØÖƵÄIOÐòºÅ 1~16
|
value ¿ØÖƵÄIOÊä³ö״̬ 0£ºµÍµçƽ 1£º¸ßµçƽ
|
*/
|
void PCA9555_Set_One_Value_Output(unsigned char num,unsigned char value)
|
{
|
if(num >0 && num <17){//µÚÒ»¸öоƬIO1-16¿ØÖÆ
|
if(num <9){
|
if(value)pca9555writedata_output[0] |= 0x01<<(num - 1);//¸³ÖµÎ»¸ß
|
else pca9555writedata_output[0] &= ~(0x01<<(num - 1));//¸³ÖµÎ»µÍ
|
}
|
else{
|
if(value)pca9555writedata_output[1] |= 0x01<<(num - 9);//¸³ÖµÎ»¸ß
|
else pca9555writedata_output[1] &= ~(0x01<<(num - 9));//¸³ÖµÎ»µÍ
|
}
|
PCA9555_write_output_port_data(PCA9555_DEVICE_ADDR,pca9555writedata_output[0],pca9555writedata_output[1]);
|
}else{//³¬³öоƬ¿ØÖÆ
|
//error
|
}
|
//µ×ÏÂΪ¶àоƬÂß¼
|
// else if(num >16 && num <33){//µÚ¶þ¸öоƬIO1-16¿ØÖÆ£¬Ê¹Óøü¶àIOÒÔ´ËÀàÍÆ£¬×î¶àÖ§³Ö0x000~0x111 ¹²8¸öоƬ´®Áª£¬¹²128¸öIO£¬Èç¹û²»¹»¿ÉÒÔʹÓÃPCA9505£¬40¸öIO£¬×î¶à´®Áª320¸öIO
|
// if(num <25){
|
// if(value)pca9555writedata[2] |= 0x01<<(num - 17);//¸³ÖµÎ»¸ß
|
// else pca9555writedata[2] &= ~(0x01<<(num - 17));//¸³ÖµÎ»µÍ
|
// }
|
// else{
|
// if(value)pca9555writedata[3] |= 0x01<<(num - 25);//¸³ÖµÎ»¸ß
|
// else pca9555writedata[3] &= ~(0x01<<(num - 25));//¸³ÖµÎ»µÍ
|
// }
|
// PCA9555_writedata(PCA9555_REG_OUT1,pca9555writedata[2],pca9555writedata[3]);
|
// }
|
// else{//³¬³öоƬ¿ØÖÆ
|
// //error
|
// }
|
}
|
/*ÉèÖõÚÒ»¸öоƬijһͨµÀIOÊäÈë»òÊä³ö
|
num ¿ØÖƵÄIOÐòºÅ 1~17
|
value ¿ØÖƵÄIOÊä³ö״̬ 0£ºµÍµçƽ 1£º¸ßµçƽ
|
*/
|
void PCA9555_Set_One_Value_Config(unsigned char num,unsigned char value)
|
{
|
|
if(num >0 && num <17){//µÚÒ»¸öоƬIO1-16¿ØÖÆ
|
if(num <9){
|
if(value)pca9555writedata_config[0] |= 0x01<<(num - 1);//¸³ÖµÎ»¸ß
|
else pca9555writedata_config[0] &= ~(0x01<<(num - 1));//¸³ÖµÎ»µÍ
|
}
|
else{
|
if(value)pca9555writedata_config[1] |= 0x01<<(num - 9);//¸³ÖµÎ»¸ß
|
else pca9555writedata_config[1] &= ~(0x01<<(num - 9));//¸³ÖµÎ»µÍ
|
}
|
PCA9555_write_config_port_data(PCA9555_DEVICE_ADDR,pca9555writedata_config[0],pca9555writedata_config[1]);
|
}else{//³¬³öоƬ¿ØÖÆ
|
//error
|
}
|
}
|
void PCA9555_init()
|
{
|
IIC_gpio_pca_init();//ÅäÖÃIIC¹Ü½Å
|
PCA9555_write_config_port_data(PCA9555_DEVICE_ADDR,0x00,0x00);//È«ÅäÖÃΪÊä³ö
|
//²âÊÔ
|
PCA9555_Set_All_Output(1);//È«²¿À¸ß
|
}
|