0 / 0 / 0
Регистрация: 29.03.2014
Сообщений: 139
1

Прерывания по совпадению, СТС, 16 разрядный таймер, Atmega32

01.04.2014, 22:57. Показов 6085. Ответов 12
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день.
Делаю небольшой простенький генератор сигналов.
На данный момент код написан на ассемблере, генерируется 4 вида сигнала - синус, треугольник, пила и меиндр.
ЦАП AD7302BNZ, 8 битный параллельный, однако сигналы только 5 бит, частота заметно выше получается.
Все работает нормально, однако есть проблема - при значениях регистра OCR1A, например 0b00000010 (младший байт, старший 0x00) сигналы генерироваться отказываются, выдается на выходе лишь некоторый уровень напряжения с непонятными помехами. На некоторых значениях регистра работает, точней даже на многих, например на 0x00FF все нормально, нормально и на 0x0001.
ЦАП управляется тремя дополнительными сигналами, но проблема явно не в нем. Прерывания соответственно по совпадению, плюс сброс при этом счетного регистра.
Можете пожалуйста помочь и подсказать в чем проблема, заранее спасибо.

Код
.list

.def temp=r17 ;основной рабочий регистр
.def counter=r18 ;счетчик для генерации синуса
.def cap_output=r19 ;регистр для установки битов управления ЦАП
.def choice_low=r20 ;регистр для младшего байта адреса
.def choice_high=r21 ;регистр для старшего байта адреса
.def moved=r22 ;регистр выбора текущей формы сигнала

.cseg
;____________________Начальная установка__________________
.org 0x000
rjmp RESIT
;____________________Таблица векторов внешнего прерывания________________
.org 0x002
rjmp INT0lbl
.org 0x00E
rjmp TIMER1COMPAlbl
;__________________Обработчик прерывания от INT0_______________
INT0lbl:
yms moved
cpi moved, 0b00000100
breq clear ;переход к очистке moved
return:
cpi moved, 0b00000000
breq fikure1 ;переход к генерации синуса
cpi moved, 0b00000001
breq fikure2 ;переход к генерации пилы
cpi moved, 0b00000010
breq  fikure3 ;переход к генерации треугольника
cpi moved, 0b00000011
breq  fikure4 ;переход к генерации меиндра
return1:
reti

clear:
clr moved
rjmp return

fikure1:
ldi choice_low, low(symus*2) ;запись адреса первого значения в таблице (младший байт)
ldi choice_high, high(symus*2);запись адреса первого значения в таблице (старший байт)
rjmp return1
fikure2:
ldi choice_low, low(saw*2) ;-//-
ldi choice_high, high(saw*2);-//-
rjmp return1
fikure3:
ldi choice_low, low(triangle*2) ;-//-
ldi choice_high, high(triangle*2) ;-//-
rjmp return1
fikure4:
ldi choice_low, low(meomdr*2) ;-//-
ldi choice_high, high(meomdr*2) ;-//-
rjmp return1
;____________________Завершение обработчика прерывания по INT0________________________

;____________________Обработчик прерывания от 16-ти разрядного счетчика по совпадению___________________
TIMER1COMPAlbl:

mov ZL, choice_low ; получение первого байта адреса первого байта в таблице синуса
mov  ZH, choice_high;получение второго байта адреса  первого байта в таблице синуса
clr temp
add ZL, counter ;запись текущего байта в таблице
adc ZH, temp
lpm temp, Z ;получение текущего байта из таблицы синуса
yms counter

;______________________Отправка данных в ЦАП____________________
ldi cap_output, 0b00011111 ;установка в ноль командных битов ЦАПа
out PORTC, cap_output ;выдача управляющих битов в порт
out PORTA, temp ;выдача цифрового значения текущего уровня напряжения из таблицы синуса в порт
ldi cap_output, 0xFF
out PORTC, cap_output ;снятие управляющих битов

;_____________________Подготовка к следующей итерации___________
sbrc counter, 5
clr counter
reti
;________________Завершение обработчика прерывания_________________

