Обсуждаем контроллеры компании Atmel.
Ответить

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

Пн июн 06, 2022 11:44:47

Подскажите про ШИМ... Его выполнение должно быть строго в пределах вектора прерывание или можно, "как-то" вынести за пределы вектора в основное тело программы. Я сделал измеритель тока мотора и мне надо его остановить при увеличении на него нагрузки... Но я еще присандалел ШИМ индикацию, и когда появляется индикация, я не могу остановить мотор, т.е. он остановится после выполнения ШИМ. Хотелось бы, что при выполнение ШИМ, я мог останавливать мотор... Пробовал запихнуть в основной цикл ШИМ... не работает индикация, а в таймере работает...

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

Пн июн 06, 2022 12:44:43

Есть такое понятие как время реакции. Время реакции локально, пример, защита двигателя по току, время реакции системы в целом. Либо время реакции на кнопку скажем. Включить двигатель, выключить. Здесь мы оперируем в десятках мс.

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

Пн июн 06, 2022 13:17:31

Подскажите про ШИМ... Его выполнение должно быть строго в пределах вектора прерывание или можно, "как-то" вынести за пределы вектора в основное тело программы. Я сделал измеритель тока мотора и мне надо его остановить при увеличении на него нагрузки... Но я еще присандалел ШИМ индикацию, и когда появляется индикация, я не могу остановить мотор, т.е. он остановится после выполнения ШИМ. Хотелось бы, что при выполнение ШИМ, я мог останавливать мотор... Пробовал запихнуть в основной цикл ШИМ... не работает индикация, а в таймере работает...

у вас программный ШИМ, что ли? что такое "ШИМ-индикация" и как она связана с управлением мотором?

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

Пн июн 06, 2022 15:00:53

Под ШИМ индикацией, я понимаю плавное мигание светодиода. А мотор посадил через токоизмеритель и пороговый уровень на отдельных микрухал, и в МК приходит 1 или 0 на PCINT. Так вот, когда "Плавное включение светодиода" работает, приходящая единица по PCINT, не срабатывает, пока не отработает вектор прерывания таймера... Вот думал разместить "Плавное включение светодиода" в основной цикл программы, чтоб его можно прервать вектором, но не работает. Отсюда вопрос, может ШИМ работать вне вектора прерывания...

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

Пн июн 06, 2022 15:07:41

Двигатель важнее. Поэтому, сделай аппаратный ШИМ для светодиодов

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

Пн июн 06, 2022 15:08:18

я не понимаю, как там у вас всё устроено...
ШИМ мотора аппаратный?
ШИМ светодиода аппаратный?
что за прерывания - по таймеру или от совпадения ШИМ?
если вы пишите на ассемблере, что мешает вам разрешить прерывания сразу при входе в обработчик "мешающего" прерывания?

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

Пн июн 06, 2022 15:30:49

Примерный код, при котором шим в таймере и он работает, но когда нужно отработать остановку, то при работе индикации, ясное дело, мотор не остановится...

Спойлер.include "tn261Adef.inc"

.def Temp0=R16
.def Temp1=R17
.def Temp2=R18
.def Temp3=R19
.def Temp4=R20
.def Temp5=R21
.def Temp6=R22
.def Temp7=R23
.def Temp8=R24
.def Temp9=R25

.dseg

.cseg

.org 0

