Контроллер LED и Клавиатуры FD650В - Как им управлять?

tretyakov
Offline
Зарегистрирован: 09.11.2014

Есть вот такой девайс : 

Внутри контроллер FD650B. DATASHEET здесь: http://www.fdhisi.com/down/upload/20141212/1418349595.rar

Инфа на китайском, но там есть пример кода на си. Подскажите как сделать скетч для работы с ним? 

tretyakov
Offline
Зарегистрирован: 09.11.2014

Так и не подключил.

Вопросы такие: Что за интерфейс в ней использован? Судя по описанию TWI?

Сканер I2C находит 128 устройств!

Пример кода у китайцев:

void MDrv_FrontPnl_Show_State(void)
{
MS_U8 i;
MS_U8 LedBuffer[4];
for(i=0;i<4;i++)
{
LedBuffer[i] = Led_Get_Code(g_u8FrontPnlstr[i]);
}
FD650_Write(0x0400|0x01|0x00); //Инициализация открыть восемой режим
// Показать данные
FD650_Write( 0x1400| LedBuffer[0] ); //Первая цифра
FD650_Write( 0x1500 | LedBuffer[1]); //Вторая цифра
if((SignalIsLock)&&(MApp_ZUI_GetActiveOSD() == 8))
FD650_Write(0x1600 | LedBuffer[2]|0x0080); //Третья цифра
else
FD650_Write(0x1600 | LedBuffer[2]|0x0000); //Третья цифра
FD650_Write( 0x1700 | LedBuffer[3] ); // Четвертая цифра
}
 
Кто может обяснить?
dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

tretyakov, шина обычная последовательная, SPI с односторонней передачей. В примере не хватает главного - самой  функции FD650_Write().

tretyakov
Offline
Зарегистрирован: 09.11.2014

dimax пишет:

tretyakov, шина обычная последовательная, SPI с односторонней передачей. В примере не хватает главного - самой  функции FD650_Write().

Там шина с двухсторонней передачей по линии DAT. Так как можно и клавиатуру подключить к микрухе.

Не понятно слать 8 бит и 8 бит или 16 бит сразу. Описания регистров нет только пример кода.

 

tretyakov
Offline
Зарегистрирован: 09.11.2014

Все, разобрался!! Это аналог TM1650! Библиотека здесь: https://github.com/arkhipenko/TM1650

svm
Онлайн
Зарегистрирован: 06.11.2016

Впервые пишу на этом форуме , если что не так, поправьте.

Мне случайно перепали пара десятков битых спутниковых ресиверов. Индикатор ваполнен ра TM1650. Просто выбросить рука не поднялась. Тем более, что китайские приставки начали сыпаться и количество микросхем растет. Начал разбираться. За месяц немного разобрался с Ардуино (последний раз прогаммировал лет 5 назад на VB и лет 20 назад на ASMe). Некоторые навыки еще остались, с железом проще, с паяльником дружу более 50 лет.  Сначала мспользовал, найденые в сети библиотеки, вдохновили не очень. Решил работать напрямую с портами микросхемы. Т.к. был необходим генератор начал с него. За основу был взят http://arduino.ru/forum/proekty/generator-s-reguliruemoei-chastotoi-na-arduino?page=3 изменен только способ ввода частоты. ТМ1650 кроме индикации позволяет опрашивать клавиатуру 7х4. Поэтому требуемое значение частоты  вводится с цифровой клавиатуры, отображается на дисплее и передается генератору. В принципе это первый почти рабочий скетч, позтому сильно тапками не кидайте. Осталось прикрутить еще один дисплей т.к. 4 разряда маловато, хотя работать уже можно, несмотря на то что старшие разряды уползают за пределы индикатора. Скетч работает на  Nano v3.0 (CH340G). Раэобраться с работой микросхемы по тексту скетча, я думаю не очень сложно. Корявый перевод даташита сделаный  мной - здесь https://yadi.sk/i/h-GKf9hMyABLL

#include <Wire.h>
 long rez;
 byte scan_code,dl;
 byte sr[8];// массив разрядов индикатора

//массив изображений 7 сегментных символов от 0 до 9 и пустота
byte simv[11]={
B00111111, //0
B00000110, //1
B01011011, //2
B01001111, //3
B01100110, //4
B01101101, //5
B01111101, //6
B00000111, //7
B01111111, //8
B01101111, //9
B00000000, //пустота
};

