Схем различных индикаторов, отображающих загруженность ЦП и памяти достаточно много. Но в основном они отображают информацию с помощью LCD дисплея, который или слишком мал, или размеры нормальные, но дорогой. Именно по этой причине я решил собрать индикатор загруженности ЦП на светодиодах.
Эта статья является логическим продолжением для применения кода, описанного в третьем видеоуроке о mikroPascal.
Исходя из того, что у меня нет лазерного принтера (ЛУТ отпадает), 2-хъядерный процессор и один светодиод стоит примерно 0.8 гривны, было решено делать 3 строки светодиодов по 10 штук в каждой. Две — под индикацию загрузки процессора, и оставшаяся под память или третье ядро (не сталкивался, но слышал).
Основная информация об устройстве:
Теперь можно перейти к схеме.
Как видите, она достаточно простая. Основа схемы — микроконтроллер ATmega8 (в корпусе DIP-28). Общее количество деталей — 40 шт., из них : светодиодов — 31, транзисторов — 5, остальное микроконтроллер и обвязка генератора.
Не слишь для экономии выводов, сколько для удобства обращения к портам я использовал такое включение светодиодов для динамической индикации:
Таким способом мне удалось «уложиться» в два порта МК (PORTB — 6 пин, PORTC — 5 пин). Можно было конечно использовать сдвиговые регистры, но это повлекло бы за собой усложнение программы, а так же занятое место на плате. По-этому решил обойтись без них.
На схеме нет токоограничительных резисторов (применительно к светодиодам), потому что они работают в импульсном режиме. Я использовал светодиоды красного, желтого и белого цветов. Красный и желтый — ЦП, белый же для дополнительной строки.
После всех манипуляций со схемой, взялся за разводку печатной платы. Вот тут то и был зарыт кирпич….Если схема была набросана минут за 5 то с платой пришлось возитсья около получаса. В итоге она получилась 2-хсторонней.
Как видите, разводка платы не самая простая. В этом виновата прежде всего динамическая индикация. Из-за нее пришлось часть проводников перенести на обратную сторону платы, а так же использовать большое количество переходных отверстий (в основном для подключения светодиодов). Но, тем не менее эту плату возможно сделать и без ЛУТа. И последнее относительно платы — я использовал текстолит толщиной 0,5 мм, потому что другого с 2-хсторонним покрытием в наличии не оказалось.
Рассмотрев аппаратную часть можно перейти к программной.
Программу для МК я как всегда писал в среде 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.
В программе тоже ничего сложного нет. Константы в самом начале программы использовались для того, что бы не писать в порт «ручками» каждый раз. В процедуре , вызываемой по прерыванию, используется такой алгоритм:
Далее, в основном цикле программы мы сначала сопоставляем, к какому ядру относятся полученные данные, а потом их присваиваем соответствующему элементу массива dat.
Вот и весь алгоритм программы.
Если вас интересует, как данные отображаются, то все так же просто:
Из фузов нужно выставить лишь внешний кварц (8 MHz).
В Khazama AVR Programmer это выглядит следующим образом:
Вот и все! Но если у вас нет каких-то деталей, но есть их аналоги…. Светодиоды можно взять любые, подходящие по току и размерам. Микроконтроллер заменить нельзя. Только взять такой же но с любым другим индексом (например, вместо ATmega8 — ATmega8L и т.д.). Транзисторы так же можно взять любые маломощные структуры p-n-p. Я использовал КТ361Г (работают нормально, хотя ещё 1987 г. выпуска 🙂 ). Резисторы — с разбросом от указанного номинала до +/- 20 %.
И напоследок, о программе для Windows, которая управляет индикацией. Она написана в Delphi xe5 и называется iCPU.
Рассчитана на 2 ядра. В настройках выбирается порт, к которому подключено устройство. Возможно использовать как встроенный COM порт (через преобразователь уровней на MAX232), так и через виртуальный COM порт, с использованием переходника на базе PL2303 и подобных. У меня в городе можно купить такой кабель для старых моделей NOKIA.
Внутри платка, которая с успехом может использоваться как 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-битATmega81
DIP-28D1-D30
СветодиодHL-A-3528H308W-S1-1330
Любые светодиоды 0805, подходящие по токуC1, C2
Конденсатор27 пФ2
0805X1
Кварцевый резонатор8 МГц1
НизкопрофильныйR2-R6
Резистор1 кОм5
0805R1, R7-R10
Резистор30 кОм5
0805Q1-Q4
Транзистор2N37025
Или КТ361Добавить все
Скачать список элементов (PDF)
Прикрепленные файлы:
- icpu-old.rar (1679 Кб)
- icpu-new.rar (1871 Кб)
- icpu-16_05_2015.rar (1841 Кб)