rjmp RESET ; Reset Handler
reti ;rjmp EXT_INT0 ; IRQ0 Handler
rjmp PCINT ; PCINT Handler
reti ;rjmp TIM1_COMPA ; Timer1 CompareA Handler
reti ;rjmp TIM1_COMPB ; Timer1 CompareB Handler
reti ;rjmp TIM1_OVF ; Timer1 Overflow Handler
rjmp TIM0_OVF ; Timer0 Overflow Handler
reti ;rjmp USI_START ; USI Start Handler
reti ;rjmp USI_OVF ; USI Overflow Handler
reti ;rjmp EE_RDY ; EEPROM Ready Handler
reti ;rjmp ANA_COMP ; Analog Comparator Handler
reti ;rjmp ADC_ISR ; ADC Conversion Handler
reti ;rjmp WDT ; WDT Interrupt Handler
reti ;rjmp EXT_INT1 ; IRQ1 Handler
reti ;rjmp TIM0_COMPA ; Timer0 CompareA Handler
reti ;rjmp TIM0_COMPB ; Timer0 CompareB Handler
reti ;rjmp TIM0_CAPT ; Timer0 Capture Event Handler
reti ;rjmp TIM1_COMPD ; Timer1 CompareD Handler
reti ;rjmp FAULT_PROTECTION ; Timer1 Fault Protection

RESET:
;(DDA7|DDA6|DDA5|DDA4|DDA3|DDA2|DDA1|DDA0)
ldi Temp0,0b00000000
out DDRA,Temp0

;(DDB7|DDB6|DDB5|DDB4|DDB3|DDB2|DDB1|DDB0)
ldi Temp0,0b00111110
out DDRB,Temp0

;(PORTA7|PORTA6|PORTA5|PORTA4|PORTA3|PORTA2|PORTA1|PORTA0)
ldi Temp0,0b11111111 ; подтяжка "1"
out PortA,Temp0

sbi PortB,7 ; подтяжка "1", для ресет
sbi PortB,6 ; подтяжка "1", для датчика вращения
sbi PortB,0 ; подтяжка "1", для токоизмерения

;ldi Temp0,high(RAMEND)
;out SPH,Temp0
ldi Temp0,low(RAMEND)
out SPL,Temp0

;(BODS|PUD|SE|SM1|SM0|BODSE|ISC01|ISC00)
ldi Temp0,0b00000000 ; PUD = 0, настройка портов в режим pull-up
out MCUCR,Temp0

;(-|-|-|-|PRTIM1|PRTIM0|PRUSI|PRADC)
ldi Temp0,0b00000011
out PRR,Temp0

;sbi ACSRA,ACD ; Отключение компоратора

;(ADEN|ADSC|ADATE|ADIF|ADIE|ADPS2|ADPS1|ADPS0)
;ldi Temp0,0b10001000
;out ADCSRA,Temp0

;(BIN|GSEL|-|REFS2|MUX5|ADTS2|ADTS1|ADTS0)
;ldi Temp0,0b00000100
;out ADCSRB,Temp0

;(REFS1|REFS0|ADLAR|MUX4|MUX3|MUX2|MUX1|MUX0)
;ldi Temp0,0b00100110 ; ADC6
;out ADMUX,Temp0

;(ADC6D|ADC5D|ADC4D|ADC3D|AREFD|ADC2D|ADC1D|ADC0D)
ldi Temp0,0b11111111
out DIDR0,Temp0

;(ADC10D|ADC9D|ADC8D|ADC7D|-|-|-|-)
ldi Temp0,0b11110000
out DIDR1,Temp0

;(OCIE1D|OCIE1A|OCIE1B|OCIE0A|OCIE0B|TOIE1|TOIE0|TICIE0)
ldi Temp0,0b00000010
out TIMSK,Temp0

;(TCW0|ICEN0|ICNC0|ICES0|ACIC0|-|-|CTC0)
ldi Temp0,0b10000000 ; 16bit
out TCCR0A,Temp0

;(-|-|-|TSM|PSR0|CS02|CS01|CS01)
ldi Temp0,0b00000100 ; CK/256
out TCCR0B,Temp0

;(COM1A1|COM1A0|COM1B1|COM1B0|FOC1A|FOC1B|PWM1A|PWM1B)
ldi Temp0,0b01010011 ; enables PWM OCR1A,OCR1B
out TCCR1A,Temp0

;(PWM1X|PSR1|DTPS11|DTPS10|CS13|CS12|CS11|CS10)
ldi Temp0,0b00000100 ; CK/8
out TCCR1B,Temp0

