Страница 12 из 15

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Вт сен 11, 2012 22:08:22
uwrtey
теперь бы придумать как его тебе попроще объяснить :-)
как придумаешь, пиши...

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Вт сен 11, 2012 23:08:28
ВитГо
смотри что придумал:

нам нужно управлять генерацией импульсов при помощи Т1

в принципе, как уже обсуждали, все управление это заливка нужной длительности в OCR1A - дальше контроллер сделает все сам.

остался вопрос: каким образом определять эти длительности?
я тут накидал один код для прерывания, но боюсь что им запросто отобью у тебя желание писать программы на асме :kill:

поэтому пойдем проще:
мы после того как зарегистрировали нажатие любой кнопки на клаве подготовим в ОЗУ еще один буфер который будет содержать в себе длительности фаз передаваемых импульсов

то есть примерно так:
нужно отправить байт 01001001

импульс у нас стандартной длины ImpLen
для нуля мы передаем длину Nullen
для единицы Onelen
(эти константы мы определим через .define в начале программы, чтобы потом если придется править не лазить и не искать где мы их использовали)

в буфере на передачу должно быть (это схематично):

Код: Выделить всё

ImpLen  ; 0
Nullen

ImpLen  ; 1
Onelen

ImpLen  ; 0
Nullen

ImpLen  ; 0
Nullen

ImpLen  ; 1
Onelen

ImpLen  ; 0
Nullen

ImpLen  ; 0
Nullen

ImpLen  ; 1
Onelen
теперь программа, следи за мыслью:

Код: Выделить всё

     ldi zl, low(transmit_buff)   ; зададим адрес начала буфера передачи в ОЗУ
     ldi zh, high(transmit_buff)

     ldi yl, low(key_buff)   ; зададим адрес начала буфера прочитанных кнопок (не помню как метка называлась)
     ldi yh, high(key_buff)

     ldi R17, 5  ; количество байт для передачи

keybuffer_loop:     
     ld  temp , y+  ; прочитаем байт для передачи

     ldi r18, 8 ; количество бит в байте для передачи

byte_loop:
    ; здесь кодируем импульс для бита
     ldi r19,high(ImpLen)   ; зададим фиксированную длительность импульса
     st z+, r19
     ldi r19,low(ImpLen)   
     st z+, r19

     ldi  xl, low(Nullen)    ; длительность для передачи нуля
     ldi  xh, high(Nullen)

     ROL temp                 ; команда сюрприз! прочитай как работает
     brnc send_nullen

     ldi  xl, low(onelen)    ; длительность для передачи единицы
     ldi  xh, high(onelen)

send_nullen:
     st z+, xh      ; сохраним в буфере на передачу
     st z+, xl
    
      dec R18      ; уменьшим счетчик бит на передачу
      brne   byte_loop

      dec R17     ; уменьшим счетчик байт для передачи
      brne   keybuffer_loop

попробуй разобраться что у нас получиться в буфере на передачу и как это получилось.
особенно как работает ROL.

ДОПОЛНИТЕЛЬНО: модифицируй код чтобы генерить бит четности (в нашем случае ситуацию когда в передаваемых байтах общее число бит=1 четное, нам нужен один бит четности на всю посылку)

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Ср сен 12, 2012 08:19:04
uwrtey
пища для ума, вечером будет над чем помыслить :) :beer:
а не проще будет объединить ImpLen и Onelen - ведь они равны ??? (или тут задумка другая...)

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Ср сен 12, 2012 11:10:50
ВитГо
uwrtey писал(а):пища для ума, вечером будет над чем помыслить :) :beer:
угу, думать полезно... может что интереснее придумаешь :beer:
uwrtey писал(а):а не проще будет объединить ImpLen и Onelen - ведь они равны ??? (или тут задумка другая...)
нет, объединять не стоит, мы же не знаем к чему приведут наши эксперименты, вдруг у нас ImpLen потом будет отличаться от Onelen? - придется по коду лазить и менять... хорошо если код в одном файле.. а если нет?
так что лучше написать отдельно, тем более это же константы, размер кода не меняется будь одна константа или две :-)

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Ср сен 12, 2012 11:25:33
uwrtey
я не згаю что такое .define
яндекс говорит что это СИ

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Ср сен 12, 2012 11:27:59
ВитГо
uwrtey писал(а):я не згаю что такое .define
яндекс говорит что это СИ
ой.. ну тогда .equ :))

