сложно что-то понять в вашем коде, слишком уж он путаный и нелогичный.
посоветую видоизменить его так, чтобы однотипные операции делались однотипно. я вижу у вас многочисленные повторы очень-очень похожих кусков кода - я уверен, что вместо повторов следует использовать циклы. кроме того, надо подумать над алгоритмом вывода вообще.
1. дисплей отображает 5 цифр. для хранения этих цифр надо использовать массив, а не 5 отдельных переменных.
2. значение каждой цифры на дисплее определяется по одному и тому же алгоритму, следовательно, для заполнения значений этого массива надо использовать цикл.
3. т.к. каждая цифра соответствует десятичному разряду числа, можно воспользоваться функцией itoa или алгоритмом, описанным в моей статье.
4. я не понял, как вы там выводите свои числа, но уверен, что это так же делается алгоритмически одинаково, т.е. не куча switch-ей, а цикл.
постарайтесь выполнить мои рекомендации и вы увидите, как существенно упростится ваша программа, заодно вы поймете, что теоретически в вашем модуле не должно быть ни одной глобальной переменной! даже массив цифр по большому счету окажется лишним.
Проблемма при отладке
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18588
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Проблемма при отладке
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Реклама
- Liv
- Вымогатель припоя
- Сообщения: 525
- Зарегистрирован: Сб сен 20, 2008 12:12:30
- Откуда: Minsk
- Контактная информация:
Re: Проблемма при отладке
Переменную ToDisplay объявлять как локальную в файле tic5234.c не надо. Это просто должен быть параметр функции.
Для примера прикрепляю файл работы с 7-сегментным индикатором:
Код: Выделить всё
void arrey(unsigned long int ToDisplay)
{
...
}
void display(unsigned long int ToDisplay)
{
arrey(ToDisplay);
load();
}
- Вложения
-
- Display.zip
- (1.71 КБ) 168 скачиваний
Re: Проблемма при отладке
У дисплея TIC5234 контроллер является обычным сдвиговым регистром на 49 бит. Загружаются биты последовательно начиная с 49-го. Дело в том что у него есть куча дополнительных сегментов которые мне использовать не нужно. А сегменты знакомест разбросаны как попало. Немогли бы Вы мне подсказать как тогда формировать пакет 49 бит для загрузки в дисплей в таком случае?
Вот тут его мучают http://www.xdevs.com/e107_*самореклама*/conte ... content.21
Вот его pdf http://www.trt.ru/products/tic/pdf/segment/TIC5234.PDF
Прошу прощения если "вылажу на голову", но обратится за помощью просто больше некуда.
Вот тут его мучают 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: Проблемма при отладке
Как вариант, дополнить вот этим:
Наверняка я что-то написал неправльно при вычислении маски, делал на ходу. Но принцип должен быть понятен. остается добавить управление всякими левыми сегментами и точками.
Upd: подправил немного...
Код: Выделить всё
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 раза.
Re: Проблемма при отладке
Liv, благодарю за пример. Простите за безграмотность, но расскажите что будет выполнять программа если, например char Dig=1, char Code=1
?
?
- Реклама
- Liv
- Вымогатель припоя
- Сообщения: 525
- Зарегистрирован: Сб сен 20, 2008 12:12:30
- Откуда: Minsk
- Контактная информация:
Re: Проблемма при отладке
Задумано было так:
Приходит на вход 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, сдвигаем единицу число раз, равное номеру бита.
И так делаем для каждого из семи сегментов.
Приходит на вход 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, сдвигаем единицу число раз, равное номеру бита.
И так делаем для каждого из семи сегментов.


