Чую время сессии близится, вроде разжевываешь, разжевываешь… Одни и те же вопросы, из года в год, от сессии к сессии. Думаю пора подвести большую жирную черту и упаковать все вопросы по таймерам в одном месте. Использовать по прямому назначению

Когда то я тоже был студентом. Честно, честно. Уже много раз говорил, что знаю абсолютно все студенческие «обстоятельства». Это лишь Ваш жизненный выбор, ничей больше, поэтому для меня студенты делятся на две группы: кому электроника интересна и кому нет. За годы жизни сайта, отличить их друг от друга стало не проблемой.

Так к чему я это все? Для некоторых людей, контрольные/курсовые/дипломы это всего лишь мелкий этап жизни, который нужно пройти и забыть навсегда. Поэтому мне задача видится так: если удастся хоть одного из этих людей увлечь, и на одного веб программиста станет меньше, а на одного электронщика больше, то это будет круто, значит жизнь не зря прожита 🙂

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

Есть еще одна проблема, о которой многие забывают. Некоторые вопросы требуют времени, т.е. их мало прочитать и понять, нужно некоторое время чтобы смириться и принять что все именно так, а не иначе. Как бы понятно не было про них расписано, за пару дней не усвоишь.

Начнем с системы счислений, так как она сильно помогает в понимании регистров. Почему то многие не дружат с двоичной системой. Возьмите калькулятор, переключите в двоичную систему счисления bin.
calc

Прибавьте 1+1 будет 10. Бум! Взрыв мозга
calc2

Если это так, то рассуждайте тарелками, которые пронумерованы от 1 до 8. В каждой тарелке может либо быть яблоко, либо может не быть. Теперь подумайте, сколько возможно разных ситуаций того, когда есть яблоко или нет в каждой из тарелок.

Начните с одной тарелки, две комбинации — в первом случае яблоко есть, во втором его нет. Потом подумайте, о количестве комбинаций, когда две тарелки. Получится четыре. В следующий раз будет восемь. Потыкайтесь с калькулятором, прибавляйте единицу и увидите простую закономерность.

Теперь разберитесь, если все комбинации перебрали и достигли максимума, если к этому числу прибавить 1, что будет?
calc3

Если самостоятельно разобрались хорошо, для ленивых будет переполнение, больше яблоки некуда пихать, высыпаем яблоки и начинаем заново с нуля. Количество комбинаций подсчитывается двойка (два состояния: есть яблоко или нет) в степени равной количеству тарелок(битов). Если 8 бит, то это 2^8 = 256 комбинаций. 8 бит = 1 байт. В слове байт больше букв, значит он больше чем бит.

Огромное множество людей не дружат со степенью. Берем калькулятор, умножаем число само на себя столько раз, в какую степень надо возвести. Бывает иногда есть число, но нужно узнать в какой это степень двойки, например когда нужно узнать сколько бит нужно отвести под число. Для этого существует логарифм, например для log2 256 = x, можно посчитать на любом калькуляторе и узнать что x = 8, т.е. чтобы получилось 256 нужно двойку возвести в 8 степень.

Что такое регистр, назовем это столом, на котором стоят тарелки, количество которых обычно 8, 16, 32 (8-16-32 битные). Регистр это участок памяти, по определенному адресу, т.е. если стол с 8 тарелками (8 битный регистр) стоит в зале, то это для гостей, если в комнате, то для домочадцев. Ни те ни другие не хавают с чужих тарелок без соответствующего разрешения. Контроллер всегда знает какие тарелки для кого, в нем это аппаратно прошито, для программиста все это указано в документации(даташите).

Обычно каждому регистру дают имя, которое указывают там же в документации. Это имя условность, контроллеру насрать как называется ваш стол с тарелками, он только знает их расположение: стол в гостинной, стол в комнате. Программист же вправе обозвать эти столы как душе угодно, главное сказать об этом контроллеру.

Чтобы облегчить труд программиста существуют библиотеки, которые обычно предоставляет производитель микроконтроллера. Для программиста они будут видны например так: PORTB или GPIOB, однако в глубинах библиотек будет просто
#define PORTB 0x8000
т.е. если вы запишете по адресу 0x8000, какое то число, то это будет равнозначно что записать в PORTB.

Регистры обычно бывают: те которые можно читать, т.е. посмотреть сколько яблок на столе, и те которые можно читать и писать, т.е. кроме просмотра можно изменять их количество. Сходу не припомню, но наверняка есть те, в которые можно только писать.

