Реклама ⓘ
Главная » Компьютерная электроника
Призовой фонд
на апрель 2024 г.
1. 100 руб.
От пользователей

Похожие статьи:


Реклама ⓘ

LED индикатор загруженности ЦП

Схем различных индикаторов, отображающих загруженность ЦП и памяти достаточно много. Но в основном они отображают информацию с помощью LCD дисплея, который или слишком мал, или размеры нормальные, но дорогой. Именно по этой причине я решил собрать индикатор загруженности ЦП на светодиодах.

Эта статья является логическим продолжением для применения кода, описанного в третьем видеоуроке о mikroPascal.

Исходя из того, что у меня нет лазерного принтера (ЛУТ отпадает), двухъядерный процессор и один светодиод стоит примерно 0.8 гривны, было решено делать 3 строки светодиодов по 10  штук в каждой. Две - под индикацию загрузки процессора, и оставшаяся под память или третье ядро (не сталкивался, но слышал).

Основная информация об устройстве:

  1. Напряжение питания: 5 V
  2. Потребляемый ток: < 50 mA 
  3. Частота обновления данных: 0,5

Теперь можно перейти к схеме. 

Как видите, она достаточно простая. Основа схемы - микроконтроллер ATmega8 (в корпусе DIP-28). Общее количество деталей - 40 шт., из них : светодиодов - 31, транзисторов - 5, остальное микроконтроллер и обвязка генератора.

Не столько для экономии выводов, сколько для удобства обращения к портам я использовал такое включение светодиодов для динамической индикации:

Рис.2 (схема включения светодиодов).

Таким способом мне удалось "уложиться" в два порта МК (PORTB - 6 пин, PORTC - 5 пин). Можно было конечно использовать сдвиговые регистры, но это повлекло бы за собой усложнение программы, а так же занятое место на плате. По-этому решил обойтись без них. 

На схеме нет токоограничительных резисторов (применительно к светодиодам), так как они работают в импульсном режиме. Я использовал светодиоды красного, желтого и белого цветов. Красный и желтый - ЦП, белый же для дополнительной строки.

После всех манипуляций со схемой, взялся за разводку печатной платы. Вот тут то и был зарыт кирпич....Если схема была набросана минут за 5 то с платой пришлось возитсья около получаса. В итоге она получилась двухсторонней. 

Как видите, разводка платы не самая простая. В этом виновата прежде всего динамическая индикация. Из-за нее пришлось часть проводников перенести на обратную сторону платы, а так же использовать большое количество переходных отверстий (в основном  для подключения светодиодов). Но, тем не менее эту плату возможно сделать и без ЛУТа. И последнее относительно платы - я использовал текстолит толщиной 0,5 мм, так как другого с двухсторонним покрытием в наличии не оказалось.

Рассмотрев аппаратную часть можно перейти к программной.

Программу для МК я как всегда писал в среде mikroPascal for AVR (v 6.01). Так как в микропаскале нет библиотеки для микроконтроллера Atmega8, которая позволяет работать с USB, то выбор пал на UART. Но так как последний видеоурок по mikroPascal был про прерывания, то решил и сюда их всунуть. И вот что в итоге получилось:

program iCPU_t;

uses AADL;

var dat:array [0..2] of byte;
    rec,i,c,enbl:byte;
    rcit,rci,ti:integer;

    
const pc: array [0..10] of byte = (31,30,28,24,16,0,30,28,24,16,0);             //Объявляем константы
const pb0: array [0..10] of byte = (0,254,254,254,254,254,253,253,253,253,253); //Они будут использоваться, как вы уже поняли из
const pb1: array [0..10] of byte = (0,251,251,251,251,251,247,247,247,247,247); //из названий, для отправки заданных значений
const pb2: array [0..10] of byte = (0,239,239,239,239,239,223,223,223,223,223); //в порт.



procedure usart_c(); iv IVT_ADDR_USART__RXC;                                    //Функция, которая вызывается по прерыванию UART
begin                                                                           //(если в буфере приема есть данные).
     rec:=UART_Read();                                                          //
     if rec=47 then enbl:=1;                                                    //Тут мы ищем нужные нам символы, и сразу их
     if enbl=1 then inc(enbl) else                                              //переводим.
     if enbl=2 then begin                                                       //
     case rec of                                                                //
     48: rec:=0;
     49: rec:=1;
     50: rec:=2;
     51: rec:=3;
     52: rec:=4;
     53: rec:=5;
     54: rec:=6;
     55: rec:=7;
     56: rec:=8;
     57: rec:=9;
     end;
     ti:=rec;
     inc(i);
     case i of
     1: rci:=ti*10;
     2: rci:=rci+(ti);
     end;
     if i>=2 then begin i:=0; enbl:=0; end;
     end;