;(COM1A1S|COM1A0S|COM1B1S|COM1B0S|COM1D1|COM1D0|FOC1D|PWM1D)
;ldi Temp0,0b00000000
;out TCCR1C,Temp0

;(FPIE1|FPEN1|FPNC1|FPES1|FPAC1|FPF1|WGM11|WGM10)
ldi Temp0,0b00000000 ; Fast PWM
out TCCR1D,Temp0

;(INT1|INT0|PCIE1|PCIE0|-|-|-|-)
ldi Temp0,0b00110000
out GIMSK,Temp0

;(PCINT7|PCINT6|PCINT5|PCINT4|PCINT3|PCINT2|PCINT1|PCINT0)
ldi Temp0,0b01111111
out PCMSK0,Temp0

;(PCINT15|PCINT14|PCINT13|PCINT12|PCINT11|PCINT10|PCINT9|PCINT8)
ldi Temp0,0b01000001
out PCMSK1,Temp0

;Загрузка значений в память
;----------

;Начальные условия работы
;----------

ldi Temp0,100 ; яркость
out OCR1B,Temp0 ; красная индикация вкл.

sbi PortB,4 ; вкл. мотора
cbi PortB,5


sei

;Основное тело программы
;----------
cycle:;бесконечный цикл
rjmp cycle

;Вектор прерывания PCINT
;----------
PCINT:
rcall d_Delay ; задержка на дребезг кнопок

sbic PinB,0 ; датчик токоизмерения
sbis PinB,0

rjmp qwe
rjmp selector

qwe:
ldi Temp0,100
out OCR1B,Temp0 ; красная индикация вкл.

cbi PortB,4 ; выкл. мотора
cbi PortB,5

rjmp end0


selector:


end0:

clr Temp0 ; сброс таймера0
out TCNT0L,Temp0
out TCNT0H,Temp0

ldi Temp0,0b00000010 ; сброс прерывания таймера0
out TIFR,Temp0

ldi Temp0,0b00100000 ; обнуление лишнего прерывания
out GIFR,Temp0

reti

;Вектор прерывания TIM0
;----------
TIM0_OVF:


green_led:;зеленая индикация
ldi Temp7,0

pwm_high0:
cpi Temp7,100 ; диапазон нарастания ШИМ
breq pwm_low0
inc Temp7
ldi Temp9,10 ; скорость ШИМ
rcall pwm_Delay

out OCR1A,Temp7 ; вывод ШИМ индикации

rjmp pwm_high0

pwm_low0:
cpi Temp7,0
breq pwm_end
dec Temp7
ldi Temp9,8 ; скорость ШИМ
rcall pwm_Delay

out OCR1A,Temp7 ; вывод ШИМ индикации

rjmp pwm_low0

red_led:;красная индикация
ldi Temp7,0

pwm_high1:
cpi Temp7,100 ; диапазон нарастания ШИМ
breq pwm_low1
inc Temp7
ldi Temp9,10 ; скорость ШИМ
rcall pwm_Delay

out OCR1B,Temp7 ; вывод ШИМ индикации

rjmp pwm_high1

pwm_low1:
cpi Temp7,0
breq pwm_end
dec Temp7
ldi Temp9,8 ; скорость ШИМ
rcall pwm_Delay

out OCR1B,Temp7 ; вывод ШИМ индикации

rjmp pwm_low1

pwm_end:
reti


Поэтому, я предположил запихнуть ШИМ в основной цикл

Спойлер.include "tn261Adef.inc"

.def Temp0=R16
.def Temp1=R17
.def Temp2=R18
.def Temp3=R19
.def Temp4=R20
.def Temp5=R21
.def Temp6=R22
.def Temp7=R23
.def Temp8=R24
.def Temp9=R25

.dseg

.cseg

.org 0

