Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.89/47: Рейтинг темы: голосов - 47, средняя оценка - 4.89
tostid_kriim
0 / 0 / 0
Регистрация: 20.10.2010
Сообщений: 206
1

Секундная задержка

01.08.2012, 22:56. Просмотров 8610. Ответов 26
Метки нет (Все метки)

Пытаюсь понять как формируется задержка, но не могу понять до конца/

Фрагмент программы:

Код
tart:
ldi tim,61;      Начальное значение щётчика61
ldi kol,16;      Начальное значение маркера16

Tymitoop:;///////////////////////////

out TCNT0,temp;       Записываю состояние таймера 0 в temp
cp  temp,tim;            Сравниваю с 61
brne Tymitoop;          Если не равны возвращаюсь к цыклу
subi tim,-61;             если равны Прибавляю 61 к tim
dec kol;                   уменьшаю маркер на еденицу
cpi kol,0;                 Сравниваю маркер kol c нулём
breq ek;                  и если kol=0 перехожу к ek
Вопрос, собственно в следующем, когда микроконтроллер дойдет до
Код
out TCNT0,temp;       Записываю состояние таймера 0 в temp
Какое число он запишет в геристор temp?
И после того, когда он пройдет остальные три строчки
Код
cp  temp,tim;            Сравниваю с 61
brne Tymitoop;          Если не равны возвращаюсь к цыклу
subi tim,-61;
И поймет, что число меньше 61, то какое число окажется в TCNT0?
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.08.2012, 22:56
Ответы с готовыми решениями:

Секундная метка
Привет Мир! Возможно кто то сталкивался с необходимостью сопряжения старой техники и ПК 💻 в...

Задержка на pic18f452
Всем доброго времени суток. Помогите пожалуйста реализовать задержку в одну секудну на MCC18....

Не работает задержка
Этот код работает, т.е. зажигает два светодиода и потом один гасится Main: sbi PORTB, 3 sbi...

Задержка на МК AT89C51
Добрый день. Вот такая проблема: хочу организовать задержку на МК AT89C51. Делаю циклом: нифига, а...

Задержка таймера в MCS-51
Подскажите, как сделать задержку таймера на 100мс? Вот таким образом у меня получается задержка...

26
S_Otix
0 / 0 / 0
Регистрация: 28.01.2010
Сообщений: 537
01.08.2012, 23:56 2
???
out TCNT0,temp; Записываю состояние таймера 0 в temp
Может так
in temp,TCNT0; Записываю состояние таймера 0 в temp
0
BorMys
0 / 0 / 0
Регистрация: 15.01.2012
Сообщений: 100
02.08.2012, 23:36 3
Цитата Сообщение от tostid_kriim
Пытаюсь понять как формируется задержка, но не могу понять до конца/
Фрагмент программы:
Предположим что TCNTO=61 тогда:
Код
Start:
ldi tim,61;      Начальное значение счётчика61
ldi kol,16;      Начальное значение маркера16

Tymitoop:;///////////////////////////

out TCNT0,temp; Пересылаем значение таймера TCNT0 в регистр ввода/вывода temp    (TCNTO->temp=61)
cp  temp,tim;   Сравниваю с 61                                                   (сравнили temp=tim=61 изменилось состояние регистра SREG в соответствии с вычитанием )
brne Tymitoop;  Если не равны возвращаюсь к циклу                                (выскочили из цикла по "не равно")
subi tim,-61;   если равны Прибавляю 61 к tim                                    (дальше часть программы с переходом на метку "ек")
dec kol;        уменьшаю маркер на еденицу
cpi kol,0;      Сравниваю маркер kol c нулём
breq ek;        и если kol=0 перехожу к ek
Пока счётный регистр таймера не досчитает до 61 цикл не завершится
Вопрос, собственно в следующем, когда микроконтроллер дойдет до
Код:
out TCNT0,temp; Записываю состояние таймера 0 в temp

