Генератор на tiny2313. Ошибка регистра TIFR

Обсуждаем контроллеры компании Atmel.
Ответить
Родился
Сообщения: 9
Зарегистрирован: Пн май 20, 2013 19:30:41

Сообщение lesh90 »

Делаю генератор на синусоид на tiny2313. Частота генерации от 100Гц, до 20кГц.
Планирую делать так: МК использует таблицу синусов -> ЦАП -> ОУ -> Выход
Кто-нибудь может поделиться соображениями,какое минимальное количество дискретов нужно взять на период синисоиды, дабы на выходе был синус?

Но главный вопрос не в этом 8)
Программу пишу в AVRStudio4,она содержит такой код:

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

wait1: 
				
	sbis  TIFR,7 ;пропустить след. командуесли флаг устанвлен
	rjmp wait1
	sbi TIFR,7 ;сброс флага	
На строку, где указан TIFR руается
error: Operand 1 out of range: 0x38

Пробовал напрямую указывать бит OCF0A -не выходит.
Подскажите, как снять информацию с регистра флагов
Реклама
akl
Друг Кота
Сообщения: 4468
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

lesh90 писал(а):Планирую делать так: МК использует таблицу синусов -> ЦАП -> ОУ -> Выход
Советую обратить внимание на метод DDS-direct digital synthesizer.
lesh90 писал(а):Подскажите, как снять информацию с регистра флагов
2. I/O Registers within the address range 0x00 - 0x1F are directly bit-accessible using the SBI and CBI instructions. In these
registers, the value of single bits can be checked by using the SBIS and SBIC instructions.
3. Some of the status flags are cleared by writing a logical one to them. Note that, unlike most other AVRs, the CBI and SBI
instructions will only operate on the specified bit, and can therefore be used on registers containing such status flags. The
CBI and SBI instructions work with registers 0x00 to 0x1F only.
4. When using the I/O specific commands IN and OUT, the I/O addresses 0x00 - 0x3F must be used. When addressing I/O
Registers as data space using LD and ST instructions, 0x20 must be added to these addresses.

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

wait1:
    IN        R22,TIFR
    SBRS   R22,7
;   sbis  TIFR,7 ;пропустить след. командуесли флаг устанвлен
   rjmp wait1
   ANDI    R22,$80
   OUT     TIFR,R22
;   sbi TIFR,7 ;сброс флага   
Реклама
Родился
Сообщения: 9
Зарегистрирован: Пн май 20, 2013 19:30:41

Сообщение lesh90 »

Большое спасибо! Заработало! Только я вот не пойму - в чем различие команда SBIS и SBRS?
akl
Друг Кота
Сообщения: 4468
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Различие в том, что SBIS проверяет бит порта ввода/вывода с адресом в пределах $00...$1F, а SBRS - бит регистра общего назначения.
Реклама
Эиком - электронные компоненты и радиодетали
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Сообщение ibiza11 »

SBIS - Skip if Bit in I/O Register Set
Пропустить следующую команду если бит в регистра ввода/вывода установлен.
SBRS - Skip if Bit in Register Set
Пропустить следующую команду если бит в регистре общего назначения установлен.
Ставим плюсы: )
Реклама
Держит паяльник хвостом
Сообщения: 927
Зарегистрирован: Вт сен 07, 2010 19:27:48
Откуда: Ташкент

Сообщение borys »

Вот здесь http://sevzirfo.narod.ru есть проект подобного генератора. Диапазон намного шире - от 1 Гц до примерно
500 кГц. В проекте указан AT90S3213, но без проблем работает ATtiny2313.
Реклама
Родился
Сообщения: 9
Зарегистрирован: Пн май 20, 2013 19:30:41

Сообщение lesh90 »

Не пойму в чем прикол.
Есть такой код

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

ldi r30, low(tabsin*2)     ;загрузка адреса начала таблицы sin
	ldi r31, low(tabsin*2) + 40

lpm r0,z+  ;число nsin прочитать в регистр r0 из памяти. След адрес в z
out portB, r0 ;вывод nsin в порт B

....
tabsin: .dw  254,252,248,240 итд.. 40 значений 
В первый раз на порт B поступает значение 254 - все как надо. Когда цикл повторяется на portB поступает 0, затем 254.
На portB поступает 254, 0, 252, 0, 248... а не то что нужно
Друг Кота
Аватара пользователя
Сообщения: 3872
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Сообщение Engineer_Keen »

lesh90 писал(а):

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

ldi r30, low(tabsin*2)     ;загрузка адреса начала таблицы sin
ldi r31, low(tabsin*2) + 40
странная конструкция, не совсем понятная...
обычно пишут:

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

ldi ZL, low(tabsin*2)     ;загрузка адреса начала таблицы sin
ldi ZH, high(tabsin*2)
и после LPM проверяют не кончилась ли таблица...

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

ldi XL, low(end*2)     ;загрузка адреса конца таблицы sin
ldi XH, high(end*2)
cp ZL,XL
cpc ZH,XH
brXX  ;тут что-то делаем если таблица кончилась

tabsin: .db 254,255... ;таблица, количество можно даже не считать, оно по следующей метке вычисляется...
end:

Родился
Сообщения: 9
Зарегистрирован: Пн май 20, 2013 19:30:41

Сообщение lesh90 »

high(tabsin*2) почему-то выдаёт 0. Поэтому я использовал low(tabsin*2) + количество элементов аблицы

А так, на первый взгляд у меня всё работает. Всего-то поменял .dw на .db
Ох уж эти тонкости.
Проверку не делал, таблица крутится с начала сама :beer:

В каком пакете лечше всего все это дело смоелировать? proteus или что-то иное?
Друг Кота
Аватара пользователя
Сообщения: 3872
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Сообщение Engineer_Keen »

lesh90 писал(а):high(tabsin*2) почему-то выдаёт 0. Поэтому я использовал low(tabsin*2) + количество элементов аблицы
где 0? если в регистре ZH, то это нормально, если tabsin начинается менее чем с 256-го адреса, а то что у вас было вообще не понятно: в ZL загружается младший байт адреса начала, а в ZH - младший байт конца, и как это должно работать?
lesh90 писал(а):Всего-то поменял .dw на .db
вот от сюда и были 0 через раз, ведь dw это word, а вы записывали туда число меньше 256
lesh90 писал(а):В каком пакете лечше всего все это дело смоелировать? proteus или что-то иное?
Можно и в самой студии, но в proteus удобнее.
Ответить

Вернуться в «AVR»