rjmp RESET ; Reset Handler
reti ;rjmp EXT_INT0 ; IRQ0 Handler
rjmp PCINT ; PCINT Handler
reti ;rjmp TIM1_COMPA ; Timer1 CompareA Handler
reti ;rjmp TIM1_COMPB ; Timer1 CompareB Handler
reti ;rjmp TIM1_OVF ; Timer1 Overflow Handler
rjmp TIM0_OVF ; Timer0 Overflow Handler
reti ;rjmp USI_START ; USI Start Handler
reti ;rjmp USI_OVF ; USI Overflow Handler
reti ;rjmp EE_RDY ; EEPROM Ready Handler
reti ;rjmp ANA_COMP ; Analog Comparator Handler
reti ;rjmp ADC_ISR ; ADC Conversion Handler
reti ;rjmp WDT ; WDT Interrupt Handler
reti ;rjmp EXT_INT1 ; IRQ1 Handler
reti ;rjmp TIM0_COMPA ; Timer0 CompareA Handler
reti ;rjmp TIM0_COMPB ; Timer0 CompareB Handler
reti ;rjmp TIM0_CAPT ; Timer0 Capture Event Handler
reti ;rjmp TIM1_COMPD ; Timer1 CompareD Handler
reti ;rjmp FAULT_PROTECTION ; Timer1 Fault Protection

RESET:
;(DDA7|DDA6|DDA5|DDA4|DDA3|DDA2|DDA1|DDA0)
ldi Temp0,0b00000000
out DDRA,Temp0

;(DDB7|DDB6|DDB5|DDB4|DDB3|DDB2|DDB1|DDB0)
ldi Temp0,0b00111110
out DDRB,Temp0

;(PORTA7|PORTA6|PORTA5|PORTA4|PORTA3|PORTA2|PORTA1|PORTA0)
ldi Temp0,0b11111111 ; подтяжка "1"
out PortA,Temp0

sbi PortB,7 ; подтяжка "1", для ресет
sbi PortB,6 ; подтяжка "1", для датчика вращения
sbi PortB,0 ; подтяжка "1", для токоизмерения

;ldi Temp0,high(RAMEND)
;out SPH,Temp0
ldi Temp0,low(RAMEND)
out SPL,Temp0

;(BODS|PUD|SE|SM1|SM0|BODSE|ISC01|ISC00)
ldi Temp0,0b00000000 ; PUD = 0, настройка портов в режим pull-up
out MCUCR,Temp0

;(-|-|-|-|PRTIM1|PRTIM0|PRUSI|PRADC)
ldi Temp0,0b00000011
out PRR,Temp0

;sbi ACSRA,ACD ; Отключение компоратора

;(ADEN|ADSC|ADATE|ADIF|ADIE|ADPS2|ADPS1|ADPS0)
;ldi Temp0,0b10001000
;out ADCSRA,Temp0

;(BIN|GSEL|-|REFS2|MUX5|ADTS2|ADTS1|ADTS0)
;ldi Temp0,0b00000100
;out ADCSRB,Temp0

;(REFS1|REFS0|ADLAR|MUX4|MUX3|MUX2|MUX1|MUX0)
;ldi Temp0,0b00100110 ; ADC6
;out ADMUX,Temp0

;(ADC6D|ADC5D|ADC4D|ADC3D|AREFD|ADC2D|ADC1D|ADC0D)
ldi Temp0,0b11111111
out DIDR0,Temp0

;(ADC10D|ADC9D|ADC8D|ADC7D|-|-|-|-)
ldi Temp0,0b11110000
out DIDR1,Temp0

;(OCIE1D|OCIE1A|OCIE1B|OCIE0A|OCIE0B|TOIE1|TOIE0|TICIE0)
ldi Temp0,0b00000010
out TIMSK,Temp0

;(TCW0|ICEN0|ICNC0|ICES0|ACIC0|-|-|CTC0)
ldi Temp0,0b10000000 ; 16bit
out TCCR0A,Temp0

