Сообщение от Sany81
|
а вот на прямую с портом работать не получится, т.к. у меня на порту сидит регистр сдвига(3 ноги) а он уже в свою очередь управляет устройствами(8шт)
|
Выталкивать в сдвиговый регистр нолики/единички тоже можно без вспомогательной переменной.
Сообщение от Sany81
|
Эта процедура длится тоже очень продолжительное время, в итоге 1 раз в секунду мой ШИМ "зависает" на некоторое время в положении лог "0" либо лог "1".
Можно ли как то этого избежать?
|
Только переместив формирование ШИМ в прерывание, к чему, как я вижу, Вы в результате и пришли:
Сообщение от Sany81
|
Содержимое функции pwm_int() перенес в вызов по прерыванию от таймера. И получил наконец то нужный мне результат, частота ШИМ стала примерно 150 Гц
|
Сообщение от Sany81
|
Но pwm_counter не может быть локальной, иначе каждый раз при входе в мою функцию, эта переменная будет всегда обнулена и тогда смысл в этой переменной отпадает так же как и смысл самой функции.
|
Это кто-то очень поторопился с советом.
Можно попробовать либо сделать её регистровой, либо локальной
и статической.
Сообщение от Sany81
|
С АСМом к сожалению не дружу.
|
А тут большого умения не потребуется - ведь нужно не писать на нём, а только читать, во что компилятор превратил операторы Си. Там сразу будет видно, загружается ли переменная каждый раз заново, или один раз, при первом к ней обращении, или вовсе хранится всегда в одном регистре.
Сообщение от gary2007
|
Времени на прерывание у вас на все про все всего 256 тактов, после этого пойдет уже следующее прерывание
|
Это верно только в простейшем случае и при единичном прескейлере.
Т.к. частота ШИМ невелика, можно попытаться разрешить вложенные прерывания и тогда времени на исполнение процедуры формирования ШИМ будет больше. Но это нужно рассматривать всё множество возможных в системе прерываний, кто там кому может нааа... пятки наступать.
Сообщение от Sany81
|
частота ШИМ стала примерно 150 Гц, этого вполне хватит под мои нужды. Только не могу понять почему так произошло
|
Потому что раньше между вызовами pwm_int() отрабатывали все операторы внутри "while (1){...}" и вызывались некоторые прописанные там функции, а теперь между вызовами pwm_int() никто не вызывается, а интервал задаётся таймером.
Сообщение от Sany81
|
у меня на дисплей например выводится информация
"10:45:12 21.5'"
|
Сообщение от Sany81
|
Большую часть времени пожирает функция sprintf. ... Пробовал воспользоваться функцией с переменным числом параметров, ...
|
Во-первых, с какого перепугу понадобилось переменное число параметров?
Во-вторых, когда требования к объёму кода и скорости выполнения выходят на первый план, конечно неразумно пользоваться printf'ами.
Почитайте
вот здесь про такие функции. Скорость и компактность редко сочетаются с универсальностью.
У Вас формат строки фиксированный, поэтому советую использовать набор коротких и быстрых вызовов вместо sprintf.
Что-то типа такого:
Код:
|
StrToUART(_int2str(Hours) );
ChrToUART(':');
StrToUART(_int2str(Minutes));
ChrToUART(':');
StrToUART(_int2str(Seconds)); |