芯片引脚及描述: 驱动代码: 头文件:nca9555.h
#ifndef USER_APP_NCA9555_H_
#define USER_APP_NCA9555_H_
#include "em_gpio.h"
#define IIC_SCL_GPIO_PORT gpioPortB
#define IIC_SCL_GPIO_PIN 1
#define IIC_SDA_GPIO_PORT gpioPortB
#define IIC_SDA_GPIO_PIN 2
#define IIC_SCL_SET_GPIO_OUTPUT_STATUS(status) if(status == 1) GPIO_PinOutSet(IIC_SCL_GPIO_PORT, IIC_SCL_GPIO_PIN);\
else if(status == 0) GPIO_PinOutClear(IIC_SCL_GPIO_PORT, IIC_SCL_GPIO_PIN);
#define IIC_SDA_SET_GPIO_OUTPUT_STATUS(status) if(status == 1) GPIO_PinOutSet(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN);\
else if(status == 0) GPIO_PinOutClear(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN);
#define IIC_SDA_GET_GPIO_INPUT_STATUS GPIO_PinInGet(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN)
void IIC_gpio_init(void);
void IIC_start(void);
void IIC_stop(void);
uint8_t IIC_wait_ack(void);
void IIC_ack(void);
void IIC_nack(void);
void IIC_send_byte(uint8_t txd);
void IIC_send_byte(uint8_t txd);
uint8_t IIC_read_byte(unsigned char ack);
#define SUCCESS 0
#define ERROR 1
#define SLAVE_ADDR0 0x40
#define SLAVE_ADDR1 0x42
#define SLAVE_ADDR2 0x44
#define HOST_WRITE_COMMAND 0x00
#define HOST_READ_COMMAND 0x01
#define INPUT_PORT_REGISTER0 0x00
#define INPUT_PORT_REGISTER1 0x01
#define OUTPUT_PORT_REGISTER0 0x02
#define OUTPUT_PORT_REGISTER1 0x03
#define POLARITY_INVERSION_PORT_REGISTER0 0x04
#define POLARITY_INVERSION_PORT_REGISTER1 0x05
#define CONFIG_PORT_REGISTER0 0x06
#define CONFIG_PORT_REGISTER1 0x07
#define GPIO_PORT0 0
#define GPIO_PORT1 1
#define GPIO_0 0x01
#define GPIO_1 0x02
#define GPIO_2 0x04
#define GPIO_3 0x08
#define GPIO_4 0x10
#define GPIO_5 0x20
#define GPIO_6 0x40
#define GPIO_7 0x80
#define NCA9555_WAIT_IS_RETURN_SUCCESS(flag, tips) if(flag != SUCCESS)\
{ \
printf("%s", tips); \
return ERROR;\
}
void nca9555_init(void);
void nca9555_read_wtite_test(void);
void nca9555_set_output_mode(uint8_t slave_num, uint8_t gpio_port, uint8_t gpio_num);
void nca9555_set_gpio_output_status(uint8_t slave_num, uint8_t gpio_port, uint8_t gpio_num, uint8_t status);
void nca9555_set_input_mode(uint8_t slave_num, uint8_t gpio_port, uint8_t gpio_num);
uint8_t nca9555_get_gpio_status(uint8_t slave_num, uint8_t gpio_port, uint8_t gpio_num);
#endif
源文件:nca9555.c
#include "nca9555.h"
#include "sl_udelay.h"
#include "em_cmu.h"
#include <stdio.h>
#include "ads1220.h"
void IIC_gpio_init(void)
{
CMU_ClockEnable(cmuClock_GPIO, true);
GPIO_PinModeSet(IIC_SCL_GPIO_PORT, IIC_SCL_GPIO_PIN, gpioModePushPull, 1);
GPIO_PinModeSet(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN, gpioModePushPull, 1);
}
static void IIC_SDA_set_output(void)
{
GPIO_PinModeSet(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN, gpioModePushPull, 1);
}
static void IIC_SDA_set_input(void)
{
GPIO_PinModeSet(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN, gpioModeInputPull, 0);
}
void IIC_start(void)
{
IIC_SDA_set_output();
IIC_SDA_SET_GPIO_OUTPUT_STATUS(1);
IIC_SCL_SET_GPIO_OUTPUT_STATUS(1);
sl_udelay_wait(6);
IIC_SDA_SET_GPIO_OUTPUT_STATUS(0);
sl_udelay_wait(6);
IIC_SCL_SET_GPIO_OUTPUT_STATUS(0);
}
void IIC_stop(void)
{
IIC_SDA_set_output();
IIC_SCL_SET_GPIO_OUTPUT_STATUS(0);
IIC_SDA_SET_GPIO_OUTPUT_STATUS(0);
sl_udelay_wait(6);
IIC_SCL_SET_GPIO_OUTPUT_STATUS(1);
IIC_SDA_SET_GPIO_OUTPUT_STATUS(1);
sl_udelay_wait(6);
}
uint8_t IIC_wait_ack(void)
{
uint8_t ucErrTime=0;
IIC_SDA_set_input();
IIC_SDA_SET_GPIO_OUTPUT_STATUS(1);
sl_udelay_wait(1);
IIC_SCL_SET_GPIO_OUTPUT_STATUS(1);
sl_udelay_wait(1);
while(IIC_SDA_GET_GPIO_INPUT_STATUS)
{
ucErrTime++;
sl_udelay_wait(1);
if(ucErrTime>250)
{
IIC_stop();
printf("return 1\r\n");
return 1;
}
}
IIC_SCL_SET_GPIO_OUTPUT_STATUS(0);
return 0;
}
void IIC_ack(void)
{
IIC_SCL_SET_GPIO_OUTPUT_STATUS(0);
IIC_SDA_set_output();
IIC_SDA_SET_GPIO_OUTPUT_STATUS(1);
sl_udelay_wait(5);
IIC_SCL_SET_GPIO_OUTPUT_STATUS(1);
sl_udelay_wait(5);
IIC_SCL_SET_GPIO_OUTPUT_STATUS(0);
}
void IIC_nack(void)
{
IIC_SCL_SET_GPIO_OUTPUT_STATUS(0);
IIC_SDA_set_output();
IIC_SDA_SET_GPIO_OUTPUT_STATUS(1);
sl_udelay_wait(5);
IIC_SCL_SET_GPIO_OUTPUT_STATUS(1);
sl_udelay_wait(5);
IIC_SCL_SET_GPIO_OUTPUT_STATUS(0);
}
void IIC_send_byte(uint8_t txd)
{
uint8_t t;
IIC_SDA_set_output();
IIC_SCL_SET_GPIO_OUTPUT_STATUS(0);
for(t=0;t<8;t++)
{
IIC_SDA_SET_GPIO_OUTPUT_STATUS((txd&0x80)>>7);
txd<<=1;
sl_udelay_wait(4);
IIC_SCL_SET_GPIO_OUTPUT_STATUS(1);
sl_udelay_wait(4);
IIC_SCL_SET_GPIO_OUTPUT_STATUS(0);
sl_udelay_wait(4);
}
}
uint8_t IIC_read_byte(unsigned char ack)
{
unsigned char i,receive=0;
IIC_SDA_set_input();
for(i=0;i<8;i++ )
{
IIC_SCL_SET_GPIO_OUTPUT_STATUS(0);
sl_udelay_wait(4);
IIC_SCL_SET_GPIO_OUTPUT_STATUS(1);
receive<<=1;
if(IIC_SDA_GET_GPIO_INPUT_STATUS)receive++;
sl_udelay_wait(4);
}
if (!ack)
IIC_nack();
else
IIC_ack();
return receive;
}
void nca9555_init(void)
{
IIC_gpio_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();
NCA9555_WAIT_IS_RETURN_SUCCESS(ret, "[ERROR] wait slave ack error!\r\n");
IIC_send_byte(command);
ret = IIC_wait_ack();
NCA9555_WAIT_IS_RETURN_SUCCESS(ret, "[ERROR] wait slave ack error!\r\n");
IIC_send_byte(write_register_data);
ret = IIC_wait_ack();
NCA9555_WAIT_IS_RETURN_SUCCESS(ret, "[ERROR] wait slave ack error!\r\n");
IIC_stop();
sl_udelay_wait(10000);
return SUCCESS;
}
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();
NCA9555_WAIT_IS_RETURN_SUCCESS(ret, "[ERROR] wait slave ack error!\r\n");
IIC_send_byte(read_register_data);
ret = IIC_wait_ack();
NCA9555_WAIT_IS_RETURN_SUCCESS(ret, "[ERROR] wait slave ack error!\r\n");
IIC_start();
IIC_send_byte(addr);
ret = IIC_wait_ack();
NCA9555_WAIT_IS_RETURN_SUCCESS(ret, "[ERROR] wait slave ack error!\r\n");
*read_data = IIC_read_byte(0);
IIC_stop();
return SUCCESS;
}
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));
}
}
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);
}
}
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));
}
}
}
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)
{
printf("[ERROR] gpio_port > 1 || gpio_num > 0x80\r\n");
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: printf("[ERROR] gpio error!\r\n");
}
return gpio_status;
}
注: NCA9555采用IIC通信,协议中涉及的延时函数务必保证精确。 上面代码可直接运行在芯科科技的EFR32BG22中。需要移植到其他的芯片中只需要确定两点: ①GPIO输入输出设置 ②精确到us级别的延时函数 将对应的的部分替换掉就可以了。
|