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

Дисплеи, датчики и прочие функциональные узлы, управляемые МК.
Аватара пользователя
uwrtey
Поставщик валерьянки для Кота
Сообщения: 2309
Зарегистрирован: Пт июл 17, 2009 07:34:07
Откуда: Свердловская обл.

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

Сообщение uwrtey »

теперь бы придумать как его тебе попроще объяснить :-)
как придумаешь, пиши...
не зная броду не лезь к вольтмоду
Реклама
ВитГо
Вымогатель припоя
Сообщения: 680
Зарегистрирован: Ср фев 24, 2010 19:16:07

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

Сообщение ВитГо »

смотри что придумал:

нам нужно управлять генерацией импульсов при помощи Т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 четное, нам нужен один бит четности на всю посылку)
Реклама
Аватара пользователя
uwrtey
Поставщик валерьянки для Кота
Сообщения: 2309
Зарегистрирован: Пт июл 17, 2009 07:34:07
Откуда: Свердловская обл.

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

Сообщение uwrtey »

пища для ума, вечером будет над чем помыслить :) :beer:
а не проще будет объединить ImpLen и Onelen - ведь они равны ??? (или тут задумка другая...)
не зная броду не лезь к вольтмоду
ВитГо
Вымогатель припоя
Сообщения: 680
Зарегистрирован: Ср фев 24, 2010 19:16:07

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

Сообщение ВитГо »

uwrtey писал(а):пища для ума, вечером будет над чем помыслить :) :beer:
угу, думать полезно... может что интереснее придумаешь :beer:
uwrtey писал(а):а не проще будет объединить ImpLen и Onelen - ведь они равны ??? (или тут задумка другая...)
нет, объединять не стоит, мы же не знаем к чему приведут наши эксперименты, вдруг у нас ImpLen потом будет отличаться от Onelen? - придется по коду лазить и менять... хорошо если код в одном файле.. а если нет?
так что лучше написать отдельно, тем более это же константы, размер кода не меняется будь одна константа или две :-)
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
uwrtey
Поставщик валерьянки для Кота
Сообщения: 2309
Зарегистрирован: Пт июл 17, 2009 07:34:07
Откуда: Свердловская обл.

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

Сообщение uwrtey »

я не згаю что такое .define
яндекс говорит что это СИ
не зная броду не лезь к вольтмоду
Реклама
ВитГо
Вымогатель припоя
Сообщения: 680
Зарегистрирован: Ср фев 24, 2010 19:16:07

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

Сообщение ВитГо »

uwrtey писал(а):я не згаю что такое .define
яндекс говорит что это СИ
ой.. ну тогда .equ :))

я тут с Verilog разбираюсь :-)) оттуда и define :)))
Реклама
Аватара пользователя
uwrtey
Поставщик валерьянки для Кота
Сообщения: 2309
Зарегистрирован: Пт июл 17, 2009 07:34:07
Откуда: Свердловская обл.

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

Сообщение uwrtey »

прочитал тут про константы, должно получиться следующее
.EQU ImpLen=0xCE4 ; длина импульса
.EQU OneLen=0xCE4 ; длина паузы для единицы
.EQU NulLen=0x19C8 ; длина паузы для нуля
не зная броду не лезь к вольтмоду
Аватара пользователя
uwrtey
Поставщик валерьянки для Кота
Сообщения: 2309
Зарегистрирован: Пт июл 17, 2009 07:34:07
Откуда: Свердловская обл.

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

Сообщение 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:
не зная броду не лезь к вольтмоду
Аватара пользователя
uwrtey
Поставщик валерьянки для Кота
Сообщения: 2309
Зарегистрирован: Пт июл 17, 2009 07:34:07
Откуда: Свердловская обл.

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

Сообщение uwrtey »

в общих чертах, как работает этот код, я понял.
Спойлер

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

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

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

Сообщение ВитГо »

uwrtey писал(а): про бит четности можно поподробней?
бит четности это фактически признак четности, нужно посчитать сколько было закодировано бит равных единице, и потом если это число четное - то установить бит четности, если число закодированных единиц не четное - то сбросить бит четности

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

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

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

Сообщение uwrtey »

В ОЗУ появился новый массив - "transmit_buff"
в этом массиве будут хранится длительности
массив будет иметь размер 8*5*2*2=160 байт (хватит - ли объема ОЗУ у этого МК ?)
оперативки то не хватит что бы записать всю информацию...
не зная броду не лезь к вольтмоду
ВитГо
Вымогатель припоя
Сообщения: 680
Зарегистрирован: Ср фев 24, 2010 19:16:07

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

Сообщение ВитГо »

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

но пока усложнять алгоритм рано.. нужно разобраться в том что есть
Аватара пользователя
uwrtey
Поставщик валерьянки для Кота
Сообщения: 2309
Зарегистрирован: Пт июл 17, 2009 07:34:07
Откуда: Свердловская обл.

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

Сообщение uwrtey »

количество единиц я смогу подсчитать и куда-нибудь запишу результат (в Temp1, например)
но как проверить этот результат на четность? поделить его на 2 и проверить будет ли остаток? (если так - то я не могу допереть как это сделать) :dont_know:
не зная броду не лезь к вольтмоду
Аватара пользователя
uwrtey
Поставщик валерьянки для Кота
Сообщения: 2309
Зарегистрирован: Пт июл 17, 2009 07:34:07
Откуда: Свердловская обл.

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

Сообщение uwrtey »

... ой .... //редактирую//
не зная броду не лезь к вольтмоду
ВитГо
Вымогатель припоя
Сообщения: 680
Зарегистрирован: Ср фев 24, 2010 19:16:07

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

Сообщение ВитГо »

проверить на четность проще паренной репы.. достаточно вспомнить
128 64 32 16 8 4 2 1 - последний бит отвечает за четность..

следовательно либо проверка установки бита либо сдвиг вправо через флаг переноса и переход по установленному\сброшенному флагу переноса
Аватара пользователя
uwrtey
Поставщик валерьянки для Кота
Сообщения: 2309
Зарегистрирован: Пт июл 17, 2009 07:34:07
Откуда: Свердловская обл.

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

Сообщение 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 значит-НЕчетное
..........
только потом увидел, что ты просишь один бит на всю посылку.
...............домой приду переделаю.
Последний раз редактировалось uwrtey Сб сен 15, 2012 20:22:56, всего редактировалось 2 раза.
не зная броду не лезь к вольтмоду
ВитГо
Вымогатель припоя
Сообщения: 680
Зарегистрирован: Ср фев 24, 2010 19:16:07

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

Сообщение ВитГо »

как то ты мудрено подошел к решению задачки


первая часть кода отличается всего 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 команды :-)
Аватара пользователя
uwrtey
Поставщик валерьянки для Кота
Сообщения: 2309
Зарегистрирован: Пт июл 17, 2009 07:34:07
Откуда: Свердловская обл.

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

Сообщение 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

не зная броду не лезь к вольтмоду
Аватара пользователя
uwrtey
Поставщик валерьянки для Кота
Сообщения: 2309
Зарегистрирован: Пт июл 17, 2009 07:34:07
Откуда: Свердловская обл.

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

Сообщение uwrtey »

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

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

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

Сообщение ВитГо »

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

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

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

Вернуться в «Периферия»