В данной статье мы рассмотрим проектирование текстового дисплея на основе светодиодной матрицы 8х8 под управлением микроконтроллера ATmega32 (семейство AVR), на котором будут прокручиваться буквы алфавита.
Светодиодная матрица 8х8 содержит 64 светодиода, упорядоченных в форму матрицы. Мы сделаем эту матрицу путем впаивания 64 светодиодов на макетную плату (также можно использовать и печатную плату). Светодиоды могут быть любого цвета – можете выбрать цвет какой вам больше всего нравится. Далее мы напишем программу на языке С (Си) для микроконтроллера AVR ATmega32, который будет управлять этой светодиодной матрицей. В соответствии с программой микроконтроллер ATmega32 будет подавать питание на соответствующие светодиоды чтобы показывать на ней символы (с прокруткой).
Необходимые компоненты
- Микроконтроллер ATmega32 (купить на AliExpress);
- Источник питания с напряжением 5 Вольт;
- Программатор AVR-ISP (купить на AliExpress), USBASP (купить на AliExpress) или другой подобный;
- 64 светодиода (купить на AliExpress);
- Резистор 1 кОм (8 шт.) (купить на AliExpress);
- Макетная плата с инструментами для пайки;
- Atmel Studio версии 6.1 (или выше).
Реклама: ООО "АЛИБАБА.КОМ (РУ)" ИНН: 7703380158
Работа схемы
Итак, у нас есть 64 светодиода, объединенных в матрицу. То есть мы имеем 8 строк и 8 столбцов. Объединим все положительные выводы каждой строки в общий провод. Данная ситуация показана на следующем рисунке.
Таким образом, для 8 строк у нас есть 8 общих положительных выводов. Рассматривая первую строку (как показано на рисунке) мы видим что 8 светодиодов с D57 до D64 имеют общий положительный вывод, обозначенный как POSITIVE0. Теперь если мы хотим зажечь один или все светодиоды первой строки мы должны подать питание на контакт A0 светодиодной матрицы. Аналогичным образом, если мы хотим зажечь светодиоды в любой другой строке, мы должны подать питание на соответствующий ей общий вывод.
Но подать питание на общий вывод какой-либо строки еще недостаточно для того чтобы зажечь светодиоды в ней – мы должны подать еще землю на соответствующие светодиоды. В светодиодной матрице отрицательные выводы всех светодиодов конкретного столбца также сгруппированы (объединены) в общий отрицательный вывод этого столбца. Таким образом, мы имеем 8 общих отрицательных выводов столбцов. К примеру, общий отрицательный вывод первого столбца можно обозначить C7 (NEGATIVE7) как показано на рисунке ниже.
Необходимо учесть все эти моменты когда будете запаивать светодиоды в макетную плату.
Теперь, если мы хотим подать землю на любой светодиод в первом столбце, нам необходимо подать землю на контакт PIN-C7 (NEGATIVE7) светодиодной матрицы. Все это справедливо и для других столбцов матрицы.
Теперь, когда мы знаем, как работают общие положительные и отрицательные выводы в матрице, попробуем объединить их чтобы посмотреть как они будут работать вместе. Таким образом, финальная схема текстового дисплея на основе светодиодной матрицы 8х8 под управлением микроконтроллера ATmega32 представлена на следующем рисунке.
Управление светодиодной матрицей 8х8 с помощью мультиплексирования
В представленной схеме если мы хотим включить LED57 нам необходимо подать питание на PORTA0 микроконтроллера ATmega32 и землю на его PORTC0. Если мы хотим одновременно зажечь LED57 и LED50 нам необходимо подать питание на PINA0, PINA1 и землю на PINC0, PINC1. Но эта операция включит не только светодиоды D57, D50, но и светодиоды D49, D58. Чтобы избежать этого мы должны использовать технологию мультиплексирования. Более подробно эта технология рассмотрена в статье про подключение светодиодной матрицы 8х8 к микроконтроллеру AVR, поэтому здесь мы ее рассмотрим лишь кратко.
Человеческий глаз не может воспринимать частоту большую чем 30 Гц. То есть если мы будем включать и выключать светодиод с частотой 30 Гц (или больше), то человеческий глаз будет воспринимать этот светодиод как непрерывно горящим. В этом и заключается смысл технологии мультиплексирования при использовании светодиодной матрицы.
Давайте рассмотрим пример когда мы хотим включить только светодиоды LED57 и LED50, при этом светодиоды D49 и D58 должны оставаться в выключенном состоянии. Технология мультиплексирования заключается здесь в том, что мы сначала подаем питание на первую строку чтобы включить LED57 и ждем 1 мсек, а затем отключаем подачу питания на первую строку. Затем мы подаем питание на вторую строку чтобы включить LED50 и ждем 1 мсек, а затем отключаем подачу питания на вторую строку. Этот цикл мы будем повторять постоянно с высокой частотой, с этой же самой частотой светодиоды LED57 иLED50 будут включаться и выключаться, но человеческий глаз будет воспринимать их непрерывно горящими. То есть в один конкретный момент времени мы подаем питание только на одну строку светодиодной матрицы, что исключает возможность включения светодиодов в других строках матрицы. Эту технологию мы используем чтобы показать все нужные нам символы.
Мы запишем десятичные значения для каждого символа и будем использовать их в программе для микроконтроллера AVR ATmega32. Программа будет переключать эти значения для этого чтобы обеспечить скроллинг символов слева направо на светодиодной матрице.
Исходный код программы на языке С (Си) с пояснениями
Представленная программа реализует горизонтальный скроллинг заданных символов на светодиодной матрице 8х8 под управлением микроконтроллера AVR ATmega32.
Чтобы изменить отображаемые символы просто замените значения в представленном символьном массиве ALPHA[] на необходимые вам.
{0,0b01111111,0b11111111,0b11001100,0b11001100,0b11001100,0b11111111,0b01111111}, //A
{0,0b00111100,0b01111110,0b11011011,0b11011011,0b11011011,0b11111111,0b11111111}, //B
{0,0b11000011,0b11000011,0b11000011,0b11000011,0b11100111,0b01111110,0b00111100}, //C
{0,0b01111110,0b10111101,0b11000011,0b11000011,0b11000011,0b11111111,0b11111111}, //D
{0,0b11011011,0b11011011,0b11011011,0b11011011,0b11011011,0b11111111,0b11111111}, //E
{0,0b11011000,0b11011000,0b11011000,0b11011000,0b11011000,0b11111111,0b11111111}, //F
{0b00011111,0b11011111,0b11011000,0b11011011,0b11011011,0b11011011,0b11111111,0b11111111}, //G
{0,0b11111111,0b11111111,0b00011000,0b00011000,0b00011000,0b11111111,0b11111111}, //H
{0b11000011,0b11000011,0b11000011,0b11111111,0b11111111,0b11000011,0b11000011,0b11000011}, //I
{0b11000000,0b11000000,0b11000000,0b11111111,0b11111111,0b11000011,0b11001111,0b11001111}, //J
{0,0b11000011,0b11100111,0b01111110,0b00111100,0b00011000,0b11111111,0b11111111}, //K
{0b00000011,0b00000011,0b00000011,0b00000011,0b00000011,0b00000011,0b11111111,0b11111111}, //L
{0b11111111,0b11111111,0b01100000,0b01110000,0b01110000,0b01100000,0b11111111,0b11111111}, //M
{0b11111111,0b11111111,0b00011100,0b00111000,0b01110000,0b11100000,0b11111111,0b11111111}, //N
{0b01111110,0b11111111,0b11000011,0b11000011,0b11000011,0b11000011,0b11111111,0b01111110}, //O
{0,0b01110000,0b11111000,0b11001100,0b11001100,0b11001100,0b11111111,0b11111111}, //P
{0b01111110,0b11111111,0b11001111,0b11011111,0b11011011,0b11000011,0b11111111,0b01111110}, //Q
{0b01111001,0b11111011,0b11011111,0b11011110,0b11011100,0b11011000,0b11111111,0b11111111}, //R
{0b11001110,0b11011111,0b11011011,0b11011011,0b11011011,0b11011011,0b11111011,0b01110011}, //S
{0b11000000,0b11000000,0b11000000,0b11111111,0b11111111,0b11000000,0b11000000,0b11000000}, //T
{0b11111110,0b11111111,0b00000011,0b00000011,0b00000011,0b00000011,0b11111111,0b11111110}, //U
{0b11100000,0b11111100,0b00011110,0b00000011,0b00000011,0b00011110,0b11111100,0b11100000}, //V
{0b11111110,0b11111111,0b00000011,0b11111111,0b11111111,0b00000011,0b11111111,0b11111110}, //W
{0b01000010,0b11100111,0b01111110,0b00111100,0b00111100,0b01111110,0b11100111,0b01000010}, //X
{0b01000000,0b11100000,0b01110000,0b00111111,0b00111111,0b01110000,0b11100000,0b01000000}, //Y
{0b11000011,0b11100011,0b11110011,0b11111011,0b11011111,0b11001111,0b11000111,0b11000011} //Z
К примеру, если вы хотите скроллить на светодиодной матрице слово "DAD", то вам необходимо будет заменить значения в символьном массиве ALPHA[] на следующие:
char ALPHA[] = {0,0,0,0,0,0,0,0,0,0,0,0,0b01111110,0b10111101,0b11000011,0b11000011,0b11000011,0b11111111,0b11111111,0,0b01111111,0b11111111,0b11001100,0b11001100,0b11001100,0b11111111,0b01111111,0,0b01111110,0b10111101,0b11000011,0b11000011,0b11000011,0b11111111,0b11111111,0,0,0,0,0,0,0,0,0,0,0};
Также в программе вам будет необходимо заменить строку с циклом на следующую:
1 2 3 4 5 6 7 |
Replace, for(int x=0;x<142;x++) //150-8(to stop overflow) {…….. With, for(int x=0;x<42;x++) //50-8(to stop overflow) {…….. |
То есть просто заменить число 142 на число 42.
Таким образом, вы можете скроллить любой текст на светодиодной матрице, внеся соответствующие изменения в представленную программу.
Теперь код программы с комментариями.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
#include <avr/io.h> // заголовок чтобы задействовать контроль данных на контактах #define F_CPU 11059200UL // задание тактовой частоты микроконтроллера #include <util/delay.h> // заголовок чтобы задействовать функции задержки в программе int main(void) { DDRD = 0xFF; //конфигурируем PORTD на вывод данных DDRA = 0xFF; // конфигурируем PORTA на вывод данных DDRC = 0xFF; // конфигурируем PORTC на вывод данных char ALPHA[]={0,0,0,0,0,0,0,0,0,0,0, 0,0b11000011,0b11000011,0b11000011,0b11000011,0b11100111,0b01111110,0b00111100,0,0, 0b11000011,0b11000011,0b11000011,0b11111111,0b11111111,0b11000011,0b11000011,0b11000011,0,0, 0b01111001,0b11111011,0b11011111,0b11011110,0b11011100,0b11011000,0b11111111,0b11111111 ,0,0, 0,0b11000011,0b11000011,0b11000011,0b11000011,0b11100111,0b01111110,0b00111100,0,0, 0b11111110,0b11111111,0b00000011,0b00000011,0b00000011,0b00000011,0b11111111,0b11111110,0,0, 0b11000011,0b11000011,0b11000011,0b11111111,0b11111111,0b11000011,0b11000011,0b11000011,0,0, 0b11000000,0b11000000,0b11000000,0b11111111,0b11111111,0b11000000,0b11000000,0b11000000,0,0, 0,0b01111110,0b10111101,0b11000011,0b11000011,0b11000011,0b11111111,0b11111111,0,0, 0b11000011,0b11000011,0b11000011,0b11111111,0b11111111,0b11000011,0b11000011,0b11000011,0,0, 0b00011111,0b11011111,0b11011000,0b11011011,0b11011011,0b11011011,0b11111111,0b11111111,0,0, 0,0b11011011,0b11011011,0b11011011,0b11011011,0b11011011,0b11111111,0b11111111,0,0, 0b11001110,0b11011111,0b11011011,0b11011011,0b11011011,0b11011011,0b11111011,0b01110011,0,0, 0b11000000,0b11000000,0b11000000,0b11111111,0b11111111,0b11000000,0b11000000,0b11000000,0,0, 0,0,0,0,0,0,0,0,0,0,0, }; char PORT[8] = {1,2,4,8,16,32,64,128}; //pin values of a port 2^0,2^1,2^2……2^7 uint8_t l =0; while(1) { // в массиве ALPHA 142 значения, которые реализуют последовательное отображение на светодиодной матрице строки 'CIRCUIT DIGEST', затем происходит повтор цикла for(int x=0;x<142;x++) { for(int a=0;a<20;a++) // показываем каждый символ 20 раз перед тем как переключим столбец { for (int i=0;i<8;i++) { PORTC = ~PORT[i]; //подаем землю на контакты PORTC PORTA = ALPHA[i+x]; //подаем питание на контакты PORTA _delay_ms(1); PORTC = PORT[i]; //очистить контакт спустя 1мсек } } } } } |
Зачем переменная l =0;, если она нигде не используется?
Опечатка. Наверное от какой либо другой программы осталась
Большое спасибо, очень помогли)
Спасибо и вам за то, что оценили мой труд