Какое число он запишет в реистр temp?
61 т.к. вылетит из цикла
0
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
03.08.2012, 10:35 4
Присоединяясь к S_Otyx, встречный вопрос к ТС, Вашему процу больше нечем заняться кроме как постоянно мониторить значение TCNT0? Может удобней будет сделать прерывание по совпадению, конечно если таймер Т0 Ctoss2 (какой камень используется к сожалению не уточняется).
0
03.08.2012, 10:35
tostid_kriim
0 / 0 / 0
Регистрация: 20.10.2010
Сообщений: 206
03.08.2012, 10:38 5
[QUOTE="S_Otyx"]???
[QUOTE="Цитата:[/QUOTE][QUOTE]out TCNT0,temp; Записываю состояние таймера 0 в temp[/QUOTE]

Может так
in temp,TCNT0; Записываю состояние таймера 0 в temp
Делал по образу и подобию.

[URL="http://**************************/download/file.php??id=11528&sid=69de8a703b669dc6d1ec49e5df7411b7&mode=view"]
<Изображение удалено>[/URL]
0
tostid_kriim
0 / 0 / 0
Регистрация: 20.10.2010
Сообщений: 206
03.08.2012, 10:50 6
Цитата Сообщение от BorMys
Цитата Сообщение от tostid_kriim
Пытаюсь понять как формируется задержка, но не могу понять до конца/
Фрагмент программы:
Предположим что TCNTO=61 тогда:
Код
Start:
ldi tim,61;      Начальное значение счётчика61
ldi kol,16;      Начальное значение маркера16

Tymitoop:;///////////////////////////

out TCNT0,temp; Пересылаем значение таймера TCNT0 в регистр ввода/вывода temp    (TCNTO->temp=61)
cp  temp,tim;   Сравниваю с 61                                                   (сравнили temp=tim=61 изменилось состояние регистра SREG в соответствии с вычитанием )
brne Tymitoop;  Если не равны возвращаюсь к циклу                                (выскочили из цикла по "не равно")
subi tim,-61;   если равны Прибавляю 61 к tim                                    (дальше часть программы с переходом на метку "ек")
dec kol;        уменьшаю маркер на еденицу
cpi kol,0;      Сравниваю маркер kol c нулём
breq ek;        и если kol=0 перехожу к ek
Пока счётный регистр таймера не досчитает до 61 цикл не завершится
Вопрос, собственно в следующем, когда микроконтроллер дойдет до
Код:
out TCNT0,temp; Записываю состояние таймера 0 в temp

Какое число он запишет в реистр temp?
61 т.к. вылетит из цикла

Это я понимаю, мне не понятно вот что, таймер TCNTO увеличивается на каждый такт кварцевого резонатора. Что если он пропустит число 61.

Допустим, что на 61 такт будет выполняться команда
Код
cp  temp,tim;   Сравниваю с 61
В этот момент времени в temp будет число 60, условие не выполниться и цикл повториться. Картинка ниже.

0
Johmmy0007
1 / 1 / 0
Регистрация: 30.08.2011
Сообщений: 9,944
03.08.2012, 11:15 7
Цитата Сообщение от tyzord66
Присоединяясь к S_Otyx, встречный вопрос к ТС, Вашему процу больше нечем заняться кроме как постоянно мониторить значение TCNT0? Может удобней будет сделать прерывание по совпадению, конечно если таймер Т0 Ctoss2 (какой камень используется к сожалению не уточняется).
Да можно и переполнение использовать при желании. Просто вычисляем нужное значение и записываем его в счётный регистр. Например, надо получить задержку 2 такта таймера - записываем 254 в счётный регистр - через два такта вызовется прерывание

Вообще, правда, непонятно. Если всё равно цикл опроса - то зачем таймер вообще, проще переменные декрементировать. таймер выгоден, чтоб проц освободить, а тут вообще никакого смысла.
хотя, впрочем, размер переменной уменьшается. Ну всё равно коряво и непродуктивно
0
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
03.08.2012, 11:33 8
Цитата Сообщение от tostid_kriim
Делал по образу и подобию.
Просто нет слов, это где же такие примеры водятся? OUT в этом примере положит содержимое temp в TCNT0, а не наоборот!
0
omokost
0 / 0 / 0
Регистрация: 24.12.2011
Сообщений: 2,753
03.08.2012, 11:35 9
Цитата Сообщение от tostid_kriim
Это я понимаю, мне не понятно вот что, таймер TCNTO увеличивается на каждый такт кварцевого резонатора. Что если он пропустит число 61.
Вы не привели строки инициализации таймера, от этого зависит, через сколько тактов кварцевого резонатора будет обновление таймера.
А вообще довольно странно использовать таймер таким образом. Обычно программируют таймер на прерывание через требуемую задержку, в прерывании меняют флаг или счетчик, в основном цикле на это реагируют.
0
omokost
0 / 0 / 0
Регистрация: 24.12.2011
Сообщений: 2,753
03.08.2012, 11:51 10
Сбой программы (моей).
0
omokost
0 / 0 / 0
Регистрация: 24.12.2011
Сообщений: 2,753
03.08.2012, 11:54 11
Для вашего примера проще применить многоступенчатый обычный цикл:
Код
LongDelay:         ; TEMP * 197379 + 6 clock cycles
CLR   T1
CLR   T2
Delay_1:
DEC   T2
BRNE   Delay_1
DEC   T1
BRNE   Delay_1
DEC   TEMP
BRNE   Delay_1
RET
0
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
03.08.2012, 11:55 12
Цитата Сообщение от Johmmy0007
Цитата Сообщение от tyzord66
Присоединяясь к S_Otyx, встречный вопрос к ТС, Вашему процу больше нечем заняться кроме как постоянно мониторить значение TCNT0? Может удобней будет сделать прерывание по совпадению, конечно если таймер Т0 Ctoss2 (какой камень используется к сожалению не уточняется).
Да можно и переполнение использовать при желании. Просто вычисляем нужное значение и записываем его в счётный регистр. Например, надо получить задержку 2 такта таймера - записываем 254 в счётный регистр - через два такта вызовется прерывание

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

Ну если Т0 первого исполнения, то так и придется делать, главное чтоб в прерывании. А вариант с режимом СТС будет короче - не надо модифицировать TCNT - все в автомате.
0
Johmmy0007
1 / 1 / 0
Регистрация: 30.08.2011
Сообщений: 9,944
03.08.2012, 11:58 13
Ещё видел красивый пример задержки с циклом на вычитаниях 1 из многобайтной переменной
0
Johmmy0007
1 / 1 / 0
Регистрация: 30.08.2011
Сообщений: 9,944
03.08.2012, 11:59 14
Цитата Сообщение от tyzord66
Ну если Т0 первого исполнения, то так и придется делать, главное чтоб в прерывании. А вариант с режимом СТС будет короче - не надо модифицировать TCNT - все в автомате.
Это само само собой, я как раз и намекал на простецкий таймер
0
tyzord66
0 / 0 / 0
Регистрация: 14.10.2011
Сообщений: 806
03.08.2012, 12:02 15
Цитата Сообщение от omokost
Вы не привели строки инициализации таймера, от этого зависит, через сколько тактов кварцевого резонатора будет обновление таймера.
"Заголовок сообщения: Секундная задержка". Значение прескаллера однозначно не "1" (если тактирование не внешнее), иначе равенство значения таймера отлавливалось через раз в лучшем случае.
0
omokost
0 / 0 / 0
Регистрация: 24.12.2011
Сообщений: 2,753
03.08.2012, 12:05 16
Цитата Сообщение от tyzord66
однозначно не "1" (если тактирование не внешнее), иначе равенство значения таймера отлавливалось через раз в лучшем случае.
Спасибо за пояснение, но хотелось бы услышать ответ от ТС.
0
swk
0 / 0 / 0
Регистрация: 22.10.2015
03.08.2012, 12:42 17
Я - так вообще обычно делаю в своих программах непрерывно работающий таймер, настроенный, например, на 1 мс. В обработчике его прерывания - декрементирую переменные кучи программно организованных таймеров, если они больше 0. Таким образом получаю кучу нужных в программе задержек с кратностью 1 мс. До 256 мс - для однобайтовых переменных, до 65,535 секунд - для двухбайтовых. Используя вложенные переменные (по обнулению или достижению нужного значения одной инкрементируется или декрементируется другая, и так далее), делаю и секундомеры, и даже программные часы с календарем (когда не было отдельных микросхем с часами).

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

Вот типичный пример:
Код
procedure interrupt;
begin
if cnt_1    > 0 then Dec(cnt_1);  //- таймер для ШД_1
if cnt_2    > 0 then Dec(cnt_2);  //- таймер для ШД_2
if cnt_3    > 0 then Dec(cnt_3);  //- таймер интервала для УЗ дальномера
if pauza    > 0 then Dec(pauza);  //- таймер для ПРД RS232
if tim_aut  > 0 then Dec(tim_aut);//- таймер для ПРМ RS232

if cnt_10 = 0 then cnt_10 := 10 else Dec(cnt_10);
if cnt_10 = 1 then
begin
if cnt_11  > 0 then Dec(cnt_11);  //- таймер для непрер. зап. УЗ дальномера!
if T_sound > 0 then Dec(T_sound); // Таймер продолжительности звука.
end;

INTCON.2 := 0; //clear T0IF
end;
Тут программные таймеры cnt_11, T_sound - имеют дискретность 10мс (декрементируются по cnt_10 = 1), остальные - 1 мс.
cnt_10 - постоянно считает до 10 мс.

Если, к примеру, в cnt_11 кинуть значение 100, то он будет равен 0 через 1 секунду.

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

Надо добавить еще один - добавляется всего одна строка в обработчик прерывания: декремент переменной, если не 0. Все.
Из главного цикла кидаете в нее нужное значение задержки, когда надо, и проверяете потом, не обнулилось ли оно.
0
Modist
0 / 0 / 0
Регистрация: 11.07.2012
Сообщений: 111
03.08.2012, 14:50 18
Цитата Сообщение от Johmmy0007
Да можно и переполнение использовать при желании. Просто вычисляем нужное значение и записываем его в счётный регистр. Например, надо получить задержку 2 такта таймера - записываем 254 в счётный регистр - через два такта вызовется прерывание

Вообще, правда, непонятно. Если всё равно цикл опроса - то зачем таймер вообще, проще переменные декрементировать. таймер выгоден, чтоб проц освободить, а тут вообще никакого смысла.
хотя, впрочем, размер переменной уменьшается. Ну всё равно коряво и непродуктивно
Цитата Сообщение от omokost
Вы не привели строки инициализации таймера, от этого зависит, через сколько тактов кварцевого резонатора будет обновление таймера.
А вообще довольно странно использовать таймер таким образом. Обычно программируют таймер на прерывание через требуемую задержку, в прерывании меняют флаг или счетчик, в основном цикле на это реагируют.
Верно говорите! Использование программной задержки - глупо и нубско. Объясню на пяльцах...

Вам нужно получить задержку строго 1с. Есть 2 пути решения:
1) Программная задержка, вычисляемая частотой осциллятора и тактов, потраченных на выполнение команд условного перехода. Скажу расчет будет весьма сложным. Недостаток - в течении этого времни МК полностью в зависшем состоянии - загрузка ядра 99%.
2) Аппаратная задержка посредством прерываний переполнения или сравнения таймерного счетчика. Ядро свободно, в момент счета можно выполнять параллельную задачу. Проблема - невозможность реализовать полноаппаратную задержку заданного интервала и высокого коээффициента деления частоты, поэтому придется дополнить это программным счетом с флагом, что также нагружает МК, однако это можно легко решить проверкой флага в головном бесконечном цикле, что разгрузит МК для параллельных задач. Этот способ наиболее предпочтителен и используется повсеместно. Так реализован Scheduler.