По основам пробежались. Следующий момент с который весьма туго. Представим себе велосипед. Стоим на ровной поверхности, не крутим педали, колесо будет крутиться? Нет. Итак, наш микроконтроллер велосипед. Он никуда не поедет, пока не начнем крутить педали. Тот кто крутит педали, будет являться тактовым генератором для мк. С каждым велосипедом в подарок идет велосипедист, который как профессионал не очень, главное что крутит педали. Это есть внутренний генератор.

Ваши задачи могут быть совершенно различны, в одном случае нужно, чтобы он просто доехал их пункта А в пункт Б. В другом случае вы можете снабдить его маленьким мешком с едой и сказать проехать медленно, но как можно дальше. Можете вместо велосипедиста идущего в комплекте, посадить профи, за которого придется доплатить это есть внешний генератор. Надеюсь аналогия понятна для чего нужен тактовый генератор.

У простых микроконтроллеров одна передняя звездочка на велосипеде. У тех что «покруче» их несколько переключаемых. Эта фича носит название умножитель частоты PLL, который в реальности может как умножать так и делить исходные усилия велогонщика, т.е. изменять тактовую частоту

Опять же аналогия архитектуры мк, шоссейный ляс намного быстрее будет ехать, чем какой то самый простенький. У некоторых великов 1-2 передачи, у каких то 27 скоростей, у каждого своя цена, каждый пригоден для своей задачи.

Какие есть ограничения? Да, если посадить ребенка, то он не сможет крутануть педали, если же крутить слишком быстро, то велосипед развалится. Для вас это значит, что есть минимальная частота тактирования и максимальная. На низкой он может не запуститься, на превышающей номинальную перегреется.

К чему же это все? Если предствлять себе таймер, в этой системе тактирования, то это будет заднее колесо лисапеда. Оно не может крутиться без задающего генератора. Оно не может крутиться быстрее максимальной частоты тактирования. Исходная частота может быть поделена только для заднего колеса, по той же аналогии это задняя звездочка, называется предделителем. И да, на практике не припомню таймеры без предделителей. Чем круче мк тем больше звездочек у него, т.е. больше предделителей.

Предделители бывают ущербные, фиксированные как у атмег, равные степени двойки 8, 64, 256 и т.п. Или не фиксированные как у стм — например любое 16 битное число от 0 до 65536. Это мегаважная фича. Если ваш генератор 8МГц, и фиксированный набор предделителей, то может так случиться, что на нужной частоте, вы никак его не заставите работать. Пример, тактовая 8МГц, я хочу чтобы таймер тикал раз в секунду, имеются предделители 1, 8, 256, как видите тикать раз в секунду он не сможет, никак.

Таймер не умеет считать ни в секундах, ни в милисекундах, НЕ УМЕЕТ, НЕ ЗНАЕТ, НЕ ПОНИМАЕТ, ему насрать на ваши секунды, годы, месяцы или в чем там вы пытаетесь измерять. Ему это не ведомо. У вас нет другой привязки к времени, кроме тактовой частоты и предделителей, таймер тикает синхронно с генератором.

Есть небольшое уточнение, таймеры бывают синхронные, это как в примере выше, связан с основной тактовой частотой и асинхронные, это ммм как бы сверху одного велосипеда, был прикреплен еще один 🙂 В этом случае таймер это колесо верхнего. Для того чтобы он работал нужен дополнительный генератор.

При этом никто не мешает нижнему стоять на месте или также ехать, а верхний крутить колеса и пинать нижнего. Обычно верхний крутит колеса медленно, на частотах кратных степени двойки, чтобы отсчитывать время, но опять же оговорюсь, таймер ничего не знает про секунды, он знает только про вращение педалей и количество оборотов колеса. Тик таймера это оборот колеса.

Самое странное почему народ не догоняет единицы измерения тиканья таймера. Это герцы, герцы карл. Наверно потому, что никто не догоняет, что такое герцы. Герц это сколько раз повторилось действие за секунду. ЗА СЕКУНДУ. Действие. Я уже пытался проводить какие то аналогии с хлопками, такое ощущение что не прокатил пример. Не знаю как еще объяснить. Может так прокатит:
秒当たりの回数
the number of times per second