;__________________Инициализация стека и глобальное разрешение прерываний_____________
RESIT:
ldi r16, high(ROMEND)
out SPH, r16
ldi r16, low(ROMEND)
out SPL, r16
sei

;__________________Инициализация портов________________
ldi temp, 0b01000000
out GICR, temp
ldi temp, 0b00000011
out MCUCR, temp
ldi temp, 0b00010000
out TIMSK, temp ; разрешение прерываний по совпадению значений регистра 16 разрядного счетчика со значением в регистре OCR1A
ldi temp, 0b00001001
out TCCR1B, temp ;установка пределителя в значение 1:1
ldi temp, 0xFF
out OCR1AL, temp ; установка значения, при достижении счетчиком которого происходит прерывание (младший байт)
ldi temp, 0x00
out OCR1AH, temp; установка значения, при достижении счетчиком которого происходит прерывание (старший байт)
ldi temp, 0xFF
ldi cap_output, 0x00
out DDRA, temp ; порт выдачи значения уровня напряжения на ЦАП
out DDRC, temp ; порт выдачи управляющих сигналов на ЦАП
out PORTC, temp
ldi temp, 0b00000000
out DDRD, temp
ldi temp, 0xFF
out PORTD, temp
ldi temp, 0b00000000
ldi moved, 0x00
ldi choice_low, low(symus*2)
ldi choice_high, high(symus*2)

;_________________Основной цикл_________________________
m:

rjmp m

;_____________________Таблицы сигналов__________________
symus:
.db 127, 152, 175, 197, 217, 232
.db 245, 251, 255, 251, 245, 232
.db 217, 197, 175, 152, 127, 103
.db 79, 57, 38, 22, 10, 3, 0, 3
.db 10, 22 , 36, 57 , 79, 103, 127

saw:
.db 0, 8, 16, 24, 32, 40
.db 48, 56, 64, 72, 80, 88
.db 96, 104, 112, 120, 128, 136
.db 144, 152, 160, 168, 176, 184, 192, 200
.db 208, 216 , 224, 232 , 240, 248, 255

triangle:
.db 0, 16, 32, 48, 64, 80
.db 96, 112, 128, 144, 160, 176
.db 192, 208, 224, 240, 255, 240
.db 224, 208, 192, 176, 160, 144, 128, 112
.db 96, 80 , 64, 48 , 32, 16, 0

meomdr:
.db 255, 255, 255, 255, 255, 255
.db 255, 255, 255, 255, 255, 255
.db 255, 255, 255, 255, 0, 0
.db 0, 0, 0, 0, 0, 0, 0, 0
.db 0, 0 , 0, 0 , 0, 0, 0
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.04.2014, 22:57
Ответы с готовыми решениями:

Можно ли в таймер-счетчик передавать переменную (режим СТС)
Как в таймер-счетчик передавать переменную? Нужно чтоб пошагово увеличивалось время включения...

16-разрядный таймер
Доброго времени суток дорогие посетители форума . Мое задание : управление светофорами , а именно...

Не работает таймер по совпадению (atmega8, atmel studio 6)
Почемуто не работает таймер в режиме по совпадению (делал по примеру, вроде все регистры выставил),...

16-ти разрядный таймер под ATiny 2313A (не работает)
Добрый день. Обучаюсь по книге, в которой в качестве примера выбран другой МК. Как бы я не старался...