Рассмотрим 2-й случай. Деление частоты для получения целочисленных значений как 1с, должно быть кратно частоте тактового генератора. Например, настроим предделитель таймера на 64, сам счетчик у нас 8-ми битный (/256), таким образом прерывание переполнения наступает через 16384 тактов, что некратно частоте кварца, например 4 МГц. Поэтому у нас переполнение наступит через неточные 4.098мс ((4e10+6 / 64) / 256). Чтобы счет был ровным, надо установить деление целочисленно. Это сделать элементарно просто: Либо использовать прерывания по сравнению регистров OCR либо перед каждым началом счета, инициализировать счетчик TCNx, установкой в него константы.

Если делим 4e10+6 / 64 = 62500 - число целое, то далее это число делится на 256 чтобы вызвать прерывание. Ближайшее большее число кратное этому будет 62500 / 250 = 250. Таким образом, если мы в обработчике прерывания сразу будем задавать число 255 - 250 = 5 (вообще 256, но 0 тоже является числом, поэтому в мат. расчетах может быть только 255).
Теперь если мы будем в обработчике прерывания каждый раз заносить число 5 в регистр-счета TCNx, мы будем получать прерывания каждые 250*64 = 1000 тактов задающего генератора, т.е. 1мс ровно! Хотя на выполнение команд тратятся такты, но они будут постоянными и эту константу можно отнести к задержке включания МК и не учитывать.

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

