PCF8575 и прерывания
- Войдите на сайт для отправки комментариев
Чт, 24/09/2020 - 08:13
Добрый день, камрады. Пытаюсь разобраться с расширителем портов PCF8575 и выводом INT. Схема такая:
скетч такой
#include <Wire.h> #define ATMEGA_PIN_INT 2 #define PCF8575_ADDRESS 0x20 // адрес модуля на шине uint8_t hi, lo; uint16_t PCF8575_dataReceive; // Данные, прочитанные из модуля uint8_t PCF8575_dataLowByte; // Младший байт (P00...P07) - выходы uint8_t PCF8575_dataHighByte; // Старший байт (P10...P17) - входы volatile bool keyPress = 0; void setup() { Wire.begin(); Serial.begin(115200); Serial.println("Started..."); PCF8575_dataHighByte = B11111111; // Высокий уровень во все входы PCF8575 PCF8575_dataLowByte = B00000000; // Низкий уровень (вкл) во все выходы PCF8575 pcf8575_write(PCF8575_dataLowByte, PCF8575_dataHighByte); // выгружаем данные в модуль pinMode(ATMEGA_PIN_INT, INPUT); attachInterrupt(0, ISRgateway, FALLING); } void ISRgateway() { keyPress = 1; } void loop() { if (keyPress == 1) { PCF8575_dataReceive = pcf8575_read(); PCF8575_dataHighByte = B11111111; // Высокий уровень во все входы PCF8575 PCF8575_dataLowByte = B00000000; // Низкий уровень (вкл) во все выходы PCF8575 pcf8575_write(PCF8575_dataLowByte, PCF8575_dataHighByte); // выгружаем данные в модуль keyPress = 0; Serial.println("Button pressed"); } } void pcf8575_write(uint8_t dtl, int8_t dth) { // Процедура записи байта в модуль Wire.beginTransmission(PCF8575_ADDRESS); Wire.write(dtl); // Записываем младший байт (P00...P07) Wire.write(dth); // Записываем старший байт (P10...P17) Wire.endTransmission(); } int16_t pcf8575_read() { // Процедура чтения байта из модуля Wire.beginTransmission(PCF8575_ADDRESS); Wire.endTransmission(); Wire.requestFrom(PCF8575_ADDRESS, 2); lo = Wire.read(); // Читаем младший байт (P00...P07) hi = Wire.read(); // Читаем старший байт (P10...P17) return (word(hi, lo)); // Возвращаем длинное слово }
Проблема в том, что прерывание срабатывает только один раз (при нажатии любой кнопки), и после отпускания кнопки, вывод INT PCF8575 не возвращается в высокое состояние. Если загрузить "пустой" скетч, то нажатия кнопок прижимает INT вниз, после отпускания кнопки вывод возвращается в высокое состояние. Что я делаю не так?
да, в обработчике прерывания запись в PCF8575 - шаманские танцы с целью вернуть вывод INT в высокое состояние, которые ни к чему не привели
Надеюсь, ты его к плюсу притянул? (вывод INT)
вот здеся:
The PCF8575 provides an open-drain interrupt (INT) output, which can be connected to the interrupt input of a microcontroller. An interrupt is generated by any rising or falling edge of the port inputs in the input mode. After time, tiv, the signal INT is valid. Resetting and reactivating the interrupt circuit is achieved when data on the port is changed to the original setting, or data is read from or written to the port that generated the interrupt. Resetting occurs in the read mode at the acknowledge (ACK) bit after the rising edge of the SCL signal or in the write mode at the ACK bit after the falling edge of the SCL signal. Interrupts that occur during the ACK clock pulse can be lost (or be very short), due to the resetting of the interrupt during this pulse. Each change of the I/Os after resetting is detected and is transmitted as INT. Reading from or writing to another device does not affect the interrupt circuit. This device does not have internal configuration or status registers. Instead, read or write to the device I/Os directly after sending the device address
что непонятного?
Надеюсь, ты его к плюсу притянул? (вывод INT)
Да, возле разъема резистор висит )
вот здеся:
The PCF8575 provides an open-drain interrupt (INT) output, which can be connected to the interrupt input of a microcontroller. An interrupt is generated by any rising or falling edge of the port inputs in the input mode. After time, tiv, the signal INT is valid. Resetting and reactivating the interrupt circuit is achieved when data on the port is changed to the original setting, or data is read from or written to the port that generated the interrupt. Resetting occurs in the read mode at the acknowledge (ACK) bit after the rising edge of the SCL signal or in the write mode at the ACK bit after the falling edge of the SCL signal. Interrupts that occur during the ACK clock pulse can be lost (or be very short), due to the resetting of the interrupt during this pulse. Each change of the I/Os after resetting is detected and is transmitted as INT. Reading from or writing to another device does not affect the interrupt circuit. This device does not have internal configuration or status registers. Instead, read or write to the device I/Os directly after sending the device address
что непонятного?
Да собственно все: "Resetting and reactivating the interrupt circuit is achieved when data on the port is changed to the original setting, or data is read from or written to the port that generated the interrupt"
when data on the port is changed to the original setting - это я так понимаю кнопка должна быть отпущена (не реагирует)
data is read from - PCF8575_dataReceive = pcf8575_read() - тоже безрезультатно
or written to the port that generated the interrupt - pcf8575_write(PCF8575_dataLowByte, PCF8575_dataHighByte); - тоже нифига.
или я не могу правильно интерпретировать написанное по-басурмански :(
Там родным по белому написано, хочешь флаг прерыания сбросить - прочитай, матьтваю, регитр вызвавший прерывание. Не помогло, ищи ошибку в схеме. По крайней мере у меня 8574 так работает. Правда, 8575 я не щюпал.
Не гневитесь - я не настоящий сварщик, маску на стройке нашел (только осваиваю программирование), поэтому не знаю как это (матьмаю) прочитать регистр. Как это сделать?
Щас взрослые придут, пацкажут.
для чего строки 49 и 50 ? Запросили запись и ничего не записали ?
для чего строки 49 и 50 ? Запросили запись и ничего не записали ?
Это остатки моих безуспешных попыток сбросить прерывание.
А вы с адресом не напутали ничего ? Какой адрес находит скетч i2C scanner ?
с адресом все нормально, один раз прерывание срабатывает и нажатие кнопки читается. При работе через библиотеку все тоже работает, но хочется понять как это работает непосредственно. по прерыванию я допустим считываю.
P.S. а не, похоже я все же со схемой намудрил.