STM32 – Bibliothekensammlung

pcf8574 .c/.h (IO-Expander)

------------------------------------------------------------------
pcf8574.h:
------------------------------------------------------------------
#ifndef PCF8574_H
#define PCF8574_H

#include "stm32h7xx_hal.h"

typedef struct {
    I2C_HandleTypeDef *hi2c;
    uint8_t address; // 7-Bit-Adresse (0x20–0x27)
    uint8_t shadow;  // Letzter geschriebener Zustand (für Schreibzugriffe)
} PCF8574_HandleTypeDef;

/**
 * Initialisiert den PCF8574 (setzt alle Pins auf High = Eingang)
 */
HAL_StatusTypeDef PCF8574_Init(PCF8574_HandleTypeDef *hpcf);

/**
 * Setzt einen Pin (0–7) auf HIGH (Eingang) oder LOW (Ausgang LOW)
 */
HAL_StatusTypeDef PCF8574_WritePin(PCF8574_HandleTypeDef *hpcf, uint8_t pin, GPIO_PinState state);

/**
 * Liest den Zustand eines bestimmten Pins (Eingang oder Ausgang)
 */
HAL_StatusTypeDef PCF8574_ReadPin(PCF8574_HandleTypeDef *hpcf, uint8_t pin, GPIO_PinState *state);

/**
 * Liest den vollständigen 8-Bit-Wert vom Port
 */
HAL_StatusTypeDef PCF8574_ReadPort(PCF8574_HandleTypeDef *hpcf, uint8_t *data);

/**
 * Schreibt den vollständigen 8-Bit-Wert auf den Port
 */
HAL_StatusTypeDef PCF8574_WritePort(PCF8574_HandleTypeDef *hpcf, uint8_t data);

#endif // PCF8574_H

------------------------------------------------------------------
pcf8574.c:
------------------------------------------------------------------
#include "pcf8574.h"

HAL_StatusTypeDef PCF8574_Init(PCF8574_HandleTypeDef *hpcf) {
    hpcf->shadow = 0xFF; // Alle Pins auf High (Eingang)
    return HAL_I2C_Master_Transmit(hpcf->hi2c, hpcf->address << 1, &hpcf->shadow, 1, HAL_MAX_DELAY);
}

HAL_StatusTypeDef PCF8574_WritePin(PCF8574_HandleTypeDef *hpcf, uint8_t pin, GPIO_PinState state) {
    if (pin > 7) return HAL_ERROR;

    if (state == GPIO_PIN_SET) {
        hpcf->shadow |= (1 << pin);  // High → Eingang
    } else {
        hpcf->shadow &= ~(1 << pin); // Low → Ausgang (LOW)
    }

    return HAL_I2C_Master_Transmit(hpcf->hi2c, hpcf->address << 1, &hpcf->shadow, 1, HAL_MAX_DELAY);
}

HAL_StatusTypeDef PCF8574_ReadPin(PCF8574_HandleTypeDef *hpcf, uint8_t pin, GPIO_PinState *state) {
    if (pin > 7 || state == NULL) return HAL_ERROR;

    uint8_t value;
    HAL_StatusTypeDef ret = HAL_I2C_Master_Receive(hpcf->hi2c, hpcf->address << 1, &value, 1, HAL_MAX_DELAY);
    if (ret != HAL_OK) return ret;

    *state = (value & (1 << pin)) ? GPIO_PIN_SET : GPIO_PIN_RESET;
    return HAL_OK;
}

HAL_StatusTypeDef PCF8574_ReadPort(PCF8574_HandleTypeDef *hpcf, uint8_t *data) {
    if (data == NULL) return HAL_ERROR;
    return HAL_I2C_Master_Receive(hpcf->hi2c, hpcf->address << 1, data, 1, HAL_MAX_DELAY);
}

HAL_StatusTypeDef PCF8574_WritePort(PCF8574_HandleTypeDef *hpcf, uint8_t data) {
    hpcf->shadow = data;
    return HAL_I2C_Master_Transmit(hpcf->hi2c, hpcf->address << 1, &data, 1, HAL_MAX_DELAY);
}

------------------------------------------------------------------
Anwendungsbeispiel:
------------------------------------------------------------------
#include "pcf8574.h"

extern I2C_HandleTypeDef hi2c1;

void Test_PCF8574(void) {
    PCF8574_HandleTypeDef io = {
        .hi2c = &hi2c1,
        .address = 0x20 // abhängig von A0–A2
    };

    PCF8574_Init(&io);

    // Setze Pin 0 auf Ausgang LOW (z. B. LED an)
    PCF8574_WritePin(&io, 0, GPIO_PIN_RESET);
    HAL_Delay(500);

    // Setze Pin 0 auf Eingang (LED aus)
    PCF8574_WritePin(&io, 0, GPIO_PIN_SET);
    HAL_Delay(500);

    // Lese Pin 7 (z. B. Taster)
    GPIO_PinState state;
    PCF8574_ReadPin(&io, 7, &state);
    if (state == GPIO_PIN_RESET) {
        // z. B. Taster gedrückt
    }
}

Tags:

Comments

Schreibe einen Kommentar

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

Search


Categories


Recent Posts


Tags