Помогите как нужно написать подпрограмму задержки чтобы на порт PB подаваласся сигнал с определеннной часстотой? И если здесь чтото лишьнее скажите? Код (Text): ;------------------------- Псевдокоманды управления .include "tn2313def.inc" ; Присоединение файла описаний .list ; Включение листинга ;------------------------- Начало программного кода .cseg ; Выбор сегмента программного кода .org 0 ; Установка текущего адреса на ноль .def temp = r16 ; Определение главного рабочего регистра .def loop1 = r17 ; Определение первого регистра цикла .def loop2 = r18 ; Определение второго регистра цикла .def loop3 = r19 ; Определение второго регистра цикла ;-------------------------- Инициализация стека ldi temp, 0x7F ; Выбор адреса вершины стека out SPL, temp ; Запись его в регистр стека ;-------------------------- Инициализация Главного предделителя ldi temp, 0x80 ; Записываем число $80 в регистр temp out CLKPR, temp ; Записываем в регистр CLKPR ldi temp, 0 ; Записываем 0 в регистр temp out CLKPR, temp ; Записываем этот ноль в CLKPR ;-------------------------- Инициализация портов ВВ out DDRD, temp ; Записываем этот ноль в DDRD (порт PD на ввод) ldi temp, 0xFF ; Записываем число $FF в регистр temp out DDRB, temp ; Записываем это число в DDRB (порт PB на вывод) out PORTB, temp ; Записываем то же число в PORTB (выключить динамик) out PORTD, temp ; Записываем его же в PORTD (включаем внутр. резисторы) ;--------------------------- Инициализация компаратора ldi temp, 0x80 ; Выключение компаратора out ACSR, temp ;-------------------------- Начало основного цикла main: sbi PORTB, 0 ; Устанавливаем PB0 в единицу выключамем динамик(тушим светодиод) in temp, PORTD ; Читаем содержимое порта PD sbrc temp, 0 ; Проверка младшего разряда rjmp main ; Если не ноль, переходим в начало ;-------------------------------- sbi PORTB, 0 ; Устанавливаем PB0 в нооль rcall wait1 ; Вызов подпрограммы задержки sbi PORTB, 1 ; Сброс PB0 в единица rcall wait1 ; Вызов подпрограммы задержки rjmp main ; К началу цикла ;--------------------------------- Подпрограмма задержки ВОТ ЭТУ ЗАДЕРЖУ НАДО ИЗМЕНИТЬ НО КАК НЕ ЗНАЮ ВООБЩЕ ВПЕРВЫЕ СТАЛКИВАЮСЬ С АССЕМБЛЕРЕМ ldi loop1, 15 ; Помещаем в loop1 константу задержки wt1: dec loop1 ; Уменьшаем значение регистра loop breq wt4 ldi loop2, 100 ; Помещаем в loop2 константу задержки wt2: dec loop2 ; Уменьшаем значение регистра loop2 breq wt1 ldi loop3, 255 ; Помещаем в loop3 константу задержки wt3: dec loop3 ; Уменьшаем значение регистра loop3 brne wt3 ; Если не ноль, продолжаем цикл rjmp wt2 ret ; Выход из подпрограммы
В псевдокоде это примерно так выглядит: loop1=15 wt1: loop1=loop-1 if loop1 = 0 goto wt4 loop2=100 wt2: loop2=loop2-1 if loop2 = 0 goto wt1 loop3=255 wt3: loop3=loop3-1 if loop3 <> 0 goto wt3 goto wt2 wt4: return Т.е. это цикл, длительностью 255*100*15, чему равна одна итерация цикла(секунд или наносекунд или ешё что), этого точно не могу сказать.
Код (Text): ldi loop1, 15 wt1: ldi loop2, 100 wt2: ldi loop3, 255 wt3: dec loop3 brne wt3 dec loop2 brne wt2 dec loop1 brne wt1 ret не следует клонировать топики
vovkax13 Это по времени будет равно выполнению 10000 раз команды декремента loop 1 и команды условного перехода.
ldi loop1, 15 wt1: ldi loop2, 100 wt2: ldi loop3, 255 wt3: dec loop3 brne wt3 dec loop2 brne wt2 dec loop1 brne wt1 ret Ну запускаю и он не выходит из этой задержки?
как я понял это программа для attiny2313 время итерации зависит от частоты на которой работает контроллер а частота от настроек в контроллере и внешнего кварца(ели он используется конечно ) так что, для точного ответа программы недостаточно В этом ftp://ftp.efo.ru/pub/atmel/articles/AVR_cmd.doc документе расписано сколько тактов занимает выполнение каждой команды. Соответственно время задержки в секундах можно посчитать по формуле t=n/f где t- время, n- количество тактов в задержке, f- частота на которой работает контроллер в герцах. На примере конкретной программы это будет выглядеть так: Код (Text): call wait ;Вызов задержки 4 такта ... wait: ldi loop1, 15 ;Загрузка числа для внешнего цикла 1 такт wt1: ldi loop2, 100 ;загрузка числа для "среднего" цикла 1 такт wt2: ldi loop3, 255 ;загрузка числа для внутреннего цикла 1 такт wt3: dec loop3 ; уменьшение на 1 значения внутреннего цикла 1 такт brne wt3;если результат не 0 переход на wt3 1 такт если 0 на след. строчку 2 такта dec loop2;уменьшение на 1 значения "среднего" цикла 1 такт brne wt2;если результат не 0 переход на wt2 1 такт если 0 на след. строчку 2 такта dec loop1;уменьшение на 1 значения внешнего цикла 1 такт brne wt1;если результат не 0 переход на wt1 1 такт если 0 на след. строчку 2 такта ret ; Возврат из задержки 4 такта Соответственно общее число тактов будет составлять 8 (ret и call) + 15*100*255(количество итераций в циклах)*2(dec+brne) + 100+15(дополнительные при переходе во внешние циклы «на след. строчку 2 такта» ) Итого 765123 тактов . при частоте работы микроконтроллера 4 мгц время задержки будет 765123/4000000=0,19128075 секунд или если считать частоту на выходе 1/0,19128075=5,2279176027906624163696555978581 герц . Слышимый диапазон примерно 16-16000 герц дальше считайте сами