Странная работа функций cbi и sbi
- Войдите на сайт для отправки комментариев
Сейчас есть задачка подключить хорошо известный, доступный и дешевый дисплейчик от нокиа 5110 (он же 3310, например тут: http://devicter.ru/goods/Nokia-5110-LCD?from=ZmNk). В общем, ничего особенного, но одно условие, которое наваязано "окружением" - нужно использовать аппаратный SPI.
Корректирую библиотеку http://henningkarlsen.com/electronics/library.php?id=48 (достаточно скорректировать всего одну ключевую функцию):
// закомментаренные вещи не нужны для SPI (пины уже определены самим аппаратным SPI) LCD5110::LCD5110(/*int SCK, int MOSI, */int DC, int RST, int CS) { //P_SCK = portOutputRegister(digitalPinToPort(SCK)); //B_SCK = digitalPinToBitMask(SCK); //P_MOSI = portOutputRegister(digitalPinToPort(MOSI)); //B_MOSI = digitalPinToBitMask(MOSI); P_DC = portOutputRegister(digitalPinToPort(DC)); B_DC = digitalPinToBitMask(DC); P_RST = portOutputRegister(digitalPinToPort(RST)); B_RST = digitalPinToBitMask(RST); P_CS = portOutputRegister(digitalPinToPort(CS)); B_CS = digitalPinToBitMask(CS); //pinMode(SCK,OUTPUT); //pinMode(MOSI,OUTPUT); pinMode(DC,OUTPUT); pinMode(RST,OUTPUT); pinMode(CS,OUTPUT); SCK_Pin=SCK; RST_Pin=RST; } void LCD5110::_LCD_Write(unsigned char data, unsigned char mode) { if (mode==LCD_COMMAND) //cbi(P_DC, B_DC); digitalWrite(5, 0); else //sbi(P_DC, B_DC); digitalWrite(5, 1); cbi(P_CS, B_CS); // убираем следующий кусок /* for (unsigned char c=0; c<8; c++) { if (data & 0x80) sbi(P_MOSI, B_MOSI); else cbi(P_MOSI, B_MOSI); data = data<<1; pulseClock; } */ // и заменяем на одну строчку SPI.transfer(data); sbi(P_CS, B_CS); }
В этом виде - работает (причем, даже на глаз заметно, что работает существенно быстрее), но тут фигурируют digitalWrite(5, 1); и в явном виде указано, на каком пине и что сделать. Функции, которые закомментированы над этими строчками (cbi и sbi, соответствено) - почему-то не работают (или работают, но дисплей не отрабатывает).
платка - нано 328, на 5 пин (который в абзаце выше фигурирует) - подключен вход DC дисплейчика (LOW - команда, HIGH - данные)
если раскоментировать вызовы cbi, sbi и убрать digitalWrite - на дисплее ничего не просиходит. Если наоборот - работает.
Оригинальная библиотека с софтверной реализацией SPI с вызовом исходных cbi и sbi - работает (конфигурация по пинам - идентичная).
Почему? Как заставить работать?
я недавно пробовал библиотеку от adafruit. Пример работает, цветочки и прочие картинки рисует. Она тоже использует софт-spi ?