Search the Community
Showing results for tags 'Flag'.
-
Здравствуйте! Пишу программу на C++ для управления LCD (HD44780) по I2C через модуль расширения портов ввода/вывода PCF8574AT. void LCD_I2C::readBF() { transmitByte(0b00001110); //transmits E, RW set to HIGH and RS, set to LOW _delay_ms(5); transmitByte(0b00001010); //transmits E, RS set to LOW and RW set to HIGH _delay_ms(5); initRestart(); transmitAddrRW(0b01111111); //sends PCF8574AT address + SLA+R do { receiveDataAck(); PORTA = storage; } while((storage & (1 << BF)) != 0); //wait until BF is 0 initRestart(); transmitAddrRW(0b01111110); } Метод void transmitByte(uint8_t data) после инициализации состояния "Старт" и отправки адреса устройства + SLA+W отправляет байт данных по TWI с ожиданием бита подтверждения (команды работают верно, проверял по регистру статуса TWI - 0x08, 0x10 и 0x24). Метод void transmitAddrRW(uint8_t address) отправляет соответственно SLA+W/R + адрес устройства (команда работает также верно). Нареканий к работе TWI у меня нет, т.к. недавно с его помощью успешно запустил часы DS1307 с интеграцией LCD. После передачи запроса на чтение флага занятости инициализируется состояние "ПОВСТАРТ", отправляется адрес устройства + SLA+R, далее идет цикл - запрос байта данных (состояние выводов PCF8574AT) с отправкой бита подтверждения uint8_t receiveDataAck() (команды работают также верно, возвращает storage = TWDR) и вывод storage на порт А микроконтроллера (там установлены светодиоды). Чтение регистра данных TWDR после принятия байта данных (receiveDataAck()) дает следующий результат - 0b00000010 - установлен только бит RW микросхемы. Таким образом, флаг занятости BF = DB7 = 7й бит оказывается сразу же сброшенным, происходит мгновенный выход из цикла - контроллер дисплея не успевает скушать информацию, и инициализация не выполняется (неудачную инициализацию определяю по отсутствию курсора). Ожидалось, что флаг занятости будет установлен в единицу и произойдет несколько итераций перед выходом из цикла. При замене метода ожидания сброса флага занятости BF на программную задержку в 250 мс везде, где это требует datasheet - инициализация происходит успешно (появляется курсор, как и должно быть). Вопрос: что можно сделать, чтобы вместо _delay_ms(250) использовать readBF(), т.к. этот путь мне кажется более верным (уж очень не хочется использовать задержку .__.)? Возможно, проблема в микросхеме, которая неверно выдает информацию при чтении? (Имеется вторая микросхема, она вообще не работает:D) З.Ы. На фото виден результат чтения флага BF и Adress Counter - установлен только бит RW. З.Ы.Ы Кому интересно - вот функция main(). Повторюсь - проблема только в методе readBF(): void LCD_I2C::init() { setBitRate(20000); initStart(); transmitAddrRW(0b01111110); //send PCF8574AT address + SLA+W _delay_ms(60); sendInstruction(0b00110000); //function set 8-bit operation _delay_ms(20); sendInstruction(0b00110000); //function set 8-bit operation _delay_ms(5); sendInstruction(0b00110000); //function set 8-bit operation _delay_ms(5); sendInstruction(0b00100000); //function set 4-bit operation readBF(); //_delay_ms(250); //debug!! sendInstruction(0b00100000); //function set 4-bit operation, 2 lines, 5x8 dots sendInstruction(0b10000000); readBF(); //_delay_ms(250); //debug!! sendInstruction(0b00000000); //display off, cursor off, blinking off sendInstruction(0b10000000); readBF(); //_delay_ms(250); //debug!! sendInstruction(0b00000000); //display clear sendInstruction(0b00010000); readBF(); //_delay_ms(250); //debug!! sendInstruction(0b00000000); //entry mode set increment, display shift off sendInstruction(0b01100000); readBF(); //_delay_ms(250); //debug!! sendInstruction(0b00000000); //display on, cursor off, blinking off sendInstruction(0b11100000); readBF();/ }