| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Управление светодиодами и микрозадержки выполнения |
| Автор: Temdegon 6.5.2009, 13:51 |
| Наткнулся на статью http://www.hardwareportal.ru/articles/Indikator_zagruzki_protsessora_i_vinchestera_svoimi_rukami/ Из статьи меня заинтересовал индикатор загрузки ЦПУ. По-моему выглядит круто. Захотел себе такой же. Но брать в руки паяльник и паять плату для управления светодиодами через ком порт мне не хочется. Вот и возникла идея возложить функции управления этими светодиодами на программу. Нужно изменять яркость свечения двух светодиодов в зависимосит от загрузки ЦПУ. Яркость светодиода изменяется не изменением напряжения, а прерыванием напряжения на на доли секунды. Решил вместо ком-порта использовать LPT, т.к. там как раз логическая единица = +5В и ток вполне достаточный для горения светодиода. Достаточно будет просто подключить светодиоды к LPT и выставлять на порте нужные значения, и ничего не нужно паять. В принципе бета-версию я написал, и она работает у меня нормально. Но есть некоторые проблемы. 1) Программа всегда должна работать с максимальным преорететом. Со средним преорететом светодиоды горят коряво при высокой загрузке ЦПУ. Как сделать так, что бы программа запускалась с максимальным преоретеом в Windows? 2) Как реализовать задержки выполнения, типа Sleep(), но не на милисекунды, а на микросекунды? Я для таких задержек написал простую функцию, которая в цикле выполняет арифметические операции и количество итераций цикла подобрал "на глаз". В результате на моем компе работает превосходно, но на других машинах уже выглядит коряво, т.к. производительность процессоров отличается, и мои "задержки" уже совсем другие. В общем, нужно как-то делать задержки в микросекундах более грамотным способом. В общем, если кому интересно, могу выложить свою прогу и распайку LPT для нее. |
| Автор: math64 6.5.2009, 15:00 |
| Чтобы горело нормально, нужно писать драйвер. Добавлено через 6 минут и 45 секунд Ну или ещё: используй COM, а не LPT. При передаче 0x00 светодиод будет гореть с полной яркостью, при 0xFF - не будет гореть (или наоборот, как схему спаяешь), задержки будут определяться скоростью передачи, а не таймером, нужно только вовремя заполнять буфер передачи. Драйвер не нужен. |
| Автор: Temdegon 6.5.2009, 15:25 |
| С ком-портом все слишком сложно. Во первых светодиода два, и ими нужно управлять. Если красный горит на 75% то синий на 25%. Что бы это реализовать, нужно паять схему. А моя цель сделать устройство максимально простым, без всяких плат, микросхем, т.к. это сложно. Через LPT у меня все работает, причем без всяких плат. Просто два светодиода тыкнуты в LPT. Прога проц не грузит вообще, диоды горят красиво, ни чуть не хуже чем на скриншотах. Проблемы всего две: запустить с максимальным преорететом и сделать задержки переносимыми. Драйверы писать не умею и не хочу учиться. А еще мне нравится вариан оформить прогу в виде службы для windows. Но об этом я ничего не знаю.. |
| Автор: cardinal 6.5.2009, 15:36 | ||
Попробуй с PWM.
http://en.wikipedia.org/wiki/Pulse-width_modulation То есть меняй скважность http://ru.wikipedia.org/wiki/%D0%A1%D0%BA%D0%B2%D0%B0%D0%B6%D0%BD%D0%BE%D1%81%D1%82%D1%8C сохраняя одну частоту. Если частота будет оставаться одинаковой, то и переносимость будет... |
| Автор: Albor 6.5.2009, 15:47 |
| Я бы какой-то буфер на LPT порт всё таки поставил (хотя бы транзисторы). Кто знает, достаточно ли мощные выходные ключи порта. Светодиоды, если взять совдеповские, светят более-менее нормально при 7~10 mA, а те что современные - 15 и более, а это многовато наверняка. |
| Автор: Temdegon 6.5.2009, 15:53 | ||
| млин. так я и делаю через изменение сважности. По другому я никак не могу заставить светодиод, висящий на LPT светиться в пол-силы. Работает так:
Тут важно понимать разницу между LPT и COM. Если послать в ком данные, то там сигнал появится короткое время, а в ЛПТ по другому. Если мы записали туда что-то, то напряжение на контактах будет до тех пор, пока мы не пошлем что-то другое. Что бы светодиод постоянно горел, нужно просто повесить его на контакт #2 и 25 и послать в порт 1. и он будет гореть, пока не пошлешь туда 0. Я дела это без задержек, но тогда проц грузится на 100%. А с задержками вообще не грузится. |
| Автор: cardinal 6.5.2009, 15:57 | ||||
http://mastershome.net.ru/vbfaq/c07.htm Добавлено через 5 минут и 55 секунд |
| Автор: math64 6.5.2009, 16:06 |
Ничего сложного - разъём и светодиод. У меня есть такая заглушка - светодиод светится если идёт передача, никаких плат не нужно. Полезно при отладке программ, работающих с ком портом. Правда паял не сам. |
| Автор: Temdegon 6.5.2009, 16:16 |
| Так кто-нить подскажет, как запустить ехе - файл с высоким преорететом? Чтоб не нужно было каждый раз через таскманагер искать его и менять преоретет вручную? И как все-таки делать задерки программы в микросекундах? У меня уже была мысть как бы калибровать функцию задержки во время первого запуска. Задержка представляет собой простой for, в котором делается чтонить типа z*=i*z*i. Т.е. сначала цикл запускается на 100к итераций, и измеряется время выполнения, а потом в корректируется количество итераций, для получения нужной задержки. Но такая задержка будет грузить проц, а это не есть гуд. |
| Автор: math64 6.5.2009, 16:31 |
| Если уж делать задержки, то используй команды процессора выдающую число тактов с его влючения. При старте программы нужно вычислить тактовую частоту. Правда, она првилегированная и её можно использовать в Win98 или в драйвере. |
| Автор: Temdegon 6.5.2009, 16:50 |
| А можно чуть-чуть подробнее. Не совсем понимаю, как зная тактовую частоту делать задержку. Я себе это решение опять же вижу как цикл, в котором проверяется, сколько тактов прошло. Но это опять же цикл, который сожрет все процессорное время. |
| Автор: xvr 6.5.2009, 16:56 |
| Если ты сделаешь своему процессу RealTime приоритет, а задержки будешь отсчитывать через QueryPerformanceCounter, то светодиоды будут гореть очень хорошо, правда ничего другого на машине уже работать не будет Любая задержка меньше ~20ms будет грузить проц, т.к. усыпить и разбудить процесс меньше, чем через тик системного таймера очень проблематично (точнее накладно) Приоритет процесса и нити в нем можно менять функциями SetPriorityClass и SetThreadPriority (менять надо оба) Лучше повесь на COM порт, как тут уже советовали. Светодиоды включить встречно - паралельно между TX и GND (не забудь резистор между ними и портом). Выводя в порт разные числа (00, 80, C0, E0, F0, F8, FC, FE, FF) можно менять яркость (надеюсь, 8ми ступеней хватит?). Выводить конечно надо постоянно, но Windows с этим вполне справится сама - сформировать буффер байт на 1000 и вывести блокирующим WriteFile (в цикле) |
| Автор: Temdegon 6.5.2009, 17:02 |
| я че-то тыкался осциллографом в ком-порт и пробовал слать даные. Нифига не понял. МОжет прохо смотрел? Я так понимаю, кроме данных, которые я буду слать в LPT, там еще будут присутствовать всякие конрольные суммы и прочие служебные биты, которые будут не лучшим образом влиять на светодиоды. А может это и не значительно... |
| Автор: xvr 6.5.2009, 19:49 | ||||
Может
|
| Автор: Temdegon 6.5.2009, 20:45 |
| Спасибо. На досуге поэкспериментирую с ком-портом. Должно получиться даже проще чем с LPT, только данные сформировать правильные |
| Автор: Temdegon 7.5.2009, 01:01 | ||
Диоды трехвольтовые. Для ограничения напряжения я параллельно светодиоду вешал стабилитрон на 3 вольта. Хотел так же сделать и для ком-порта, но что-то у мене возникли сомнения, можно ли так сделать в случае с ком-портом? Получится что параллельно двум диодам будут встречно-параллельно висеть два стабилитрона? как вы считаете? а то дома резисторов нету =(. А если вешать резистор, то какой? З.Ы. > Я понимаю, что это не форум для паяльников, не пинайте сильно. Сорри за оффтоп. |
| Автор: xvr 7.5.2009, 08:39 |
| ТОЛЬКО РЕЗИСТОР! Светодиод - прибор с очень нелинейной ВАХ, и для нормальной работы через него нормируется именно ТОК. При изменении напряжения на нем на 0.1В ток может изменится на порядок! Так что никакой стабилитрон не спасет. |