Вторник, 23.04.2024, 20:39
Вы вошли как Гость | Группа "Гости"Приветствую Вас Гость | RSS
Главная | Пропорциональное управление на МК с нуля - Страница 11 - Форум | Мой профиль | Регистрация | Выход | Вход
Обитель RC-инженера
Форма входа
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
Модератор форума: ВитГо  
Форум » Разработка электронных устройств » Разрабатываю ! » Пропорциональное управление на МК с нуля (пошаговое строительство пропорционального управления с нуля)
Пропорциональное управление на МК с нуля
uwrteyДата: Вторник, 19.03.2013, 10:08 | Сообщение # 151
Генерал-майор
Группа: Администраторы
Сообщений: 3270
Репутация: 11
Статус: Offline
да, в главном цикле я накосячил... huh

не успеваю за своими мыслями......
 
uwrteyДата: Вторник, 19.03.2013, 12:30 | Сообщение # 152
Генерал-майор
Группа: Администраторы
Сообщений: 3270
Репутация: 11
Статус: Offline
наверно как то так. ( я сейчас на работе, сосредоточится не могу )
Прикрепления: 7559055.asm (15.8 Kb)


не успеваю за своими мыслями......
 
ВитГоДата: Вторник, 19.03.2013, 13:55 | Сообщение # 153
Полковник
Группа: Администраторы
Сообщений: 2422
Репутация: 20
Статус: Offline
нет, так тоже не правильно:
Код


cicle:

     ldi Temp6, 0     ; счетчик отправленных каналов ( фаза передачи )

     ldi Temp7, 3     ; только что отправили синхроимпульс ( или это запуск МК )

loop_wait_2:      ; цикл вывода PPM

     cpi Temp6, 5     ; отправили синхроимпульс ???
     brne loop_wait_2    ; если нет, то циклимся

               

loop_wait_3:      ; цикл опроса каналов АЦП

     cpi Temp5, 3     ; прочитали все три канала ?
     brne loop_wait_3    ; если нет, то циклимся

     Rjmp cicle


у тебя должно быть одно прерывание по ocr !

для работы этого прерывания заводи переменные:
ch_count - количество каналов для передачи (или ты завтра, когда будешь делать 5ти канальную аппу - будешь все с нуля переписывать?)
curr_ch - номер текущего канала
ch_phase - фаза передачи (канальный импульс или пауза в 300 мкс)
pack_len - общая длительность пакета ppm (бывает 20 а бывает 22,5 или даже 25 мс)
ну и конечно массив для хранения длительностей каналов

вот это ты должен настроить в main своей программы (то есть при старте) после настроек портов, дисплеев и так далее..

после этого ты должен включить прерывания и включить процесс генерации
далее - захват данных с ацп и генерация сигнала ппм должны происходить автоматически в прерывании ocr ! без какого либо участия главной программы - поверь в ней ты найдешь чем заняться (и таймер полета считать, и на дисплее положение ручек рисовать, ну а в будущем микшированием заниматься)

соответственно в прерывании сразу проверяем фазу передачи (ch_phase) - если например =0 то значит переходим на передачу паузы в 300 мкс, и для следующего вызова (когда нужно будет передавать импульс) устанавливаем ch_phase = 1 и выходим из прерывания ! пусть дальше работает программа в main, для передачи сейчас ничего делать не нужно ! (все уже сделали, пауза передается)

если же ch_phase = 1 - значит нужно передавать импульс ! для этого на будущее устанавливаем ch_phase=0 (потом паузу передавать будем), и берем номер канала для передачи curr_ch и количество каналов всего ch_count - если curr_ch<ch_count то читаем значение канала из памяти и отправляем в ocr, если равны - то читаем значение паузы и отправляем в ocr
причем если отправили канал - то вычитаем его значение из длительности всей пачки (первоначально это pack_len) - таким образом после передачи всех каналов у нас будет известна общая длительность паузы..
далее, если передали все каналы и передаем паузу - то сбрасываем все переменные для передачи паузы перед нулевым каналом.. в том числе сбрасываем длительность паузы по значению pack_len - чтобы в новой пачке начать отсчет паузы заново
ну и в простом варианте здесь же можно читать все каналы АЦП (это плохой вариант, но он простой)
либо читать АЦП после передачи соответствующего канала (то есть когда передали канал, запускаем преобразование АЦП, и потом значение с АЦП забираем когда передаем паузу)...

вот где то такой алгоритм должен быть

поскольку вся работа в прерывании - то при входе в прерывание нужно сохранять все регистры (которые потрешь в работе) а на выходе их нужно восстановить - иначе не будет работать основная программа

сейчас попробуй набросать каркас процедуры прерывания без чтения значений ацп..

вообще начни с начала:
селектор фазы импульс\пауза
селектор канал\пауза пакета
и так далее..
таким образом и подойдешь уже к ацп....

цель : написать прерывание которое работает полностью отдельно от основной программы !!!

если это сделаешь - то вот тебе и многозадачность в передатчике :-) вернее двузадачность.. но в принципе на прерываниях можно делать сколько угодно таких задач (лишь бы производительности хватило)


