Ассемблер (ASM) для AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Ответить
xkp
Опытный кот
Аватара пользователя
Сообщения: 781
Зарегистрирован: Ср ноя 18, 2009 12:50:31
Откуда: ковров

Сообщение xkp »

исправил
Спойлер.INCLUDE "m8DEF.INC"
.def tmp=r16
.def tmp0=r17
.cseg
случайно удалил вместе с коментариями в программе пока её сюда вам копировал))
R5VCH
Хотелки:
СпойлерАналоговый осциллограф С1-112, С1-118, другие
не/рабочие модули от комплекса ОДА-102
всё что касается AVR, arduino, raspberry
всё что касается КВ-УКВ-радиосвязи, mashtastic
Контактная информация:
Реклама
Мудрый кот
Аватара пользователя
Сообщения: 1812
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

xkp писал(а):Я пока их не читал.
А может попробовать прочитать.
Симулятор вещь не надёжная. :)
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Реклама
xkp
Опытный кот
Аватара пользователя
Сообщения: 781
Зарегистрирован: Ср ноя 18, 2009 12:50:31
Откуда: ковров

Сообщение xkp »

СпойлерTIM1_CAPT:
push tmp ;сохраняем данные
push tmp0 ;которые можем потерять
in tmp,sreg ;tmp, tmp0,
push tmp ;sreg
in tmp,icr1l
in tmp0,icr1h


pop tmp ;восстанавливаем ранее
out sreg,tmp ;сохранённые данные
pop tmp0 ;в обратном порядке
pop tmp ;sreg,tmp,tmp0
reti
думаю проблема не в том что я их не читаю... Скорее в инициализации прерываний что то забыл написать.
R5VCH
Хотелки:
СпойлерАналоговый осциллограф С1-112, С1-118, другие
не/рабочие модули от комплекса ОДА-102
всё что касается AVR, arduino, raspberry
всё что касается КВ-УКВ-радиосвязи, mashtastic
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 4966
Зарегистрирован: Сб май 05, 2012 20:19:55
Откуда: Минск

Сообщение Seriyvolk »

Привет всем! Опять я к вам со своими проблемами. :))
Есть задача: сделать схему на МК, где при старте сам МК выдавал бы на выход плавно растущую частоту (скважность 0.4, важно) начиная от 1 Гц до 300-500 Гц. Что-то вообще никаких мыслей нет, как это организовать. Железный ШИМ чётко привязан к ЗГ МК, софтовый... даже не знаю... Толкните плиз в нужную сторону. :)
Прибор, защищённый предохранителем, сгорает первым, защитив предохранитель. Закон Мерфи.
Реклама
Эиком - электронные компоненты и радиодетали
Вымогатель припоя
Аватара пользователя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Сообщение zero648 »

Для Seriyvolk
Смотря какой камень, в 16 меге, например, для этого подходят 14 и 15 режимы таймера1:
в 14 режиме для изменения частоты меняешь значение регистра ICR1, для изменения скважности меняешь OCR1A или OCR1B, можно использовать оба канала, но разрешение у обоих будет ICR1.
в 15 режиме для изменения частоты меняешь значение регистра OCR1A, для изменения скважности меняешь OCR1B, можно использовать только канал B.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4966
Зарегистрирован: Сб май 05, 2012 20:19:55
Откуда: Минск

Сообщение Seriyvolk »

Да, забыл упомянуть... Хотелось бы обойтись 13-й тинькой. Но намёк я понял, спасибо!
Прибор, защищённый предохранителем, сгорает первым, защитив предохранитель. Закон Мерфи.
Реклама
akl
Друг Кота
Сообщения: 4470
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

xkp писал(а):Скорее в инициализации прерываний что то забыл написать.
В регистр ICR1 значение таймера1 заносится аппаратно (по умолчанию по спаду ICES1=0, при ICES1=1 по фронту) при изменении сигнала на входе ICP1(PB0). У Вас таймер не запущен, значит в регистр ICR1 будет заноситься состояние TCNT1=0. Попробуйте попереключать в студии PINB0(ICP1); должны увидеть занесение значения TCNT1 в ICR1 при переходе 0->1.
Спойлер

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