;(-|-|-|TSM|PSR0|CS02|CS01|CS01)
ldi Temp0,0b00000100 ; CK/256
out TCCR0B,Temp0

;(COM1A1|COM1A0|COM1B1|COM1B0|FOC1A|FOC1B|PWM1A|PWM1B)
ldi Temp0,0b01010011 ; enables PWM OCR1A,OCR1B
out TCCR1A,Temp0

;(PWM1X|PSR1|DTPS11|DTPS10|CS13|CS12|CS11|CS10)
ldi Temp0,0b00000100 ; CK/8
out TCCR1B,Temp0

;(COM1A1S|COM1A0S|COM1B1S|COM1B0S|COM1D1|COM1D0|FOC1D|PWM1D)
;ldi Temp0,0b00000000
;out TCCR1C,Temp0

;(FPIE1|FPEN1|FPNC1|FPES1|FPAC1|FPF1|WGM11|WGM10)
ldi Temp0,0b00000000 ; Fast PWM
out TCCR1D,Temp0

;(INT1|INT0|PCIE1|PCIE0|-|-|-|-)
ldi Temp0,0b00110000
out GIMSK,Temp0

;(PCINT7|PCINT6|PCINT5|PCINT4|PCINT3|PCINT2|PCINT1|PCINT0)
ldi Temp0,0b01111111
out PCMSK0,Temp0

;(PCINT15|PCINT14|PCINT13|PCINT12|PCINT11|PCINT10|PCINT9|PCINT8)
ldi Temp0,0b01000001
out PCMSK1,Temp0

;Загрузка значений в память
;----------

;Начальные условия работы
;----------

ldi Temp0,100 ; яркость
out OCR1B,Temp0 ; красная индикация вкл.

sbi PortB,4 ; вкл. мотора
cbi PortB,5


sei

;Основное тело программы
;----------
cycle:;бесконечный цикл
;rjmp cycle

green_led:;зеленая индикация
ldi Temp7,0

pwm_high0:
cpi Temp7,100 ; диапазон нарастания ШИМ
breq pwm_low0
inc Temp7
ldi Temp9,10 ; скорость ШИМ
rcall pwm_Delay

out OCR1A,Temp7 ; вывод ШИМ индикации

rjmp pwm_high0

pwm_low0:
cpi Temp7,0
breq pwm_end
dec Temp7
ldi Temp9,8 ; скорость ШИМ
rcall pwm_Delay

out OCR1A,Temp7 ; вывод ШИМ индикации

rjmp pwm_low0

red_led:;красная индикация
ldi Temp7,0

pwm_high1:
cpi Temp7,100 ; диапазон нарастания ШИМ
breq pwm_low1
inc Temp7
ldi Temp9,10 ; скорость ШИМ
rcall pwm_Delay

out OCR1B,Temp7 ; вывод ШИМ индикации

rjmp pwm_high1

pwm_low1:
cpi Temp7,0
breq pwm_end
dec Temp7
ldi Temp9,8 ; скорость ШИМ
rcall pwm_Delay

out OCR1B,Temp7 ; вывод ШИМ индикации

rjmp pwm_low1

pwm_end:
rjmp cycle

;Вектор прерывания PCINT
;----------
PCINT:
rcall d_Delay ; задержка на дребезг кнопок

sbic PinB,0 ; датчик токоизмерения
sbis PinB,0

rjmp qwe
rjmp selector

qwe:
ldi Temp0,100
out OCR1B,Temp0 ; красная индикация вкл.

cbi PortB,4 ; выкл. мотора
cbi PortB,5

rjmp end0


selector:


end0:

clr Temp0 ; сброс таймера0
out TCNT0L,Temp0
out TCNT0H,Temp0

ldi Temp0,0b00000010 ; сброс прерывания таймера0
out TIFR,Temp0

ldi Temp0,0b00100000 ; обнуление лишнего прерывания
out GIFR,Temp0

reti

