LCD 16x2 и прерывание - странности поведения

sds
Offline
Зарегистрирован: 29.10.2012

Добрый день, всем

Играюсь с TLC5940 и все там, собственно, хорошо. Решил вот добавить в проект экранчик 16х2.

В итоге, наткнулся на странность их совместной работы. Даташитов/мануалов в достаточной степени пока не накурился (в процессе это), но есть подозрения, что ошибка очень проста, но на замыленный глаз мой не видна с первого раза.

Из всего проекта сделал тестовый скетч, показывающий ошибку.

Итак, вот код работы с экранчиком:

#include <LiquidCrystal.h>

const unsigned char lcdEnablePin = 3; // PD3 pin включения/выключения lcd
const unsigned char lcdDB4Pin = A4; // PC4
const unsigned char lcdDB5Pin = A5; // PC5
const unsigned char lcdDB6Pin = 12; // PB4
const unsigned char lcdDB7Pin = 4;  // PD4
const unsigned char lcdRSPin = A2;  // PC2
const unsigned char lcdEPin = A3;   // PC3

LiquidCrystal lcd(lcdRSPin, lcdEPin, lcdDB4Pin, lcdDB5Pin, lcdDB6Pin, lcdDB7Pin);

void setup() {
  pinMode(lcdEnablePin, OUTPUT); 

  lcd.begin(16, 2);
  digitalWrite(lcdEnablePin, HIGH);
  lcd.setCursor(0, 0);
  lcd.print("*** 11111 ***");
  delay(2000);

  lcd.setCursor(0, 1);
  lcd.print("*** 22222 ***");
  delay(2000);
  digitalWrite(lcdEnablePin, LOW);
}

void loop() {
}

С ним все в порядке и он в таком виде дает ожидаемый результат, а именно: при старте экран зажигается, в первой строке выводятся единички, потом во второй двоечки и потом через 2 сек все заснет

Теперь этот скетч дополняю блоком настройки прерывания, необходимого для работы TLC5940:

 

#include <LiquidCrystal.h>

const unsigned char lcdEnablePin = 3; // PD3 pin включения/выключения lcd
const unsigned char lcdDB4Pin = A4; // PC4
const unsigned char lcdDB5Pin = A5; // PC5
const unsigned char lcdDB6Pin = 12; // PB4
const unsigned char lcdDB7Pin = 4;  // PD4
const unsigned char lcdRSPin = A2;  // PC2
const unsigned char lcdEPin = A3;   // PC3

LiquidCrystal lcd(lcdRSPin, lcdEPin, lcdDB4Pin, lcdDB5Pin, lcdDB6Pin, lcdDB7Pin);

void setup() {
  pinMode(lcdEnablePin, OUTPUT); 

  lcd.begin(16, 2);
  digitalWrite(lcdEnablePin, HIGH);
  lcd.setCursor(0, 0);
  lcd.print("*** 11111 ***");
  delay(2000);

  // ->>>> start probleb block

  // Enable SPI, Master, set clock rate fck/2
  SPCR = (1 << SPE) | (1 << MSTR);
  SPSR = (1 << SPI2X); 
  // CTC with OCR0A as TOP
  TCCR0A = (1 << WGM01); 
  // clk_io/1024 (From prescaler)
  TCCR0B = ((1 << CS02) | (1 << CS00)); 
  // Generate an interrupt every 4096 clock cycles
  OCR0A = 3; 
  // Enable Timer/Counter0 Compare Match A interrupt
  TIMSK0 |= (1 << OCIE0A);
  
  sei();

  // ->>>> end probleb block

  lcd.setCursor(0, 1);
  lcd.print("*** 22222 ***");
  delay(2000);
  digitalWrite(lcdEnablePin, LOW);
}

void loop() {
}

ISR(TIMER0_COMPA_vect) {
}

Блок настройки прерывания скопипастен из доки "Demystifying-the-TLC5940.pdf" и сам по себе работает (проверялось, но без LCD).

После запуска измененного скетча получаем следующее:
  1. Строка с двойками пишется на первой строке, т.е. переключения на вторую строку не выполняется
  2. Экран не выключается. Вобще никак. Пробовал добавлять в loop мигание экраном через дрыгание lcdEnablePin - реакции никакой
  3. Появляется несколько разное поведение при смене пинов подключения LCD: в первой строке могут появляться козябры, квадратики или экран совсем не зажигаться
 
Если у кого есть мысли по данному странному поведению устройства, буду признателен за ответ
Axell
Offline
Зарегистрирован: 23.03.2013

сорри..

Axell
Offline
Зарегистрирован: 23.03.2013

сорри..

__Alexander
Offline
Зарегистрирован: 24.10.2012

Axell, где Вы увидели хоть кусочек кода в обработчике прерывания?

 

sds, причина банальная, у Вас пин D12 висит на дисплее. Когда Вы включаете SPI, этот пин является MISO для протокола SPI, т.е. настраивается прежде всего на вход.

Короче, перенесите с D12 на какой-то другой да и делов, че я сопли жую )

sds
Offline
Зарегистрирован: 29.10.2012

__Alexander пишет:
 перенесите с D12 на какой-то другой

Спасибо большое. Вечером сегодня проверю

Какую-нибудь такую подлянку и ожидал от этих настроек ...

sds
Offline
Зарегистрирован: 29.10.2012

Да, после ухода с 12-го пина экранчик стал показывал текст правильно, но его выключение не происходит (digitalWrite(lcdEnablePin, LOW); не работает)

Вернее, все хитрее получается ...

Если до блока инициализации прерывания установить пин в HIGH, то экран все время "горит", а если заранее поставить его в LOW, то больше и не зажигается.

Короче, полный игнор дрыгания ноги с 1 в 0 и обратно

Перебрал несколько разных пустых ног (аналоговых/цифровых). Поведение везде одинаковое.

Есть ли мысли у уважаемого сообщества по данной странности?

__Alexander
Offline
Зарегистрирован: 24.10.2012

А что это за нога в индикаторе 16х2?

 

sds
Offline
Зарегистрирован: 29.10.2012

Использую анод от подсветки: 15 — A, питание для подсветки ⇨ +5 В

__Alexander
Offline
Зарегистрирован: 24.10.2012

хм. вы питаете подсветку напрямую от ардуины?