.INCLUDE "m8DEF.INC"
.def tmp=r16
.def tmp0=r17
.cseg
;INTERRUPT VECTORS
   rjmp reset            ; Reset Handler
   reti;   rjmp EXT_INT0          ; IRQ0 Handler
   reti               ;   rjmp EXT_INT1 ; IRQ1 Handler
   reti               ;rjmp TIM2_COMP ; Timer2 Compare Handler
   reti               ;rjmp TIM2_OVF ; Timer2 Overflow Handler
	IN	XL,ICR1L	;Timer1 Capture Handler
	IN	XH,ICR1H
;   rjmp TIM1_CAPT;Timer1 Capture Handler
   reti               ;rjmp TIM1_COMPA ; Timer1 CompareA Handler
;   reti               ;rjmp TIM1_COMPB ; Timer1 CompareB Handler
;   reti               ;rjmp TIMPINC 4 191_OVF   ;Timer1 Overflow Handler
;reti;   rjmp look            ;tim0_ovf ; Timer0 Overflow Handler
;   reti               ;rjmp SPI_STC ; SPI Transfer Complete Handler
;   reti               ;rjmp USART_RXC ; USART RX Complete Handler
;   reti               ;rjmp USART_UDRE ; UDR Empty Handler
;   reti               ;rjmp USART_TXC ; USART TX Complete Handler
;   reti               ;rjmp ADC_inc ; ADC Conversion Complete Handler
;   reti               ;rjmp EE_RDY ; EEPROM Ready Handler
;   reti               ;rjmp ANA_COMP ; Analog Comparator Handler
;   reti               ;rjmp TWSI ; Two-wire Serial Interface Handler
;   reti               ;rjmp SPM_RDY ; Store Program Memory Ready Handler
RESET:
   ldi tmp,low(RAMEND)
   out spl,tmp
   ldi tmp,high(RAMEND)
   out sph,tmp

   ldi tmp,0b00000000
   out ddrb,tmp
   ldi tmp,0b00000001
   out portb,tmp

   ldi tmp,(1<<ticie1)
   out timsk,tmp

   OUT	TIFR,tmp

;   ldi tmp,(0<<icnc1)|(1<<ices1)
 ;  out tccr1b,tmp


   LDI	R22,(1<<ices1|1<<cs10)
   OUT	TCCR1B,R22

   sei
main:
   rjmp main

;TIM1_CAPT:
;   push tmp         ;сохраняем данные
;   push tmp0         ;которые можем потерять
;   in tmp,sreg         ;tmp, tmp0,
;   push tmp         ;sreg



;   pop tmp            ;восстанавливаем ранее
;   out sreg,tmp      ;сохранённые данные
;   pop tmp0         ;в обратном порядке
;   pop tmp            ;sreg,tmp,tmp0
;   reti
.exit
Seriyvolk писал(а):... сам МК выдавал бы на выход плавно растущую частоту (скважность 0.4, важно) начиная от 1 Гц до 300-500 Гц.
По мне, слабенький таймер tiny13 с такой задачей не справится, т.к. диапазон роста частоты слишком широкий. Как предложение. Организовать цепочку из 5 регистров, чтобы можно было точно формировать требуемую скважность ( не стал менять т.к. скважность, по определению, не может быть меньше 1 и речь идёт о коэффициенте заполнения) и сдвигать по прерыванию таймера. Темп этого сдвига будет определяться значениями,заложенными в таймере. Примерно так как ниже.
Спойлер

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

; Проба изменяемой в пределах 1...300 Гц частоты Fout
.include "tn13def.inc"; используемое устройство

.equ	Fo=9600000

.equ	Fout=1
;.equ	Fout=300

.equ	Tout=Fo/40/Fout	; длительность периода сдвига R0...R4
; длительность 1/40 периода придется рассчитываь или сводить в таблицу!!!!!!!!
   .CSEG
   .ORG	0
	RJMP	START
   .ORG	$03
OVER_T0:
	SBIW	YL,1
	BRPL	OUT_RETI