Есть еще предположение, что никто не вкуривает что такое секунда. В 1 секунде 1000мс. Но запомнить нужно, что когда считаешь герцы, то это повторения за 1 секунду, не милисекунду, не микросекунду. Что будет, если поделить 1 секунду на количество повторений, это будет время выполнения 1 действия. Этому времени есть вполне конкретный термин — период. Если что то происходит 1000 раз в секунду, т.е. с частотой 1000Гц, это действие будет выполняться раз в 1/1000 = 0,001 секунды. Думаю это самая больная часть всех вопросов про таймеры, почему это сложно посчитать, не понятно.

Итак, каждый таймер должен уметь считать, поэтому у каждого счетного таймера есть счетный регистр, что нибудь с названием CNT, TCNT и т.п. = счетчик. Представьте, количество яблок на этом столе изменяется, само, постоянно на единицу, со скоростью … правильно! Тактовая на предделитель.

Этот регистр обычно можно читать, а также туда писать. Да, да вы можете считать не с нуля. Этот регистр отвечает за разрядность таймера, т.е. если говорят что таймер 8 битный, то это значит что на регистр отведено 8 бит, т.е. он может считать от 0 до 255. Чем больше разрядность таймера тем он круче, точнее.

Представим тактовая 8МГц, предделитель фиксированный 256, т.е. за секунду таймер сделает 8000000/256 = 31250 тиков, 1 тик будет происходить раз в 1/31250 = 0,000032 секунды

если таймер 8 битный, то он отсчитает
(1/31250) * 256 = 0,008192 секунды, после этого он обнулится, что весьма печально, если нам нужно было отсчитать 1 секунду. Зато с 16 битным таймером таких проблем нет, он будет обнуляться раз в
(1/31250) * 65536 = 2,097152 секунды

Важно запомнить, что таймер, который умеет только тикать нахер не нужен. Это как часы, которые умеют только показывать время. Поэтому у таймеров есть некий аналог будильника. Это регистр сравнения. Пишем в него число, как только число в счетном регистре совпало с регистром сравнения, прям как в будильнике… Смысл в том, что у микроконтроллера одно ядро, каждая строчка выполняется последовательно, шаг за шагом. Когда зазвенит «будильник» основная программа остановится. Этот процесс называется прерывание.

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

Не все таймеры имеют прерывание по совпадению, однако не припомню ни одного таймера без прерывания по переполнению, т.е. когда таймер достигает максимума и обнуляется.

Почему то очень часто возникает непонятная мне проблема, когда люди путают ШИМ и прерывание. Скорее всего проблема в том, что оба эти режима используют регистр сравнения. Честно даже не знаю, что сказать по этому поводу. Помоему тут все прозрачно.

ШИМ это ВНЕШНЕЕ, управляет чем то, выдает напряжение на ножке, за счет времени включения/выключения, он полностью независим от основной программы, он молотит сам по себе, это полностью аппаратная фича.

Прерывание это ВНУТРЕННЕЕ, выполняет кусок кода в моменты совпадения. Хоть эта фича тоже аппаратная, но она влияет только на выполнение, куска кода, никакими внешними устройствами она управлять не может.

Не понимаю как можно путать два этих режима, которые совершенно не похожи.

Теперь разберемся с термином флаг. Поразмыслим, ты пират, повесил флаг с черепом и костями, завидя тебя, всем сразу понятно, что ты собрался грабить корованы, или ты машешь белыми трусами, признавая поражение. Цель флага дать сигнал, который сразу дает тебе какую то информацию. Может ли один флаг давать несколько сигналов? Загугли семафорная азбука, двумя флажками можно замутить аж целый алфавит. Так что все зависит только от фантазии.

Итак с точки зрения программы флаг это просто переменная, с точки зрения программера флаг это переменная, которая говорит о каком то событии, абсолютно не важно каком, смысл закладываете вы. Допустим случилось нажатие кнопки, в обработчике, который проверяет это нажатие, пишем в переменную 1, или 0, или 0xff, или любое другое понятное нам число. Теперь где то в другой части программы, мы сможем прочитать этот флаг и сказать что другой части программы нужно выполниться, или не выполниться в зависимости от пожеланий разработчика, после этого стоит сбросить флаг, т.е. сделать так чтобы обработка не выполнялась снова, до следующего нажатия.

