Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Импульс со сдвигом 120 эл. градусов
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Booleek789
Пытаюсь написать на МК Atmega8535 программу, представляющую собой одноканальную СИФУ, осуществляющую вывод короткого импульса на фазы А,В,С с фазовым сдвигом 120. эл градусов. (PinA4,Pina5,Pina6 соответственно) пишу на ассемблере. Поскольку для синхронизации в одноканальной СИФУ требуется 1 фаза, например А, то алгоритм таков: сеть переменного тока будет имитировать генератор прямоугольных импульсов частотой 50 Гц. По переднему фронту происходит прерывание, в котором перезапускается таймер Т0, отвечающий за выработку импульса в фазе А. Таймер досчитывает до записанного предварительно в регистр сравнения ocr0 значения "угла управления", срабатывает прерывание таймера Т0, в котором происходит выдача импульса в фазу А, в этом же прерывании происходит запуск таймера Т2, и когда он досчитает до значения 208 (при настройке Т2 с предделителем 256 время как раз составит 120 Эл градусов). Как только таймер Т2 досчитает, сработает прерывание таймера Т2, в котором произойдёт выдача импульса в фазу В, в этом же прерывании я перенастраиваю таймер на новые 120 Эл. градусов, и когда таймер опять досчитает, опять сработает прерывание, но произойдёт уже выдача импульса в фазу С (выбор нужной фазы реализован следующим образом, во время первого перехода в прерывание таймера Т2 мы увеличиваем значение регистра r24 на 1 (inc r24), потом сравниваем значение с числом 2, поскольку в r24 значение не равно 2 (проверку осуществляем командой breq - перейти, если равно), то осуществляется переход на выдачу импульса в фазе B, во время второго срабатывания значение в r24 уже будет равно 2, поэтому осуществится переход на выдачу импульса в фазе С. Код приложен ниже
CODE
.include "m8535def.inc"
.cseg
.org 0
rjmp reset
.org 0x001
rjmp synchr
.org 0x003
rjmp impulseT2
.org 0x013
rjmp impulseT0
.org 0x015
reset:
;????????????? ?????:
ldi r16,high(RAMEND)
out sph,r16
ldi r17,low(RAMEND)
out spl,r16
;????????? ??????:
ldi r16,0b11111000
out ddra,r16
ldi r16,0b00000111
out porta,r16
ldi r16,0b11111011
out ddrb,r16
ldi r16,0xff
out ddrc,r16
;????????? ??????? ??????????:
ldi r16,0b01100000
out gicr,r16
ldi r16,0b00000011
out mcucr,r16
ldi r16,0b01000000
out mcucsr,r16
;????????? ?????????? ?? ?????????? ??????? ? ?????? ???????:
ldi r16,0b00000010
out timsk,r16
ldi r16,0b00001101
out tccr0,r16
ldi r20,0b00001111
out ocr0,r20
main:
k1:
sbic pina,0
rjmp k1
sei
k2:
sbic pina,1
rjmp k2
cli
rjmp main
synchr:
cli
in r15,sreg
;?????????? ???????:
ldi r16,0b00000000
out timsk,r16
ldi r16,0b00011000
out tccr0,r16
clr r16
out tcnt0,r16
;????????? ???????:
ldi r16,0b00000010
out timsk,r16
ldi r16,0b00001101
out tccr0,r16
out sreg,r15
sei
reti
impulseT0:
cli
in r15,sreg
ldi r16,0b00000000
out timsk,r16
ldi r16,0b00011000
out tccr0,r16
clr r16
out tcnt0,r16
ldi r16,0b00010111
out porta,r16
clr r18
I1:
inc r18
cpi r18,0xff
brne I1
ldi r16,0b00000111
out porta,r16
ldi r16,0b00000110
out tccr2,r16
ldi r16,0b11010000
out ocr2,r16
ldi r16,0b10000000
out timsk,r16
out sreg,r15
sei
reti

impulseT2:
cli
in r15,sreg
ldi r16,0b00000000
out timsk,r16
ldi r16,0b00000000
out tccr2,r16
ldi r16,0b00000000
out tcnt2,r16
inc r24
cpi r24,0b00000010
breq C
B:
ldi r16,0b00000110
out tccr2,r16
ldi r16,0b11010000
out ocr2,r16
ldi r16,0b10000000
out timsk,r16
ldi r16,0b00100111
out porta,r16
clr r18
I11:
inc r18
cpi r18,0xff
brne I11
ldi r16,0b00000111
out porta,r16
out sreg,r15
sei
reti
C:
ldi r16,0b00000000
out timsk,r16
ldi r16,0b00000000
out tccr2,r16
clr r16
out tcnt2,r16
ldi r16,0b01000111
out porta,r16
clr r18
I111:
inc r18
cpi r18,0xff
brne I111
ldi r16,0b00000111
out porta,r16
out sreg,r15
sei
reti


Вроде алгоритм верный, но протеус выдаёт следующую ерунду:
Нажмите для просмотра прикрепленного файла

Помогите разобраться, в чём причина, вроде алгоритм верный. Самое интересное, что в этом случае можно было сослаться на глюк протеуса, но реальный МК выдаёт такие же сигналы.

P.S. С помощью программной задержки делать импульсы получалось.
domowoj
Цитата(Booleek789 @ Jan 6 2015, 09:57) *
Пытаюсь написать на МК Atmega8535 программу, представляющую собой одноканальную СИФУ,
осуществляющую вывод короткого импульса на фазы А,В,С с фазовым сдвигом 120. эл градусов

Не понятно почему выбраны восьмиразрядные таймеры,
вам же еще и двигать нужно эти импульсы в пределах 0...360 град по периоду каждой из фаз.
Задействуйте 16_ти разрядный таймер.
Сначала измерьте период в тиках таймера, затем поделив на 3 получите 120 градусов в тиках,
и уж потом можно ими манипулировать.
При использования втутреннего RC генератора МК можно вообще, манипулируя регистром
OSCCAL подстроить частоту таким образом, чтобы значение периода в тиках таймера было кратно 360,
тогда проще будет математика( не нужно будет делить на 3), т.е. быстрее будет работать ваша программа.

А не получилось у вас, наверное, потому, что где-нибудь напортачили,
хотя бы посмотреть на вашу конструкцию типа:
Цитата
synchr:
cli
;?????????? ???????:
...........................
sei
reti

Зачем "cli /sei" в теле обработчика прерывания???
Booleek789
Да, там действительно была небольшая ошибка, вроде разобрался. Спасибо за ответ!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.