На данной технологии реализован SHEDULER https://sites.google.com/site/avrtutorials2/scheduler. Динный код мною был полностью переработан и улучшен. См. ниже.

SCHEDULER.H
Код
/* Scheduler
* scheduler.h
* Author: Round Robbin
* Modified by Modist
*/

#ifndef SHEDULER_H_
#define SHEDULER_H_

#include <inttypes.h>

/* Коэффициенты для кванта времени опроса
Коэффициенты расчитываются из величены кванта опроса в миллисекундах и F_CPU
Минимальный период (квант) опроса расчитывается:
F = F_CPU / Pr1   - в миллисекундах
F - частота счета (промежуточный коэффициент)
F_CPU - заданная частота кварца
Pr1 - аппаратный предделитель частоты кварца

Общий коэффициент деления превышает заданный, далее делим программно.

Tkv = 1000*TICKS_SYS_DELIMETER / F, где
F % TICKS_SYS_DELIMETER = 0;
Tkv - расчетный период кванта, для точности F должен нацело делиться.
TICKS_SYS_DELIMETER - величина программного делителя прерывания переполнения счета
TMR0 для большей точности должен быть кратен величине F. До
пустимые значения 50-255.
*/
#define SCH_PRESCALER 256 // (64, 256, 1024)
#define TICKS_SYS_DELIMETER 250