я тут с Verilog разбираюсь :-)) оттуда и define :)))

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Чт сен 13, 2012 07:18:36
uwrtey
прочитал тут про константы, должно получиться следующее
.EQU ImpLen=0xCE4 ; длина импульса
.EQU OneLen=0xCE4 ; длина паузы для единицы
.EQU NulLen=0x19C8 ; длина паузы для нуля

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Чт сен 13, 2012 08:03:26
uwrtey
почитал про ROL http://www.gaw.ru/html.cgi/txt/doc/micr ... sm/rol.htm
Сдвиг всех битов Rd на одно место влево. Флаг переноса (С) регистра состояния (SREG) смещается на место бита "0" регистра Rd. Бит "7" смещается во флаг переноса (C).
регистр состояния (SREG) http://controllersystems.com/books/prak ... -sreg.html
Флаг переноса (C) устанавливается в "1" , если в результате выполнения операции произошел выход за границы байта
*** тут есть небольшое замечание к первой цитате ...
лучше будет если поменять предложения местами - вот так "Сдвиг всех битов Rd на одно место влево. Бит "7" смещается во флаг переноса (C).Флаг переноса (С) регистра состояния (SREG) смещается на место бита "0" регистра Rd." А то можно неправильно понять смысл... (что я сначала и сделал)
***
Получается, что команда ROL смещает байт целиком на 1 шаг, зацикливая его
или другими словами старший бит занимает место младшего бита
- пример 01001001
01001001
10010010
00100101
01001010

Теперь не понятно что такое brnc ! :dont_know: (яндекс то же не знает!)

Код: Выделить всё


     ROL temp                 ; команда сюрприз! прочитай как работает
     brnc send_nullen
наверно ты хотел сказать
BRCC (Перейти если перенос очищен)??? http://www.gaw.ru/html.cgi/txt/doc/micr ... m/brcc.htm
или BRHC (Перейти если флаг внутреннего переноса очищен) ??? http://www.gaw.ru/html.cgi/txt/doc/micr ... m/brhc.htm
:dont_know:

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Чт сен 13, 2012 23:00:28
uwrtey
в общих чертах, как работает этот код, я понял.
Спойлер

Код: Выделить всё

В ОЗУ появился новый массив - "transmit_buff"
в этом массиве будут хранится длительности
массив будет иметь размер 8*5*2*2=160 байт (хватит - ли объема ОЗУ у этого МК ?)
про бит четности можно поподробней?
и как связать этот код с режимом CTC - я не догоняю..........

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Пт сен 14, 2012 09:50:06
ВитГо
uwrtey писал(а): про бит четности можно поподробней?
бит четности это фактически признак четности, нужно посчитать сколько было закодировано бит равных единице, и потом если это число четное - то установить бит четности, если число закодированных единиц не четное - то сбросить бит четности

потом конечно же прибавить в нашу последовательность для передачи значение для передачи полученного бита четности

например, для передачи подготовили следующую последовательность 010101010111 - в ней 7 бит =1, значит бит четности равен 0
а вот если для передачи подготовили 110011001100 - 6 бит=1, значит бит четности равен 1
uwrtey писал(а):и как связать этот код с режимом CTC - я не догоняю..........
ты об этом пока не думай, делай подсчет бита четности и его добавление в последовательность для передачи (соответственно она у тебя должна увеличиться на 4 байта (2 байта на задание времени импульса+2 байта на задание времени паузы)

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Пт сен 14, 2012 12:01:37
uwrtey
В ОЗУ появился новый массив - "transmit_buff"
в этом массиве будут хранится длительности
массив будет иметь размер 8*5*2*2=160 байт (хватит - ли объема ОЗУ у этого МК ?)
оперативки то не хватит что бы записать всю информацию...

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Пт сен 14, 2012 13:15:05
ВитГо
uwrtey писал(а):
В ОЗУ появился новый массив - "transmit_buff"
в этом массиве будут хранится длительности
массив будет иметь размер 8*5*2*2=160 байт (хватит - ли объема ОЗУ у этого МК ?)
оперативки то не хватит что бы записать всю информацию...
угу, не хватит..
потом перепишем на передачу 5 бит каждого байта (по числу кнопок)
потом сделаем предделитель для Т1 и перейдем к заданию интервала одним байтом а не двумя

но пока усложнять алгоритм рано.. нужно разобраться в том что есть

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Пт сен 14, 2012 22:47:41
uwrtey
количество единиц я смогу подсчитать и куда-нибудь запишу результат (в Temp1, например)
но как проверить этот результат на четность? поделить его на 2 и проверить будет ли остаток? (если так - то я не могу допереть как это сделать) :dont_know:

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Сб сен 15, 2012 08:57:07
uwrtey
... ой .... //редактирую//

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Сб сен 15, 2012 13:28:31
ВитГо
проверить на четность проще паренной репы.. достаточно вспомнить
128 64 32 16 8 4 2 1 - последний бит отвечает за четность..

следовательно либо проверка установки бита либо сдвиг вправо через флаг переноса и переход по установленному\сброшенному флагу переноса

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Сб сен 15, 2012 14:43:55
uwrtey
нам нужен один бит четности на всю посылку)
я сначала тупанул и сделал один бит четности на каждый прочитанный байт :oops:
вот так
Спойлер

