mcu io模拟i2c 驱动tca6424a


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#ifndef __TCA6424A_H__
#define __TCA6424A_H__

#include <stdint.h>
#include "NUC123.h"

#define CLOSE_LED		0
#define CHANNEL_SELECT	1
#define MODE_SELECT		2
#define VOLT2			3
#define TRIGGER			4
#define	VOLT1			5
#define FREQ			6
#define CH1				7
#define CH2				8
#define CH3				9
#define CH4				10
#define CH5				11
#define CH6				12

#define I2C1_SDA_OUT()   GPIO_SetMode(PA, BIT10, GPIO_PMD_QUASI)
#define I2C1_SDA_IN()    GPIO_SetMode(PA, BIT10, GPIO_PMD_QUASI)
#define I2C1_READ_SDA    (PA10)

#define I2C1_INT    (PB12)
#define I2C1_SCL    (PA11)
#define I2C1_SDA    (PA10)
#define I2C1_RESET  (PD8)

#define I2C2_SDA_OUT()   GPIO_SetMode(PF, BIT2, GPIO_PMD_QUASI)
#define I2C2_SDA_IN()    GPIO_SetMode(PF, BIT2, GPIO_PMD_QUASI)
#define I2C2_READ_SDA    (PF2)

#define I2C2_INT    (PB8)
#define I2C2_SCL    (PF3)
#define I2C2_SDA    (PF2)
#define I2C2_RESET  (PB15)


/************************** I2C Address ***************************************/
#define TCA6424A_IIC_ADDR			0x22 		// I2C Address 0100 01 + ADDR + R/W
												// ADDR tied to P2.3 of LaunchPad
/************************** I2C Registers *************************************/
#define TCA6424A_INPUT_REG0			0x00		// Input status register
#define TCA6424A_INPUT_REG1			0x01		// Input status register
#define TCA6424A_INPUT_REG2			0x02		// Input status register
#define TCA6424A_OUTPUT_REG0		0x04		// Output register to change state of output BIT set to 1, output set HIGH
#define TCA6424A_OUTPUT_REG1		0x05		// Output register to change state of output BIT set to 1, output set HIGH
#define TCA6424A_OUTPUT_REG2		0x06		// Output register to change state of output BIT set to 1, output set HIGH
#define TCA6424A_POLARITY_REG0 	    0x08		// Polarity inversion register. BIT '1' inverts input polarity of register 0x00
#define TCA6424A_POLARITY_REG1 	    0x09		// Polarity inversion register. BIT '1' inverts input polarity of register 0x00
#define TCA6424A_POLARITY_REG2 	    0x0A		// Polarity inversion register. BIT '1' inverts input polarity of register 0x00
#define TCA6424A_CONFIG_REG0   	    0x0C		// Configuration register. BIT = '1' sets port to input BIT = '0' sets port to output
#define TCA6424A_CONFIG_REG1   	    0x0D		// Configuration register. BIT = '1' sets port to input BIT = '0' sets port to output
#define TCA6424A_CONFIG_REG2   	    0x0E		// Configuration register. BIT = '1' sets port to input BIT = '0' sets port to output

#define TCA6424A_LOW                0
#define TCA6424A_HIGH               1
#define TCA6424A_POLARITY_NORMAL    0
#define TCA6424A_POLARITY_INVERTED  1
#define TCA6424A_OUTPUT             0
#define TCA6424A_INPUT              1
#define TCA6424A_AUTO_INCREMENT     0x80
#define TCA6424A_IO_ALL				0xFF

#define IS_BIT_LOW(num, x)			(num & (1 << x) ? 0 : 1)

typedef struct TCA6424A_KEY
{
	uint8_t key[13];
}I2C_KEY_T;

typedef struct TCA6424A_IO
{
	uint8_t io[6];
}I2C_IO_T;


typedef struct TCA6424A_LED
{
	uint8_t led[12];
}I2C_LED_T;

void tca6424a_io_init(void);
void tca6424a_io_int_init(void);
void tca6424a_key_init(void);
void tca6424a_key_int_init(void);
void GPAB_IRQHandler(void);

