Организация индикации на TIC5234

  • Печать

TIC5234Одна из проблем, в общем-то, неплохого индикатора TIC5234, связана с внутренней схемой подключения ЖК-сегментов к контроллеру. Не понятно чем руководствовались разработчики, подключая отдельные элементы для разных цифр в разном порядке, но каким-то образом работать с индикатором надо. Простые алгоритмы здесь уже не подойдут и соответственно необходимо создавать что-то более громоздкое. Один из вариантов, прошедший обкатку в железе описан далее.

Сразу хочется сказать, что не следует считать приведенную программу оптимальной. Тем не менее, она относительно проста и работает. Функции написаны для компилятора mikroC под STM32, поэтому имеют некоторые нестандартные решения. В частности используются встроенные процедуры настройки портов и работы с отдельными битами.

Основу программы составляет набор функций, главная из которых showdisplay(). В этой функции организован цикл, в котором производится последовательный перебор номеров сегментов от 1 до 49. В зависимости от типа сегмента вызывается либо его обработка (для цифры), либо сразу же определяется необходимость включения (для спецсимволов). В этом же цикле организовано включение линий порта ввода/вывода для загрузки сдвигового регистра индикатора.

Функции обработки отдельных цифровых сегментов идентичны по своей структуре. Входной информацией является целое число, представляющее собой цифру от 0 до 9, либо какие-то дополнительные символы. В частности в приведенном ниже примере реализованы шестнадцатеричная система счисления с цифрами в виде A,b,C,d,E,F, а также дополнительные символы P,H и знак градуса. Соответственно значение входной переменной может лежать в диапазоне от 0 до 18. Если это значение выходит из указанного диапазона, сегмент не отображается. Это можно использовать для организации пустого знакоместа на индикаторе. Работа функций включения сегментов сводится к возврату 1, если данный сегмент не принадлежит какому-либо символу, в котором он не горит. Несколько сложно, но проще объяснить не получается, хотя можно сделать и наоборот: сегмент будет зажигаться, если он присутствует в полученной цифре. Выбор в пользу обратной логики был сделан по причине большей компактности функций.

Перед вызовом функции showdisplay() следует установить все значения отображаемых цифр в переменных dig1-dig5, а также наличие или отсутствие спецсимволов, путем записи 1 или 0 в соответствующие переменные. 

Пример программы загрузки индикатора TIC5234
#define Load GPIOB_ODR.B14      //Сигнал загрузки индикатора
#define Din GPIOB_ODR.B12       //Линия данных индикатора
#define Dclc GPIOB_ODR.B13      //Тактовая линия индикатора
 
char dot1,dot2,dot3,dot4,dot5;   //Точки
char dig1,dig2,dig3,dig4,dig5;   //Цифры
char Battery,Battery1,Battery2,Battery3,RH,kPa,MPa,kGs,Temperatur; //Спецсимволы
 
//Преобразование сегментов
char SegC(char dig){if (dig!=2&&dig!=12&&dig!=14&&dig!=15&&dig!=16&&dig<18) 
                       return 1; else return 0;}
char SegB(char dig){if (dig!=5&&dig!=6&&dig!=11&&dig!=12&&dig!=14&&dig!=15&&dig<19) 
                       return 1; else return 0;}
char SegA(char dig){if (dig!=1&&dig!=4&&dig!=11&&dig!=13&&dig!=17&&dig<19) 
                       return 1; else return 0;}
char SegF(char dig){if (dig!=1&&dig!=2&&dig!=3&&dig!=7&&dig!=13&&dig<19) 
                       return 1; else  return 0;}
char SegG(char dig){if (dig!=0&&dig!=1&&dig!=7&&dig!=12&&dig<20) 
                       return 1; else return 0;}
char SegE(char dig){if (dig!=1&&dig!=3&&dig!=4&&dig!=5&&dig!=7&&dig!=9&&dig<18) 
                       return 1; else return 0;}
char SegD(char dig){if (dig!=1&&dig!=7&&dig!=4&&dig!=10&&dig!=15&&dig<16) 
                       return 1; else return 0;}
 
 
