#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);//È«²¿À­¸ß }