stm8 max7219 tx1838

skoctehs
Offline
Зарегистрирован: 27.02.2016
//
// программка вывода цифр на 7 сегментный дисплей
// использует процедуры библиотеки MAX7219.h Jonathan Evans
// stm8 only С. В оригинале библиотека на С++, использует классы и конструкты.

#define MAX_CLK 10  // stm8 PD1
#define MAX_CS  11  // stm8 PD2
#define MAX_DIN 12  // stm8 PD3

#define REG_DECODE        0x09
#define REG_INTENSITY     0x0a
#define REG_SCAN_LIMIT    0x0b
#define REG_SHUTDOWN      0x0c
#define REG_DISPLAY_TEST  0x0f

#define INTENSITY_MIN     0x00
#define INTENSITY_MAX     0x0f
char mx_Font[] = {0b1111110, 0b0110000, 0b1101101, 0b1111001, 0b0110011, 0b1011011, 0b1011111, 0b1110000, 0b1111111, 0b1111011};

// для ИК пульта
#define READ_PIN 2    //stm8 A3
bool stay, state, flag = false;
uint32_t tmr;

#define stay_delay 200  // ms удержание после нажатия кнопки, продлевается от любого нажатия в этот период
// каждые 110 мс передаётся специальный код повтора

byte ii, n, z = 0;
char ch, ch1 = ' '; // нажатая кнопка пульта
word keycode = 0;
unsigned long tm, tm_stay = 0;
unsigned long last, last_stay = 0;

void mxTx(volatile byte opcode, volatile byte data) {
  digitalWrite(MAX_CS, LOW);
  shiftOut(MAX_DIN, MAX_CLK, MSBFIRST, opcode);
  shiftOut(MAX_DIN, MAX_CLK, MSBFIRST, data);
  digitalWrite(MAX_CS, HIGH);
}


void mx_ShutdownStart ()
{
  mxTx(REG_SHUTDOWN, 0);
}

void mx_DisplayTestStart ()
{
  mxTx(REG_DISPLAY_TEST, 1);
}

void mx_Clear() {
  z = 8;
  for (int i = 0; i < 8; i++)
  {
    mxTx(i + 1, 0x00);
  }
}

void mx_DisplayTestStop ()
{
  mxTx(REG_DISPLAY_TEST, 0);
}

void mx_SetBrightness (char brightness)
{
  brightness &= 0x0f;
  mxTx(REG_INTENSITY, brightness);
}




// печать в позиции digit цифру value (0-9)
void mx_print(int digit, byte value) {
  mxTx(digit, mx_Font[value]);
}

void mx_ShutdownStop ()
{
  mxTx(REG_SHUTDOWN, 1);
}



void setup() {
  pinMode(READ_PIN, INPUT); // ir recv
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)

  pinMode(LED_BUILTIN, OUTPUT);
  z = 1;
  pinMode(MAX_DIN, OUTPUT);
  pinMode(MAX_CS, OUTPUT);
  pinMode(MAX_CLK, OUTPUT);

  mxTx(REG_SCAN_LIMIT, 7);
  mxTx(REG_DECODE, 0x00);
  mx_ShutdownStop();
  mx_DisplayTestStop();
  mx_Clear();
  mx_SetBrightness(5);
  // mx_print(8, 128);
}

void keypressed()
{
  n = 0;
  switch (keycode)
  {
    case 0x1FE:
      ch = '1';
      break;
    case 0xFE:
      ch = '2';
      break;
    case 0x817E:
      ch = '3';
      break;
    case 0x41BE:
      ch = '4';
      break;
    case 0x40BE:
      ch = '5';
      break;
    case 0xC13E:
      ch = '6';
      break;
    case 0x21DE:
      ch = '7';
      break;
    case 0x20DE:
      ch = '8';
      break;
    case 0xA15E:
      ch = '9';
      break;
    case 0x609E:
      ch = '0';
      break;
    case 0x619E:
      ch = '*';
      break;
    case 0xE11E:
      ch = '#';
      break;
    case 0x51AE:
      ch = 'L';
      break;
    case 0x10EE:
      ch = 'U';
      break;
    case 0xD12E:
      ch = 'R';
      break;
    case 0x30CE:
      ch = 'D';
      break;
    case 0x50AE:
      ch = 'M';
      break;
    default:
      ch = ' ';
  }

}
void txout()
{


  if (ii < 10) {
    mx_print(z, ii);
  } else {
    mxTx(z, ii);
  }

}


void stay_on() // вкл выход
{
  stay = true;
  //mxTx(z,255);
  tm_stay = millis() + 200;
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
}

void stay_off() // откл текущий z выход
{
  stay = false;
  //mxTx(z,128);
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
}

void loop() {
  //  mxTx(8, 128);
  n = 0;
  while (n < 32)
  {
    // ждем импульс = 0
    state = !digitalRead(READ_PIN);
    while (state) {
      state = !digitalRead(READ_PIN);


      if (stay) if (millis() > tm_stay) stay_off();
    }
    tmr = micros();

    // ждем конец импульса = 1
    state = digitalRead(READ_PIN);
    while (state) {
      state = digitalRead(READ_PIN);
      if (stay) if (millis() > tm_stay) stay_off();

    }
    last = micros();

    tm = last - tmr;
    n += 1;
    if (tm > 3000) {
      keycode = 0;
      n = 0;
      // также функция удержания
      stay_on();
    }
    if (n > 8) {
      if (tm > 1500) keycode += 1;
      keycode = keycode << 1;
    }

  }

  //   mxTx(8, 120);
  keypressed();    // однократное действие после нажатия кнопки на пульте

  if (ch != ch1) stay_off(); // было нажатие другой кнопки

  ch1 = ch;
  ii = ch - 48;
  if (z == 0) {
    // z = 8;
    mx_Clear();
  }
  txout();
  z--;
}

 

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Кроссаффчег

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Зачем здесь этот классический говнокод?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

DetSimen пишет:

Зачем здесь этот классический говнокод?

за то какие краски, какая экспрессия )))

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

DetSimen пишет:

Зачем здесь этот классический говнокод?

Похвастаться, видимо )))))

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

DetSimen пишет:

Зачем здесь этот классический говнокод?

Чтобы дать повод ещё раз поговорить о переполнении millis, кое здесь в полный рост присутствует.

skoctehs
Offline
Зарегистрирован: 27.02.2016

Прочитал про великое переполнение , я не сам же эту команду выдумал - скопипастил.

Там для меня Ваш пример в статье вообще не читабелен, бейсик/паскаль мне ближе.

Ну а тут хвастаюсь, что раздербанил чужую библиотеку и использовал ее для использования с STM8, т.к. ее нельзя подключить из-за ограничения языка С.

Вот таково тут моё достижение, а также алгоритм работы с ИК пультами лично обдуманный и работоспособный с любым китайским пультом.

Может кому-то пригодится что-то... 

Пишу не на продажу, вот и код такой, зачем страдать...