В подпрограмме генератор прямоугольных импульсов (меандра) вычислим частоту звукового сигнала на выводе микроконтроллера.
Программа генератор для микроконтроллера ATtiny13 работающего на частоте ядра 9600000 Гц:
;****************************************************************************** ;***** Программа включает и выключает порт PB2 микроконтроллера ATtiny13 ****** ;***** Created: 2015-02-05 01:28 ******** Site: http://integrator.adior.ru **** ;****************************************************************************** .includepath "/home/dior/AVR" ; Папка с файлами заголовками .include "tn13def.inc" ; Используем ATtiny13 ;============================================================================== rjmp reset ; начало программы reset: ldi r23, RAMEND ; Загрузить в R23 адрес последней ячейки памяти out SPL, r23 ; Инициализация стека sbi DDRB, DDB2 ; PB2 будет работать на выход ldi r23, 4 ; Загрузить в R23 4 out PORTB, r23 ; PB2 установить уровень 1. На PB2 подкл. динамик. main: ldi r25, 4 ; Длительность звучания ldi XL, 255 ; Длительность полупериода (младший байт) ldi XH, 4 ; Длительность полупериода (старший байт) rcall duratone ; Вызов подпрограммы генерации ноты stop: rjmp main ; Останов или бесконечный цикл ; Подпрограммы duratone: ; Подпрограмма генератор тона с таймером ; Длительность таймера R25 ; Высота тона (точнее, длительность полупериода) XH:XL movw YL, XL ; ╔>Загрузить в счетчик Y длительность полупериода из X swap r23 ; ║Поменять местами полубайты в r23 out PORTB, r23 ; ║Инвертировать сигнал на PB2 halfcycle: sbiw YH:YL,1 ; ║╔>Y=Y-1 (65535...0) brcc halfcycle ; ║╚<Повторять пока не было переноса sbiw r25:r24,1 ; ║R25:R24=R24:R24-1 brcc duratone ; ╚<Повторять пока не было переноса ret ; Возврат из подпрограммы ; Задействованы регистры R23, R24, R25, R26, R27, R28, R29 ; Компилировать avra test.s ; Загрузить avrdude -C/home/dior/AVR/avrdude.conf -v -v -v -v -pattiny13 -cstk500v1 -P/dev/ttyUSB0 -b19200 -Uflash:w:test.s.hex:i ; Фьюзы avrdude -C/home/dior/AVR/avrdude.conf -v -v -v -v -pattiny13 -cstk500v1 -P/dev/ttyUSB0 -b19200 -e -Uhfuse:w:0xff:m -Ulfuse:w:0x7a:m
В симулятор simulavr всю программу, предварительно установив XL=2, XH=0. Читайте Simulavr - эмулятор микроконтроллеров Atmel AVR
Для анализа выделим интересующий нас фрагмент кода, собственно генератор с таймером времени звучания:
duratone: ; Подпрограмма генератор тона с таймером ; Длительность таймера R25 ; Высота тона (точнее, длительность полупериода) XH:XL 1 16 movw YL, XL ; ╔>Загрузить в счетчик Y длительность полупериода из X 2 18 swap r23 ; ║Поменять местами полубайты в r23 3 1a out PORTB, r23 ; ║Инвертировать сигнал на PB2 4 1c halfcycle: sbiw YH:YL,1 ; ║╔>Y=Y-1 (65535...0) 5 1e brcc halfcycle ; ║╚<Повторять пока не было переноса 6 20 sbiw r25:r24,1 ; ║R25:R24=R24:R24-1 7 22 brcc duratone ; ╚<Повторять пока не было переноса 8 24 ret ; Возврат из подпрограммы
В левой колонке адрес каждой команды №п/п в словах и в байтах подпрограммы duratone в Flash памяти микроконтроллера ATtiny13.
Составим таблицу всех используемых в подпрограмме команд и время их выполнения в тактах микроконтроллера:
Команда | Операция | Описание | Число тактов |
---|---|---|---|
movw Rd, Rr | Rd+1:Rd=Rr+1:Rr | Пересылка двух байтов | 1 |
swap Rd | bit 7 6 5 4 ↔ bit 3 2 1 0 | Обмен местами полубайтов | 1 |
out A, Rr | A=Rr | Пересылка из регистра РОН в РВВ | 1 |
sbiw Rdh:Rdl, K | Rdh:Rdl=Rdh:Rdl-K | Вычитание константы из регистровой пары | 2 |
brcc k | Если C=0, то PC=PC+1+k | Переход если нет переноса | 1/2 |
Номер команды выполняемой за 2 такта подкрасим в зеленый цвет, а номер команды, выполняемой за количество тактов,зависящее от направления ветвления, в красный.
Составим диаграмму сигнала на ножке PB2 с момента отрицательного перепада произошедшего сразу после 1-го выполнения команды №3 out PORTB, r23
На выводе микроконтроллера PB2 оба полупериода сигнала одинаковы. Если значение двухбайтового регистра X=2, длительность полупериода выходного сигнала равна 18 тактов.
Если значение двухбайтового регистра X=3, длительность полупериода выходного сигнала равна 18+4 тактов. В общем случае:
T/2(n)=n*4+10 тактов
Один такт выбранного нами микроконтроллера ATtiny13 равен 1/F=1/9600000 сек.
Длительность периода меандра на выходе PB2 микроконтроллера:
Частота сигнала на выводе PB2 микроконтроллера ATtiny13 (с собственной тактовой частотой 9600000 Гц)
Расчет числа n, загружаемого в регистр X микроконтроллера исходя из требуемой частоты f