void setup() {
//Serial.begin(9600);  
  Wire.begin();
// *********инициализация таймеров генератора************
pinMode (9,OUTPUT);      // выход генератора
TCCR1A=1<<COM1A0;        //подключить выход OC1A первого таймера
TCCR1B=0;                //

// адреса регистров управления и данных ТМ1650
// 1-0х24
// 2-0х25
// 3-0х26
// 4-0х27
// *********инициализация дисплея************
//___________________________________________
//b7 b6 b5 b4 b3 b2 b1 b0 IФункция   I опис. I
//___________________________________________
//x  0  0  0      x  x    I          I   8   I
//x  0  0  1      x  x    I          I   1   I
//x  0  1  0      x  x    I          I   2   I
//x  0  1  1      x  x    I яркость  I   3   I
//x  1  0  0      x  x    I          I   4   I
//x  1  0  1      x  x    I          I   5   I
//x  1  1  0      x  x    I          I   6   I
//x  1  1  1      x  x    I          I   7   I
//____________________________________________
//x           0   x  x    I  режим   I 8ceгм I
//x           1   x  x    I 7/8 bit  I 7ceгм I
//____________________________________________
//x               x  x  0 Ibit ON/OFFI  OFF  I
//x               x  x  1 I  дисплея I   ON  I
//____________________________________________


Wire.beginTransmission(0x24);   //обращаемся к любому порту 0х24-0х27
   Wire.write(0b01000001);      //включаем:яркость 4,8 битный режим, отображение ON
Wire.endTransmission();         // закрываем сессию

}

void loop() {
 
  //********************* чтение клавиатуры *************************
 readkl:
 Wire.beginTransmission(0x25);        // обращаемся к клавиатуре(к любому порту 0х24-0х27)
 Wire.requestFrom((0x25), 1);         //запрашиваем один байт
  scan_code = Wire.read();            // читаем скан код
 Wire.endTransmission();              // закрываем сессию 
 if (scan_code <69) goto readkl;
 if (scan_code ==70 )scan_code =1;
 if (scan_code ==69 )scan_code =2;
 if (scan_code ==79 )scan_code =3;
 if (scan_code ==101)scan_code =4;
 if (scan_code ==87 )scan_code =5;
 if (scan_code ==117)scan_code =6;
 if (scan_code ==103)scan_code =7;
 if (scan_code ==102)scan_code =8;
 if (scan_code ==119)scan_code =9;
 if (scan_code ==78 )scan_code =0;
 if (scan_code ==110)rez=0;sr[1]=0;sr[2]=0;sr[3]=0;sr[4]=0;           // обнулить
 if (scan_code ==94 ){rez=rez/10; goto wuw;}// коррекция
 if (scan_code <12 ){ rez=rez*10; rez= rez+scan_code; }


 
  wuw:
  //Serial.println(rez);

//Выделяем разряды и записываем их в массив разрядов индикатора
sr[0]=(rez%10);
sr[1]=(rez%100/10);
sr[2]=(rez%1000/100);
sr[3]=(rez%10000/1000);
sr[4]=(rez%100000/10000);
sr[5]=(rez%1000000/100000);
sr[6]=(rez%10000000/1000000);
sr[7]=(rez%100000000/10000000);
 
// адреса разрядов индикатора
// 1-0х34
// 2-0х35
// 3-0х36
// 4-0х37 
 
Wire.beginTransmission(0x37);//Пишем в 4 разряд
  Wire.write(simv[sr[0]]);
Wire.endTransmission();             // закрываем сессию

Wire.beginTransmission(0x36);//Пишем в 3 разряд
  Wire.write(simv[sr[1]]);
Wire.endTransmission();             // закрываем сессию

Wire.beginTransmission(0x35);//Пишем вo 2 разряд
  Wire.write (simv[sr[2]]);
Wire.endTransmission();             // закрываем сессию

Wire.beginTransmission(0x34);//Пишем в 1 разряд
  Wire.write(simv[sr[3]]);//
Wire.endTransmission();             // закрываем сессию
 
 delay(200);
//_________________ * ГЕНЕРАТОР * _________________
//http://arduino.ru/forum/proekty/generator-s-reguliruemoei-chastotoi-na-arduino?page=3

static uint32_t enc=1; //
uint32_t ocr; uint32_t divider; float freq;

 enc = rez; //передаем значение частоты в герцах в ГЕНЕРАТОР
            //расчёт прескалера и OCR по нужной частоте
   divider=1; ocr = (F_CPU / enc /2 /divider);
   if (ocr >65536) { divider=8; ocr = F_CPU / enc /2 /divider;
       if (ocr >65536) { divider=64; ocr = F_CPU / enc /2 /divider;
           if (ocr >65536)  {divider=256; ocr = F_CPU / enc /2 /divider;
               if (ocr >65536) { divider=1024; ocr = F_CPU / enc /2 /divider;
                   if (ocr >65536){ocr=65536; }}}}} OCR1A=ocr-1; 
              //запись в регистр прескалера            
   switch (divider) {
     case 1: TCCR1B=1|(1<<WGM12); break;
      case 8: TCCR1B=2|(1<<WGM12); break;
       case 64: TCCR1B=3|(1<<WGM12); break;
        case 256: TCCR1B=4|(1<<WGM12); break;
         case 1024: TCCR1B=5|(1<<WGM12); break;  }


}

 