Код: Выделить всё


.EQU ImpLen=0xCE4 			; длина импульса
.EQU OneLen=0xCE4 			; длина паузы для единицы
.EQU NulLen=0x19C8			; длина паузы для нуля

;******************************************************************************************************



	Ldi Temp1,0			; счетчик четности///////////////////////////////////////////


	ldi zl,low(transmit_buff)	; зададим в "Z" адрес начала буфера передачи в ОЗУ	
	ldi zh,high(transmit_buff)

	ldi yl, low(key_buff)		; зададим в "Y" адрес начала буфера прочитанных кнопок
	ldi yh, high(key_buff)

	ldi R17,5			; количество байт для передачи


keybuffer_loop:    
 	
	ld temp,y+ 			; прочитаем байт для передачи, увеличим адрес "y" на единицу.

	ldi r18,8			; количество бит в байте для передачи


byte_loop:				; здесь кодируем импульс для бита

	ldi r19,high(ImpLen)		; зададим фиксированную длительность импульса	
	st z+,r19			; запишем данные в ОЗУ по адресу из "Z"
	ldi r19,low(ImpLen)   	
	st z+,r19


	ldi  xl,low(Nullen) 		; длительность для передачи нуля	
	ldi  xh,high(Nullen)

	ROL temp			; сдвигаем байт влево	
	BRCC send_nullen		; если старши бит = "0" то переходим на метку


	ldi  xl,low(onelen)		; длительность для передачи единицы	
	ldi  xh,high(onelen)



	cpi Temp1,1			; если в прошлый раз была единица, то идем на метку///////////
	breq chetnost

	inc Temp1			; увеличение на 1 (нечетное)//////////////////////////////////
	rjmp send_nullen


chetnost:
   
	dec Temp1			; уменьшение на 1 (четное)////////////////////////////////////


send_nullen:	

	st z+,xh			; запишем данные в ОЗУ по адресу из "Z"
	st z+,xl

   	dec R18				; уменьшим счетчик бит на передачу	
	brne byte_loop

	dec R17				; уменьшим счетчик байт для передачи	
	brne keybuffer_loop



;*******************************


если Temp1=0 значит-четное, если Temp1=1 значит-НЕчетное
..........
только потом увидел, что ты просишь один бит на всю посылку.
...............домой приду переделаю.

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Сб сен 15, 2012 19:52:36
ВитГо
как то ты мудрено подошел к решению задачки


первая часть кода отличается всего 2мя строчками !! (с регистром R21) - и мы уже считаем биты=1 при передаче !

добавленные команды в первой части я выделил в коде (относительно первоначального)
Спойлер

Код: Выделить всё

     ldi R21, 0                        ; это будет счетчик единичек в передаче @@@ ДОБАВЛЕНО @@@

     ldi zl, low(transmit_buff)   ; зададим адрес начала буфера передачи в ОЗУ
     ldi zh, high(transmit_buff)

     ldi yl, low(key_buff)   ; зададим адрес начала буфера прочитанных кнопок 
     ldi yh, high(key_buff)

     ldi R17, 5  ; количество байт для передачи

keybuffer_loop:     
     ld  temp , y+  ; прочитаем байт для передачи

     ldi r18, 8 ; количество бит в байте для передачи

byte_loop:
    ; здесь кодируем импульс для бита
     ldi r19,high(ImpLen)   ; зададим фиксированную длительность импульса
     st z+, r19
     ldi r19,low(ImpLen)   
     st z+, r19

     ldi  xl, low(Nullen)    ; длительность для передачи нуля
     ldi  xh, high(Nullen)

     ROL temp                 ; команда сюрприз! прочитай как работает
     brcc send_nullen       ; если С=0 то записываем нулевую длительность

     ldi  xl, low(onelen)    ; длительность для передачи единицы
     ldi  xh, high(onelen)
     inc  R21                  ; передаем единицу - увеличим счетчик  @@@ ДОБАВЛЕНО @@@

send_nullen:
     st z+, xh      ; сохраним в буфере на передачу
     st z+, xl
   
      dec R18      ; уменьшим счетчик бит на передачу
      brne   byte_loop

      dec R17     ; уменьшим счетчик байт для передачи
      brne   keybuffer_loop


; --------------------------------------------------------------------------------------------- 
;
; здесь формируем посылку для бита четности
;
; здесь фактически код для формирования одного бита
; 
    ; здесь кодируем импульс для бита
     ldi r19,high(ImpLen)   ; зададим фиксированную длительность импульса
     st z+, r19
     ldi r19,low(ImpLen)   
     st z+, r19