uint8_t i2c1_read_reg(uint8_t reg);
void i2c1_conf_reg(uint8_t reg, uint8_t data);
void i2c1_write_pin(uint8_t reg, uint8_t read_data, uint8_t pin, uint8_t state);

uint8_t i2c2_read_reg(uint8_t reg);
void i2c2_conf_reg(uint8_t reg, uint8_t data);
void i2c2_write_pin(uint8_t reg, uint8_t read_data, uint8_t pin, uint8_t state);

void key_handler(uint8_t *data);
void led_handler(uint8_t *in_data);

#endif
#include "tca6424a.h"
#include <stdlib.h>
#include <stdio.h>
#include "system_NUC123.h"
//menu.c
extern uint8_t volt_disp_reset, volt_disp_mutex;

uint8_t key_led_flag = 0;
uint8_t key_value_tca6424a[3] = {0};
I2C_KEY_T i2c_key = {0};
I2C_LED_T i2c_led = {0};
//产生IIC起始信号
static void I2C1_Start(void)
{
    I2C1_SDA_OUT();     //sda线输出
    I2C1_SDA = 1;
    I2C1_SCL = 1;
    delay_us(4);
    I2C1_SDA = 0;//START:when CLK is high,DATA change form high to low
    delay_us(4);
    I2C1_SCL = 0;//钳住I2C总线,准备发送或接收数据
}

//产生IIC停止信号
static void I2C1_Stop(void)
{
    I2C1_SDA_OUT();//sda线输出
    I2C1_SCL = 0;
    I2C1_SDA = 0;//STOP:when CLK is high DATA change form low to high
    delay_us(4);
    I2C1_SCL = 1;
    delay_us(4);
    I2C1_SDA = 1;//发送I2C总线结束信号
    delay_us(4);
}

//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
static uint8_t I2C1_Wait_Ack(void)
{
    uint8_t time = 0;
    I2C1_SDA_IN();      //SDA设置为输入  
    I2C1_SDA = 1;
    delay_us(4);
    I2C1_SCL = 1;
    delay_us(4);
    while (I2C1_READ_SDA)
    {
        time++;
        if (time > 250)
        {
            I2C1_Stop();
            return 1;
        }
    }
    I2C1_SCL = 0;//时钟输出0
    return 0;
}

//产生ACK应答
static void I2C1_Ack(void)
{
    I2C1_SCL = 0;
    I2C1_SDA_OUT();
    I2C1_SDA = 0;
    delay_us(4);
    I2C1_SCL = 1;
    delay_us(4);
    I2C1_SCL = 0;
}

//不产生ACK应答		    
static void I2C1_NAck(void)
{
    I2C1_SCL = 0;
    I2C1_SDA_OUT();
    I2C1_SDA = 1;
    delay_us(4);
    I2C1_SCL = 1;
    delay_us(4);
    I2C1_SCL = 0;
}

//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答			  
static void I2C1_Send_Byte(uint8_t txd)
{                        
    uint8_t t = 0;
    I2C1_SDA_OUT();
    I2C1_SCL = 0;//拉低时钟开始数据传输
    for (t = 0; t < 8; t++)
    {
        I2C1_SDA = ((txd & 0x80) >> 7);
        txd <<= 1;
        delay_us(4);   //对TEA5767这三个延时都是必须的
        I2C1_SCL = 1;
        delay_us(4);
        I2C1_SCL = 0;
        delay_us(4);
    }
}

//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
static uint8_t I2C1_Read_Byte(unsigned char ack)
{
	unsigned char i = 0, receive = 0;
    I2C1_SDA_IN();//SDA设置为输入
    for (i = 0; i < 8; i++)
    {
        I2C1_SCL = 0; 
        delay_us(4);
        I2C1_SCL = 1;
        receive <<= 1;
        if (I2C1_READ_SDA)
        {
            receive++;
        }
        delay_us(4);
    }
    if (!ack)
    {
        I2C1_NAck();//发送nACK
    }
    else
    {
        I2C1_Ack(); //发送ACK   
    }
    return receive;
}