Виталий (аka ВитГо)
 
uwrteyДата: Среда, 20.03.2013, 13:20 | Сообщение # 154
Генерал-майор
Группа: Администраторы
Сообщений: 3270
Репутация: 11
Статус: Offline
up

переменные так заводить ?

.set ch_count=2 ; - количество каналов для передачи
.set curr_ch=0 ;- номер текущего канала
.set ch_phase=0 ;- фаза передачи (канальный импульс или пауза в 300 мкс)
.set pack_len=40000 ;- общая длительность пакета ppm (длительность в "тиках таймера")

или переменные в РОН сделать?

.def ch_count=R22 ; указатель отправленного канала
.def curr_ch=R23 ;- номер текущего канала
.def ch_phase=R24 ;- фаза передачи (канальный импульс или пауза в 300 мкс)
.def pack_len=R25 ;- общая длительность пакета ppm (длительность в "тиках таймера")


не успеваю за своими мыслями......

Сообщение отредактировал uwrtey - Среда, 20.03.2013, 22:02
 
ВитГоДата: Среда, 20.03.2013, 15:23 | Сообщение # 155
Полковник
Группа: Администраторы
Сообщений: 2422
Репутация: 20
Статус: Offline
нет в регистрах точно не делать !!
ведь тогда их нельзя будет использовать в основной программе !!


Виталий (аka ВитГо)
 
uwrteyДата: Среда, 20.03.2013, 22:20 | Сообщение # 156
Генерал-майор
Группа: Администраторы
Сообщений: 3270
Репутация: 11
Статус: Offline
я не работал с переменными типа .SET ...=..., гугл особо не помог...
так что тут туплю....
можно ли с переменными такого типа работать как с РОН ?

например:

.set curr_ch=0___________________; номер текущего канала
....
....
INC curr_ch_____________________; увеличиваем номер канала ADC для чтения / так можно делать???


????

или такую переменную можно изменить только с помощью .set ?

например:

.set curr_ch=0_____________________; номер текущего канала
......
......
.set curr_ch=1_____________________; номер текущего канала


________________________________________________________

Цитата (ВитГо)
у тебя должно быть одно прерывание по ocr !

всмысле? прерывания по АЦП не должно быть?

видимо АЦП устроен аппаратно и процессор ему не нужен ( как с ШИМ ) ?

вижу два варианта:
1) можно генерировать АЦП по таймеру
2) можно генерировать АЦП вручную при входе в прерывание по таймеру ( скорее всего этот вариант )


не успеваю за своими мыслями......

Сообщение отредактировал uwrtey - Четверг, 21.03.2013, 01:22
 
uwrteyДата: Четверг, 21.03.2013, 01:21 | Сообщение # 157
Генерал-майор
Группа: Администраторы
Сообщений: 3270
Репутация: 11
Статус: Offline
Лучше я сразу покажу, что наделал - пока я совсем далеко не ушел.. smile ( а то сейчас наделаю делов... )

Виталий, посмотри пожалуйста, это Ты хотел увидеть ? и правильно ли я работаю с переменными ?
Прикрепления: 6512220.asm (9.2 Kb)


не успеваю за своими мыслями......

Сообщение отредактировал uwrtey - Четверг, 21.03.2013, 02:15
 
ВитГоДата: Четверг, 21.03.2013, 11:44 | Сообщение # 158
Полковник
Группа: Администраторы
Сообщений: 2422
Репутация: 20
Статус: Offline
неа, у тебя прямо си какой то :-)))

переменная это ячейка ОЗУ

ch_count: .byte 1

соответственно читаем переменную
LDS R16, ch_count

потом работаем с ней как с регистром R16

и в когда нужно сохраняем опять в ячейку памяти
STS ch_count, R16

конечно можно использовать и другие регистры (не только R16)


Виталий (аka ВитГо)
 
uwrteyДата: Четверг, 21.03.2013, 13:30 | Сообщение # 159
Генерал-майор
Группа: Администраторы
Сообщений: 3270
Репутация: 11
Статус: Offline
ясно, спасибо biggrin
информацию взял тут , так и знал, что как то не так smile


не успеваю за своими мыслями......

Сообщение отредактировал uwrtey - Четверг, 21.03.2013, 22:02
 
uwrteyДата: Четверг, 21.03.2013, 23:56 | Сообщение # 160
Генерал-майор
Группа: Администраторы
Сообщений: 3270
Репутация: 11
Статус: Offline
Виталий, я постоянно путаюсь при работе с метками.
А если быть точнее, то путаюсь я в том, что не знаю работаю я с данными, содержащимися по адресу метки, или с адресом этой метки...

Цитата
LDI Загрузить константу

LDS Прямая загрузка

LD Косвенная загрузка

например:

здесь в регистровую пару загрузится адрес метки

Код

key_buff: .byte 1________________; зарезервируем 1 байт в ОЗУ

______________________________; загружаем адрес метки (key_buff) находящейся в ОЗУ в регистровую пару "Z"
___ldi ZL,low (key_buff)__________; младший байт адреса
___ldi ZH,high(key_buff)__________; старший байт адреса       


