STM32 – Bibliothekensammlung

PCA9555 .c/.h (IO-Expander)

------------------------------------------------------------------
pca9555.h:
------------------------------------------------------------------

#ifndef PCA9555_H
#define PCA9555_H

#include "stm32h7xx_hal.h"

// Register-Adressen des PCA9555
#define PCA9555_INPUT_PORT_0     0x00
#define PCA9555_INPUT_PORT_1     0x01
#define PCA9555_OUTPUT_PORT_0    0x02
#define PCA9555_OUTPUT_PORT_1    0x03
#define PCA9555_POL_INV_PORT_0   0x04
#define PCA9555_POL_INV_PORT_1   0x05
#define PCA9555_CONFIG_PORT_0    0x06
#define PCA9555_CONFIG_PORT_1    0x07

typedef struct {
    I2C_HandleTypeDef *hi2c;
    uint8_t address; // 7-bit address (z.B. 0x20)
} PCA9555_HandleTypeDef;

HAL_StatusTypeDef PCA9555_Init(PCA9555_HandleTypeDef *hpca);
HAL_StatusTypeDef PCA9555_ConfigPin(PCA9555_HandleTypeDef *hpca, uint8_t pin, uint8_t isInput);
HAL_StatusTypeDef PCA9555_WritePin(PCA9555_HandleTypeDef *hpca, uint8_t pin, GPIO_PinState state);
HAL_StatusTypeDef PCA9555_ReadPin(PCA9555_HandleTypeDef *hpca, uint8_t pin, GPIO_PinState *state);

#endif // PCA9555_H
------------------------------------------------------------------
pca9555.c:
------------------------------------------------------------------
#include "pca9555.h"

static HAL_StatusTypeDef PCA9555_ReadReg(PCA9555_HandleTypeDef *hpca, uint8_t reg, uint8_t *data) {
    return HAL_I2C_Mem_Read(hpca->hi2c, hpca->address << 1, reg, I2C_MEMADD_SIZE_8BIT, data, 1, HAL_MAX_DELAY);
}

static HAL_StatusTypeDef PCA9555_WriteReg(PCA9555_HandleTypeDef *hpca, uint8_t reg, uint8_t data) {
    return HAL_I2C_Mem_Write(hpca->hi2c, hpca->address << 1, reg, I2C_MEMADD_SIZE_8BIT, &data, 1, HAL_MAX_DELAY);
}

HAL_StatusTypeDef PCA9555_Init(PCA9555_HandleTypeDef *hpca) {
    // Konfiguriere alle Pins als Output (0) beim Init
    HAL_StatusTypeDef ret;
    ret = PCA9555_WriteReg(hpca, PCA9555_CONFIG_PORT_0, 0x00);
    if (ret != HAL_OK) return ret;
    return PCA9555_WriteReg(hpca, PCA9555_CONFIG_PORT_1, 0x00);
}

HAL_StatusTypeDef PCA9555_ConfigPin(PCA9555_HandleTypeDef *hpca, uint8_t pin, uint8_t isInput) {
    if (pin > 15) return HAL_ERROR;

    uint8_t reg = (pin < 8) ? PCA9555_CONFIG_PORT_0 : PCA9555_CONFIG_PORT_1;
    uint8_t bit = pin % 8;
    uint8_t config;

    HAL_StatusTypeDef ret = PCA9555_ReadReg(hpca, reg, &config);
    if (ret != HAL_OK) return ret;

    if (isInput) config |= (1 << bit);
    else         config &= ~(1 << bit);

    return PCA9555_WriteReg(hpca, reg, config);
}

HAL_StatusTypeDef PCA9555_WritePin(PCA9555_HandleTypeDef *hpca, uint8_t pin, GPIO_PinState state) {
    if (pin > 15) return HAL_ERROR;

    uint8_t reg = (pin < 8) ? PCA9555_OUTPUT_PORT_0 : PCA9555_OUTPUT_PORT_1;
    uint8_t bit = pin % 8;
    uint8_t output;

    HAL_StatusTypeDef ret = PCA9555_ReadReg(hpca, reg, &output);
    if (ret != HAL_OK) return ret;

    if (state == GPIO_PIN_SET) output |= (1 << bit);
    else                       output &= ~(1 << bit);

    return PCA9555_WriteReg(hpca, reg, output);
}

HAL_StatusTypeDef PCA9555_ReadPin(PCA9555_HandleTypeDef *hpca, uint8_t pin, GPIO_PinState *state) {
    if (pin > 15 || state == NULL) return HAL_ERROR;

    uint8_t reg = (pin < 8) ? PCA9555_INPUT_PORT_0 : PCA9555_INPUT_PORT_1;
    uint8_t bit = pin % 8;
    uint8_t input;

    HAL_StatusTypeDef ret = PCA9555_ReadReg(hpca, reg, &input);
    if (ret != HAL_OK) return ret;

    *state = (input & (1 << bit)) ? GPIO_PIN_SET : GPIO_PIN_RESET;
    return HAL_OK;
}
------------------------------------------------------------------
Anwendungsbeispiel:
------------------------------------------------------------------
#include "pca9555.h"

extern I2C_HandleTypeDef hi2c1;

PCA9555_HandleTypeDef hpca = {
    .hi2c = &hi2c1,
    .address = 0x20 // Setze entsprechend deiner Adresspins A0-A2
};

void StartDefaultTask(void *argument) {
    PCA9555_Init(&hpca);
    PCA9555_ConfigPin(&hpca, 0, 0); // P0_0 als Ausgang

    while (1) {
        PCA9555_WritePin(&hpca, 0, GPIO_PIN_SET);
        osDelay(500);
        PCA9555_WritePin(&hpca, 0, GPIO_PIN_RESET);
        osDelay(500);
    }
}

Tags:

Comments

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Search


Categories


Recent Posts


Tags