//产生IIC起始信号
static void I2C2_Start(void)
{
    I2C2_SDA_OUT();     //sda线输出
    I2C2_SDA = 1;
    I2C2_SCL = 1;
    delay_us(4);
    I2C2_SDA = 0;//START:when CLK is high,DATA change form high to low
    delay_us(4);
    I2C2_SCL = 0;//钳住I2C总线,准备发送或接收数据
}

//产生IIC停止信号
static void I2C2_Stop(void)
{
    I2C2_SDA_OUT();//sda线输出
    I2C2_SCL = 0;
    I2C2_SDA = 0;//STOP:when CLK is high DATA change form low to high
    delay_us(4);
    I2C2_SCL = 1;
    delay_us(4);
    I2C2_SDA = 1;//发送I2C总线结束信号
    delay_us(4);
}

//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
static uint8_t I2C2_Wait_Ack(void)
{
    uint8_t time = 0;
    I2C2_SDA_IN();      //SDA设置为输入  
    I2C2_SDA = 1;
    delay_us(4);
    I2C2_SCL = 1;
    delay_us(4);
    while (I2C2_READ_SDA)
    {
        time++;
        if (time > 250)
        {
            I2C2_Stop();
            return 1;
        }
    }
    I2C2_SCL = 0;//时钟输出0
    return 0;
}

//产生ACK应答
static void I2C2_Ack(void)
{
    I2C2_SCL = 0;
    I2C2_SDA_OUT();
    I2C2_SDA = 0;
    delay_us(4);
    I2C2_SCL = 1;
    delay_us(4);
    I2C2_SCL = 0;
}

//不产生ACK应答		    
static void I2C2_NAck(void)
{
    I2C2_SCL = 0;
    I2C2_SDA_OUT();
    I2C2_SDA = 1;
    delay_us(4);
    I2C2_SCL = 1;
    delay_us(4);
    I2C2_SCL = 0;
}

//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答			  
static void I2C2_Send_Byte(uint8_t txd)
{                        
    uint8_t t = 0;
    I2C2_SDA_OUT();
    I2C2_SCL = 0;//拉低时钟开始数据传输
    for (t = 0; t < 8; t++)
    {
        I2C2_SDA = ((txd & 0x80) >> 7);
        txd <<= 1;
        delay_us(4);
        I2C2_SCL = 1;
        delay_us(4);
        I2C2_SCL = 0;
        delay_us(4);
    }
}

//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
static uint8_t I2C2_Read_Byte(unsigned char ack)
{
	unsigned char i = 0, receive = 0;
    I2C2_SDA_IN();//SDA设置为输入
    for (i = 0; i < 8; i++)
    {
        I2C2_SCL = 0; 
        delay_us(4);
        I2C2_SCL = 1;
        receive <<= 1;
        if (I2C2_READ_SDA)
        {
            receive++;
        }
        delay_us(4);
    }
    if (!ack)
    {
        I2C2_NAck();//发送nACK
    }
    else
    {
        I2C2_Ack(); //发送ACK   
    }
    return receive;
}

uint8_t i2c1_read_reg(uint8_t reg)
{
    uint8_t temp = 0;
    I2C1_Start();
    I2C1_Send_Byte((TCA6424A_IIC_ADDR << 1) | 0);
    I2C1_Wait_Ack();
    I2C1_Send_Byte(reg);
    I2C1_Wait_Ack();
    I2C1_Start();
    I2C1_Send_Byte((TCA6424A_IIC_ADDR << 1) | 1);
    I2C1_Wait_Ack();
    temp = I2C1_Read_Byte(0);
    // IIC_NAck();//发送nACK
    I2C1_Stop();
    return temp;
}

uint8_t i2c2_read_reg(uint8_t reg)
{
    uint8_t temp = 0;
    I2C2_Start();
    I2C2_Send_Byte((TCA6424A_IIC_ADDR << 1) | 0);
    I2C2_Wait_Ack();
    I2C2_Send_Byte(reg);
    I2C2_Wait_Ack();
    I2C2_Start();
    I2C2_Send_Byte((TCA6424A_IIC_ADDR << 1) | 1);
    I2C2_Wait_Ack();
    temp = I2C2_Read_Byte(0);
    // IIC_NAck();//发送nACK
    I2C2_Stop();
    return temp;
}

