| | |
| | | #include "PCA9555.h" |
| | | |
| | | uint8_t gps_led_output_state,tts_enbale_output_state,wake_up_output_state,air780e_enable_output_state,sos_enable_output_state,gps_backup_output_state,gps_power_output_state,main_ri_output_state;//1组output IO口从左到右1.0~1.7 |
| | | uint8_t mcu_a_output_state,chg_g_output_state,lora_irq_output_state,lora_nrst_output_state,adc_minius_output_state,input_5v_output_state,pwr_on_output_state,pwr_enable_output_state;//2组output IO口从左到右0.0~0.7 |
| | | uint8_t pca9555writedata_config[10];//暂存寄存器所有配置的数组 |
| | | uint8_t pca9555writedata_output[10]; |
| | | uint8_t pca9555writedata_output[10];//暂存输出高低电平配置的数组 |
| | | uint8_t pca9555writedata_input[10];//暂存输入寄存器所有配置的数组 |
| | | uint8_t pca9555writedata_polarity[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_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); |
| | |
| | | |
| | | void IIC2_pca_Start(void) |
| | | { |
| | | // IIC2_SDA_OUT(); //sda线输出 |
| | | //// 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); |
| | | |
| | | // IIC2_SDA_OUT(); //sda线输出 |
| | | SDA_1; |
| | | delay_us(10); |
| | | // delay_us(10); |
| | | SCL_1; |
| | | delay_us(10); |
| | | // delay_us(10); |
| | | SDA_0;//START:when CLK is high,DATA change form high to low |
| | | delay_us(10); |
| | | SCL_0;//钳住I2C总线,准备发送或接收数据 |
| | | } |
| | | void IIC_pca_Ready(void) |
| | | { |
| | |
| | | void IIC2_pca_Stop(void) |
| | | { |
| | | |
| | | SDA_0;//STOP:when CLK is high DATA change form low to high |
| | | // 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); |
| | | |
| | | delay_us(10); |
| | | SCL_1; |
| | | delay_us(10); |
| | | SDA_1;//发送I2C总线结束信号 |
| | | delay_us(10); |
| | | SCL_0; |
| | | SDA_0;//sToP:when ClK is high DATA change form low to high |
| | | delay_us(10); |
| | | SCL_1; |
| | | //delay_us(10); |
| | | SDA_1;//7发送I2C总线结束信号 |
| | | delay_us(10); |
| | | } |
| | | //等待应答信号到来 |
| | | //返回值:1,接收应答失败 |
| | |
| | | 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); |
| | | // IIC2_SDA_IN(); |
| | | |
| | | gpio_pin_set_dir(SDA_PIN,GPIO_DIR_IN,1); //SDA设置为输入等待接收端的应答信号 |
| | | SDA_1; |
| | | delay_us(6); |
| | | SCL_1; |
| | | delay_us(6); |
| | | // SDA_1; |
| | | // delay_us(6); |
| | | |
| | | |
| | | while(IIC2_READ_SDA) |
| | | { |
| | |
| | | if(ucErrTime>250) |
| | | { |
| | | IIC2_pca_Stop(); |
| | | gpio_pin_set_dir(SDA_PIN , GPIO_DIR_OUT, 1); |
| | | return 1; |
| | | } |
| | | } |
| | | gpio_pin_set_dir(SDA_PIN , GPIO_DIR_OUT, 1); |
| | | gpio_pin_set_dir(SDA_PIN , GPIO_DIR_OUT, 0); |
| | | 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; |
| | | SDA_0;//读取SDA电平为低则有应答 |
| | | delay_us(10); |
| | | SCL_1; |
| | | 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; |
| | | SDA_1;//读取SDA电平为高则无应答信号 |
| | | delay_us(10); |
| | | SCL_1; |
| | | delay_us(10); |
| | | SCL_0; |
| | | } |
| | | //IIC发送一个字节,WRITE |
| | | //返回从机有无应答 |
| | | //1,有应答 |
| | | //0,无应答 |
| | | uint8_t statistic_num; |
| | | void IIC2_Send_pca_Byte(uint8_t txd) |
| | | { |
| | | uint8_t t; |
| | | // IIC2_SDA_OUT(); |
| | | SCL_0;//拉低时钟开始数据传输 |
| | | // delay_us(10); |
| | | for(t=0; t<8; t++) |
| | | { |
| | | if((txd&0x80)>>7) |
| | |
| | | SCL_0; |
| | | delay_us(10); |
| | | } |
| | | SDA_1;//新增sda拉高 |
| | | delay_us(10); |
| | | // statistic_num=txd; |
| | | // 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设置为输入 |
| | | gpio_pin_set_dir(SDA_PIN,GPIO_DIR_IN,0); //设置为输入读取电平 |
| | | // io_pull_set(SDA_PIN , IO_HIGH_Z, IO_PULL_UP_NONE); |
| | | for(i=0; i<8; i++ ) |
| | | { |
| | | SCL_0; |
| | | delay_us(10); |
| | | delay_us(6);//修改时间 |
| | | 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 |
| | | SCL_0; |
| | | if(ack==2){ |
| | | gpio_pin_set_dir(SDA_PIN,GPIO_DIR_OUT,0); //设置为输出恢复ACK |
| | | }else{ |
| | | gpio_pin_set_dir(SDA_PIN,GPIO_DIR_OUT,1); //设置为输出恢复ACK |
| | | } |
| | | |
| | | // io_pull_set(SDA_PIN , IO_PULL_UP, IO_PULL_UP_LEVEL2);//输出高阻态 |
| | | // if (!ack) |
| | | // IIC2_pca_send_NAck();//发送nACK |
| | | // else |
| | | // IIC2_pca_send_Ack(); //发送ACK |
| | | return receive; |
| | | } |
| | | |
| | |
| | | high_byte 写入芯片的前后位数据 |
| | | *********************************************************/ |
| | | //写pca9555第一层,最底层驱动 |
| | | int temp_ack3,temp_ack4,temp_ack5,temp_ack6; |
| | | 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(); |
| | | temp_ack3=IIC2_Wait_pca_Ack(); |
| | | IIC2_Send_pca_Byte(reg_addr); |
| | | IIC2_Wait_pca_Ack(); |
| | | temp_ack4=IIC2_Wait_pca_Ack(); |
| | | IIC2_Send_pca_Byte(low_byte); |
| | | IIC2_Wait_pca_Ack(); |
| | | temp_ack5=IIC2_Wait_pca_Ack(); |
| | | IIC2_Send_pca_Byte(high_byte); |
| | | IIC2_Wait_pca_Ack(); |
| | | temp_ack6=IIC2_Wait_pca_Ack(); |
| | | IIC2_pca_Stop(); |
| | | } |
| | | |
| | | // IIC2_Start(); |
| | | // IIC2_Send_Byte(addr & 0xfe); //发送写命令 |
| | | // temp_ack3=IIC2_Wait_pca_Ack(); |
| | | // IIC2_Send_Byte(reg_addr); //发送地址 |
| | | // temp_ack4=IIC2_Wait_pca_Ack(); |
| | | // IIC2_Send_Byte(low_byte); //发送字节 |
| | | // temp_ack5=IIC2_Wait_pca_Ack(); |
| | | // IIC2_Send_Byte(high_byte); //发送字节 |
| | | // temp_ack6=IIC2_Wait_pca_Ack(); |
| | | // IIC2_Stop();//产生一个停止条件 |
| | | |
| | | } |
| | | /* |
| | | // IIC2_Start(); |
| | | // IIC2_Send_Byte(addr & 0xfe); //发送写命令 |
| | | // temp_ack3=IIC2_Wait_Ack(); |
| | | // IIC2_Send_Byte(reg_addr); //发送地址 |
| | | // temp_ack4=IIC2_Wait_Ack(); |
| | | // IIC2_Send_Byte(low_byte); //发送字节 |
| | | // temp_ack5=IIC2_Wait_Ack(); |
| | | // IIC2_Send_Byte(high_byte); //发送字节 |
| | | // temp_ack6=IIC2_Wait_Ack(); |
| | | // IIC2_Stop();//产生一个停止条件 |
| | | */ |
| | | int temp_ack,temp_ack1,temp_ack2; |
| | | uint8_t temp=0; |
| | | 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(); |
| | | temp_ack=IIC2_Wait_pca_Ack(); |
| | | IIC2_Send_pca_Byte(reg_addr); |
| | | IIC2_Wait_pca_Ack(); |
| | | temp_ack1=IIC2_Wait_pca_Ack(); |
| | | |
| | | IIC2_pca_Start(); |
| | | IIC2_Send_pca_Byte(addr | 0x01); |
| | | IIC2_Wait_pca_Ack(); |
| | | temp_ack2=IIC2_Wait_pca_Ack(); |
| | | |
| | | // if(num==2){ |
| | | // pBuffer[0]=IIC2_Read_Byte(1); |
| | | // pBuffer[1]=IIC2_Read_Byte(0); |
| | | // }else{ |
| | | // pBuffer[0]=IIC2_Read_Byte(0); |
| | | // } |
| | | |
| | | while (num) |
| | | { |
| | | *pBuffer = IIC2_Read_pca_Byte(1); |
| | | *pBuffer = IIC2_Read_pca_Byte(num); |
| | | if (num == 1) |
| | | { |
| | | IIC2_pca_send_NAck(); |
| | | //IIC2_NAck(); |
| | | } |
| | | else |
| | | { |
| | | IIC2_pca_send_Ack(); |
| | | //IIC2_Ack(); |
| | | } |
| | | pBuffer++; |
| | | num--; |
| | | } |
| | | IIC2_pca_Stop(); |
| | | |
| | | |
| | | // IIC2_Start(); |
| | | // IIC2_Send_Byte(addr & 0xfe); //发送写命令 |
| | | // IIC2_Wait_pca_Ack(); |
| | | // IIC2_Send_Byte(reg_addr); //发送读地址 |
| | | // IIC2_Wait_pca_Ack(); |
| | | // IIC2_Start(); |
| | | // IIC2_Send_Byte(0x41); //发送读命令,进入接收模式 |
| | | // IIC2_Wait_pca_Ack(); |
| | | // temp=IIC2_Read_Byte(0); |
| | | // IIC2_Stop(); //产生一个停止条件 |
| | | |
| | | } |
| | | |
| | | /*写pca9555第二层驱动,可辅助逻辑不破坏最底层驱动,该函数默认配置输出寄存器 |
| | |
| | | { |
| | | 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; |
| | | pca9555writedata_output[1]= data_H; |
| | | } |
| | | |
| | | /*写pca9555第二层驱动,可辅助逻辑不破坏最底层驱动,该函数默认配置输出寄存器 |
| | |
| | | { |
| | | 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; |
| | | pca9555writedata_config[1]= data_H; |
| | | } |
| | | /*写pca9555第二层驱动,可辅助逻辑不破坏最底层驱动,该函数默认配置输入极性翻转寄存器 1翻转 2不变 |
| | | addr 芯片地址,0x40表示第一个芯片地址 |
| | | data_L 写入芯片的前八位数据 |
| | | data_H 写入芯片的前后位数据 |
| | | */ |
| | | void PCA9555_write_polarity_port_data(unsigned char addr,unsigned char data_L,unsigned char data_H) |
| | | { |
| | | IIC_Write_Pca9555(addr,PCA9555_REG_POL0,data_L,data_H);// PCA9555_REG_OUT0 输出寄存器0地址 |
| | | pca9555writedata_polarity[0]= data_L;//保存该次设置数据 |
| | | pca9555writedata_polarity[1]= data_H; |
| | | } |
| | | |
| | | /*读pca9555第二层驱动,可辅助逻辑不破坏最底层驱动 |
| | | addr 芯片地址,0x40表示第一个芯片地址 |
| | | pBuffer 读出芯片的数据 2个寄存器的gpio电平 |
| | | pBuffer 读出芯片的数据 2个输入寄存器的值仅限输入模式使用 |
| | | */ |
| | | void PCA9555_readdata(unsigned char addr,unsigned char* pBuffer) |
| | | { |
| | | IIC_Read_Pca9555(addr,PCA9555_REG_IN0,pBuffer,2);//2为读出芯片数据组数,9555为2组,全部读出 |
| | | } |
| | | /*读pca9555第二层驱动,可辅助逻辑不破坏最底层驱动 |
| | | addr 芯片地址,0x40表示第一个芯片地址 |
| | | pBuffer 读出芯片的数据 2个寄存器的值仅限输出模式,此模式下仅回复输入输出的控制模式的值,而非电平值 |
| | | */ |
| | | void PCA9555_readdata_from_output_register(unsigned char addr,unsigned char* pBuffer) |
| | | { |
| | | IIC_Read_Pca9555(addr,PCA9555_REG_OUT0,pBuffer,2);//2为读出芯片数据组数,9555为2组,全部读出 |
| | | } |
| | | /*读pca9555第二层驱动,可辅助逻辑不破坏最底层驱动 |
| | | addr 芯片地址,0x40表示第一个芯片地址 |
| | | pBuffer 读出芯片的数据 2个寄存器的值仅限输出模式,此模式下仅回复输入输出的控制模式的值,而非电平值 |
| | | */ |
| | | void PCA9555_readdata_from_polarity_register(unsigned char addr,unsigned char* pBuffer) |
| | | { |
| | | IIC_Read_Pca9555(addr,PCA9555_REG_POL0,pBuffer,2);//2为读出芯片数据组数,9555为2组,全部读出 |
| | | } |
| | | /*读pca9555第二层驱动,可辅助逻辑不破坏最底层驱动 |
| | | addr 芯片地址,0x40表示第一个芯片地址 |
| | | pBuffer 读出芯片的数据 配置2个寄存器的数值 |
| | | */ |
| | | void PCA9555_readdata_from_config_register(unsigned char addr,unsigned char* pBuffer) |
| | | { |
| | | IIC_Read_Pca9555(addr,PCA9555_REG_CFG0,pBuffer,2);//2为读出芯片数据组数,9555为2组,全部读出 |
| | | } |
| | | ///*配置芯片的对应管脚输入输出功能 |
| | | // addr 芯片地址,0x40表示第一个芯片地址 |
| | |
| | | } |
| | | /*设置第一个芯片某一通道IO输入或输出 |
| | | num 控制的IO序号 1~17 |
| | | value 控制的IO输出状态 0:低电平 1:高电平 |
| | | value 控制的IO输出状态 0:输出 1:输入 |
| | | */ |
| | | void PCA9555_Set_One_Value_Config(unsigned char num,unsigned char value) |
| | | { |
| | |
| | | } |
| | | void PCA9555_init() |
| | | { |
| | | IIC_gpio_pca_init();//配置IIC管脚 |
| | | PCA9555_write_config_port_data(PCA9555_DEVICE_ADDR,0x00,0x00);//全配置为输出 |
| | | //IIC_gpio_pca_init();//配置IIC管脚 |
| | | |
| | | PCA9555_write_config_port_data(PCA9555_DEVICE_ADDR,PCA_OUTPUT_CONFIG_MASK,PCA_OUTPUT_CONFIG_MASK);//全配置为输出 |
| | | |
| | | //PCA9555_write_config_port_data(PCA9555_DEVICE_ADDR,PCA_INPUT_CONFIG_MASK,PCA_INPUT_CONFIG_MASK);//全配置为输入 |
| | | //PCA9555_write_polarity_port_data(PCA9555_DEVICE_ADDR,0x00,0x00);//翻转 |
| | | PCA9555_Set_One_Value_Config(WAKE_UP,1); |
| | | //PCA9555_Set_All_Output(1); |
| | | |
| | | //PCA9555_readdata_from_output_register(PCA9555_DEVICE_ADDR,pca9555writedata_input); |
| | | //PCA9555_Set_One_Value_Output(AIR780E_ENBALE,0); |
| | | //PCA9555_Set_One_Value_Output(PWR_ON,0); |
| | | // PCA9555_Set_All_Output(0); |
| | | //PCA9555_readdata_from_polarity_register(PCA9555_DEVICE_ADDR,pca9555writedata_input); |
| | | PCA9555_readdata(PCA9555_DEVICE_ADDR,pca9555writedata_input);//读输入寄存器的值 |
| | | PCA9555_readdata_from_config_register(PCA9555_DEVICE_ADDR,pca9555writedata_config); |
| | | // PCA9555_Set_All_Output(0);//全部拉低 |
| | | |
| | | //测试 |
| | | PCA9555_Set_All_Output(1);//全部拉高 |
| | | //PCA9555_Set_All_Output(1);//全部拉高 |
| | | //PCA9555_Set_All_Output(0);//全部拉低 |
| | | |
| | | } |
| | | |