#include "hal_nca9555.h" #define READ_SDA1 GPIO_ReadInputPins(GPIO_PORT_C,GPIO_PIN_10) #define IIC_SDA1(n) (n?GPIO_SetPins(GPIO_PORT_C, GPIO_PIN_10):GPIO_ResetPins(GPIO_PORT_C, GPIO_PIN_10)) #define IIC_SCL1(n) (n?GPIO_SetPins(GPIO_PORT_C, GPIO_PIN_11):GPIO_ResetPins(GPIO_PORT_C, GPIO_PIN_11)) static void delay_us(uint16_t time) { uint16_t i; for(i=time;i>0;i--) { __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop(); } } static void iic1_init(void) { stc_gpio_init_t pstcGpioInit1; GPIO_StructInit(&pstcGpioInit1); pstcGpioInit1.u16PinDir = PIN_DIR_OUT; pstcGpioInit1.u16PinState = PIN_STAT_RST; GPIO_Init(GPIO_PORT_C, GPIO_PIN_10,&pstcGpioInit1); GPIO_Init(GPIO_PORT_C, GPIO_PIN_11,&pstcGpioInit1); GPIO_SetPins(GPIO_PORT_C, GPIO_PIN_10); GPIO_SetPins(GPIO_PORT_C, GPIO_PIN_11); } static void SDA_IN1(void) { stc_gpio_init_t pstcGpioInit3;//iic的引脚 pstcGpioInit3.u16PinDir = PIN_DIR_IN; GPIO_Init(GPIO_PORT_C, GPIO_PIN_10,&pstcGpioInit3); } static void SDA_OUT1(void) { stc_gpio_init_t pstcGpioInit3; pstcGpioInit3.u16PinDir = PIN_DIR_OUT; pstcGpioInit3.u16PinOutputType=PIN_OUT_TYPE_NMOS; GPIO_Init(GPIO_PORT_C, GPIO_PIN_10,&pstcGpioInit3); } static void iic_start(void) { SDA_OUT1(); IIC_SDA1(1); IIC_SCL1(1); delay_us(5); IIC_SDA1(0); delay_us(5); IIC_SCL1(0); } static void iic_stop(void) { SDA_OUT1(); IIC_SCL1(0); IIC_SDA1(0); delay_us(5); IIC_SCL1(1); IIC_SDA1(1); delay_us(5); } static void iic_ack(void) { SDA_OUT1(); IIC_SCL1(0); IIC_SDA1(0); delay_us(5); IIC_SCL1(1); delay_us(5); IIC_SCL1(0); } static void iic_nack(void) { SDA_OUT1(); IIC_SCL1(0); IIC_SDA1(1); delay_us(5); IIC_SCL1(1); delay_us(5); IIC_SCL1(0); } static uint8_t iic_wait_ack(void) { uint16_t t =200; SDA_OUT1(); IIC_SDA1(1);delay_us(1); IIC_SCL1(1);delay_us(1); SDA_IN1(); while(READ_SDA1) { t--; if(t==0) { iic_stop(); return 1; } delay_us(1); } IIC_SCL1(0); return 0; } static void iic_send_byte(uint8_t byte) { uint8_t bit_cnt; SDA_OUT1(); IIC_SCL1(0); for(bit_cnt=0;bit_cnt<8;bit_cnt++) { if(byte&0x80) IIC_SDA1(1); else IIC_SDA1(0); byte<<=1; delay_us(5); IIC_SCL1(1); delay_us(5); IIC_SCL1(0); } } static uint8_t iic_recive_byte(unsigned char ack) { uint8_t retc = 0; uint8_t bit_cnt; SDA_IN1(); for(bit_cnt=0;bit_cnt<8;bit_cnt++) { IIC_SCL1(0); delay_us(5); IIC_SCL1(1); retc=retc<<1; if(READ_SDA1) retc++; delay_us(5); } return(retc); } void nca9555_init(void) { iic1_init(); } uint8_t nca9555_write_byte(uint8_t addr, uint8_t command, uint8_t write_register_data) { uint8_t ret = 1; iic_start(); iic_send_byte(addr); ret = iic_wait_ack(); iic_send_byte(command); ret = iic_wait_ack(); iic_send_byte(write_register_data); ret = iic_wait_ack(); iic_stop(); return SUCCESS; } /* * nca9555读取寄存器值 * * addr 读取地址 * read_register_data 要读取的寄存器 * read_data 读取数据存放地址 * * * 返回值:读取成功返回SUCCESS 失败返回ERROR * * */ uint8_t nca9555_read_byte(uint8_t slave_num, uint8_t addr, uint8_t read_register_data, uint8_t *read_data) { uint8_t ret = 0; iic_start(); iic_send_byte(slave_num); ret = iic_wait_ack(); iic_send_byte(read_register_data); ret = iic_wait_ack(); iic_start(); /* 开始接收数据 */ iic_send_byte(addr); ret = iic_wait_ack(); *read_data = iic_recive_byte(0); iic_stop(); return SUCCESS; } /* * 设置指定GPIO的模式 * * slave_num 需要操作的从机设备 * gpio_port gpio端口 端口0/1 * gpio_num 哪一个GPIO * * 返回值:void * */ void nca9555_set_output_mode(uint8_t slave_num, uint8_t gpio_port, uint8_t gpio_num) { uint8_t register_original_data = 0; if(gpio_port > 1 || gpio_num > 0x80) return; if(gpio_port == 0) { nca9555_read_byte(slave_num, slave_num | HOST_READ_COMMAND, CONFIG_PORT_REGISTER0, ®ister_original_data); nca9555_write_byte(slave_num | HOST_WRITE_COMMAND, CONFIG_PORT_REGISTER0, register_original_data & (~gpio_num)); } else if(gpio_port == 1) { nca9555_read_byte(slave_num, slave_num | HOST_READ_COMMAND, CONFIG_PORT_REGISTER1, ®ister_original_data); nca9555_write_byte( slave_num | HOST_WRITE_COMMAND, CONFIG_PORT_REGISTER1, register_original_data & (~gpio_num)); } } /* * 设置GPIO输出状态 * * slave_num 需要操作的从机设备 * gpio_port gpio端口 端口0/1 * gpio_num 哪一个GPIO * status 输出状态 * * 返回值:void **/ void nca9555_set_gpio_output_status(uint8_t slave_num, uint8_t gpio_port, uint8_t gpio_num, uint8_t status) { uint8_t register_original_data = 0; if(gpio_port > 1 || gpio_num > 0x80) return; if(gpio_port == 0) { nca9555_read_byte(slave_num, slave_num | HOST_READ_COMMAND, OUTPUT_PORT_REGISTER0, ®ister_original_data); if(status == 1) { nca9555_write_byte(slave_num | HOST_WRITE_COMMAND, OUTPUT_PORT_REGISTER0, register_original_data | gpio_num); } else { nca9555_write_byte(slave_num | HOST_WRITE_COMMAND, OUTPUT_PORT_REGISTER0, register_original_data & (~gpio_num)); } } else if(gpio_port == 1) { nca9555_read_byte(slave_num, slave_num | HOST_READ_COMMAND, OUTPUT_PORT_REGISTER1, ®ister_original_data); if(status == 1) { nca9555_write_byte(slave_num | HOST_WRITE_COMMAND, OUTPUT_PORT_REGISTER1, register_original_data | gpio_num); } else { nca9555_write_byte(slave_num | HOST_WRITE_COMMAND, OUTPUT_PORT_REGISTER1, register_original_data & (~gpio_num)); } } } /* * 设置GPIO为输入模式 * * slave_num 需要操作的从机设备 * gpio_port gpio端口 端口0/1 * gpio_num 哪一个GPIO * * 返回值:void **/ void nca9555_set_input_mode(uint8_t slave_num, uint8_t gpio_port, uint8_t gpio_num) { uint8_t register_original_data = 0; if(gpio_port > 1 || gpio_num > 0x80) return; if(gpio_port == 0) { nca9555_read_byte(slave_num, slave_num | HOST_READ_COMMAND, CONFIG_PORT_REGISTER0, ®ister_original_data); nca9555_write_byte(slave_num | HOST_WRITE_COMMAND, CONFIG_PORT_REGISTER0, register_original_data & gpio_num); } else if(gpio_port == 1) { nca9555_read_byte(slave_num, slave_num | HOST_READ_COMMAND, CONFIG_PORT_REGISTER1, ®ister_original_data); nca9555_write_byte(slave_num | HOST_WRITE_COMMAND, CONFIG_PORT_REGISTER1, register_original_data & gpio_num); } } /* * 获取GPIO状态 * * slave_num 需要操作的从机设备 * gpio_port gpio端口 端口0/1 * gpio_num 哪一个GPIO * * 返回值:GPIO状态 **/ uint8_t nca9555_get_gpio_status(uint8_t slave_num, uint8_t gpio_port, uint8_t gpio_num) { uint8_t register_original_data = 0; uint8_t gpio_status = 0; if(gpio_port > 1 || gpio_num > 0x80) { return 2; } if(gpio_port == 0) { nca9555_read_byte(slave_num, slave_num | HOST_READ_COMMAND, INPUT_PORT_REGISTER0, ®ister_original_data); } else if(gpio_port == 1) { nca9555_read_byte(slave_num, slave_num | HOST_READ_COMMAND, INPUT_PORT_REGISTER1, ®ister_original_data); } switch(gpio_num) { case 0x01: gpio_status = register_original_data & gpio_num;break; case 0x02: gpio_status = (register_original_data & gpio_num) >> 1;break; case 0x04: gpio_status = (register_original_data & gpio_num) >> 2;break; case 0x08: gpio_status = (register_original_data & gpio_num) >> 3;break; case 0x10: gpio_status = (register_original_data & gpio_num) >> 4;break; case 0x20: gpio_status = (register_original_data & gpio_num) >> 5;break; case 0x40: gpio_status = (register_original_data & gpio_num) >> 6;break; case 0x80: gpio_status = (register_original_data & gpio_num) >> 7;break; default: break; } return gpio_status; } #include "FreeRTOS.h" #include "FreeRTOSConfig.h" #include "task.h" #include "hal_sc7a20.h" void nca9555_task(void *argv) { nca9555_set_output_mode(SLAVE_ADDR0,GPIO_PORT0,GPIO_Pin00|GPIO_Pin01|GPIO_Pin02|GPIO_Pin03); while(1) { nca9555_set_gpio_output_status(SLAVE_ADDR0,GPIO_PORT0,GPIO_Pin00|GPIO_Pin01|GPIO_Pin02|GPIO_Pin03,HIGH); vTaskDelay(500); nca9555_set_gpio_output_status(SLAVE_ADDR0,GPIO_PORT0,GPIO_Pin00|GPIO_Pin01|GPIO_Pin02|GPIO_Pin03,LOW); vTaskDelay(500); } }