end;


begin
Uart1_init(9600);                                                               //Инициализация UART

UCSRB.B7:=1;                                                                    //Прерывание по приему данных UART
SREG_I_bit:=1;                                                                  //Разрешаем прерывания


DDRC:=0xFF;
DDRB:=0xFF;
DDD7_bit:=1;

PORTD7_bit:=0;

for c:=0 to 2 do dat[c]:=0;

While TRUE do begin
        rcit:=rci;
        if (rcit>30) and (rcit<40) then dat[2]:=rcit-30;                        //Присваиваем значение различным
        if (rcit>20) and (rcit<30) then dat[1]:=rcit-20;                        //элементам массива dat, в зависимости от того,
        if (rcit>10) and (rcit<20) then dat[0]:=rcit-10;                        //какому ядру они соответствуют.
             for c:=0 to 2 do begin
                 case c of
                      0: if dat[c]<=5 then begin                                //Дальше обеспечиваем индикацию.
                            PORTC:=pc[dat[c]];
                            PORTB:=pb0[dat[c]];
                            delay_ms(1);
                         end else begin
                             PORTC:=pc[5];
                             PORTB:=pb0[dat[c]-5];
                             delay_ms(1);
                             PORTC:=pc[dat[c]];
                             PORTB:=pb0[dat[c]];
                             delay_ms(1);
                         end;
                      1: if dat[c]<=5 then begin
                            PORTC:=pc[dat[c]];
                            PORTB:=pb1[dat[c]];
                            delay_ms(1);
                         end else begin
                             PORTC:=pc[5];
                             PORTB:=pb1[dat[c]-5];
                             delay_ms(1);
                             PORTC:=pc[dat[c]];
                             PORTB:=pb1[dat[c]];
                             delay_ms(1);
                         end;
                      2: if dat[c]<=5 then begin
                            PORTC:=pc[dat[c]];
                            PORTB:=pb2[dat[c]];
                            delay_ms(1);
                         end else begin
                             PORTC:=pc[5];
                             PORTB:=pb2[dat[c]-5];
                             delay_ms(1);
                             PORTC:=pc[dat[c]];
                             PORTB:=pb2[dat[c]];
                             delay_ms(1);
                         end;
                 end;
             end;
    end;
end.

В программе тоже ничего сложного нет. Константы в самом начале программы использовались для того, что бы не писать в порт "ручками" каждый раз. В процедуре , вызываемой по прерыванию, используется такой алгоритм:

  1. Анализируем принятые данные, если они соответствуют "/", то разрешаем в следующий раз программе пройти дальше.
  2. Расшифровываем из ANCII кодировки.
  3. Рассчитываем и записываем в переменную

Далее, в основном цикле программы мы сначала сопоставляем, к какому ядру относятся полученные данные, а потом их присваиваем соответствующему элементу массива dat. 

Вот и весь алгоритм программы.

Если вас интересует, как данные отображаются, то все так же просто:

  1. Смотрим, какая строка сейчас должна обновиться.
  2. Выбираем из массива dat нужный элемент.
  3. Если нужно зажечь пять или меньше светодиодов в строке, то просто оправляем значение в порт. Если же больше пяти (число n), то сначала зажигаем первые пять, а потом то что осталось (n-5). Все это крутится в цикле.

Из фузов нужно выставить только внешний кварц (8 MHz).

В Khazama AVR Programmer это выглядит следующим образом:

Рис. 4(фузы).

Вот и все! Но если у вас нет каких-то деталей, но есть их аналоги.... Светодиоды можно взять любые, подходящие по току и размерам. Микроконтроллер заменить нельзя. Только взять такой же но с любым другим индексом (например, вместо ATmega8 - ATmega8L и т.д.). Транзисторы так же можно взять любые маломощные структуры p-n-p. Я использовал КТ361Г (работают нормально, хотя еще 1987 г. выпуска :) ). Резисторы - с разбросом от указанного номинала до +/- 20 %.

И напоследок, о программе для Windows, которая управляет индикацией. Она написана в Delphi xe5 и называется iCPU. 

Рис.5(iCPU).\

Рассчитана на 2 ядра. В настройках выбирается порт, к которому подключено устройство. Возможно использовать как встроенный COM порт (через преобразователь уровней на MAX232), так и через виртуальный COM порт, с использованием переходника на базе PL2303 и подобных. У меня в городе можно купить такой кабель для старых моделей NOKIA.

Рис.6(кабель).

Внутри платка, которая с успехом может использоваться как USB-COM переходник.

Вот несколько фотографий готового устройства.