; здесь в R21 число единичек
     ldi  xl, low(Nullen)    ; длительность для передачи нуля
     ldi  xh, high(Nullen)

     ROR R21                 ; команда сюрприз! прочитай как работает
     brcs send_bitchetn   ; если С установлен значит нечетное число единиц у нас

     ldi  xl, low(onelen)    ; длительность для передачи единицы
     ldi  xh, high(onelen)

send_bitchetn:
     st z+, xh      ; сохраним в буфере на передачу
     st z+, xl
вот и весь бит четности

p.s. главное не крылья и не хвост, главное алгоритм ! 8)

p.p.s. кстати сможешь из двух кусков передачи бита сделать подпрограмму ? - за это я люблю ассемблер, иногда оптимизацию можно сделать даже для блоков в 3-4 команды :-)

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Сб сен 15, 2012 21:00:22
uwrtey
а вот что у меня получилось
Спойлер

Код: Выделить всё


.EQU ImpLen=0xCE4 			; длина импульса
.EQU OneLen=0xCE4 			; длина паузы для единицы
.EQU NulLen=0x19C8			; длина паузы для нуля

;******************************************************************************************************


	Ldi Temp1,0			; счетчик четности///////////////////////////////////////////


	ldi zl,low(transmit_buff)	; зададим в "Z" адрес начала буфера передачи в ОЗУ	
	ldi zh,high(transmit_buff)

	ldi yl, low(key_buff)		; зададим в "Y" адрес начала буфера прочитанных кнопок
	ldi yh, high(key_buff)

	ldi R17,5			; количество байт для передачи


keybuffer_loop:    
 	
	ld temp,y+ 			; прочитаем байт для передачи, увеличим адрес "y" на единицу.

	ldi r18,8			; количество бит в байте для передачи


byte_loop:				; здесь кодируем импульс для бита

	ldi r19,high(ImpLen)		; зададим фиксированную длительность импульса	
	st z+,r19			; запишем данные в ОЗУ по адресу из "Z"
	ldi r19,low(ImpLen)   	
	st z+,r19


	ldi  xl,low(Nullen) 		; длительность для передачи нуля	
	ldi  xh,high(Nullen)

	ROL temp			; сдвигаем байт влево	
	BRCC send_nullen		; если старши бит = "0" то переходим на метку


	ldi  xl,low(onelen)		; длительность для передачи единицы	
	ldi  xh,high(onelen)



	cpi Temp1,1			; если в прошлый раз была единица, то идем на метку///////////
	breq chetnost

	inc Temp1			; увеличение на 1 (нечетное)//////////////////////////////////
	rjmp send_nullen


chetnost:
   
	dec Temp1			; уменьшение на 1 (четное)////////////////////////////////////


send_nullen:	

	st z+,xh			; запишем данные в ОЗУ по адресу из "Z"
	st z+,xl

   	dec R18				; уменьшим счетчик бит на передачу	
	brne byte_loop

	dec R17				; уменьшим счетчик байт для передачи	
	brne keybuffer_loop



;*******************************



     ldi r19,high(ImpLen)		; зададим фиксированную длительность импульса
     st z+, r19
     ldi r19,low(ImpLen)   
     st z+, r19


     ldi  xl, low(Nullen)		; длительность для передачи нуля (нечетное)
     ldi  xh, high(Nullen)

     cpi Temp1,1			; проверка на нечетность 
     breq send_bitchetn			; "0"=четное, "1"=нечетное

     ldi  xl, low(onelen)		; длительность для передачи единицы (четное)
     ldi  xh, high(onelen)

send_bitchetn:

     st z+, xh				; сохраним в буфере на передачу
     st z+, xl


Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Сб сен 15, 2012 21:04:33
uwrtey

Код: Выделить всё

ROR R21                 ; команда сюрприз! прочитай как работает
brcs send_bitchetn   ; если С установлен значит нечетное число единиц у нас
ROR это тот же ROL, только в другую сторону... :))
ВитГо писал(а):кстати сможешь из двух кусков передачи бита сделать подпрограмму
что то я Тебя не понял... каких двух кусков ?

Re: Пропорциональное управление на МК (Знание=Сила)

Добавлено: Сб сен 15, 2012 22:32:33
ВитГо
uwrtey писал(а):
ВитГо писал(а):кстати сможешь из двух кусков передачи бита сделать подпрограмму
что то я Тебя не понял... каких двух кусков ?
Посмотри внимательно программу которую я привел во второй раз..

разве там не повторяющегося кода ?

и разве руки не чешутся засунуть код в подпрограмму и сделать его вызов через RCALL ?