// config regsiter, 1->bit input, 0->bit output
void i2c1_conf_reg(uint8_t reg, uint8_t data)
{
    I2C1_Start();
    I2C1_Send_Byte((TCA6424A_IIC_ADDR << 1) | 0);
    I2C1_Wait_Ack();
    I2C1_Send_Byte(reg);
    I2C1_Wait_Ack();
    I2C1_Send_Byte(data);
    I2C1_Wait_Ack();
    I2C1_Stop();
}


// config regsiter, 1->bit input, 0->bit output
void i2c2_conf_reg(uint8_t reg, uint8_t data)
{
    I2C2_Start();
    I2C2_Send_Byte((TCA6424A_IIC_ADDR << 1) | 0);
    I2C2_Wait_Ack();
    I2C2_Send_Byte(reg);
    I2C2_Wait_Ack();
    I2C2_Send_Byte(data);
    I2C2_Wait_Ack();
    I2C2_Stop();
}

// state: 0 -> LED on, 1 -> LED off
void i2c1_write_pin(uint8_t reg, uint8_t read_data, uint8_t pin, uint8_t state)
{
    if (state)
    {
        read_data |= (1 << pin);
    }
    else
    {
        read_data &= (~(1 << pin));
    }
    I2C1_Start();
    I2C1_Send_Byte((TCA6424A_IIC_ADDR << 1) | 0);
    I2C1_Wait_Ack();
    I2C1_Send_Byte(reg);
    I2C1_Wait_Ack();
    I2C1_Send_Byte(read_data);
    I2C1_Wait_Ack();
    I2C1_Stop();
}

// state: 0 -> LED on, 1 -> LED off
void i2c2_write_pin(uint8_t reg, uint8_t read_data, uint8_t pin, uint8_t state)
{
    if (state)
    {
        read_data |= (1 << pin);
    }
    else
    {
        read_data &= (~(1 << pin));
    }
    I2C2_Start();
    I2C2_Send_Byte((TCA6424A_IIC_ADDR << 1) | 0);
    I2C2_Wait_Ack();
    I2C2_Send_Byte(reg);
    I2C2_Wait_Ack();
    I2C2_Send_Byte(read_data);
    I2C2_Wait_Ack();
    I2C2_Stop();
}

void i2c1_write_allpin(uint8_t reg, uint8_t w_data)
{
    I2C1_Start();
    I2C1_Send_Byte((TCA6424A_IIC_ADDR << 1) | 0);
    I2C1_Wait_Ack();
    I2C1_Send_Byte(reg);
    I2C1_Wait_Ack();
    I2C1_Send_Byte(w_data);
    I2C1_Wait_Ack();
    I2C1_Stop();
}

void tca6424a_io_init(void)
{
    GPIO_SetMode(PA, BIT10, GPIO_PMD_QUASI);    // SDA
    SYS->ALT_MFP &= (~(1 << 12));
    SYS->GPA_MFP &= (~(1 << 10));
    GPIO_SetMode(PA, BIT11, GPIO_PMD_QUASI);    // SCL
    SYS->ALT_MFP &= (~(1 << 11));
    SYS->GPA_MFP &= (~(1 << 11));
    GPIO_SetMode(PD, BIT8, GPIO_PMD_OUTPUT);    // RESET
    SYS->GPD_MFP &= (~(1 << 8));
    // I2C1_RESET = 0;
    // delay_100ms(1);
    I2C1_RESET = 1;
    i2c1_conf_reg(TCA6424A_CONFIG_REG0, 0x00);  //i0.0 - i0.7 output
    i2c1_conf_reg(TCA6424A_CONFIG_REG1, 0xf0);  //i1.0 - i1.3 output, i1.4 - i1.7 input
    i2c1_conf_reg(TCA6424A_CONFIG_REG2, 0xff);  //i2.0 - i2.7 input
    i2c1_write_allpin(TCA6424A_OUTPUT_REG0, 0xC0);
    i2c1_write_allpin(TCA6424A_OUTPUT_REG1, 0x0f);
}

