Попадёт, не путайте людей.
Ассемблер (ASM) для AVR в вопросах и ответах
- Сообщения: 615
- Зарегистрирован: Вс дек 28, 2014 21:54:05
[uquote="Alexeyslav",url="/forum/viewtopic.php?p=3557822#p3557822"]Скорей ньюансы со считыванием регистров. Там имеется защёлка, когда один регистр читаешь то пока второй не прочитаешь защёлка не уберётся и новое значение в регистр не попадёт.[/uquote]
Попадёт, не путайте людей.
Попадёт, не путайте людей.
Я всё-всё узнAю и стану профессором.
- Реклама
[uquote="МКС",url="/forum/viewtopic.php?p=3557561#p3557561"]ADMUX (ADLAR = 1)
in XH, ADCH
in XL, ADCL[/uquote]
МКС, если вам достаточно 8 старших бит от АЦП, то выровненный в лево результат читайте из старшего регистра АЦП, а младший не трогайте совсем.
При чтении из младшего регистра доступ к регистрам АЦП блокируется пока не прочитаете старший. Т.е. АЦП не сможет поместить новое значение в регистры пока не прочитаете в программе старший регистр!
Поэтому или пользуетесь только старшим регистром или читаете сначала младший, а потом старший.
in XH, ADCH
in XL, ADCL[/uquote]
МКС, если вам достаточно 8 старших бит от АЦП, то выровненный в лево результат читайте из старшего регистра АЦП, а младший не трогайте совсем.
При чтении из младшего регистра доступ к регистрам АЦП блокируется пока не прочитаете старший. Т.е. АЦП не сможет поместить новое значение в регистры пока не прочитаете в программе старший регистр!
Поэтому или пользуетесь только старшим регистром или читаете сначала младший, а потом старший.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
- Сообщения: 147
- Зарегистрирован: Чт янв 10, 2013 21:03:18
Alexeyslav, akl, dgrett, Kavka - очень выручили ребята! Все так и было! Проблема исчезла после перестановки порядка считывания регистров (ADCL затем ADCH). Очень благодарен!!!
Эх, давно это было...
[uquote="Z_h_e",url="/forum/viewtopic.php?p=2898950#p2898950"]Вместо того, чтобы сладко спать, я до сего времени пытался запустить Ваш макрос.[/uquote]Z_h_e, как же я вас понимаю.
[uquote="Z_h_e",url="/forum/viewtopic.php?p=2898950#p2898950"]Данный макрос коварен.
Если Вы напишите PUSH Я1, то компилятор выдаст ошибку, а если ENTER Я1, то компилятор это проглотит и регистр не будет сохранен. Так что тут проще вляпаться, чем перечислять ПушиПопы.[/uquote][uquote="ARV",url="/forum/viewtopic.php?p=2899099#p2899099"]при наличии таких мощных макросов слабО сделать так, чтобы эта ситуация обрабатывалась?
[/uquote]
Слегка
модифицированный вариант.
[uquote="Z_h_e",url="/forum/viewtopic.php?p=2898950#p2898950"]Вместо того, чтобы сладко спать, я до сего времени пытался запустить Ваш макрос.[/uquote]Z_h_e, как же я вас понимаю.
[uquote="Z_h_e",url="/forum/viewtopic.php?p=2898950#p2898950"]Данный макрос коварен.
Слегка
Спойлер
Код: Выделить всё
; -----------------------------------------------
; Авторы: ARV, Z_h_e, Kavka с форума radiokot.ru
; -----------------------------------------------
#include <avr/io.h>
.macro ENTER arg:vararg ; макрос имеет переменное число параметров
.set selector, 0 ; в этой переменной будем отмечать нужные регистры
.set sel_sreg, 0 ; в этой переменной будем отмечать сохранение SREG
; перебераем аргументы и проверяем на допустимость
.irp reg,\arg
.set ch, 1
.irp p, r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16,r17,r18,r19,r20,r21,r22,r23,r24,r25,r26,r27,r28,r29,r30,r31
.if (\p == \reg) ; если аргументом макроса совпадает с элементов из списка
.set ch, 0
.endif
.endr
.irp p, R0,R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,R12,R13,R14,R15,R16,R17,R18,R19,R20,R21,R22,R23,R24,R25,R26,R27,R28,R29,R30,R31
.if (\p == \reg)
.set ch, 0
.endif
.endr
.irp p, xl,xh,yl,yh,zl,zh,sreg,XL,XH,YL,YH,ZL,ZH,SREG
.if (\p == \reg)
.set ch, 0
.endif
.endr
.if ( ch )
; ругаемся если аргумент не опознан... :-)
.print "Error: macro ENTER - unkown register"
.err
.endif
.endr
; перебрать аргументы и отметить их битами в selector
.irp reg,\arg
.set i, 0
; надо перечислить все регистры по порядку!!!
.irp p, r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16,r17,r18,r19,r20,r21,r22,r23,r24,r25,r26,r27,r28,r29,r30,r31
.if (\p == \reg) ; если аргументом макроса совпадает с элементов из списка
.set selector ,(selector | (1 << i)) ; сделаем отметку в нужном бите
.endif
.set i, i+1 ; и продолжим счет
.endr
.endr
.irp reg,\arg
.set i, 0
.irp p, R0,R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,R12,R13,R14,R15,R16,R17,R18,R19,R20,R21,R22,R23,R24,R25,R26,R27,R28,R29,R30,R31
.if (\p == \reg)
.set selector ,(selector | (1 << i))
.endif
.set i, i+1
.endr
.endr
; альтернативные названия регистров
.irp reg,\arg
.set i, 26
; надо перечислить все регистры в соответствии с номерами
.irp p, XL,XH,YL,YH,ZL,ZH
.if (\p == \reg)
.set selector ,(selector | (1 << i))
.endif
.set i, i+1
.endr
.endr
.irp reg,\arg
.set i, 26
.irp p, xl,xh,yl,yh,zl,zh
.if (\p == \reg)
.set selector ,(selector | (1 << i))
.endif
.set i, i+1
.endr
.endr
; проверяем список аргументов на SREG
.irp reg,\arg
.irp p, SREG, sreg
.if (\p == \reg)
.set selector ,(selector | 1) ; сделаем отметку для r0
.set sel_sreg ,1 ; сделаем отметку для SREG
.endif
.endr
.endr
; сохраняем регистры
; сначала r0
.if (selector & (1))
push r0
.endif
; потом SREG
.if (sel_sreg)
in r0, _SFR_IO_ADDR(SREG) ; _SFR_IO_ADDR(SREG) - извлекаем адрес порта
push r0
.endif
; наконец все остальные, перебрать биты selector от МЛАДШЕГО к старшему и сохранить нужные регистры
.set i, 1
.irp p, r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16,r17,r18,r19,r20,r21,r22,r23,r24,r25,r26,r27,r28,r29,r30,r31
.if (selector & (1<< i))
push \p
.endif
.set i, i+1
.endr
.endm
;----------------------------------------
.macro LEAVE
.set i, 31
; регистры до r1
.irp p, r31,r30,r29,r28,r27,r26,r25,r24,r23,r22,r21,r20,r19,r18,r17,r16,r15,r14,r13,r12,r11,r10,r9,r8,r7,r6,r5,r4,r3,r2,r1
.if selector &(1<< i)
; если бит в маске установлен - регистр извлекается из стека
pop \p
.endif
; перебор битов ведется в обратном порядке!!!
.set i, i - 1
.endr
.if (sel_sreg)
pop r0
out _SFR_IO_ADDR(SREG), r0
.endif
.if (selector & (1))
pop r0
.endif
.endm
; Например, вот такой исходник
;.global main
;main:
;ENTER r2,r3,SREG,ZH,ZL
;nop
;LEAVE
; Тут нужен препроцесор, т.к. avr-as его не умеет,
; а определения регистров ввода-вывода прописаны
; в Си-шных заголовочных файлах (привет SREG :-) ).
; С помощью вот таких командочек
; avr-gcc -E -mmcu=atmega48 gnu-as_macros.S | avr-as -mmcu=atmega48 -
; avr-objdump -d a.out
; Получим вот такой код
;00000000 <main>:
; 0: 0f 92 push r0
; 2: 0f b6 in r0, 0x3f ; 63
; 4: 0f 92 push r0
; 6: 2f 92 push r2
; 8: 3f 92 push r3
; a: ef 93 push r30
; c: ff 93 push r31
; e: 00 00 nop
; 10: ff 91 pop r31
; 12: ef 91 pop r30
; 14: 3f 90 pop r3
; 16: 2f 90 pop r2
; 18: 0f 90 pop r0
; 1a: 0f be out 0x3f, r0 ; 63
; 1c: 0f 90 pop r0
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Что-то крепко торможу - поясните пожалуйста.
AVR MEGA использую таймер 1 в режиме WGM10 =1, WGM11 =0, WGM12 =0, WGM13 =1
От скольких и до скольких считает собственно таймер и в какой момент обновляется позиция по которой переключается ШИМ выход ? Не момент переключения выхода а момент с которого число для сравнения, загруженное в OCR1A(B) будет актуально. При каком значении таймера. (предполагаю что 0)
А второй вопрос - вот такой код : (Ячейка может содержать значения 1-4), R1=0, P1-P4 - метки на некие программные действия, ВЫХОД - ничего не делать как вообще работает и зачем он такой сложный...
lds r24, Ячейка
lds r25, Ячейка
cpi r24, 2
cpc r25, R1
breq P2
cpi r24, 3
cpc r25, R1
brcc P3
sbiw r24, 1
brne ВЫХОД
rjmp P1
P3:
cpi r24, 3
cpc r25, R1
breq P4
sbiw r24, 4
brne ВЫХОД
AVR MEGA использую таймер 1 в режиме WGM10 =1, WGM11 =0, WGM12 =0, WGM13 =1
От скольких и до скольких считает собственно таймер и в какой момент обновляется позиция по которой переключается ШИМ выход ? Не момент переключения выхода а момент с которого число для сравнения, загруженное в OCR1A(B) будет актуально. При каком значении таймера. (предполагаю что 0)
А второй вопрос - вот такой код : (Ячейка может содержать значения 1-4), R1=0, P1-P4 - метки на некие программные действия, ВЫХОД - ничего не делать как вообще работает и зачем он такой сложный...
lds r24, Ячейка
lds r25, Ячейка
cpi r24, 2
cpc r25, R1
breq P2
cpi r24, 3
cpc r25, R1
brcc P3
sbiw r24, 1
brne ВЫХОД
rjmp P1
P3:
cpi r24, 3
cpc r25, R1
breq P4
sbiw r24, 4
brne ВЫХОД
- Реклама
В DS на меги явно указано когда для режима 9 идет занесение. За счет буфера можно заносить не заботясь о глюках. Актуальное значение в OCR1A будет выполнено в следующих, после переноса циклах.