;Вектор прерывания TIM0
;----------
TIM0_OVF:
reti


И так индикация не работает. Вот это хотелось узнать... почему...

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

Вт июн 07, 2022 11:26:15

Странно, сейчас добавил... и заработало... Единственное что потом добавил это

cli
out OCR1A,Temp7
sei

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

Пт июн 10, 2022 14:08:53

Задержка в прерывании - это как матерится в дамском обществе.

Добавлено after 1 minute 38 seconds:
Код написан жутко.

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

Пт июн 10, 2022 16:58:00

Зависит от задачи. А данном случае три такта. Но и чем. Код. Ну да.

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

Чт дек 29, 2022 20:53:19

Здравствуйте. Возник вопрос, как в AVR ассемблере посчитать длину строки, размещенной в памяти программ директивой DB.
Например, в 8051 для этого достаточно отнять от адреса метки после строки, адрес метки самой строки. Сделано по-людски, один адрес - один байт.
Но в AVR, одному адресу зачем-то соответствует два байта, и я не очень понимаю, как оно там размещается, и как это считать

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

Чт дек 29, 2022 21:41:00

Ну так и считать
отнять от адреса метки после строки, адрес метки самой строки.
, только умножить на 2. в чём проблема?

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

Чт дек 29, 2022 21:47:55

Jack_A, а если строка с нечетным количеством символов? И добита нулем в конце до четного ?

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

Чт дек 29, 2022 22:48:21

Just_Fluffy писал(а):а если строка с нечетным количеством символов? И добита нулем в конце до четного ?

Оно само так делает :)
Код:
home/lester/AVR/avra-master/includes/m48def.inc(914) : PRAGMA directives currently ignored
asmtest.asm(31) : Warning : A .DB segment with an odd number of bytes is detected. A zero byte is added.

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

Пт дек 30, 2022 00:05:29

Shuspano, да, студия умная. Но вопрос остается - как определить нечетную длину строки?

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

Пт дек 30, 2022 03:21:13

Подсчитать число символов в строке, кроме нуля. Если младший байт 1, значит нечётное.

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

Пт дек 30, 2022 07:01:04

Shuspano, да, студия умная. Но вопрос остается - как определить нечетную длину строки?

Так, как говорит Demiurg. "В лоб" - программно. Сам так поступаю.
Код:
#define Text  "Ля-Ля-Ля"
.
.
.Macro   ldiw
ldi    @0L,low(@1)
ldi   @0H,High(@1)
.EndMacro
.
.
textptr: .db Text,'\0'   
.
.
ldiw Z,textptr*2
clr   r16
loop1:   
inc r16
lpm r17,Z+
tst r17
brne loop1
;            r16 - длина строки


Ну или совсем просто

ldi r16,STRLEN(Text)

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

Пт дек 30, 2022 12:26:59

Хе... "В лоб" там вообще не нужно знать конец строки, только начало. Но это только в Run-Time.
А на этапе компиляции, увы, только по дельте 2 меток, помноженной на 2. И принимать потом уже программные меры, что б не схавать лишний ноль.

С.Н.,
STRLEN(Text)
- простите, это что? Фишка препроцессора?
Каюсь, я уже достаточно давно перестала писать под АВР на асме... Хотя это был первый асм для МК, который изучала вместе с АВРками. Эхххх.. где моя любимая отладка 2313....

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

Пт дек 30, 2022 14:13:06

В avrasm2 такой директивы (strlen) нету...
Или макрос или чего-то из микрочипстудио...
:dont_know:

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

Пт дек 30, 2022 17:57:57

В avrasm2 такой директивы (strlen) нету...
Или макрос или чего-то из микрочипстудио...
:dont_know:

Нет проблем. Сам как-то пропустил.
Стр. 33.
Я сначала проверил, прежде чем выкладывать версию.
Вложения
AVRASM2 Assembler Manual.pdf
(312.32 KiB) Скачиваний: 56
Ответить