void tca6424a_io_int_init(void)
{
    GPIO_SetMode(PB, BIT12, GPIO_PMD_INPUT);        // interruput
    SYS->ALT_MFP &= (~(1 << 10));
    SYS->GPB_MFP &= (~(1 << 12));
    // pin外部是高电平,当按下时产生下降沿,松开时产生上升沿
    GPIO_EnableInt(PB, BIT12, GPIO_INT_FALLING);    // 双边沿采样
    NVIC_EnableIRQ(GPAB_IRQn);                      // 设置中断
    NVIC_SetPriority(GPAB_IRQn, 3);
    GPIO_SET_DEBOUNCE_TIME(GPIO_DBCLKSRC_LIRC, GPIO_DBCLKSEL_64);    // 设置消抖时钟
    GPIO_ENABLE_DEBOUNCE(PB, BIT12);                // 使能消抖
}


void tca6424a_key_init(void)
{
    GPIO_SetMode(PB, BIT15, GPIO_PMD_OUTPUT);   // reset
    SYS->ALT_MFP &= (~(1 << 24));
    SYS->GPB_MFP &= (~(1 << 15));
    GPIO_SetMode(PF, BIT2, GPIO_PMD_QUASI);     // sda
    SYS->ALT_MFP &= (~(3 << 24));
    SYS->GPF_MFP &= (~(1 << 2));
    GPIO_SetMode(PF, BIT3, GPIO_PMD_QUASI);     // scl
    SYS->ALT_MFP &= (~(3 << 26));
    SYS->GPF_MFP &= (~(1 << 3));
    I2C2_RESET = 0;
    delay_100ms(1);
    I2C2_RESET = 1;
    i2c2_conf_reg(TCA6424A_CONFIG_REG0, 0xff);  // i0.0 - i0.7 input
    i2c2_conf_reg(TCA6424A_CONFIG_REG1, 0x0f);  // i1.0 - i1.3 input,i1.4 - i1.7 output
    i2c2_conf_reg(TCA6424A_CONFIG_REG2, 0x00);  // i2.0 - i2.7 output
}


void tca6424a_key_int_init(void)
{
    GPIO_SetMode(PB, BIT8, GPIO_PMD_INPUT);     // interruput
    SYS->GPB_MFP &= (~(1 << 8));
    // pin外部是高电平,当按下时产生下降沿,松开时产生上升沿
    GPIO_EnableInt(PB, 8, GPIO_INT_FALLING);
    NVIC_EnableIRQ(GPAB_IRQn);                 // 设置中断
    NVIC_SetPriority(GPAB_IRQn, 3);
    GPIO_SET_DEBOUNCE_TIME(GPIO_DBCLKSRC_LIRC, GPIO_DBCLKSEL_32);    // 设置消抖时钟
    GPIO_ENABLE_DEBOUNCE(PB, BIT8);            // 使能消抖
}

void GPAB_IRQHandler(void)
{
    uint8_t a = 0, b = 0;
    if (GPIO_GET_INT_FLAG(PB, BIT8))
    {
        GPIO_CLR_INT_FLAG(PB, BIT8);
        if (key_value_tca6424a[2] == 0)
        {
            a = i2c2_read_reg(TCA6424A_INPUT_REG0);
            b = i2c2_read_reg(TCA6424A_INPUT_REG1);
            if (a != 255)
            {
                key_value_tca6424a[0] = a;
                key_value_tca6424a[2] = 1;
            }
            if ((b | 0xf0) != 255)
            {
                key_value_tca6424a[1] = b;
                key_value_tca6424a[2] = 2;
            }
        }
    }
}

