Не могу не присоединиться, точнее переборола свою лень.
Способов отрисовки разряда семисегментника множество
и это множество реализуется без особого напряжения ума.
Первая подсказка. Каждая IO линия каждого порта имеет свой "вес".
И обсчет "готовых" символов делается в момент компиляции.
Пример на ассме (не многим отличается от Си)
Код: Выделить всё
#define _. .1 ; RB0
#define _C .2 ; RB1
#define _D .4 ; RB2
#define _E .8 ; RB3
#define _B .16 ; RB4
#define _A .32 ; RB5
#define _F .64 ; RB6
#define _G .128 ; RB7
; если индикатор с общим анодом, то сумму
; нужно отнять от 255, например, для
; символа "1" написать 255-(_B+_C)
#define _0 addlw (_A+_B+_C+_D+_E+_F)
#define _1 addlw (_B+_C)
#define _2 addlw (_A+_B+_G+_E+_D)
#define _3 addlw (_A+_B+_G+_C+_D)
#define _4 addlw (_F+_G+_B+_C)
#define _5 addlw (_A+_F+_G+_C+_D)
#define _6 addlw (_A+_F+_G+_C+_D+_E)
#define _7 addlw (_A+_B+_C)
#define _8 addlw (_A+_B+_C+_D+_E+_F+_G)
#define _9 addlw (_A+_B+_C+_D+_F+_G)
#define _Н addlw (_B+_C+_E+_F+_G)
Как видим - это всё лишь арифметика. И при этом
я даже не задумываюсь, а сколько там символу "9"
соответствует число, которое будет отправлено в порт.
При всей простоте подхода это решение (как и многие другие)
накладывает ограничения на свободу разводки печатной платы.
Классическая школа программирования из "кода в код" "навяливает"
подключение разряда на линии одного порта. Это неудобно
с т.зр. рисования печатной платы. Всё прекрасно работает и на
разных портах. Правда Протеус не переваривает на частоте
более 1мгц тактовой. На Си выглядит не менее сложно.
Ниже Си пример подключения вразноброд линий двух разрядов
к разным портам (чтобы понять идею, см. печатную плату;
схему не рисовала, т.к. по железу всё и так понятно )
Код: Выделить всё
// === сопоставление сигнальных линий индикатора
// первый сегмент (десятки)
#define A1 RB5
#define B1 RB4
#define C1 RA0
#define D1 RA7
#define E1 RA6
#define F1 RB7
#define G1 RB6
#define H1 RA1
[b]#define Y1 RA2 // общ катод[/b]
// второй сегмент (единицы)
#define A2 RB5
#define B2 RB6
#define C2 RA6
#define D2 RA0
#define E2 RA1
#define F2 RB4
#define G2 RA7
#define H2 RB7
[b]#define Y2 RA3 // общ катод[/b]
Далее описываем символы (форма записи элементарна,
первое что пришло в голову)
Код: Выделить всё
// === массив констант с описанием символов
const unsigned char sim[10] = {
// 0bABCDEFGH
0b11111100, // 0
0b01100000, // 1
0b11011010, // 2
0b11110010, // 3
0b01100110, // 4
0b10110110, // 5
0b10111110, // 6
0b11100000, // 7
0b11111110, // 8
0b11110110, // 9
};
Далее собственно отрисовка
Код: Выделить всё
// === рисуем сегменты
void ris (unsigned char zn, unsigned char s)
// zn - знакоместо, s - собственно символ
{ if (zn == 1) {
tmp = sim[s];
A1 = tmp.b0;
B1 = tmp.b1;
C1 = tmp.b2;
D1 = tmp.b3;
E1 = tmp.b4;
F1 = tmp.b5;
G1 = tmp.b6;
H1 = tmp.b7;
}
if (zn == 2) {
tmp = sim[s];
A2 = tmp.b0;
B2 = tmp.b1;
C2 = tmp.b2;
D2 = tmp.b3;
E2 = tmp.b4;
F2 = tmp.b5;
G2 = tmp.b6;
H2 = tmp.b7;
}
}
Ну и третье. Кому ну очень много индикаторов надо - сделайте
так как во втором приложенном файле - мне потребовалось три
сигнальных линии для управления 64-ю светодиодными сегментами.
ARV - и я того же мнения.