115 lines
3.5 KiB
C
115 lines
3.5 KiB
C
#include "lcd_headers.h"
|
|
uint8_t pcf8574_pinstatus[PCF8574_MAXDEVICES];
|
|
|
|
// инициализация pcf
|
|
void pcf8574_init() {
|
|
#if PCF8574_I2CINIT == 1
|
|
// инитим i2c
|
|
i2c_init();
|
|
_delay_us(10);
|
|
#endif
|
|
uint8_t i = 0;
|
|
for(i=0; i<PCF8574_MAXDEVICES; i++)
|
|
pcf8574_pinstatus[i] = 0;
|
|
|
|
}
|
|
|
|
// получаем статус вывода
|
|
int8_t pcf8574_getoutput(uint8_t deviceid) {
|
|
int8_t data = -1;
|
|
if((deviceid >= 0 && deviceid < PCF8574_MAXDEVICES)) {
|
|
data = pcf8574_pinstatus[deviceid];
|
|
}
|
|
return data;
|
|
}
|
|
|
|
// получаем статус пинов вывода
|
|
int8_t pcf8574_getoutputpin(uint8_t deviceid, uint8_t pin) {
|
|
int8_t data = -1;
|
|
if((deviceid >= 0 && deviceid < PCF8574_MAXDEVICES) && (pin >= 0 && pin < PCF8574_MAXPINS)) {
|
|
data = pcf8574_pinstatus[deviceid];
|
|
data = (data >> pin) & 0b00000001;
|
|
}
|
|
return data;
|
|
}
|
|
|
|
// настройка вывода
|
|
int8_t pcf8574_setoutput(uint8_t deviceid, uint8_t data) {
|
|
if((deviceid >= 0 && deviceid < PCF8574_MAXDEVICES)) {
|
|
pcf8574_pinstatus[deviceid] = data;
|
|
i2c_start(((PCF8574_ADDRBASE+deviceid)<<1) | I2C_WRITE);
|
|
i2c_write(data);
|
|
i2c_stop();
|
|
return 0;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
// установить выходные контакты, заменить фактический статус устройства из pinstart для i2c
|
|
int8_t pcf8574_setoutputpins(uint8_t deviceid, uint8_t pinstart, uint8_t pinlength, int8_t data) {
|
|
if((deviceid >= 0 && deviceid < PCF8574_MAXDEVICES) && (pinstart - pinlength + 1 >= 0 && pinstart - pinlength + 1 >= 0 && pinstart < PCF8574_MAXPINS && pinstart > 0 && pinlength > 0)) {
|
|
uint8_t b = 0;
|
|
b = pcf8574_pinstatus[deviceid];
|
|
uint8_t mask = ((1 << pinlength) - 1) << (pinstart - pinlength + 1);
|
|
data <<= (pinstart - pinlength + 1);
|
|
data &= mask;
|
|
b &= ~(mask);
|
|
b |= data;
|
|
pcf8574_pinstatus[deviceid] = b;
|
|
//рестартим
|
|
i2c_start(((PCF8574_ADDRBASE+deviceid)<<1) | I2C_WRITE);
|
|
i2c_write(b);
|
|
i2c_stop();
|
|
return 0;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
// настройка пинов вывода
|
|
int8_t pcf8574_setoutputpin(uint8_t deviceid, uint8_t pin, uint8_t data) {
|
|
if((deviceid >= 0 && deviceid < PCF8574_MAXDEVICES) && (pin >= 0 && pin < PCF8574_MAXPINS)) {
|
|
uint8_t b = 0;
|
|
b = pcf8574_pinstatus[deviceid];
|
|
b = (data != 0) ? (b | (1 << pin)) : (b & ~(1 << pin));
|
|
pcf8574_pinstatus[deviceid] = b;
|
|
//рестартим
|
|
i2c_start(((PCF8574_ADDRBASE+deviceid)<<1) | I2C_WRITE);
|
|
i2c_write(b);
|
|
i2c_stop();
|
|
return 0;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
// установка высокого уровня на выходных пинах
|
|
int8_t pcf8574_setoutputpinhigh(uint8_t deviceid, uint8_t pin) {
|
|
return pcf8574_setoutputpin(deviceid, pin, 1);
|
|
}
|
|
|
|
// установка низкого уровня на выходных пинах
|
|
int8_t pcf8574_setoutputpinlow(uint8_t deviceid, uint8_t pin) {
|
|
return pcf8574_setoutputpin(deviceid, pin, 0);
|
|
}
|
|
|
|
// получение входных данных
|
|
int8_t pcf8574_getinput(uint8_t deviceid) {
|
|
int8_t data = -1;
|
|
if((deviceid >= 0 && deviceid < PCF8574_MAXDEVICES)) {
|
|
i2c_start(((PCF8574_ADDRBASE+deviceid)<<1) | I2C_READ);
|
|
data = ~i2c_readNak();
|
|
i2c_stop();
|
|
}
|
|
return data;
|
|
}
|
|
|
|
// получение входного контакта (высокий или низкий)
|
|
int8_t pcf8574_getinputpin(uint8_t deviceid, uint8_t pin) {
|
|
int8_t data = -1;
|
|
if((deviceid >= 0 && deviceid < PCF8574_MAXDEVICES) && (pin >= 0 && pin < PCF8574_MAXPINS)) {
|
|
data = pcf8574_getinput(deviceid);
|
|
if(data != -1) {
|
|
data = (data >> pin) & 0b00000001;
|
|
}
|
|
}
|
|
return data;
|
|
} |