void key_handler(uint8_t *data)
{
    static uint8_t read_value = 0;
    GPIO_DisableInt(PB, 8);
    NVIC_DisableIRQ(GPAB_IRQn);
    if (key_value_tca6424a[2] == 1)
    {
        if (IS_BIT_LOW(key_value_tca6424a[0], 5) == TCA6424A_HIGH)    //menu
        {
            data[CLOSE_LED] ^= 1;
        }

        if (IS_BIT_LOW(key_value_tca6424a[0], 6) == TCA6424A_HIGH)    //channel select
        {
            data[CHANNEL_SELECT]++;
            data[MODE_SELECT] = t1.lcc6_ch[(data[1] % 7) - 1].output_mode;
            data[VOLT1] = 0;//v1
            data[VOLT2] = 0;//v2
            data[FREQ] = 0;//freq
            data[TRIGGER] = 0;//internal external
        }
        else if (IS_BIT_LOW(key_value_tca6424a[0], 7) == TCA6424A_HIGH)    //output mode
        {
            read_value = t1.lcc6_ch[(data[1] % 7) - 1].output_mode;
            data[MODE_SELECT] = ++read_value;
            if (data[MODE_SELECT] == 4)
            {
                data[MODE_SELECT] = 1;
            }
            t1.lcc6_ch[(data[1] % 7) - 1].output_mode = data[MODE_SELECT];
            data[TRIGGER] = 0;//internal
        }
        else if (IS_BIT_LOW(key_value_tca6424a[0], 0) == TCA6424A_HIGH)    //frequence base modulate
        {
            if (data[MODE_SELECT] != 3)
            {
                data[FREQ] ^= 1;
            }
            else
            {
                data[FREQ]++;
            }
            data[VOLT1] = 0;//v1
            data[VOLT2] = 0;//v2
        }
        else if (IS_BIT_LOW(key_value_tca6424a[0], 1) == TCA6424A_HIGH)    //ch2 output enable/disable
        {
            data[CH2] ^= 1;
        }
        else if (IS_BIT_LOW(key_value_tca6424a[0], 2) == TCA6424A_HIGH)    //ch5 output enable/disable
        {
            data[CH5] ^= 1;
        }
        else if (IS_BIT_LOW(key_value_tca6424a[0], 3) == TCA6424A_HIGH)    //voltage 2
        {
            data[VOLT2] ^= 1;   //V2
            data[VOLT1] = 0;//v1
            data[FREQ] = 0;//freq
            volt_disp_reset = 5;
            volt_disp_mutex = 0;
        }
        else if (IS_BIT_LOW(key_value_tca6424a[0], 4) == TCA6424A_HIGH)    //trigger internal/external
        {
            if ((data[MODE_SELECT] % 3) == 0) //当调制模式时
            {
                data[TRIGGER] ^= 1;  //选择内部或者外部
            }
            data[VOLT1] = 0;//v1
            data[VOLT2] = 0;//v2
            data[FREQ] = 0;//freq
        }
        key_led_flag = 1;
    }
    else if (key_value_tca6424a[2] == 2)
    {
        if (IS_BIT_LOW(key_value_tca6424a[1], 0) == TCA6424A_HIGH)    //ch1 output enable/diable
        {
            data[CH1] ^= 1;
        }
        else if (IS_BIT_LOW(key_value_tca6424a[1], 1) == TCA6424A_HIGH)    //ch4 output enable/disable
        {
            data[CH4] ^= 1;
        }
        else if (IS_BIT_LOW(key_value_tca6424a[1], 2) == TCA6424A_HIGH)    //voltage 1
        {
            data[VOLT1] ^= 1;   //V1
            data[VOLT2] = 0;    //V2
            data[FREQ] = 0;    //FREQ
            volt_disp_reset = 5;
            volt_disp_mutex = 0;
        }
        else if (IS_BIT_LOW(key_value_tca6424a[1], 3) == TCA6424A_HIGH)    //ch3 output enable/disable
        {
            data[CH3] ^= 1;
        }
        key_led_flag = 2;
    }
    key_value_tca6424a[2] = 0;
}