dhog1
Offline
Зарегистрирован: 01.03.2016

Это я заминусовал ваш пост.

За _больше_года_пребывания_на_форуме многое повидал, но всегда (ну почти) воздерживался от неодобрительных комментариев. Тут ведь дело в чём - вы и в самом деле считаете, что по "Корявый перевод даташита" в чём-то разобрались, а "найденые в сети библиотеки, вдохновили не очень" (с чем соглашусь). Но хотя бы посмотрели и их в попытках разобраться.

Белая полярная лисичка.

Дай Б-г вам еще не менее 50 лет дружбы с паяльником (о чём вы трогательно так сообщаете, считая это чем-то значимым, а не фактом вашей биографии), всего лучшего и творческих успехов.

"Раэобраться с работой микросхемы по тексту скетча, я думаю не очень сложно". Очень сложно с т.з. здравомыслия но, впрочем, не надо.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

А я поставил плюс.   Разобраться с чипом по его скетчу -не просто , а очень просто. Всё откомментировано и понятно.

dhog1
Offline
Зарегистрирован: 01.03.2016

Я поначалу не разобрался в _назначении_ приведенного кода. Перепутал цель - управление генератором, со способом управления микросхемой. Лажанулся.

Приношу автору поста свои сожаления за некорректные формулировки и свои торопливые ошибочные предположения.

direxru
Offline
Зарегистрирован: 01.02.2019

Благодарю, использовал Ваш код как основу. Завести FD650B (аналог TM1650) в плане получения информации с клавиатуры удалось, закомментив Wire.BeginTransmission(0x25); и оставив только Wire.requestFrom(0x27, 1); [Адрес заработал только 0x27]. Единственный момент - при опросе клавиатуры выдаёт последнюю нажатую клавишу, даже если я её уже считал. Обнуляется только отключением от питания ардуины, повторение инициализационной процедуры не помогают. Код такой:

Wire.requestFrom(0x27, 1);
if (Wire.available())scan_code = Wire.read();
Serial.println(scan_code);
delay(500);
Wire.endTransmission();

При этом выводится постоянно скан-код последней нажатой клавиши, то есть если мы нажмаем одну - идёт бесконечно её скан-код, нажимвем за ней другую, будет бесконечно идти скан-код другой клавиши. Задача - чтобы как только получен скан-код, буфер очищался до следующей нажатой клавиши. Иначе невозможно определить, нажата клавишат раз или нажимается раз за разом или постоянно зажата.

direxru
Offline
Зарегистрирован: 01.02.2019

Удалось накопать немного: 

https://github.com/jinzhifeng/SourceCode_old/blob/master/fd650.c

https://github.com/jinzhifeng/SourceCode_old/blob/master/fd650.h

в т.ч. функцию FD650_Write, но нет заголовочных файлов:

https://www.wendangwang.com/doc/94470484f96814787f300e07

svm
Онлайн
Зарегистрирован: 06.11.2016

direxru пишет:

При этом выводится постоянно скан-код последней нажатой клавиши, то есть если мы нажмаем одну - идёт бесконечно её скан-код, нажимвем за ней другую, будет бесконечно идти скан-код другой клавиши. Задача - чтобы как только получен скан-код, буфер очищался до следующей нажатой клавиши. Иначе невозможно определить, нажата клавишат раз или нажимается раз за разом или постоянно зажата.

Если клавиша нажата, выдается ее скан код, если отпустили, то ее скан код отпускания. Он изменится только при следующем  нажатии на клавиши. Скан коды нажатия и отпускания различны, поэтому можно отслеживать нажата-ли клавиша, или нажималась между опросами. Обратите внимание на строку 69. Там проверяется, что пришло - код нажатия или отпускания. Код минималистичен и не использует никаких библиотек для микросхемы. Теоретически должны работать все адреса, эти микросхемы идентичны. А вывод на дисплей тоже не совпадает?

