Проблемма при отладке

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18588
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Проблемма при отладке

Сообщение ARV »

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

1. дисплей отображает 5 цифр. для хранения этих цифр надо использовать массив, а не 5 отдельных переменных.
2. значение каждой цифры на дисплее определяется по одному и тому же алгоритму, следовательно, для заполнения значений этого массива надо использовать цикл.
3. т.к. каждая цифра соответствует десятичному разряду числа, можно воспользоваться функцией itoa или алгоритмом, описанным в моей статье.
4. я не понял, как вы там выводите свои числа, но уверен, что это так же делается алгоритмически одинаково, т.е. не куча switch-ей, а цикл.

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

Мой уютный бложик... заходите!
Реклама
Аватара пользователя
Liv
Вымогатель припоя
Сообщения: 525
Зарегистрирован: Сб сен 20, 2008 12:12:30
Откуда: Minsk
Контактная информация:

Re: Проблемма при отладке

Сообщение Liv »

Переменную ToDisplay объявлять как локальную в файле tic5234.c не надо. Это просто должен быть параметр функции.

Код: Выделить всё

void arrey(unsigned long int ToDisplay)
{
   ...
}

void display(unsigned long int ToDisplay)
{
  arrey(ToDisplay);
  load();
}
Для примера прикрепляю файл работы с 7-сегментным индикатором:
Вложения
Display.zip
(1.71 КБ) 168 скачиваний
Реклама
SABRAT
Первый раз сказал Мяу!
Сообщения: 28
Зарегистрирован: Вт июн 24, 2008 17:17:08
Откуда: Киев

Re: Проблемма при отладке

Сообщение SABRAT »

У дисплея TIC5234 контроллер является обычным сдвиговым регистром на 49 бит. Загружаются биты последовательно начиная с 49-го. Дело в том что у него есть куча дополнительных сегментов которые мне использовать не нужно. А сегменты знакомест разбросаны как попало. Немогли бы Вы мне подсказать как тогда формировать пакет 49 бит для загрузки в дисплей в таком случае?

Вот тут его мучают http://www.xdevs.com/e107_*самореклама*/conte ... content.21

Вот его pdf http://www.trt.ru/products/tic/pdf/segment/TIC5234.PDF

Прошу прощения если "вылажу на голову", но обратится за помощью просто больше некуда.
Аватара пользователя
Liv
Вымогатель припоя
Сообщения: 525
Зарегистрирован: Сб сен 20, 2008 12:12:30
Откуда: Minsk
Контактная информация:

Re: Проблемма при отладке

Сообщение Liv »

Как вариант, дополнить вот этим:

Код: Выделить всё

char SegCopy[7]; //массив копий сегментов

__flash char SEG_POS[7, 5] =
{
  {  7, 18, 27, 35, 44 }, //позиции сегментов A из datasheet
  {  8, 19, 28, 36, 45 }, //позиции сегментов B из datasheet
  { 13, 20, 29, 38, 46 }, //позиции сегментов C из datasheet
  {  3, 14, 22, 30, 39 }, //позиции сегментов D из datasheet
  {  4, 15, 23, 32, 40 }, //позиции сегментов E из datasheet
  {  6, 17, 25, 34, 42 }, //позиции сегментов F из datasheet
  {  5, 16, 24, 33, 41 }  //позиции сегментов G из datasheet
}

Conv(char Dig, char Code) //номер разряда, выводимая цифра
{
  char s = Font[Code]; //в таблице знакогенератора D0 - "A", D1 - "B" и т.д.
  for(char i = 0; i < 7; i++)
  {
    char n = (SEG_POS[i, Dig] - 1) / 8; //номер байта в сдвиговом регистре
    char m = 1 << (SEG_POS[i, Dig] - 1) % 8 //маска сегмента в этом байте
    if(s & (1 << i)) SegCopy[n] |= m;
      else SegCopy[n] &= ~m;
  }
}

//сначала нужно заполнить буфер для всех разрядов,
//вызвав функцию Conv() для каждого из них.
//Затем нужно передать буфер SegCopy[] в сдвиговый
//регистр индикатора.
Наверняка я что-то написал неправльно при вычислении маски, делал на ходу. Но принцип должен быть понятен. остается добавить управление всякими левыми сегментами и точками.

Upd: подправил немного...
Последний раз редактировалось Liv Вт дек 07, 2010 03:11:34, всего редактировалось 2 раза.
Реклама
Эиком - электронные компоненты и радиодетали
SABRAT
Первый раз сказал Мяу!
Сообщения: 28
Зарегистрирован: Вт июн 24, 2008 17:17:08
Откуда: Киев

Re: Проблемма при отладке

Сообщение SABRAT »

Liv, благодарю за пример. Простите за безграмотность, но расскажите что будет выполнять программа если, например char Dig=1, char Code=1
?
Реклама
Аватара пользователя
Liv
Вымогатель припоя
Сообщения: 525
Зарегистрирован: Сб сен 20, 2008 12:12:30
Откуда: Minsk
Контактная информация:

Re: Проблемма при отладке

Сообщение Liv »

Задумано было так:
Приходит на вход Code = 1. Первым делом этот код символа преобразуется в 7-сегментный код. Делается это с помощью таблицы Font (можно взять из примера, который я постил раньше, только сегменты переставить подряд: D0 - A, D1 - B, D2 - C и т.д.). Фактически из таблицы выбирается байт под номером 1. А он содержит единицы в тех разрядах, которые соответствуют горящим сегментам. Для единицы это сегменты "B" и "C", поэтому в переменную s попадет число 00000110.
Далее в цикле мы пробегаемся по разрядам числа s, и если обнаруживаем единичку, то устанавливаем один из битов в массиве SegCopy, который соответствует горящему сегменту. Если же обнаруживаем нолик, то, наоборот, сбрасываем бит.
Первым в цикле проверяется бит D0. При первом проходе цикла (s & (1 << i)) равно (s & 1), т.е. условие выполнится, если разряд D0 числа s равен единице. Но у нас он равен нулю, значит будет выполняться else. А там в элементе массива SegCopy с номером n будет сброшен бит, который соответствует ненулевому биту в маске m. Для вычисления n и m используется специальный массив SEG_POS, котрый заполнен глядя на datasheet индикатора. Первый индекс массива - это сегмент (0..6 соответствует A..G). Второй индекс - это знакоместо (тут нам понадобится парамтр функции Dig). А внутри массива находятся номера битов сдвигового регистра индикатора, которые к этим сегментам подключены. Например, сегмент "B" пятого знакоместа подключен к выходу сдвигового регистра под номером 45. Номера выходов в datasheet начинаются с единицы, я не стал это изменять. В результате в программе мне приходится вычетать единицу. Но это мелочь. Массив SegCopy фактически представляет собой копию сдвигового регистра индикатора, так как из него тот и будет загружен. Но сдвиговый регистр непрерывный, а массив поделен на байты. Поэтому первым делом находим, в каком байте находится интересующий нас сегмент. Для этого делим номер сегмента на 8. Получаем n. Теперь нужно узнать, какой бит в байте соответствует нашему сегменту. Номер бита будет равен остатку от деления номера сегмента на 8. Чтобы получить маску m, сдвигаем единицу число раз, равное номеру бита.
И так делаем для каждого из семи сегментов.
Реклама
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»