Помогите заставить работать 7-сегментный дисплей

Bobre
Offline
Зарегистрирован: 01.12.2014

Купил на Ebay дисплеи (фото дальше). В описании было, что работает на TM1637, действительно, так такие платы есть, но ни один из примеров из интернета не выводит ничего нормального на дисплей, иногда получается выводить какие-то соверщенно случайные линии, иногда "8888" иногда " hh "  и тому подобное. Подскажите, как сделать, чтобы это заработало, так как отпаевать от платы исплеи не охота..

Входы необычные - 5 пинов VCC, SCLK, RCLK, DIO, GND

Спасибо

Alex_Sk
Offline
Зарегистрирован: 06.01.2015

Обычный SPI интерфейс. Примеры надо смотреть от 74HC595. Например этот:

http://www.instructables.com/id/74HC595-digital-LED-Display-Based-on-Arduino-Code-/step5/Code-for-Your-Reference/

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

DIO = MOSI

SCK= SCK

Похоже схема матричная - на регистрах - это жесть. Первый байт это Символ, второй это разряд. И нужно постоянно слать эту последовательность по очереди для каждой цифры...

Bobre
Offline
Зарегистрирован: 01.12.2014

Если кому будет необходимо, для моего дисплея пришлось доделывать такой код 

//Дисплей
#define   HC_DATA_H digitalWrite(data, HIGH)   // data line output high
#define   HC_DATA_L digitalWrite(data, LOW)   //date line output low
#define   HC_RCK_H digitalWrite(rck, HIGH)   // rck output high
#define   HC_RCK_L digitalWrite(rck, LOW)  // rck output low
#define   HC_SCK_H digitalWrite(sck, HIGH)   // sck output high
#define   HC_SCK_L digitalWrite(sck, LOW)  // sck output low

int Num_matrix[10]= {3,159,37,13,153,73,65,31,1,9};

int data =12;  
int rck =11;
int sck =10;
int sclr = 13;

void setup(){
}

void loop(){
  writeNum(1234);
}


/////ДИСПЛЕЙ
void reset_display(){write_74HC595(1);}

void writeNum(int num){
  write_74HC595(Num_matrix[num/1000] + 4096);
  write_74HC595(Num_matrix[num/100 - (num/1000)*10] + 8192);
  write_74HC595(Num_matrix[num/10 - (num/100)*10] + 16384);  
  write_74HC595(Num_matrix[num/1 - (num/10)*10] + 32768);
}

void write_74HC595( unsigned int data_a) 
{
  char look =0;
  HC_RCK_L;  //latch open
  HC_SCK_L;


 
  for (;look < 16; ++look)
  {
    if(data_a&0x0001) {
    HC_DATA_H;
  }
    else {HC_DATA_L;}
    HC_SCK_H;

    HC_SCK_L;
    data_a >>= 1;
  }
  HC_RCK_H;
}

 

ankurmanov
Offline
Зарегистрирован: 03.07.2016

Может пригодится кому. Мой вариант, с обновлением дисплея по прерыванию по таймеру, для 8 сегментного.

#define SCK_LOW() PORTB &= ~(1 << 3)
#define SCK_HIGH() PORTB |= (1 << 3)
#define RCK_LOW() PORTB &= ~(1 << 4)
#define RCK_HIGH() PORTB |= (1 << 4)
#define DIO_LOW() PORTB &= ~(1 << 2)
#define DIO_HIGH() PORTB |= (1 << 2)

#define SCK_PIN() DDRB |= (1 << 3) // 11
#define RCK_PIN() DDRB |= (1 << 4) // 12
#define DIO_PIN() DDRB |= (1 << 2) // 10

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

const static char charTable[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90};
boolean Dot[8] = {false, false, false, false, false, false, false, false};

volatile unsigned long DNum = 0;
unsigned long TNum = 0;
char NDigit = 0B00001000;
char IDig = 0;

void sOut(char data)
{
  for (char i = 0; i < 8; i++)
  {
    if (data & 0x80)
    {
      DIO_HIGH();
    }
    else
    {
      DIO_LOW();
    }
    SCK_HIGH();
    SCK_LOW();
    data = data << 1;
  }
}

void PrintDigit(char Nomer, char data, boolean Dot = false)
{
  if (Dot)
  {
    data &= ~(1 << 7);
  }
  RCK_LOW();
  sOut(data);
  sOut(Nomer);
  RCK_HIGH();
}

ISR(TIMER2_OVF_vect)
{
  if (IDig == 8) IDig = 0;
  if (IDig == 0)
  {
    TNum = DNum;
    NDigit = 0B00001000;
  }
  if (IDig == 4) NDigit = 0B10000000;
  if (TNum > 0)
  {
    PrintDigit(NDigit, charTable[TNum % 10], Dot[IDig]);
  }
  else
  {
    PrintDigit(NDigit, 255, false);
  }
  NDigit = NDigit >> 1;
  TNum = TNum / 10;
  IDig++;
}

