Свежие обсуждения
Микроконтроллеры

Как программно уменьшить частоту в 10 или 12 раз?

1 2

Смысл в том, что нужно в одном прерывании по таймеру переключать два выхода (меандр), но один с частотой меньше другого в 10 или 12 раз.

Пробовал вот такой код: Меандр чёткий в обоих случаях и частота на D.1 меньше частоты на D.2 ровно вдвое. И если t==4 или t==8 - тоже нормально.

interrupt [TIM0_COMP] void timer0_comp_isr(void)
{
t++;
PORTD.2^=1;

if(!(t%2))
{
PORTD.1^=1;
}}

А вот если сделать (t%10) или (t%12), то почему то на переходе переменной t от 255...10 импульс вдвое укорачивается; а почему так, не могу понять и как победить это тоже?

 

Вот так, например при t%10

 

Попробовал, если t%10, ограничивать t от 0 до 250 - помогает, но для 12 уже - нет. Вот ерунда-то. Может как-то по другому можно?

 

interrupt [TIM0_COMP] void timer0_comp_isr(void)
{
t++;
PORTD.2^=1;

if(t>=10)
{
PORTD.1^=1;
t=0;
}}

 

Не написал ранее, прошу прощения, но t используется в программе как общий счётчик и его желательно не ограничивать до 10(12). так нормально, но надо будет ещё одну переменную вводить

 

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

 

chav1961: так что вместо одной команды аппаратного сложения получите полторы сотни команд на программное деление. В обработчике прерываний только делениями и заниматься
А как тогда лучше сделать в таком случае, если надо в одном обработчике переключать одновременно два выхода с отличающейся частотой? Как в варианте Zandy (т.е. лишний счётчик - меньшее зло)? А команду % можно заменить на что-то, чтоб счётчик не ограничивать?
Вообще это тот случай, наверное, когда короче не значит быстрее , как в теме про swith...case if..else высказались.

 

А два счетчика нельзя сделать? Или с ОЗУ напряг?

 

chav1961: А два счетчика нельзя сделать? Или с ОЗУ напряг?
Пока нет, не напряг, но может разрастись в недалёком будущем, поэтому стараюсь сразу экономить (да и чтоб не плодить на каждый "чих" переменные, а то сам потом с трудом разберусь в программе). А так пробую сейчас с двумя счётчиками, но без операции "%", т.к. проверил, код по объёму всё-таки меньше получается после компиляции, чем с % и, действительно, аппаратно процессор не умеет делить (аппаратно его АЛУ вообще мало что умеет).

 

Digital: чтоб не плодить на каждый "чих" переменные
А чего их экономить-то?
Помнится, когда на ассемблере баловался, у меня почти все переменные были глобальные.
Когда начал баловаться на Си, осознал, что локальные переменные - отличная штука. Вроде бы они есть, а на самом деле нет. Т. е. места в ОЗУ не занимают. Конечно, в вашем случае t должна быть глобальная, но тем не менее. А можно часть регистра использовать, если уж приперло. Вам же всего до 10 считать - четыре бита. Считывать и записывать в локальную переменную через маску. А работать с локальной переменной в прерывании, как с обычным charом. Только следить, чтобы за четыре разряда не зашкаливало.
Конечно, все это извращения. Выбрать контроллер помощнее - и забыть о скупердяйстве. Я конечно понимаю, хочется минимальными средствами обойтись, чтобы все впритирочку выходило. Сам этим грешен. Тоже не люблю многоногих сколопендр, особенно, когда ноги и порты эти нафиг не нужны, а приходится выбирать только ради мощи.