SET_Tout:
	LDI	YH,BYTE3(Tout)
	LDI	YL,BYTE2(Tout)
	LDI	R16,BYTE1(256-low(Tout)-1)
	OUT	TCNT0,R16

	OUT	TIMSK0,R17
	OUT	TIFR0,R17

	SET
	RET
OUT_RETI:
	RETI
;*************************************************
START:
	CLR	R0
	CLR	R1
	CLR	R2
	LDI	R16,$FF
	MOV	R3,R16
	MOV	R4,R16

	SBI	PORTB,1
	SBI	DDRB,1
	
	LDI	R22,$80
	OUT	ACSR,R22	; выключить аналоговый компаратор
;*************************************************
GO:
; настройка таймера
	LDI	ZH,40

	LDI	R17,$02
	RCALL	SET_Tout
	CLT
;*************************************************
	LDI	R22,$20
	OUT	MCUCR,R22	; разрешение режима SLEEP IDLE

	LDI	R22,1
	OUT	TCCR0B,R22
;*************************************************
	SEI
WAIT:
	SLEEP
	BRTC	WAIT
	CLT

GO_TIME:
	IN	R16,PORTB

	CLC
	SBRC	R4,0
	SEC

	ROR	R0	
	ROR	R1	
	ROR	R2	
	ROR	R3	
	ROR	R4
	
	CBR		R16,$02
	BRCC	PC+2
	SBR		R16,$02
	OUT		PORTB,R16

	DEC	ZH
	BRNE	WAIT-1
;вычисление периода следующей частоты
SET_PERIOD:
;***
;***
;***
;***
	RJMP	GO
;*************************************************
xkp
Опытный кот
Аватара пользователя
Сообщения: 781
Зарегистрирован: Ср ноя 18, 2009 12:50:31
Откуда: ковров

Сообщение xkp »