Зачем нужен подобный подход? Почему не обрабатывать все сразу? Задачи могут быть разные, может мне не критично, через сколько микросекунд будет обработана кнопка, зато критична например отправка данных, в этом случае пока не отправятся данные, не будет вызвана обработка того, что кнопка нажата, но в уме то мы знаем, что это нужно сделать.

В связи с выше сказанным, флаги должны иметь понятные имена: IsButton_Pressed(кнопка нажата?), IsLed_On(светодиод включен?) и значения флагов выбирать 1 = да, 0 = нет или true/false. Мне очень понравился подобный подход в C#, когда перед переменной Is, то сразу понятно что она булевая, т.е. содержит либо да либо нет. Вы можете не придерживаться этого подхода, но например для меня условия читаются понятно без комментариев:
if(IsButton_Pressed == true) //если кнопка нажата? Да
if(IsLed_On == false) //если светодиод включен? Нет

А вот такие флаги фтопку, автора на кол. Что такое i? Что такое 1?
if(i==1)

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

Итак обобщим, нужно для работы с таймерами:
1. Определить какой регистр счетный, т.е. как он называется. С ним придется дело иметь часто.
2. Определить регистр сравнения. С ним тоже придется часто возиться
3. Найти бит, который включает таймер/разрешает ему тикать.
4. Найти регистр с предделителем
5. Найти бит разрешающий прерывание
6. Найти биты разрешающие дрыгать ногами аппаратно

Может есть еще настройки, но на вскидку вроде все. Некоторые регистры могут быть объединены, но не вижу в этом никакой проблемы. Как видите в общем смысле настройка таймера простая.

Вы не поверите, но все это есть в даташите, прям с названиями, нужными битами и описанием. Конечно же всем лень его открыть, тогда гуглите. Инфы много, если и это лень и на AVR, и на STM есть кодогенераторы, которые сами расставят нужные биты, но помните придет тот день, когда все равно придется заглянуть в даташит. Так зачем откладывать? 🙂

В стм это можно сделать с помощью библиотек, но все таки советую курнуть даташит, хотя бы однократно. Это сильно поможет в понимании.

Теперь перейдем к самому главному. К основным проблемам, решаемым таймерами.

1. Проблема: замер длительности какого то действия — длительность удержания кнопки, длительность импульса, длительность действия/бездействия.

Решение: Вам должно быть известно примерное время, между событиями, если не известно — осциллограф вам в руки, если нет осцилла — экспериментируем. Таймер должен быть настроен так, чтобы между двумя событиями не возникало переполнения. Измеряем, прикидываем, считаем предделитель. Если без переполнения не обойтись, заводим переменную/счетчик который учитывает каждое переполнение.

Нужно подумать к чему должен быть привязан таймер. Если нужна точность, скорее всего это будет какое то прерывание. В первый заход обнуляем таймер, запускаем его, ставим флаги. Во второй заход читаем значение счетного регистра, сохраняем его. Сбрасываем флаги. Если нужно выключаем таймер.

Могут быть ситуации, когда таймер задействован еще на что то и выключать нельзя. В первый заход читаем первое значение, ставим флаг, во второй заход читаем второе значение, разницу и обработку можно посчитать по флагам в основном цикле. Если было переполнение, обрабатываем. Если точность не нужна то идея в общем то не меняется, вместо прерываний используем какие то условия в основном цикле.

2. Проблема: У меня есть таймер, но он мне не подходит, т.к. прерывание происходит слишком часто. Допустим прерывание таймера можно настроить только раз в 0.1мс, а нужно обрабатывать действие раз в 1 секунду

Решение: заводим отдельную переменную, раз в 0.1с ее увеличиваем. Когда она достигнет 10, очевидно пройдет ваша секунда. Условие может быть вроде такого:

temp_time++; 
if(temp_time > 9)
{....
обработчик
temp_time = 0;
}

3. Проблема: У меня таймер имеет только прерывание по переполнению, а мне нужно получить точный отсчет. Актуально для таймера 0 в атмеге

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

4. Проблема: мне нужен ШИМ от 10Гц до 10+кГц на атмеге, с шагом 1Гц/0.1Гц или т.п.

Решение: любимый вопрос, если вы прочли и осознали все выше описанное, но у вас остался этот вопрос, то это очень плохо. Если мозгами пораскинуть, то частота зависит от предделителей, которые у атмеги фиксированные. Ответ аппаратно никак.