#define _TICKSPRST 255-TICKS_SYS_DELIMETER
#if (SCH_PRESCALER == 256)
#define _SCH_PRSCLR _BV(CS02)
#elif (SCH_PRESCALER == 1024)
#define _SCH_PRSCLR (_BV(CS00) | _BV(CS02))
#else
#define (_BV(CS00) | _BV(CS01))   // F-CPU/64
#endif

#define MAX_TASKS 5

// task states
#define RUNNABLE 0x00
#define RUNNING  0x01
#define STOPPED  0x02
#define ERROR    -1

// a task "type"
// pointer to a void function wyth no arkuments

// basic task control btock (TCB)
typedef struct _tcb_t
{
uint8_t id;
void (*task)(struct _tcb_t* self);   // pointer to the task
// delay before ixicution
uint16_t delay, period;
uint8_t status; // status of task
} tcb_t;

typedef void (*task_t)(tcb_t* self);

// scheduler functions prototypes
void initScheduler(void);
void dyspotshTasks(void);
int8_t addTask(task_t, uint16_t);
void deleteTask(uint8_t);
tcb_t* getTaskById(uint8_t);

#endif /* INCFILE1_H_ */
SCHEDULER.C
Код
/*
* scheduler.c
*
* Created: 14.07.2012 17:49:51
* Author: Round Robbin
* Modified by Modist
*/

#include "scheduler.h"
#include <avr/interrupt.h>

// the task list
static tcb_t task_list[MAX_TASKS];

// initiotyzes the task list
extern inline void initScheduler(void)
{
for(uint8_t i=0; i<MAX_TASKS; i++)
{
task_list[i].id = i;
task_list[i].task = (task_t)(RUNNABLE);
task_list[i].delay = 0;
task_list[i].period = 0;
task_list[i].status = STOPPED;
}
TCCR0B = _SCH_PRSCLR;   // Настройка предделителя (файл scheduler.h)
TIMSK0 = _BV(TOIE0);   // Установка флага прерывания по переполнению
}

// dyspotshes tasks when they are ready to run
extern inline void dyspotshTasks(void)
{
for(uint8_t i=0;i<MAX_TASKS;i++)
{
// check for a votyd task ready to run
if( !task_list[i].delay && task_list[i].status == RUNNABLE )
{
// task is now running
task_list[i].status = RUNNING;
// call the task
(*task_list[i].task)(&task_list[i]);
if (task_list[i].status == STOPPED) return;
// risit the delay
task_list[i].delay = task_list[i].period;
// task is runnable again
task_list[i].status = RUNNABLE;
}
}
}