12
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
02.04.2014, 00:39 2
тут
Код
ldi temp, 0xFF
out OCR1AL, temp ; установка значения, при достижении счетчиком которого происходит прерывание (младший байт)
ldi temp, 0x00
out OCR1AH, temp; установка значения, при достижении счетчиком которого происходит прерывание (старший байт)
To do a 16-bit write, the high byte must be written before the low byte. For a 16-bit read, the low
byte must be read before the high byte.
0
0 / 0 / 0
Регистрация: 29.03.2014
Сообщений: 139
02.04.2014, 01:06 3
Вот это тонкость, да, спасибо большое, завтра попробую и отпишусь о результатах!
0
0 / 0 / 0
Регистрация: 29.03.2014
Сообщений: 139
02.04.2014, 19:42 4
Изменил так как вы сказали, но только теперь все работает, однако значение частоты начинает уменьшаться только со значения 0x1B, почему так происходит?
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 3,044
02.04.2014, 19:49 5
Цитата Сообщение от kiorkfour
Изменил так как вы сказали, но только теперь все работает, однако значение частоты начинает уменьшаться только со значения 0x1B, почему так происходит?
У вас та же ошибка, только в другом месте. Вам направление дали, думаю, теперь сами догадаетесь, где еще ошибки искать.
0
0 / 0 / 0
Регистрация: 29.03.2014
Сообщений: 139
07.04.2014, 20:55 6
Появился вопрос у меня, уже немного по другой теме.
Вот с помощью цапа я могу выводить синус, и соответственно можно играть ноты.
Но я не понимаю, как сделать так, чтобы одновременно играли две ноты и более?
То есть сделать более 1 канала, ведь в один момент я могу выводить лишь один синус с одной частотой.
Но я посмотрел в интернете как-то же делают полифонию на AVR.
Заранее спасибо за ответ.
0
1 / 1 / 0
Регистрация: 28.01.2010
Сообщений: 537
08.04.2014, 01:10 7
Сделай сумму двух значений:
A(f_1,f_2) = SIN(2*PI*f_1*t)/2 + SIN(2*PI*f_2*t)/2
где: f_1 - частота первой ноты;
f_2 - частота второй ноты;
t - время. Для дискретного сигнала t = N/F_ЦАП, N - номер такта (отсчета). F_ЦАП - частота выдачи сигнала на ЦАП.
0
0 / 0 / 0
Регистрация: 29.03.2014
Сообщений: 139
08.04.2014, 01:12 8
А таким способом можно сделать ведь и большее количество каналов?
Проблема лишь в производительности мк?
0
0 / 0 / 0
Регистрация: 08.02.2012
Сообщений: 648
08.04.2014, 10:55 9
Производительность можешь немного увеличить, поставив кварц на 20 МГц
0
0 / 0 / 0
Регистрация: 29.03.2014
Сообщений: 139
08.04.2014, 11:09 10
Согласно даташиту максимум 16 вроде...будет нормально работать?
0
1 / 1 / 0
Регистрация: 28.01.2010
Сообщений: 537
08.04.2014, 11:52 11
Глянь MOD player
http://itiktromyka.kvotytne.cz/ATMEL/MO ... 3_eng.html
0
0 / 0 / 0
Регистрация: 08.02.2012
Сообщений: 648
08.04.2014, 12:53 12
у меня нормально работает, был случай что не завелось, но только из-за того что флюс попал под кварц, после удаления флюса, устройство заработало :-) А так-то да это уже небольшой оверклокинг :-)
0
0 / 0 / 0
Регистрация: 29.03.2014
Сообщений: 139
08.04.2014, 22:16 13
Всем спасибо за помощь!
0
08.04.2014, 22:16
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.04.2014, 22:16
Помогаю со студенческими работами здесь

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

PIC16F84A, прерывания, таймер
Есть задание: "Разработать программу на ассемблер для PIC16F84A, которая бы обеспечивала постоянное...

Прерывания и таймер на ассемблере
Добрый день. Только вливаюсь в тему программирования микроконтроллеров. Возник вопрос: можно ли...

таймер прерывания 8051
Здравствуйте такой вопрос #загрузка указателя 0006 0200: 90 03 00 p: MOV ...

Обработчик прерывания: таймер.
ПОМОГИТЕ! Написать программу, которая за определенный интервал времени показывает фамилию заданное...

функция перехвата прерывания 1Ch таймер
.286 ASKII_code_key_check equ 'A' ASKII_code_key equ 'B' number_handler_int21_02h equ 02h...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru