Цитата(prottoss @ Aug 30 2006, 21:12)

Цитата(SasaVitebsk @ Aug 31 2006, 01:42)

Си прогу я привёл просто так. Обсуждаемая явно ассемблерная. Ваша на Си использует регистры. Просто Вы не знаете.

Использует стэк. Длинее по коду. Так в чём выигрыш?
Не хотел больше отвечать на обидные слова в мой адрес, и, тем более, оскорбления и насмешки (касается
defunct и иже с ним), но Вы туда же лезете) Я знаю, что программа использует регистры. Когда Вы привели пример на Си, я же не напоминал Вам о том, что она использует регистры, то есть я не посчитал Вас идиотом, так?
Поскольку вы написали, что это касается и меня, то вынужден ответить на этот пост.
Ваши "проблемы" исходят от вас же, почитайте ветку с начала "со стороны". Или попросите почитать друга, но не говорите ему вашего ник-нейма и потом спросите его, кто на его взгляд в этой ветке вел себя хамовато. Если вы чуствуете что в ваш адрес было сказано что-то уж очень обидное, тогда может быть в пора почитать
это?
Цитата
Для тех, кто на бронепоезде, повторю еще раз, что не вижу смысла пользовать прерывание для ожидания прохождения отрезка времени и при этом висеть в цикле...
Зачем повторять ваше мнение многократно, к тому же отдельно тем кто на бронепоезде или в танке и т.п. Совсем тупых, чтобы возникала необходимость в многократном разжевывании вашего мнения, полагаю здесь нет. С вашим мнением уже ознакомились, еще на первой странице этой ветки.
Цитата
В чем выйгрыш? Да ни в чем, просто я привел то же самое, что и Вы но без прерываний.
Выигрыш в том, что с прерыванием можно легко организовать HAL (Hardware Abstraction Layer) и т.о. заданные интервалы задержек не будут зависеть от частоты кварца и от латентности других прерываний.
пример:
задаем в hal константу - чатоту чипа.
задаем в hal формулу расчета делителя для таймера для получения периода в 1ms.
пишем в hal обработчик "системного таймера" и отводим две переменных: одну под счетчик (системное время) и одну под таймер (декремент до нуля).
далее в программах пользуемся этими переменными и всегда знаем что счетчик считает миллисекунды, а таймер отнимает миллисекунды. И не заморачиваем себе голову тем сколько циклов надо отмерять для получения задержки в N ms.
При переносе проекта под другой процессор, просто немного подправляем hal - меняем частоту, меняем формулу, меняем синтаксис обработчика прерывания, а все остальное оставляем как было. И все задержки используемые в любых других модулях остаются правильными.
Не забываем о том, что такая задержка будет много точнее холостых циклов за счет независимости от других прерываний и их латентности.
Иллюстрация: требуется организовать задержку в 100 ms при частоте чипа 1 Mhz и при наличии в программе 5-ти обработчиков прерываний (_IRQ0_handler, _IRQ1_handler, ... _IRQ4_Handler)
с длительностью обработки:
_IRQ0 - 50 циклов (цикл для AVR = 1 такт)
_IRQ1 - 100 циклов
_IRQ2 - 150 циклов
_IRQ3 - 200 циклов
_IRQ4 - 250 циклов.
Допускается, что за 1 ms каждое из прерываний может произойти не более одного раза.
Вопрос каким способом мы можем наиболее точно организовать задержку в 100ms?
1. Рассмотрим способ предлагаемый prottoss. (без использования прерываний):- рассчитываем количество циклов Nc требуемое для организации задержки в 100ms на 1Mhz
Nc = 1Mhz * 0.1c = 1*10^5
формируем и запускаем функцию задержки на 1*10^5 циклов.
А теперь оценим точность.
С учетом того, что в системе имеется 5 обработчиков прерываний, и каждое из них может произойти раз в 1ms, то в наихудшем случае за 100 ms, каждое и прерываний произойдет 100 раз. Суммируем количество циклов требуемое на обработку всех этих прерываний Nirqc (ведь
в момент обработки прерываний, функция отсчитывающая задержку приостанавливается).
Nirqc = (50 + 100 + 150 + 200 + 250) * 100 = 7.5*10^4
т.о. 75 тыс циклов не будут нами учтены функцией задержки, врезультате чего вместо 1*10^5 циклов наша функция задержки пропустит 1*10^5 + 7.5*10^4 = 1.75*10^5 циклов, а это в 1.75 раза больше чем требовалось. И вместо задержки в 100ms у нас получится задержка в 175ms.
Суммарная точность получится:Acc = +-(7.5*10^4) *100%/ (1*10^5) =
+-75% 2. Рассмотрим способ обсуждаемый в сабж.- пишем еще один обработчик прерывания либо модифицируем существующий. который будет вызываться раз в 1 ms и декрементировать до нуля определенную переменную. Код такого обработчика:
Код
if (__Timer > 0)
__Timer -= 1;
- формируем функцию задержки как:
Код
__Timer = 100;
while (__Timer) __no_operation;
Оценим точность:
за одну ms проц выполняет 1mhz * 10^(-3)с = 1000 циклов. Суммарная нагрузка обработчиков прерываний в 1 ms составляет (50 + 100 + 150 + 200 + 250) = 750 циклов, т.о. наше прерывание с периодом вызова 1ms в худшем случае вызовется с отставанием на 750 циклов, если будет иметь наинизший приоритет. Отставание в 750 циклов и будет единственной погрешностью нашей функции задержки с использованием прерываний, поскольку наше прерывание выполняется через каждую 1ms.
Итого наша функция задержки с использованием прерывания обеспечит точность: Acc = +-(0.75ms)*100%/100ms =
+-0.75%Ну так где выше точность?
prottoss, Вы поняли разницу или вы на бронепоезде?
Цитата
Если не понимаешь о чем говорит человек, то стоит сначала осмыслить его слова, и уж потом умничать.
Вот именно. Хороший совет вы дали. Следуйте ему.