void ShowDisplay(){
char i;
  for (i=1;i<50;i++){
    Din=0;
    switch(i){
      case 1: if (dot3) Din=1; break;         //49 Точка цифры 3
      case 2: if (dot4) Din=1; break;         //48 Точка цифры 4
      case 3: if (dot5) Din=1; break;         //47 Точка цифры 5
      case 4: Din=SegC(dig5);  break;         //46 Сегмент C цифры 5
      case 5: Din=SegB(dig5);  break;         //45 Сегмент B цифры 5
      case 6: Din=SegA(dig5);  break;         //44 Сегмент A цифры 5
      case 7: if (Temperatur) Din=1;break;    //43 Знак температуры
      case 8: Din=SegF(dig5);  break;         //42 Сегмент F цифры 5
      case 9: Din=SegG(dig5);  break;         //41 Сегмент G цифры 5
      case 10: Din=SegE(dig5); break;         //40 Сегмент E цифры 5
      case 11: Din=SegD(dig5); break;         //39 Сегмент D цифры 5
      case 12: Din=SegC(dig4); break;         //38 Сегмент C цифры 4
      case 13: if (kGs) Din=1; break;         //37 Знак  кГc
      case 14: Din=SegB(dig4); break;         //36 Сегмент B цифры 4
      case 15: Din=SegA(dig4); break;         //35 Сегмент A цифры 4
      case 16: Din=SegF(dig4); break;         //34 Сегмент F цифры 4
      case 17: Din=SegG(dig4); break;         //33 Сегмент G цифры 4
      case 18: Din=SegE(dig4); break;         //32 Сегмент E цифры 4
      case 19: if (MPa) Din=1; break;         //31 Знак МПа
      case 20: Din=SegD(dig4); break;         //30 Сегмент D цифры 4
      case 21: Din=SegC(dig3); break;         //29 Сегмент C цифры 3
      case 22: Din=SegB(dig3); break;         //28 Сегмент B цифры 3
      case 23: Din=SegA(dig3); break;         //27 Сегмент A цифры 3
      case 24: if (kPa) Din=1; break;         //26 Знак  кПа
      case 25: Din=SegF(dig3); break;         //25 Сегмент F цифры 3
      case 26: Din=SegG(dig3); break;         //24 Сегмент G цифры 3
      case 27: Din=SegE(dig3); break;         //23 Сегмент E цифры 3
      case 28: Din=SegD(dig3); break;         //22 Сегмент D цифры 3
      case 29: if (RH) Din=1;  break;         //21 Знак  RH
      case 30: Din=SegC(dig2); break;         //20 Сегмент C цифры 2
      case 31: Din=SegB(dig2); break;         //19 Сегмент B цифры 2
      case 32: Din=SegA(dig2); break;         //18 Сегмент A цифры 2
      case 33: Din=SegF(dig2); break;         //17 Сегмент F цифры 2
      case 34: Din=SegG(dig2); break;         //16 Сегмент G цифры 2
      case 35: Din=SegE(dig2); break;         //15 Сегмент E цифры 2
      case 36: Din=SegD(dig2); break;         //14 Сегмент D цифры 2
      case 37: Din=SegC(dig1); break;         //13 Сегмент C цифры 1
      case 38: if (Battery3) Din=1; break;    //12 Знак  Battery3
      case 39: if (Battery1) Din=1; break;    //11 Знак  Battery1
      case 40: if (Battery2) Din=1; break;    //10 Знак  Battery2
      case 41: if (Battery) Din=1;  break;    //9 Знак  Battery
      case 42: Din=SegB(dig1); break;         //8 Сегмент B цифры 1
      case 43: Din=SegA(dig1); break;         //7 Сегмент A цифры 1
      case 44: Din=SegF(dig1); break;         //6 Сегмент F цифры 1
      case 45: Din=SegG(dig1); break;         //5 Сегмент G цифры 1
      case 46: Din=SegE(dig1); break;         //4 Сегмент E цифры 1
      case 47: Din=SegD(dig1); break;         //3 Сегмент D цифры 1
      case 48: if (dot1) Din=1;  break;       //2 Точка цифры 2
      case 49: if (dot2) Din=1;  break;       //1 Точка цифры 1
    }
    Dclc = 1;  //Тактовый импульс
    Dclc = 0;
  }
  Load=1;      //Импульс загрузки регистра на индикацию
  Load=0;
}
void main() {
  GPIO_Digital_Output(&GPIOB_BASE, _GPIO_PINMASK_12|_GPIO_PINMASK_13|_GPIO_PINMASK_14);  //GPIO
  dot5=0;dot4=0;dot3=0;dot2=0;dot1=0;
  Battery=1;Temperatur=1;
  dig1=1;dig2=2;dig3=3;dig4=4;dig5=5;
  ShowDisplay();
  while(1){}
}