Контроллер 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
Offline
Зарегистрирован: 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

001#include <Wire.h>
002 long rez;
003 byte scan_code,dl;
004 byte sr[8];// массив разрядов индикатора
005 
006//массив изображений 7 сегментных символов от 0 до 9 и пустота
007byte simv[11]={
008B00111111, //0
009B00000110, //1
010B01011011, //2
011B01001111, //3
012B01100110, //4
013B01101101, //5
014B01111101, //6
015B00000111, //7
016B01111111, //8
017B01101111, //9
018B00000000, //пустота
019};
020 
021void setup() {
022//Serial.begin(9600); 
023  Wire.begin();
024// *********инициализация таймеров генератора************
025pinMode (9,OUTPUT);      // выход генератора
026TCCR1A=1<<COM1A0;        //подключить выход OC1A первого таймера
027TCCR1B=0;                //
028 
029// адреса регистров управления и данных ТМ1650
030// 1-0х24
031// 2-0х25
032// 3-0х26
033// 4-0х27
034// *********инициализация дисплея************
035//___________________________________________
036//b7 b6 b5 b4 b3 b2 b1 b0 IФункция   I опис. I
037//___________________________________________
038//x  0  0  0      x  x    I          I   8   I
039//x  0  0  1      x  x    I          I   1   I
040//x  0  1  0      x  x    I          I   2   I
041//x  0  1  1      x  x    I яркость  I   3   I
042//x  1  0  0      x  x    I          I   4   I
043//x  1  0  1      x  x    I          I   5   I
044//x  1  1  0      x  x    I          I   6   I
045//x  1  1  1      x  x    I          I   7   I
046//____________________________________________
047//x           0   x  x    I  режим   I 8ceгм I
048//x           1   x  x    I 7/8 bit  I 7ceгм I
049//____________________________________________
050//x               x  x  0 Ibit ON/OFFI  OFF  I
051//x               x  x  1 I  дисплея I   ON  I
052//____________________________________________
053 
054 
055Wire.beginTransmission(0x24);   //обращаемся к любому порту 0х24-0х27
056   Wire.write(0b01000001);      //включаем:яркость 4,8 битный режим, отображение ON
057Wire.endTransmission();         // закрываем сессию
058 
059}
060 
061void loop() {
062  
063  //********************* чтение клавиатуры *************************
064 readkl:
065 Wire.beginTransmission(0x25);        // обращаемся к клавиатуре(к любому порту 0х24-0х27)
066 Wire.requestFrom((0x25), 1);         //запрашиваем один байт
067  scan_code = Wire.read();            // читаем скан код
068 Wire.endTransmission();              // закрываем сессию
069 if (scan_code <69) goto readkl;
070 if (scan_code ==70 )scan_code =1;
071 if (scan_code ==69 )scan_code =2;
072 if (scan_code ==79 )scan_code =3;
073 if (scan_code ==101)scan_code =4;
074 if (scan_code ==87 )scan_code =5;
075 if (scan_code ==117)scan_code =6;
076 if (scan_code ==103)scan_code =7;
077 if (scan_code ==102)scan_code =8;
078 if (scan_code ==119)scan_code =9;
079 if (scan_code ==78 )scan_code =0;
080 if (scan_code ==110)rez=0;sr[1]=0;sr[2]=0;sr[3]=0;sr[4]=0;           // обнулить
081 if (scan_code ==94 ){rez=rez/10; goto wuw;}// коррекция
082 if (scan_code <12 ){ rez=rez*10; rez= rez+scan_code; }
083 
084 
085  
086  wuw:
087  //Serial.println(rez);
088 
089//Выделяем разряды и записываем их в массив разрядов индикатора
090sr[0]=(rez%10);
091sr[1]=(rez%100/10);
092sr[2]=(rez%1000/100);
093sr[3]=(rez%10000/1000);
094sr[4]=(rez%100000/10000);
095sr[5]=(rez%1000000/100000);
096sr[6]=(rez%10000000/1000000);
097sr[7]=(rez%100000000/10000000);
098  
099// адреса разрядов индикатора
100// 1-0х34
101// 2-0х35
102// 3-0х36
103// 4-0х37
104  
105Wire.beginTransmission(0x37);//Пишем в 4 разряд
106  Wire.write(simv[sr[0]]);
107Wire.endTransmission();             // закрываем сессию
108 
109Wire.beginTransmission(0x36);//Пишем в 3 разряд
110  Wire.write(simv[sr[1]]);
111Wire.endTransmission();             // закрываем сессию
112 
113Wire.beginTransmission(0x35);//Пишем вo 2 разряд
114  Wire.write (simv[sr[2]]);
115Wire.endTransmission();             // закрываем сессию
116 
117Wire.beginTransmission(0x34);//Пишем в 1 разряд
118  Wire.write(simv[sr[3]]);//
119Wire.endTransmission();             // закрываем сессию
120  
121 delay(200);
122//_________________ * ГЕНЕРАТОР * _________________
124 
125static uint32_t enc=1; //
126uint32_t ocr; uint32_t divider; float freq;
127 
128 enc = rez; //передаем значение частоты в герцах в ГЕНЕРАТОР
129            //расчёт прескалера и OCR по нужной частоте
130   divider=1; ocr = (F_CPU / enc /2 /divider);
131   if (ocr >65536) { divider=8; ocr = F_CPU / enc /2 /divider;
132       if (ocr >65536) { divider=64; ocr = F_CPU / enc /2 /divider;
133           if (ocr >65536)  {divider=256; ocr = F_CPU / enc /2 /divider;
134               if (ocr >65536) { divider=1024; ocr = F_CPU / enc /2 /divider;
135                   if (ocr >65536){ocr=65536; }}}}} OCR1A=ocr-1;
136              //запись в регистр прескалера           
137   switch (divider) {
138     case 1: TCCR1B=1|(1<<WGM12); break;
139      case 8: TCCR1B=2|(1<<WGM12); break;
140       case 64: TCCR1B=3|(1<<WGM12); break;
141        case 256: TCCR1B=4|(1<<WGM12); break;
142         case 1024: TCCR1B=5|(1<<WGM12); break;  }
143 
144 
145}

 

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
Offline
Зарегистрирован: 06.11.2016

direxru пишет:

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

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

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

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

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

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

svm
Offline
Зарегистрирован: 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
Offline
Зарегистрирован: 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
Offline
Зарегистрирован: 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?