а вот ниже в регистровую пару сразу загрузим значение из константы

Код

.EQU ImpLen=0xCE4_________;константа

___LDI XH ,high(ImpLen)______; загрузим значение из константы
___LDI XL,low(ImpLen)________;


почему такая разница?


не успеваю за своими мыслями......

Сообщение отредактировал uwrtey - Пятница, 22.03.2013, 01:20
 
uwrteyДата: Пятница, 22.03.2013, 05:44 | Сообщение # 161
Генерал-майор
Группа: Администраторы
Сообщений: 3270
Репутация: 11
Статус: Offline
ну вот, исправил переменные.

осталось написать:
1) Проверку количества отправленных каналов. И если три канала отправлено, то отправлять синхроимпульс
2) Вычисление длины синхроимпульса

Добавлено (22.03.2013, 05:44)
---------------------------------------------
Виталий, а можно вместо

Код

    ldi YL, low(ADC_len)   ; загружаем в "Y" адрес метки "ADC_len"
    ldi YH, High(ADC_len)   ;

    ld XL, Y+    ; загружаем в "X" данные из адреса находящегося в "Y"
    ld XH, Y+    ;
       


сделать вот так

Код

    lds XL, ADC_len   ; загружаем в "X" данные из метки "ADC_len"
    lds XH, ADC_len+1   ;


???
Прикрепления: 6661971.asm (11.1 Kb)


не успеваю за своими мыслями......

Сообщение отредактировал uwrtey - Пятница, 22.03.2013, 21:39
 
ВитГоДата: Пятница, 22.03.2013, 07:42 | Сообщение # 162
Полковник
Группа: Администраторы
Сообщений: 2422
Репутация: 20
Статус: Offline
просто если LDI - то ты загружаешь в регистр число ! это может быть константа, а может быть адрес указанный в виде метки (это же тоже число)

а если LDS - то ты загружаешь в регистр содержимое ОЗУ по указанному адресу (константе) причем это может быть и метка и вручную заданная константа..

ну и по LD - ты загружаешь в регистр значение из содержимого ОЗУ адрес которого указан в регистровой паре (X, Y, Z)

ну и для чтения flash есть команда LPM - это чтение в регистр содержимого флеша, адрес всегда в регистре Z

поэтому вместо
Цитата (uwrtey)
Код

  ldi YL, low(ADC_len)   ; загружаем в "Y" адрес метки "ADC_len"
  ldi YH, High(ADC_len)   ;

  ld XL, Y+    ; загружаем в "X" данные из адреса находящегося в "Y"
  ld XH, Y+    ;
   


конечно можно

Цитата (uwrtey)
Код

  lds XL, ADC_len   ; загружаем в "Y" адрес метки "ADC_len"
  lds XH, ADC_len+1   ;


Виталий (аka ВитГо)
 
uwrteyДата: Пятница, 22.03.2013, 09:39 | Сообщение # 163
Генерал-майор
Группа: Администраторы
Сообщений: 3270
Репутация: 11
Статус: Offline
Цитата
конечно можно

ок. up Это радует. Значит в моей голове по тихоньку начинает наводится порядок.

Цитата
если LDS - то ты загружаешь в регистр содержимое ОЗУ по указанному адресу (константе) причем это может быть и метка и вручную заданная константа..

с меткой понятно, а как это "в ручную заданная константа"?
Ты имел ввиду, что можно указывать не только метку, но и просто адрес ОЗУ в виде числа...???


не успеваю за своими мыслями......

Сообщение отредактировал uwrtey - Пятница, 22.03.2013, 21:40
 
ВитГоДата: Пятница, 22.03.2013, 23:44 | Сообщение # 164
Полковник
Группа: Администраторы
Сообщений: 2422
Репутация: 20
Статус: Offline
Цитата (uwrtey)
с меткой понятно, а как это "в ручную заданная константа"?
Ты имел ввиду, что можно указывать не только метку, но и просто адрес ОЗУ в виде числа...???


конечно !
разверни смысл метки - это же просто число ! а число может быть и константой !
поэтому ничто тебе не мешает задавать адреса вручную.. просто так голову сломаешь все помнить и метками проще (особенно когда между двумя переменными воткнешь третью) - компилятор все сам рассчитывает
но иногда и вручную можно это делать


Виталий (аka ВитГо)
 
uwrteyДата: Суббота, 23.03.2013, 00:24 | Сообщение # 165
Генерал-майор
Группа: Администраторы
Сообщений: 3270
Репутация: 11
Статус: Offline
ну вот, я что-то сделал, но еще не проверял... dry smile
Прикрепления: 1336436.asm (13.6 Kb)


не успеваю за своими мыслями......

Сообщение отредактировал uwrtey - Суббота, 23.03.2013, 00:46
 
Форум » Разработка электронных устройств » Разрабатываю ! » Пропорциональное управление на МК с нуля (пошаговое строительство пропорционального управления с нуля)
Поиск:


Copyright MyCorp © 2024
Сделать бесплатный сайт с uCoz