Спойлер
- Вложения
-
- M8515_COMP9.PNG
- (76.06 КБ) 429 скачиваний
А величина этого BOTTOM чем определяется - так как похоже не до 65535 считает и по коду вопрос стоит.
Там же в DS
По коду. Херь какая-то.BOTTOM Signalize that TCNTn has reached minimum value (zero).
- Сообщения: 147
- Зарегистрирован: Чт янв 10, 2013 21:03:18
Подскажите, как правильно организовать спящий режим во время работы АЦП в ATmega8 и самое главное как из него выйти сразу же после окончания однократного преобразования? Вот фрагмент программы:
main:
/
/ ; выполняется программа
/
/
sleep ; здесь надо заснуть, что-бы работе АЦП ничего не мешало
ldi R16, 0b00000000
out ADMUX, R16
ldi R16, 0b11001100
out ADCSRA, R16
; здесь надо проснуться
in XL, ADCL
in XH, ADCH
mov R17, XL
mov R18, XH
sleep ; здесь надо опять заснуть, что-бы работе АЦП ничего не мешало
m7: ldi R16, 0b00000000
out ADMUX, R16
ldi R16, 0b11001100
out ADCSRA, R16
; здесь надо опять проснуться
in XL, ADCL
in XH, ADCH
cp XL, R17
cpc XH, R18
brne main
cp XL, YL
cpc XH, YH
breq main
brlo m3
rcall vpravo
rjmp main
m3: rcall vlevo
rjmp main
main:
/
/ ; выполняется программа
/
/
sleep ; здесь надо заснуть, что-бы работе АЦП ничего не мешало
ldi R16, 0b00000000
out ADMUX, R16
ldi R16, 0b11001100
out ADCSRA, R16
; здесь надо проснуться
in XL, ADCL
in XH, ADCH
mov R17, XL
mov R18, XH
sleep ; здесь надо опять заснуть, что-бы работе АЦП ничего не мешало
m7: ldi R16, 0b00000000
out ADMUX, R16
ldi R16, 0b11001100
out ADCSRA, R16
; здесь надо опять проснуться
in XL, ADCL
in XH, ADCH
cp XL, R17
cpc XH, R18
brne main
cp XL, YL
cpc XH, YH
breq main
brlo m3
rcall vpravo
rjmp main
m3: rcall vlevo
rjmp main
Как вариант
Спойлер
Код: Выделить всё
;
.include "m8def.inc"
.cseg
.org 0
;ВЕКТОР ПРЕРЫВАНИЙ
RESET:
rjmp initial
.org 0x0E
ADC_COMPLETE:
in XL, ADCL
in XH, ADCH
RET
;*************************************************
initial:
CLI
ldi R16,low(RAMEND)
out SPL,R16
ldi R16,high(RAMEND)
out SPH,R16
GO:
LDI R16,1<<SE|1<<SM2 ; ADC NOISE
OUT MCUCR,R16
ldi R16, 0b00000000
out ADMUX, R16
main:
LDI R16,1<<ADEN|1<<ADSC|1<<ADIE|1<<ADIF|1<<ADPS2 ;/16
OUT ADCSRA, R16
SEI
sleep ; здесь надо заснуть, что-бы работе АЦП ничего не мешало
; NOP
;ldi R16, 0b00000000
;out ADMUX, R16
;ldi R16, 0b11001100
;out ADCSRA, R16
; здесь надо проснуться
; in XL, ADCL
; in XH, ADCH
mov R17, XL
mov R18, XH
SBI ADCSRA,ADSC
SEI
sleep ; здесь надо опять заснуть, что-бы работе АЦП ничего не мешало
; NOP
m7:
; ldi R16, 0b00000000
;out ADMUX, R16
;ldi R16, 0b11001100
;out ADCSRA, R16
; здесь надо опять проснуться
;in XL, ADCL
;in XH, ADCH
cp XL, R17
cpc XH, R18
brne GO
cp XL, YL
cpc XH, YH
breq GO
brlo m3
rcall vpravo
rjmp GO
m3:
rcall vlevo
rjmp GO
VPRAVO:
RET
VLEVO:
RET
.EXIT
интересно, а что может мешать работе АЦП?
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
- Сообщения: 147
- Зарегистрирован: Чт янв 10, 2013 21:03:18
У меня в двух младших битах числа нестабильно фиксируются. Прочитал, что это может быть результат помехи от АЛУ и др. периферии
Сначала проверьте качество разводки AGND, фильтрацию AVCC потом уже АЛУ...
- Сообщения: 147
- Зарегистрирован: Чт янв 10, 2013 21:03:18
Согласен. Я проверяю программу на самодельном отладочном устройстве, где на выводы AVcc и AREF соединены вместе и подключены к +5V через дроссель 10 мкГн. К обоим концам дросселя подпаяны конденсаторы по 0,1 мкФ на общий вывод. А вот печатная плата отладчика односторонняя и дорожки с подводом питания к АЦП относительно длинные. Сейчас делаю печатную плату из двухстороннего фольгированного стеклотекстолита с другой разводкой дорожек (более короткой длиной) Верхний слой фольги печатной платы оставлю в качестве экрана.
Просто соблюдения схемы ещё ндостаточно, нужно соблюсти ещё и топологию на плате. Так чтобы по AGND проводу не шли цифровые токи. На дорожке даже в 1мм шириной миливольты набираются только так!
[uquote="МКС",url="/forum/viewtopic.php?p=3560981#p3560981"]У меня в двух младших битах числа нестабильно фиксируются...[/uquote]
Из даташита:
Из даташита:
±2 LSB Absolute Accuracy
Docendo discimus
- Сообщения: 473
- Зарегистрирован: Ср янв 11, 2012 18:20:26
[uquote="МКС",url="/forum/viewtopic.php?p=3560981#p3560981"]У меня в двух младших битах числа нестабильно фиксируются.[/uquote]
Недавно тоже испытал такое. Помогла установка после некоторых команд небольших (10мсек) задержек или просто nop-ов.
Недавно тоже испытал такое. Помогла установка после некоторых команд небольших (10мсек) задержек или просто nop-ов.
если "мсек" это МИЛЛИсекунды, то 10 - это очень много! это очень большая задержка по МК-шным меркам. и тут явно что-то не так в схемотехнике, раз нестабильность показаний лечится таким способом...shonty писал(а):Помогла установка после некоторых команд небольших (10мсек) задержек или просто nop-ов
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Для повышения стабильности значений АЦП сделан специальный режим сна 
, когда тактирование ядра, портов ввода-вывода останавливается и обслуживаются только разрешенные прерывания.ADC Noise Reduction
Спойлер
- Вложения
-
- ADC_NOISE.PNG
- (66.23 КБ) 488 скачиваний
[uquote="МКС",url="/forum/viewtopic.php?p=3560981#p3560981"]...нестабильно фиксируются...[/uquote]
Определиться бы для начала - насколько точные значения нужны? Для чего?
Определиться бы для начала - насколько точные значения нужны? Для чего?
Docendo discimus