И еще непонятно как Вы обращаетесь к микросхеме, закомментировав начало сессии обмена? Выложите полный код. И еще, в приведенном вами кусочке кода, нет смысла проверять наличие данных, оно всегда у этой микросхемы есть. Или код нажатой в данный момент клавиши, или код отпускания последней нажатой клавиши.

Remaster
Offline
Зарегистрирован: 09.03.2020

Помогите куда подключать эту лабуду?

На примере ардуино уно

svm
Онлайн
Зарегистрирован: 06.11.2016

Remaster пишет:

Помогите куда подключать эту лабуду?

На примере ардуино уно

Это Вы о чем?

abomin
Offline
Зарегистрирован: 09.04.2018

ПодскажИте, плиз: в даташите одни адреса прописаны, а в этом скетче - другие?

Здесь:       0x24  0x25  0x34  0x35  0x36  0x37

Datasheet:   0x48  0x49  0x68  0x6A  0x6C  0x6E

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

abomin пишет:

ПодскажИте, плиз: в даташите одни адреса прописаны, а в этом скетче - другие?

Здесь:       0x24  0x25  0x34  0x35  0x36  0x37

Datasheet:   0x48  0x49  0x68  0x6A  0x6C  0x6E

 

Так эти два адреса отличаются на 1 во втором байте. Только форма записи разная. Почитайте что-нибудь об i2c.

abomin
Offline
Зарегистрирован: 09.04.2018

andriano пишет:
Так эти два адреса отличаются на 1 во втором байте.
Какие два? Я привёл в пример шесть пар адресов.
Цитата:
Только форма записи разная.
В смысле? MSB-LSB? Нет, здесь больше похоже на сдвиг на один бит...
Цитата:
Почитайте что-нибудь об i2c.
В даташите же указаны адреса, разве не такие и нужно слать? Непонятно...

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

abomin пишет:

Нет, здесь больше похоже на сдвиг на один бит...

Цитата:
Почитайте что-нибудь об i2c.
В даташите же указаны адреса, разве не такие и нужно слать? Непонятно...

Поэтому я Вам и посоветовал почитать об i2c, чтобы Вы поняли, откуда этот сдвиг берется, и что именно нужно слать.

svm
Онлайн
Зарегистрирован: 06.11.2016

abomin пишет:

ПодскажИте, плиз: в даташите одни адреса прописаны, а в этом скетче - другие?

Здесь:       0x24  0x25  0x34  0x35  0x36  0x37

Datasheet:   0x48  0x49  0x68  0x6A  0x6C  0x6E

 

В ТМ1650 второй байт не используется, поэтому ей безразлично что Вы пошлете. Во всяком случае в моем даташите  https://yadi.sk/i/h-GKf9hMyABLL, там стояло Х т.е. безразлично. Возможно я не совсем разобрался и для чего то этот байт нужен.

abomin
Offline
Зарегистрирован: 09.04.2018

Про какой ВТОРОЙ байт Вы говорите? В даташите про него не нашёл. Про адреса - вот: 

Но они здесь однобайтные.

svm
Онлайн
Зарегистрирован: 06.11.2016

abomin пишет:

Про какой ВТОРОЙ байт Вы говорите? В даташите про него не нашёл. Про адреса - вот: 

Но они здесь однобайтные.

Извиняюсь, это я с другой МС перепутал. Там засылаются два байта. Один безразлично какой. Код из #5, полностью рабочий. Хотя я его писал сам, как и перевод даташита, но уже не помню откуда брал эти адреса. Давно было, возможно где-то еще информацию находил. Или сканер выдал эти адреса. 

abomin
Offline
Зарегистрирован: 09.04.2018

andriano пишет:
abomin пишет:
ПодскажИте, плиз: в даташите одни адреса прописаны, а в этом скетче - другие?

Здесь:       0x24  0x25  0x34  0x35  0x36  0x37

Datasheet:   0x48  0x49  0x68  0x6A  0x6C  0x6E

 

Так эти два адреса отличаются на 1 во втором байте. Только форма записи разная. Почитайте что-нибудь об i2c.
Кажется, я понял... Китайцы в своём даташите слепляют семибитный i2c адрес с битом R/W. Так?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

При чем здесь китайцы, если это предусмотрено стандартом i2c?