int main(void)
{
  SCK_PIN();
  RCK_PIN();
  DIO_PIN();

  TIMSK2 = 0B00000001;
  TCCR2A = 0B00000000;
  TCCR2B = 0B00000100;
  TCNT2 = 0;
  
  sei();

  while (1)
  {
    for (DNum = 0; DNum <= 100000; DNum++)
    {
      _delay_ms(10);
    }
  }
  return 0;
}

 

kyrios
Offline
Зарегистрирован: 29.12.2015

Это не TM1637 а 74HC595. С таким мучаюсь месяц .Я тему закинул  http://arduino.ru/forum/programmirovanie/perezaliv-1307

Там рабочий код,только со временем не разберусь

ankurmanov
Offline
Зарегистрирован: 03.07.2016

Точно, не прочитал, глянул на фото, по виду было как на двух 74HC595. TM1637 не пробовал, я так понял это типа MAX7219, если так там же проще, не надо постоянно как в этом обновлять дисплей, сам обновляет

kyrios
Offline
Зарегистрирован: 29.12.2015

Это именно на двух  74HC595. Я узнаю его из тысячи.Как он меня достал-время не могу вывести.С температурой тоже пляски.Лучше бы взял TM1637

ankurmanov
Offline
Зарегистрирован: 03.07.2016

Пробовал отключить опрос датчика, и так вывести время?

kyrios
Offline
Зарегистрирован: 29.12.2015

Я только осваиваю.Мне написали код.Как это сделать "безболезненно" для кода?

arduinec
Offline
Зарегистрирован: 01.09.2015
const byte clockPin = 7;  // SCLK (CLK, SH_CP)
const byte latchPin = 6;  // RCLK (SS, ST_CP)
const byte dataPin  = 5;  // DIO (SDI, DS)

byte digits[25] = {
  B11000000, B11111001, B10100100, B10110000, B10011001,  // 0 1 2 3 4
  B10010010, B10000010, B11111000, B10000000, B10010000,  // 5 6 7 8 9
  B01000000, B01111001, B00100100, B00110000, B00011001,  // 0. 1. 2. 3. 4.
  B00010010, B00000010, B01111000, B00000000, B00010000,  // 5. 6. 7. 8. 9.
  B01111111, B10111111, B10011100, B11000110, B11111111   // . - degree C empty
};
byte digitpos[4] = {1, 2, 4, 8};

void setup()
{
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin,  OUTPUT);
}

void loop()
{
  int value = 1234;
  display(value);
}

void Indicate(byte p, byte d)
{
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, digits[d]);
  shiftOut(dataPin, clockPin, MSBFIRST, digitpos[p]);
  digitalWrite(latchPin, HIGH);
  delay(5);
}

void Display(int disp)
{
  Indicate(0, disp % 10);
  for (byte i=1; i<4; i++) {
    disp /= 10;
    if (disp) Indicate(i, disp % 10);
    else Indicate(i, 24);
  }
}

 

kyrios
Offline
Зарегистрирован: 29.12.2015

Спасибо ,решилось

pedro
Offline
Зарегистрирован: 08.10.2016

Подскажите, как в этом коде:

int value = 1234;
вместо цифр 1234, вывести значение переменной, куда после определенных вычислений записываеться число.

Те, задача такая. Прошел опрос датчика, путем матиматических манипуляций вышло значение. Его надо показать на этом дисплее. Но вся сложность в том, что это значение надо выводить скажем 5 секунд. А насколько я понимаю, этот дисплей на таком драйвере, это не может. 

Иными словами. Результат отображается долю секунды и все. Фишка в том, что опрос датчика разовый,а не постоянный как с температурой например. 

Буду благодарен за любую подсказку. 
nik182
Offline
Зарегистрирован: 04.05.2015

По прерыванию таймера раз в 20мс вызывается подпрограмма отрисовки значения.

pedro
Offline
Зарегистрирован: 08.10.2016

Можно на пальцах или любой похожий кусок кода? 

nik182
Offline
Зарегистрирован: 04.05.2015

http://arduino.ru/forum/programmirovanie/podklyuchenie-semisegmentnogo-indikatora здесь намётки.

http://chipenable.ru/index.php/programming-avr/item/58-uchebnyy-kurs-sem... здесь пятый пример - только таймер надо брать первый. 

ankurmanov
Offline
Зарегистрирован: 03.07.2016

Выше код скидывал, как раз на прерываниях по таймеру. Или вопрос не про это был? Только там для 8 разрядного. Но лучше 4 брать, 7..8 разряд смазываются. 4 если будет то нормально