Все это дело работает на внутреннем тактовом генераторе, без использования внешнего кварца. Переключение сигнал/пауза происходит по прерыванию компаратора. Питание - 5 вольт через стабилизатор. Скачков напряжения не вижу.
Отчего же такая неровная работа МК? Проблема в генераторе или может быть другая причина?
Спойлер
Код: Выделить всё
.cseg
rjmp RESET
reti ; INT0
reti ; INT1
reti ; TIMER1 CAPT
rjmp TIMER1_COMPA
reti ; TIMER1_OVF
reti ; TIMER0 OVF
reti ; USART0, RX
reti ; USART0, UDRE
reti ; USART0, TX
reti ; ANALOG COMP
reti ; PCINT0
reti ; TIMER1 COMPB
reti ; TIMER0 COMPA
reti ; TIMER0 COMPB
reti ; USI START
reti ; USI OVERFLOW
reti ; EE READY
reti ; WDT OVERFLOW
reti ; PCINT1
reti ; PCINT2
RESET:
; Резервируем R16 = 255, R17 = 0, R18 - текущее состояние PORTB, R19 - текущий индекс массива TONES (см. внизу).
ser R16
clr R17
ser R18
clr R19
; Определяем PB0-PB7 как источники тока.
out DDRB, R16
out PORTB, R18
; Настраиваем делитель таймера 1 на 1/64.
ldi R20, 3
out TCCR1B, R20
; Обрабатываем текущий элемент массива TONES.
rcall READ_TONE
; Разрешаем прерывание компаратора 1.
ldi R20, 0x40
out TIMSK, R20
; Разрешаем прерывания.
sei
LOOP:
; Уходим в цикл.
rjmp LOOP
TIMER1_COMPA:
; Инвертируем PORTB.
com R18
out PORTB, R18
; Обрабатываем текущий элемент массива TONES.
rcall READ_TONE
; Выходим из обработчика.
reti
READ_TONE:
; Загружаем адрес TONES в Z.
ldi ZH, HIGH(TONES * 2)
ldi ZL, LOW(TONES * 2)
; Переходим к элементу R19.
add ZL, R19
adc ZH, R17
; Обнуляем таймер 1.
out TCNT1H, R17
out TCNT1L, R17
; Присваиваем значение компаратору 1.
lpm
out OCR1AH, R0
out OCR1AL, R16
; Инкрементируем индекс R19.
inc R19
; Проверяем переполнение индекса.
cpi R19, LENGTH
brne READ_TONE_RET
clr R19
READ_TONE_RET:
; Выходим из подпрограммы
ret
; Массив воспроизводимых кодов Морзе размером LENGTH.
; Нечетные элементы - продолжительность сигналов, четные - продолжительность пауз между ними.
; Продолжительность - (TONES[i] + 1) * 0xFF тактов таймера.
TONES:
; МУХА – – · · – · · · – · –
.db 0x7F, 0x3F, 0x7F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x7F, 0x3F, 0x3F
.db 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x7F, 0x3F, 0x3F, 0x3F, 0x7F, 0xFF
.equ LENGTH = 22
;; СОС · · · – – – · · ·
;.db 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x7F, 0x3F, 0x7F
;.db 0x3F, 0x7F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xFF
;.equ LENGTH = 18