Спасибо большое! Дописал в программу вывод на графический индикатор и протестил в протеусе. Пока вроде все устраивает. но и тут появились НО ((
При частоте тактирования МК в 1мГц таймер-счетчик "переполняется" при входном сигнале ниже 15 Гц, тоесть насчитывает больше чем $FFFF (вернее тактов проходит больше чем максимальное значение счетчика), и естественно когда вычитает из нового значение старое, то получается котовасия.
Спойлер

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

tim1_capt:
	push tmp			;сохраняем данные
	push tmp0			;которые можем потерять
	in tmp,sreg			;tmp, tmp0,
	push tmp			;sreg

in tmp,icr1l
in tmp0,icr1h
lds r18,timl
lds r19,timh
sts timl,tmp
sts timh,tmp0
clc
sub tmp,r18
sbc tmp0,r19
sts timindl,tmp
sts timindh,tmp0

	pop tmp				;восстанавливаем ранее
	out sreg,tmp		;сохранённые данные
	pop tmp0			;в обратном порядке
	pop tmp				;sreg,tmp,tmp0
	reti
Как решить эту проблему? Очевидно нужно добавить третий регистр в результат.
Примерно так, но это работать не будет.
Спойлер

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

in tmp,icr1l
in tmp0,icr1h
lds r18,timl
lds r19,timh
sts timl,tmp
sts timh,tmp0
clc
clr r20
sub tmp,r18
sub tmp0,r19
ror r20
sts timindl,tmp
sts timindh,tmp0
sts timindh2.r20
R5VCH
Хотелки:
СпойлерАналоговый осциллограф С1-112, С1-118, другие
не/рабочие модули от комплекса ОДА-102
всё что касается AVR, arduino, raspberry
всё что касается КВ-УКВ-радиосвязи, mashtastic
Контактная информация:
akl
Друг Кота
Сообщения: 4470
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Вы должны разрешить прерывания по переполнению таймера, в каждом из которых наращивать счётчик. Это и будет старшая часть общего счётчика. Дополнительно этот регистр использую для отсечки заданного времени измерения. Может посмотрите кусок кода с обработкой прерываний из CLR2313.
Спойлер

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

RESET:
	RJMP	START		; On Reset
	RJMP	ON_OFF		; On Interrupt 0
	RJMP	GO_ISR1		; On Interrupt 1 прерывание при нажатии кнопки "РЕЖИМ"

	IJMP			; Timer 1 capture
	RETI			; Timer 1A compare
	ADIW	XL,1		; Timer 1 overflow
	CPI	XH,$10		; время измерения ~32 сек
	BRCS	IZM
	SET
IZM:
	RETI
;***************************************************************************
;***************************************************************************
;***************************************************************************
;***************************************************************************
;***************************************************************************
CAPT:
	IN	R1,ICR1L
	IN	R0,ICR1H
	CLR	XH
	CLR	XL		; очистить старшее слово nx_begin
		
;	LDI	ZH,HIGH(CAPT_1)
	LDI	ZL,LOW (CAPT_1); следующее прерывание будет на CAPT_1
	RETI
CAPT_1:
	IN	R19,ICR1L
	IN	R18,ICR1H	; конечное значение nx
	
	ADIW	YL,1		; Nx=Nx+1
		
	CPI	XL,40		; время измерения закончилось?
	CPC	XH,ZH
	BRCC	CAPT_3		; да
	RETI			; нет
CAPT_3:
	IN	R16,TIFR
	SBRC	R16,7		; если есть необработанное требование прерывания OVER_T1
	RETI			; выход для его обработки и ожидания
				; окончания следующего периода

	OUT	TCCR1B,ZH	; STOP T1
	OUT	TIMSK,ZH

	SUB	R19,R1
	SBC	R18,R0
	SBC	XL,ZH
	SBC	XH,ZH		; nx-nx_begin
		
	STS	$76,XH
	STS	$77,XL
	STS	$78,R18
	STS	$79,R19		; nx
		
	STS	$86,ZH
	STS	$87,ZH
	STS	$88,YH
	STS	$89,YL		; Nx
		
	SET
	RETI
;***************************************************************************
xkp
Опытный кот
Аватара пользователя
Сообщения: 781
Зарегистрирован: Ср ноя 18, 2009 12:50:31
Откуда: ковров

Сообщение xkp »

Хорошая идея. только вот вопрос....
сначало о хорошем. Предыдущее значение, например, 1. Текущее 4. Переполнения небыло. результат 3.
А вот теперь при тех же самых условиях но с переполнением. Предыдущее = $FFFE, текущее = 1. Результат тот же - 3. но тут было переполнение и к старшему байту прибавится 1. Получится $010003 что равно 65539, вместо нашего числа 3.
Вобщем я не понял как это можно использовать.
R5VCH
Хотелки:
СпойлерАналоговый осциллограф С1-112, С1-118, другие
не/рабочие модули от комплекса ОДА-102
всё что касается AVR, arduino, raspberry
всё что касается КВ-УКВ-радиосвязи, mashtastic
Контактная информация:
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

Переполнение не надо учитывать в таких вычитаниях. Такие вот фокусы двоичной арифметики в ограниченной разрядности.
Контактная информация:
xkp
Опытный кот
Аватара пользователя
Сообщения: 781
Зарегистрирован: Ср ноя 18, 2009 12:50:31
Откуда: ковров

Сообщение xkp »

А как тогда учитывать это переполнение?
Может сделать как я выше постом написал но еще в tim1_cap сбрасывать таймер счетчик каждый раз? тогда и вычитание не нужно будет.
R5VCH
Хотелки:
СпойлерАналоговый осциллограф С1-112, С1-118, другие
не/рабочие модули от комплекса ОДА-102
всё что касается AVR, arduino, raspberry
всё что касается КВ-УКВ-радиосвязи, mashtastic
Контактная информация:
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

Никак его не надо учитывать. Есть только одно условие - разница между предыдущим и текущим значением должна быть меньше 0xFFFF для 16 бит счетчика если он работает только на увеличение и 0x7FFF если меняться может в произвольную сторону иначе никак нельзя будет определить направление изменения.
Контактная информация:
xkp
Опытный кот
Аватара пользователя
Сообщения: 781
Зарегистрирован: Ср ноя 18, 2009 12:50:31
Откуда: ковров

Сообщение xkp »

так разница ни как не может быть больше FFFF, т.к. счетчик считает только до FFFF а потом обнуляется.
R5VCH
Хотелки:
СпойлерАналоговый осциллограф С1-112, С1-118, другие
не/рабочие модули от комплекса ОДА-102
всё что касается AVR, arduino, raspberry
всё что касается КВ-УКВ-радиосвязи, mashtastic
Контактная информация:
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

А если он за время опроса 3 раза прокрутится через переполнение? посчитанная разница конечно будет меньше FFFF но она будет далека от реальной.
Контактная информация:
xkp
Опытный кот
Аватара пользователя
Сообщения: 781
Зарегистрирован: Ср ноя 18, 2009 12:50:31
Откуда: ковров

Сообщение xkp »

так в этом и есть мой опрос. Я еще с самого начала писал
Если да то как и сколько байт памяти будет занимать максимально возможный результат? Думаю 3 байта...
может в tim1_over (по переполнению) каждый раз инкрементировать старший (третий) бай. а в tim1_capt уже работать (вычитать) не с 2 байтами а с 3.
R5VCH
Хотелки:
СпойлерАналоговый осциллограф С1-112, С1-118, другие
не/рабочие модули от комплекса ОДА-102
всё что касается AVR, arduino, raspberry
всё что касается КВ-УКВ-радиосвязи, mashtastic
Контактная информация:
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

С 3-мя байтами будут потенциальные проблемы. 16-битный счетчик имеет специальный механизм синхронизации, а вот с 3-м байтом надо что-то делать. будет промежуток времени между чтением первых 16 бит и 3-го байта когда могут произойти несинхронизированные изменения. Допустим, таймер досчитал до FFFF и мы это значение считали на следующем такте он переполняется возникает прерывание и в 3-й байт уходит +1, потом мы считываем третий байт который уже не соответствует значению счетчика считанному несколькими тактами ранее.
Контактная информация:
akl
Друг Кота
Сообщения: 4470
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

xkp писал(а):может в tim1_over (по переполнению) каждый раз инкрементировать старший (третий) бай. а в tim1_capt уже работать (вычитать) не с 2 байтами а с 3.
Да, именно так. С учётом того, что на время обработки прерывания флаг I в SREG сбрасывается аппаратно и прерывание tim1_capt имеет более высокий приоритет чем tim1_over. Т.е. если прерывание переполнения пришло хоть на один такт раньше захвата, программа сработает правильно и старший байт счетчика инкрементируется, а из ICR1 будет считано правильное значение. Если же переполнение пришло в обработчике захвата, то тут может быть несколько вариантов
- Работа по одному периоду. Просто таймер останавливается, прерывания запрещаются, полученное значение счётчика используется для обработки.
- Работа по заданному времени измерения, т.е. когда измеряется целое число периодов. По захвату считывается ICR1 и идёт анализ окончания времени измерения. Если время измерения закончилось и нет требования переполнения, то таймер останавливается, прерывания запрещаются, полученное значение счётчика используется для обработки. Если время измерения закончилось и есть требование переполнения, то измерение продолжается до тех пор пока не будет необслуженного переполнения. Некоторые разруливают эту ситуацию анализом считанного ICR1, но мне такой анализ не нравится.
xkp
Опытный кот
Аватара пользователя
Сообщения: 781
Зарегистрирован: Ср ноя 18, 2009 12:50:31
Откуда: ковров

Сообщение xkp »

Может есть МК AVR с 24-битным таймер-счетчиком?
R5VCH
Хотелки:
СпойлерАналоговый осциллограф С1-112, С1-118, другие
не/рабочие модули от комплекса ОДА-102
всё что касается AVR, arduino, raspberry
всё что касается КВ-УКВ-радиосвязи, mashtastic
Контактная информация:
Мучитель микросхем
Сообщения: 453
Зарегистрирован: Ср июн 08, 2011 20:25:20

Сообщение bob1 »

серия Xmega. Там 16 битные счетчики можно через систему событий соединить.
Контактная информация:
Ответить

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