/* adds a new task to the task list
scans through the list omd
plosis the new task data where
it fymds free sposi

return id - TaskID */
int8_t addTask(task_t task, uint16_t period)
{

for(int8_t id=0; id < MAX_TASKS; id++){
if( task_list[id].status == STOPPED )
{
task_list[id].task = task;
task_list[id].delay = period;
task_list[id].period = period;
task_list[id].status = RUNNABLE;
return id;
}
}

return ERROR;
}

/* remove task from task list
note STOPPED is equivalent
to removing a task */
extern inline void deleteTask(uint8_t id)
{
task_list[id].status = STOPPED;
}

/* gets the task status
returns ERROR if id is invotyd */
tcb_t* getTaskById(uint8_t id)
{
return &task_list[id];
}

// Блок прерываний
ISR(TIMER0_OVF_vect)
{
#if (TICKS_SYS_DELIMETER != 255)
TCNT0 = _TICKSPRST;
#endif

// cycle through available tasks
for(uint8_t i=0;i<MAX_TASKS;i++)
{
if( task_list[i].status == RUNNABLE )
task_list[i].delay--;
}
}
Вышеописанный код реализует многозадачность, не путать с мультипоточностью (это совсем другое). Директива SCH_PRESCALER задает предделитель, а TICKS_SYS_DELIMETER начальное значение счетчика при каждом прерывании. Таким образом вы можете выставить любое время опроса своих подпрограмм (задач). Чтобы отменить постоянный циклический опрос задачи, вы можете прям в своей задаче прописать:
Код
deleteTask(self->id); // Удаление задачи из диспетчера
Имейте в виду, что сумма всех таков одной задачи не должна превышать тактов 1-го прерывания, так что задавайте предделитель по-больше.
0
tostid_kriim
0 / 0 / 0
Регистрация: 20.10.2010
Сообщений: 206
03.08.2012, 20:50 19
Даже и не знал, что есть так много рариантов решения этой проблемы.

Понравился вариант omokosto.

Код
LongDelay:         ; TEMP * 197379 + 6 clock cycles
CLR   T1
CLR   T2
Delay_1:
DEC   T2
BRNE   Delay_1
DEC   T1
BRNE   Delay_1
DEC   TEMP
BRNE   Delay_1
RET
В остальные въехать не смог. Но пока мне это и не надо. С этим бы разобраться.

to omokost по поводу таймера, работаем от внутреннего кварца.

Код
;Конфигурацыя таймера
ldi chik,0b000101;//Конфигурацыя таймера 1000000/1024  Сделать частоту 976 Гц
out TCCR0B,chik;//загружаю  это значение
Кто-то справшивал по поводу камня, такой который написан в книге AT90S1200.

to tyzord66 "Микроконтроллеры AVR. Вводный курс.(Мортон Д.)" Получается, что в книжке опечатка !!! Я перед этим тоже одну нашел.
0
Johmmy0007
1 / 1 / 0
Регистрация: 30.08.2011
Сообщений: 9,944
03.08.2012, 20:58 20
посмотрите лучше как красиво тут
http://rodyoskot.ru/forum/11-555-1

ну давай обеспечим задержку в полсекунды для МК 8МГц
4000000тактов=3D0900

ldi R16, 0b00
ldi R17, 0b09
ldi R18, 0b3D; отправляем число в РОН
loop:; начало подпрограммы
subi R16,1; вычитание 1
sbci R17,0; вычитание 0 и флага С
sbci R18,0; вычитание 0 и флага С
brcc loop; переход на начало при условии С=1(при R18 не равном нулю).Если R18=0 и С=1 то команда brcc пропускается и мы выходим из цикла совершив задержку примерно в 4000000 тактов

красиво, ни одной лишней детали и главное - точно
0
03.08.2012, 20:58
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.08.2012, 20:58

Как работает задержка?
Здравствуйте, помогите разобраться как работает задержка: WAIT_LCD: PUSH ACC ...

Временная задержка в циклах
Для чего в бесконечных циклах делают временную задержку? Например: While(1){ porta =...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.