Обсуждаем контроллеры компании Atmel.
Пн июн 06, 2022 11:44:47
Подскажите про ШИМ... Его выполнение должно быть строго в пределах вектора прерывание или можно, "как-то" вынести за пределы вектора в основное тело программы. Я сделал измеритель тока мотора и мне надо его остановить при увеличении на него нагрузки... Но я еще присандалел ШИМ индикацию, и когда появляется индикация, я не могу остановить мотор, т.е. он остановится после выполнения ШИМ. Хотелось бы, что при выполнение ШИМ, я мог останавливать мотор... Пробовал запихнуть в основной цикл ШИМ... не работает индикация, а в таймере работает...
Пн июн 06, 2022 15:00:53
Под ШИМ индикацией, я понимаю плавное мигание светодиода. А мотор посадил через токоизмеритель и пороговый уровень на отдельных микрухал, и в МК приходит 1 или 0 на PCINT. Так вот, когда "Плавное включение светодиода" работает, приходящая единица по PCINT, не срабатывает, пока не отработает вектор прерывания таймера... Вот думал разместить "Плавное включение светодиода" в основной цикл программы, чтоб его можно прервать вектором, но не работает. Отсюда вопрос, может ШИМ работать вне вектора прерывания...
Пн июн 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
И так индикация не работает. Вот это хотелось узнать... почему...
Чт дек 29, 2022 20:53:19
Здравствуйте. Возник вопрос, как в AVR ассемблере посчитать длину строки, размещенной в памяти программ директивой DB.
Например, в 8051 для этого достаточно отнять от адреса метки после строки, адрес метки самой строки. Сделано по-людски, один адрес - один байт.
Но в AVR, одному адресу зачем-то соответствует два байта, и я не очень понимаю, как оно там размещается, и как это считать