Страница 1 из 1

Неровная работа тактового генератора

Добавлено: Пн апр 21, 2014 01:22:15
Против часовой
В учебных целях написал маленькую программу для tiny2313: на порт B выводится код Морзе. Повесил на один из контактов пищалку - все работает. Однако, время от времени, то сигналы, то паузы между сигналами тянутся дольше положенного. Это заметно на слух. При чем такие сбои не имеют какой-то заметной регулярности. Происходят, когда захотят.
Все это дело работает на внутреннем тактовом генераторе, без использования внешнего кварца. Переключение сигнал/пауза происходит по прерыванию компаратора. Питание - 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

Re: Неровная работа тактового генератора

Добавлено: Пн апр 21, 2014 04:34:43
akl
Установите стек, выровняйте массив МУХА по словам в каждой строке.
Спойлер

Код: Выделить всё

; Массив воспроизводимых кодов Морзе размером LENGTH.
; Нечетные элементы - продолжительность сигналов, четные - продолжительность пауз между ними.
; Продолжительность - (TONES[i] + 1) * 0xFF тактов таймера.
TONES:
  ;     МУХА – – · · – · · · – · –
	.DB		0x7F, 0x3F, 0x7F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F
	.DB		0x7F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F
	.DB		0x7F, 0x3F, 0x3F, 0x3F, 0x7F, 0xFF
TONES_END:
;	.db   0x7F, 0x3F, 0x7F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x7F, 0x3F, 0x3F
;	.db   0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x7F, 0x3F, 0x3F, 0x3F, 0x7F, 0xFF

Re: Неровная работа тактового генератора

Добавлено: Пн апр 21, 2014 08:29:26
ИС-пытатель
Проблема в кривых руках! :)))

Вы думаете, что разработчики настолько лохи, что засунули в МК генератор, стабильность которого плавает фиг знает от чего, да еще и со скоростью в несколько кГц?

Re: Неровная работа тактового генератора

Добавлено: Пн апр 21, 2014 13:53:53
ibiza11
Спойлер
ИС-пытатель писал(а):скоростью в несколько кГц?
:facepalm:

Re: Неровная работа тактового генератора

Добавлено: Пн апр 21, 2014 15:11:03
ИС-пытатель
Скорость изменения частоты (частота изменения частоты). Вы прекрасно поняли, о чем я. Не надо тут ерничать.

Re: Неровная работа тактового генератора

Добавлено: Пн апр 21, 2014 16:07:37
Против часовой
Стек установил, массив выровнял. Пока никаких изменений. :(
Спойлер
ИС-пытатель писал(а):Вы думаете, что разработчики настолько лохи, что засунули в МК генератор, стабильность которого плавает фиг знает от чего, да еще и со скоростью в несколько кГц?
ИС-пытатель писал(а):Не надо тут ерничать.
P.S.: Для наглядности вот аудиозапись зуммера: http://file.qip.ru/file/p8jwpTfB/1.html.

Re: Неровная работа тактового генератора

Добавлено: Пн апр 21, 2014 18:48:02
BOB51
Вложенная в прерывание от таймера подпрограмма в работе оказывается длиннее, чем интервал между прерываниями по таймеру.
:tea:

Re: Неровная работа тактового генератора

Добавлено: Вт апр 22, 2014 02:36:35
Против часовой
На выполнение кода прерывания требуется не более 29 тактов. Плюс еще несколько на инициирование прерывания. А минимальное возможное расстояние между двумя прерываниями (в конкретном случае) - более 1 млн тактов. К тому же, подобные недочеты, равно как ошибки в коде, привели бы к какой-то заметной периодичности багов.

Re: Неровная работа тактового генератора

Добавлено: Вт апр 22, 2014 06:57:02
akl
Программа работает нормально. Смотрел осциллом. Чтобы синхронизировать посылку вывел импульс на PD0 и увеличил частоту в 64 раза. Тактирование tiny2313 от встроенного генератора 8МГц. Где-то сбоит в другом месте.
Спойлер

Код: Выделить всё

.include "tn2313Adef.inc"

.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:
     ldi r16,low(RAMEND)       ;загрузка указателя стека
     out SPL,r16
  ; Резервируем R16 = 255, R17 = 0, R18 - текущее состояние PORTB, R19 - текущий индекс массива TONES (см. внизу).
  ser   R16
  clr   R17
  ser   R18
  clr   R19

	OUT	DDRD,R16
	OUT	PORTD,R17

  ; Определяем PB0-PB7 как источники тока.
  out   DDRB, R16
  out   PORTB, R18
  ; Настраиваем делитель таймера 1 на 1/64.
  ldi   R20,1
;  ldi   R20, 3
  out   TCCR1B, R20
  ; Обрабатываем текущий элемент массива TONES.
  rcall READ_TONE
  ; Разрешаем прерывание компаратора 1.
  ldi   R20, 0x40
  out   TIMSK, R20
  ; Разрешаем прерывания.
  sei

LOOP:
  ; Уходим в цикл.
  rjmp  LOOP

TIMER1_COMPA:
	CBI	PORTD,0
  ; Инвертируем 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
	SBI	PORTD,0
READ_TONE_RET:
  ; Выходим из подпрограммы
  ret

; Массив воспроизводимых кодов Морзе размером LENGTH.
; Нечетные элементы - продолжительность сигналов, четные - продолжительность пауз между ними.
; Продолжительность - (TONES[i] + 1) * 0xFF тактов таймера.
TONES:
  ;     МУХА - - · · - · · · - · -
	.DB		0x7F, 0x3F, 0x7F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F
	.DB		0x7F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F
	.DB		0x7F, 0x3F, 0x3F, 0x3F, 0x7F, 0xFF
;  .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

Re: Неровная работа тактового генератора

Добавлено: Вт апр 22, 2014 07:12:25
Flasher
слухай, таймер останови, когда с ним работаешь.