Можно попробовать программно. В зависимости от требований конечно. Как? Ответ выше, заводите несколько переменных, одна считает период, другая заполнение. Если тактовой хватит, то задача реализуема, но это будет жрать процессорное время. Чем выше частота ШИМ, тем чаще проц будет зависать в прерываниях. Получится не получится считайте самостоятельно.

5. Проблема: мне нужно 2 шима, 3 шима, 100 шимов/мне не хватает каналов

Решение: любимый вопрос, который мне не понятен. Открываем даташит и смотрим сколько каналов есть у каждого таймера. Лень? Для атмеги открываем кодвизард, для стм открываем куб. Там довольно таки подробно расписано, какие каналы есть. Бери камень, у которого хватает таймеров. Если нет, см. предыдущий вопрос.

Понимаю, вопрос того как работает ШИМ тяжело воспринимается сходу, почитай тут. Не понятно, потому что есть пробелы в основах? Вперед осваивать основы. Не хочется? Тогда тут помогать бесполезно.

6. Проблема: нужно генерить сигнал с определенной частотой

Решение: берется 2 таймера. 1 это ШИМ, который своим заполнением регулирует напряжение, т.е. амплитуду сигнала, частота на которой работает ШИМ будет влиять на максимальную скорость, с которой он мог бы изменяться. Таймер2 будет влиять на период сигнала, т.е. подставлять величины ШИМ через определенные промежутки. Почитать тут

7. Проблема: как мне настроить таймер на определенную частоту.

Решение: вопрос как минимум странен, если прочитав все это он остался, почитать можно тут

8. Проблема: как мне получить напряжение ШИМ больше/меньше чем питание контроллера

Решение: через транзистор, операционный усилитель и т.п.

9. Проблема: как мне получить несколько сигналов со смещенной фазой, относительно друг друга?

Решение: в общем случае — считаем период сигналов в секундах, делим его на 360градусов. Получаем длительность 1 градуса. Думаем на сколько нужно сместить сигнал относительно другого в градусах. Теперь умножаем количество нужных градусов на длительность одного, либо пропорцией. Получим длительность в секундах. Запускаем первый сигнал, ждем нужное количество времени(см ответ на 1 вопрос), запускаем 2 сигнал.

10. Проблема: получить шим управляемый от ацп/переменной и т.п.

Решение: так и не понимаю этой проблемы, по сути из одной переменной положить в другую. В самом простом случае ацп 8битный, шим 8 битный, загоняем число из одного регистра в другой. Разная битность? Пересчитай пропорцией/отсеки не значащие биты. Когда ложить? Например в прерывании АЦП.

11. Проблема: почему при нулевом заполнении ШИМ горит светодиод?

Решение: нужно выключать таймер, по другому никак

В общем то, что вспомнил навскидку вроде все. Надеюсь не оскорбил чувства верующих, сей статьей. Все что хотелось сказать, что все эти вопросы решаются очень и очень просто, буквально за минуты/секунды. Нужно приложить немного усилий, буквально капельку.

