Kaptain.
Telegram /
LinkedIn /
Email /
GIT /
RSS /
GPG /
Заказ печатных плат

№ 2824 В разделах:
Electronics
Programming
от May 9th, 2011,
В подшивках: Arduino, Displays
Сидите вы наверно сейчас и думаете о том, как же вывести цифры.
Вы слышали когда-нибудь про динамическую развертку? Сейчас услышите 🙂 У нас 4 индикатора и все их подключить на наш МК не получится, т.к. просто не хватит ножек. Конечно, вы можете использовать сдвиговые регистры и прочее, но это немного усложнит устройство и сделает его минимум на 40 рублей дороже 🙂 Для начала подключите ваши индикаторы по следующей схеме (не забудьте подключить дополнительные резисторы на все 8 ног данных! транзисторы тоже желательно применять, чтобы не нагружать МК):
Мы видим, что все линии данных индикаторов подключены параллельно к порту D, а ноги питания на 4 пина порта C. При таком подключении работать “правильно” может только 1 из 4. Конечно же, это вас не удовлетворит и вы захотите сделать на сдвиговых регистрах (к тому же и 4 ноги порта C сэкономите), но постойте! Если переключать ноги питания индикаторов очень быстро (МК это может делать хоть 1000 раз в секунду), то вы просто не заметите того факта, что горит только 1 из 4. Вам будет казаться, что горят все 4.
Теперь поговорим о генерации символов. В зависимости от подключения вашего индикатора к МК составьте таблицу знаков. У меня получилась такая:
unsigned char digits[]=
{
0b01001000, // 0
0b11101011, // 1
0b10001100, // ..
0b10001001,
0b00101011,
0b00011001,
0b00011000,
0b11001011, // ..
0b00001000, // 8
0b00001001, // 9
0b11111111 // не горит ничего
};
Как же теперь взять любую цифру и вывести ее на экран? Вы можете извращаться сколько хотите, но лучше всего сделать так:
void indicator_natural(int cifra) {
//вывод обычного натурального числа (беззнаковое, целое)
int C0=0, C1=0, C2=0, C3=0; //индексы для массива знаков
while(cifra > 0) {
//отнимаем тысячи
if (cifra > 1000) {
cifra = cifra - 1000;
C0++;
} else {
//отнимаем сотни
if (cifra > 100) {
cifra = cifra - 100;
C1++;
} else {
//отнимаем десятки
if (cifra > 10) {
cifra = cifra - 10;
C2++;
} else {
//отнимаем единицы
if (cifra > 0) {
cifra = cifra - 1;
C3++;
}
}
}
}
}
//если первая цифра 0, то не зажигаем ничего. последний 0 будет показываться!
if (C0 == 0) { C0=11; }
if ((C0 + C1) == 0) { C0=C1=11; }
if ((C0 + C1 + C2) == 0) { C0=C1=C2=11; }
}
Для тех, кто не понял: например, у нас есть число 401 и всего 4 знака на индикаторе (тысячи, сотни, десятки и единицы). Вот мы и проверяем циклом и вычитанием сколько у нас сотен, десятков и т.д. Если число оказывается с каждым циклом больше определенного минимума, то переменные Cx инкрементируются. Cx это и есть индексы для того самого массива символов. Последние 3 условия чисто для красоты, чтобы нули не вылазили вперед числа. Если убрать эти условия, то на индикаторе получится 0401.
Теперь у нас есть все 4 индекса для вывода на индикатор. Осталось только менять данные на портах в цикле по следующему алгоритму:
Таким способом можно подключать любые семисегментные индикаторы от одного, до целых паровозов из них.

Другой пример подключения от Романа Киселева.
Fortune cookie: There once was a miner named Dave, Who kept a dead whore in his cave. She was ugly as shit, And missing one tit, But think of the money he saves.
Красивый код! А главное быстрый по сравнению с умножением и остатком от деления для выделения разрядов.
Возьму себе на заметку!