Обновление от 20.07.2014:
Доработал программу, теперь можно выводить на 3-ю строку загруженность памяти. А так же мелкие исправления.

Обновление от 01.05.2015:

Полностью переписан код как прошивки для МК, так и программы для Windows. Теперь есть отдельная версия для Windows x64.

Для МК прошивка писалась в WinAVR (Cpp).

ВНИМАНИЕ! Старая прошивка + новая версия программы НЕСОВМЕСТИМЫ, как и новая прошивка + старая версия программы.

При прошивке фузы указывать те же, что и для старой версии, за исключением (выставлять как на скрине):

.

Из "нововведений":

  • Возможность применять "выравнивание" (по левому краю, по центру и по правому краю).
  • Автоматическое отключение индикации через 10с (например, если комп погрузили "в сон").
  • Теперь есть "тестовый" режим, в котором включаются все светодиоды (например, при первых включениях уст-ва, для выявления неполадок).
  • Если у вас в системе многоядерный процессор, то будут отображаться только первые 2 ядра (на уст-ве, в программе будет видно загрузку всех ядер). В противном случае, на уст-ве будут активными только 1-я и 3-я строки (1 ядро и память соответственно).

Так же хочу заметить, что перед первым запуском программы, впишите номер ком порта, к которому подключено устройство, в файл "settings.ini". Он лежит в папке с exe-шником. Иначе, скорее всего, будете через каждые 0.5с получать окна с ошибками!

В аппаратную часть устройства никакие правки не вносились.

Немного фотографий:

Обновление от 16.05.2015:

Оптимизирован код. Добавлена возможность регулировки яркости (программный ШИМ на таймере T2). Внесены некоторые правки в программу для Windows (теперь, если COM порт выбран неверно (порта с таким номером в системе нет), не будет +100500 окон с ошибками).

Список радиоэлементов

Обозначение Тип Номинал Количество ПримечаниеМагазинМой блокнот
U1 МК AVR 8-бит
ATmega8
1 DIP-28Поиск в магазине ОтронВ блокнот
D1-D30 СветодиодHL-A-3528H308W-S1-1330 Любые светодиоды 0805, подходящие по токуПоиск в магазине ОтронВ блокнот
C1, C2 Конденсатор27 пФ2 0805Поиск в магазине ОтронВ блокнот
X1 Кварцевый резонатор8 МГц1 НизкопрофильныйПоиск в магазине ОтронВ блокнот
R2-R6 Резистор
1 кОм
5 0805Поиск в магазине ОтронВ блокнот
R1, R7-R10 Резистор
30 кОм
5 0805Поиск в магазине ОтронВ блокнот
Q1-Q4 Транзистор2N37025 Или КТ361Поиск в магазине ОтронВ блокнот
Добавить все

Скачать список элементов (PDF)

Прикрепленные файлы:

Теги:

Опубликована: Изменена: 16.05.2015 0 0
Я собрал 0 1
x

Оценить статью

  • Техническая грамотность
  • Актуальность материала
  • Изложение материала
  • Полезность устройства
  • Повторяемость устройства
  • Орфография
0

Средний балл статьи: 4.3 Проголосовало: 1 чел.

Комментарии (8) | Я собрал (0) | Подписаться

0
BARS_ #
Плату поменьше раза в 3 и будет очень даже неплохо
Ответить
0

[Автор]
zeconir #
Да вот, первый опыт так сказать. Раньше как-то не приходилось с таким кол-вом светодиодов маяться.
Ответить
+1
civil #
Интересно.
А исходник на Дельфях покажете? И хорошо бы отрабатывать ситуацию отсутствия ком-портов, а то я программу еле прибил через диспетчер задач.
Ответить
0

[Автор]
zeconir #
Да, скиньте в ЛС почту. А программу я еще допиливать буду (на присутствие портов + индикация загрузки в трее).
Ответить
0
Artos5 #
Рассмешили. Эту ситуацию надо учитывать .. и обрабатывать подобные исключения.
Ответить
0

[Автор]
zeconir #
Изначально, если прочитать статью, то понятно, что на ПК без COM порта (виртуального или физического) устройство по определению работать не будет, соответственно, программа там тоже не нужна.
А если 6 ядер, то будет брать только первые два (или три. В программе правку внести).
Ответить
0
Artos5 #
Уважаемый автор! А если у меня 6 ядер, как устройство будет себя вести?
Ответить
+1
Глеб #
Собрал данное устройство, все работает, спасибо автору.
Ответить
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется электрическая мощность?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

МиниПК MK809V - 4 ядра, Android 4.4.2
МиниПК MK809V - 4 ядра, Android 4.4.2
Конструктор: DDS генератор сигналов Программатор Pickit3
вверх