17 комментариев: Студентам. О таймерах. Популярно.

  • Все разжевали как первокурсникам, оно Вам надо? Все равно будут спрашивать. Лучше создать раздел «Часто задаваемые вопросы» и всех отправлять туда 😀

  • Пускай эта тема и будет FAQ.

  • Мдааа….

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

    1) Электронщики — что такое и зачем нужен микроконтроллер;

    2) Программисты — чем ‘void’ отличается от, скажем, ‘int’;

    3) Электропривода — что такое датчик Холла;

    4) Отличие 3-проводной и 4-проводной трёхфазных сетях электроснабжения.

  • А связисты не отвечают на вопрос о различии пакетной передачи данных и потоковой передачи данных.

  • 9 проблема, там как я думаю помоему человек хотел сделать автомат что бы запускать 3 фазный двигатель от 1 фазы. ну это уже не светодиодом поуправлять и не студенские лаборатории. 😉

  • Мне нужен ответ. У меня в Attiny 1 таймер, в регистр сравнения я изменяя OCRA изменяю угол фазы открытия семистора. Каким образом мне еще можно отсчитывать определенные интервалы времени… По переполнению? Но у меня изменяется регистр совпадения от 0x00 до 0xFF;

  • Jman ответ есть в статье, это же очевидно. У вас есть один таймер и несколько задач, которые он решает. Значит вариант один: заводите 2 переменные, которые увеличиваются например раз в 1мс, это как раз регулирует таймер. А уже относительно этих двух переменных решаете свои задачи.

  • Делаю прерывание по совпадению раз 1 мс…Регистр не трогаю. Изменяю только переменные…
    // Timer 0 output compare A interrupt service routine. Совпадение каждые 1 мс;.
    interrupt [TIM0_COMPA] void timer0_compa_isr(void)
    {
    clock++;
    if (clock > 5000)
    triac_angle_open ++; // Угол открытия симистора (считаем время);
    if (triac_angle_open>10) // 10мс.
    {
    LED_STATUS = ~LED_STATUS;
    //подаем импульс на симистор;
    TRIAC_KICK = 1;
    delay_us(t_TRIAC_PULSE);
    TRIAC_KICK = 0;
    triac_angle_open=0;
    //TCCR0A = 0;
    }

    }
    Я правильно Вас понял?

  • В общем смысле да, только причесать надо по мелочи, например это лучше убрать delay_us(t_TRIAC_PULSE);

  • Спасибо. Теперь я понял. Просто я из-за непонимания изменял регистр сравнения. А задержку убрать программную потому, что это не комильфо? Я где-то слышал, что формируют пачку ШИМ для отпирания симистора.

  • если задержка не мешает то можно и так оставить, но вообще так как она в прерывании, то будет влиять

  • Спасибо за разъяснения! Очень полезный ресурс для чайников вроде меня.

  • Все разжевали как первокурсникам, оно Вам надо?….
    😈 Если вы умеете… 👿
    ДА надо . Я электронщик со стажем ну уже год не могу в ехать в STM на С. ПИК(8/16) програмил на АСЕМБЛЕРЕ . Там на пример загружай из таблиц, и получай любой интервал до переполнения таймера(С учётом тактов выполнения процедур).
    Таблици
    №.- Счёт до переполнения. — Маска pin
    0 — 65535-128 — Пауза 0001
    1 — от 0 до Fvar — Фаза А 1001
    *1 — от 0 до Fvar — Фаза В 0101
    *1 — от 0 до Fvar — Фаза C 0011
    2 — Fvar/2 //задержка остановки. Стоп 0000
    При Fvar=0 частота минимальна (Период =3*65536) при Fvar=max=400 Частота оборотов =400Гц / 3 фазы / 6 чередований
    (400/3/6)*60С=1300об\м
    Последовательность Прерываний (2МГц кварц min= 2 000 000/(65536 — 2 222)=900Hz >> Частота оборотов =900 / 3 фазы / 6 чередований=50
    оборота в СЕКУНДУ . 50*60=3 000(Зашкальная цифра, никогда не проверялась на практике)
    Последовательность Прерываний (2МГц кварц min= 2 000 000/(2^16 — 0)=30.5Hz >> Частота оборотов =30.5Гц / 3 фазы / 6 чередований=1,7 оборота в СЕКУНДУ.( автозамена инструмента,нарезка резьбы.)
    ШИМ отдельно регулировал общий ток фаз, через шаговый ШПИНДЕЛЬ двигатель1800W.
    При этом при всём у ЦП оставалась куча времени для Вывода : Значений тока АЦП на 3х7-ми сегментный дисплей ,приём настроек RS -458 и управлением 10-ми реле.
    ПС Поделился если кому будет полезно. АВТОРУ СПАСИБО !!!

  • 你好谢了 :mrgreen:

  • Чёткая статья!
    Мне лично на данный момент надо разобраться с разными методиками и терминологией, например флаги, я что-то подобное делал, но это лишь было то к чему я пришел включая фантазию, а зачем придумывать велосипед, если есть готовые и проверенные методики….

  • Я вообще к контроллерам отношения не имею, я начинающий программист и так мимо делом сюда заглянул. Но даже я кое-что понял из статьи, автор хорошо объясняет, с юмором 🙂 Респект! И удачи вам всем, контроллерщики 😎

    p.s. про void надо взять на заметку

  • мне ваша статья понравилась.Кстати я написал программку в as7(в студии)управление ацп шим осуществляю без переменых OCR2=~ADC/4;может это неправильно.но работает в железе я вписал этот код в прерывании.Буду дальше изучать ваши статьи.Я по жизни ученик.Не программист .Электрик.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Последние комментарии
  • Загрузка...
Счетчик
Яндекс.Метрика