void led_handler(uint8_t *in_data)
{
    uint8_t temp = 0;
    if (key_led_flag == 1)
    {
        if (in_data[CHANNEL_SELECT] % 7 == 1)    //channel select
        {
            if (in_data[TRIGGER] == 1)        //trigger internal or external
            {
                temp = i2c2_read_reg(TCA6424A_OUTPUT_REG1);
                i2c2_write_pin(TCA6424A_OUTPUT_REG1, temp, 4, 0);
            }
            else
            {
                temp = i2c2_read_reg(TCA6424A_OUTPUT_REG1);
                i2c2_write_pin(TCA6424A_OUTPUT_REG1, temp, 4, 1);
            }
        }
        else if (in_data[CHANNEL_SELECT] % 7 == 2)
        {
            if (in_data[TRIGGER] == 1)        //trigger internal or external
            {
                temp = i2c2_read_reg(TCA6424A_OUTPUT_REG1);
                i2c2_write_pin(TCA6424A_OUTPUT_REG1, temp, 6, 0);
            }
            else
            {
                temp = i2c2_read_reg(TCA6424A_OUTPUT_REG1);
                i2c2_write_pin(TCA6424A_OUTPUT_REG1, temp, 6, 1);
            }
        }
        else if (in_data[CHANNEL_SELECT] % 7 == 3)
        {
            if (in_data[TRIGGER] == 1)        //trigger internal or external
            {
                temp = i2c2_read_reg(TCA6424A_OUTPUT_REG2);
                i2c2_write_pin(TCA6424A_OUTPUT_REG2, temp, 0, 0);
            }
            else
            {
                temp = i2c2_read_reg(TCA6424A_OUTPUT_REG2);
                i2c2_write_pin(TCA6424A_OUTPUT_REG2, temp, 0, 1);
            }
        }
        else if (in_data[CHANNEL_SELECT] % 7 == 4)
        {
            if (in_data[TRIGGER] == 1)        //trigger internal or external
            {
                temp = i2c2_read_reg(TCA6424A_OUTPUT_REG2);
                i2c2_write_pin(TCA6424A_OUTPUT_REG2, temp, 2, 0);
            }
            else
            {
                temp = i2c2_read_reg(TCA6424A_OUTPUT_REG2);
                i2c2_write_pin(TCA6424A_OUTPUT_REG2, temp, 2, 1);
            }
        }
        else if (in_data[CHANNEL_SELECT] % 7 == 5)
        {
            if (in_data[TRIGGER] == 1)        //trigger internal or external
            {
                temp = i2c2_read_reg(TCA6424A_OUTPUT_REG2);
                i2c2_write_pin(TCA6424A_OUTPUT_REG2, temp, 4, 0);
            }
            else
            {
                temp = i2c2_read_reg(TCA6424A_OUTPUT_REG2);
                i2c2_write_pin(TCA6424A_OUTPUT_REG2, temp, 4, 1);
            }
        }
        else if (in_data[CHANNEL_SELECT] % 7 == 6)
        {
            if (in_data[TRIGGER] == 1)        //trigger internal or external
            {
                temp = i2c2_read_reg(TCA6424A_OUTPUT_REG2);
                i2c2_write_pin(TCA6424A_OUTPUT_REG2, temp, 6, 0);
            }
            else
            {
                temp = i2c2_read_reg(TCA6424A_OUTPUT_REG2);
                i2c2_write_pin(TCA6424A_OUTPUT_REG2, temp, 6, 1);
            }
        }

        if (in_data[CH2])     //ch2->led8
        {
            temp = i2c2_read_reg(TCA6424A_OUTPUT_REG1);
            i2c2_write_pin(TCA6424A_OUTPUT_REG1, temp, 7, 0);
        }
        else
        {
            temp = i2c2_read_reg(TCA6424A_OUTPUT_REG1);
            i2c2_write_pin(TCA6424A_OUTPUT_REG1, temp, 7, 1);
        }

        if (in_data[CH5])     //ch5->led11
        {
            temp = i2c2_read_reg(TCA6424A_OUTPUT_REG2);
            i2c2_write_pin(TCA6424A_OUTPUT_REG2, temp, 5, 0);
        }
        else
        {
            temp = i2c2_read_reg(TCA6424A_OUTPUT_REG2);
            i2c2_write_pin(TCA6424A_OUTPUT_REG2, temp, 5, 1);
        }
    }
    else if (key_led_flag == 2)
    {
        if (in_data[CH1])     //ch1->led7
        {
            temp = i2c2_read_reg(TCA6424A_OUTPUT_REG1);
            i2c2_write_pin(TCA6424A_OUTPUT_REG1, temp, 5, 0);
        }
        else
        {
            temp = i2c2_read_reg(TCA6424A_OUTPUT_REG1);
            i2c2_write_pin(TCA6424A_OUTPUT_REG1, temp, 5, 1);
        }

        if (in_data[CH3])    //ch3->led9
        {
            temp = i2c2_read_reg(TCA6424A_OUTPUT_REG2);
            i2c2_write_pin(TCA6424A_OUTPUT_REG2, temp, 1, 0);
        }
        else
        {
            temp = i2c2_read_reg(TCA6424A_OUTPUT_REG2);
            i2c2_write_pin(TCA6424A_OUTPUT_REG2, temp, 1, 1);
        }

        if (in_data[CH4])     //ch4->led10
        {
            temp = i2c2_read_reg(TCA6424A_OUTPUT_REG2);
            i2c2_write_pin(TCA6424A_OUTPUT_REG2, temp, 3, 0);
        }
        else
        {
            temp = i2c2_read_reg(TCA6424A_OUTPUT_REG2);
            i2c2_write_pin(TCA6424A_OUTPUT_REG2, temp, 3, 1);
        }

        if (in_data[CH6])
        {
            temp = i2c2_read_reg(TCA6424A_OUTPUT_REG2);
            i2c2_write_pin(TCA6424A_OUTPUT_REG2, temp, 7, 0);
        }
        else
        {
            temp = i2c2_read_reg(TCA6424A_OUTPUT_REG2);
            i2c2_write_pin(TCA6424A_OUTPUT_REG2, temp, 7, 1);
        }
    }
    key_led_flag = 0;
    GPIO_EnableInt(PB, 8, GPIO_INT_FALLING);
    NVIC_EnableIRQ(GPAB_IRQn);
    GPIO_SET_DEBOUNCE_TIME(GPIO_DBCLKSRC_LIRC, GPIO_DBCLKSEL_64);
    GPIO_ENABLE_DEBOUNCE(PB, BIT8);
}

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
TCA6408A是一款I2C接口的8位GPIO扩展器,可以通过I2C总线控制8个GPIO引脚的输入和输出状态。下面是STM32驱动TCA6408A的基本步骤: 1. 配置I2C接口:配置STM32I2C接口,设置速率、地址、模式等参数。 2. 初始化TCA6408A:向TCA6408A发送初始化命令,包括设置输入/输出模式、上下拉电阻等。 3. 控制GPIO:通过I2C接口向TCA6408A写入控制寄存器的值,实现对GPIO引脚的输入和输出状态控制。 下面是一个简单的示例代码,以STM32F4为例: ```c #include "stm32f4xx.h" #define TCA6408A_ADDR 0x20 // TCA6408A的I2C地址 #define TCA6408A_REG 0x03 // 控制寄存器的地址 void I2C_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; I2C_InitTypeDef I2C_InitStructure; // 打开I2C和GPIO时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); // 配置SCL和SDA引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOB, &GPIO_InitStructure); // 将SCL和SDA引脚设置为I2C功能 GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1); GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_I2C1); // 配置I2C参数 I2C_InitStructure.I2C_ClockSpeed = 400000; I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = 0x00; I2C_InitStructure.I2C_Ack = I2C_Ack_Disable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_Init(I2C1, &I2C_InitStructure); // 使能I2C总线 I2C_Cmd(I2C1, ENABLE); } void TCA6408A_Init(void) { uint8_t data[2]; // 设置寄存器0x03为输出模式 data[0] = TCA6408A_REG; data[1] = 0x00; I2C_Write(I2C1, TCA6408A_ADDR, data, 2); // 设置上拉电阻 data[0] = TCA6408A_REG | 0x06; data[1] = 0xFF; I2C_Write(I2C1, TCA6408A_ADDR, data, 2); } void TCA6408A_Write(uint8_t value) { uint8_t data[2]; // 写入控制寄存器的值 data[0] = TCA6408A_REG; data[1] = value; I2C_Write(I2C1, TCA6408A_ADDR, data, 2); } int main(void) { I2C_Configuration(); TCA6408A_Init(); while (1) { // 将P0~P7引脚设置为高电平 TCA6408A_Write(0xFF); } } ``` 这是一个简单的示例代码,具体的GPIO配置和控制方式可以根据实际需求进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值