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

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

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

Сообщение uwrtey »

в принципе, должно быть достаточно того, что мы удалим всего две строчки в коде, которые производят запись младшего байта в ОЗУ
Спойлер

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

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

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

    
;-------------------------------------------------------------------------------------------------

	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:				; здесь кодируем импульс для бита

	ROL temp			; двигаем байт влево (циклический сдвиг влево)

	RCALL send_bit			; подпрограмма отправки нашего бита данных!
   
	dec R18				; уменьшим счетчик бит на передачу
	brne byte_loop

	dec R17				; уменьшим счетчик байт для передачи
	brne keybuffer_loop
     
; ---------------------------------------------------------------------------------------------
; здесь формируем посылку для бита четности
; здесь фактически код для формирования одного бита

	COM R21				; побитная инверся????????????????????????????????????????????

	ROR R21				; двигаем байт вправо (циклический сдвиг вправо)

	RCALL send_bit			; подпрограмма отправки нашего бита четности

	ret				; конец подпрограммы подготовки данных на отправку

; --------------------------------------------------------------------------------------------------
;  А НИЖЕ ТА САМАЯ ПОДПРОГРАММА КОТОРАЯ ГОТОВИТ ОТПРАВКУ ОДНОГО БИТА
;
; подпрограмма подготовки одного бита для отправки --------------------------------------


send_bit:
					; команды LDI не меняют состояния флага "С" - который мы выставили
					; до входа в подпрограмму


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

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

					; вот здесь мы реагируем на флаг "С" который установили до входа в
					; подпрограмму, он не изменился после команд LDI которые были
					; исполнены до него !


	brcc send_nullen		; если "С"=0 то записываем нулевую длительность

	ldi xl,low(onelen)		; длительность для передачи единицы
	ldi xh,high(onelen)
	inc R21				; передаем единицу - увеличим счетчик  

send_nullen:

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

	ret				; возврат из подпрограммы

;------------------------------------------------------------------------------------------------------------------
я отметил эти строчки многочисленными СЛЭШами и закоментировал их...

а можно вот так
Спойлер

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

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

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

    
;-------------------------------------------------------------------------------------------------

	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:				; здесь кодируем импульс для бита

	ROL temp			; двигаем байт влево (циклический сдвиг влево)

	RCALL send_bit			; подпрограмма отправки нашего бита данных!
   
	dec R18				; уменьшим счетчик бит на передачу
	brne byte_loop

	dec R17				; уменьшим счетчик байт для передачи
	brne keybuffer_loop
     
; ---------------------------------------------------------------------------------------------
; здесь формируем посылку для бита четности
; здесь фактически код для формирования одного бита

	COM R21				; побитная инверся????????????????????????????????????????????

	ROR R21				; двигаем байт вправо (циклический сдвиг вправо)

	RCALL send_bit			; подпрограмма отправки нашего бита четности

	ret				; конец подпрограммы подготовки данных на отправку

; --------------------------------------------------------------------------------------------------
;  А НИЖЕ ТА САМАЯ ПОДПРОГРАММА КОТОРАЯ ГОТОВИТ ОТПРАВКУ ОДНОГО БИТА
;
; подпрограмма подготовки одного бита для отправки --------------------------------------


send_bit:
					; команды LDI не меняют состояния флага "С" - который мы выставили
					; до входа в подпрограмму


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

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

					; вот здесь мы реагируем на флаг "С" который установили до входа в
					; подпрограмму, он не изменился после команд LDI которые были
					; исполнены до него !


	brcc send_nullen		; если "С"=0 то записываем нулевую длительность

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

	inc R21				; передаем единицу - увеличим счетчик единиц для проверки кратности...

send_nullen:

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

	ret				; возврат из подпрограммы

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

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

Сообщение uwrtey »

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

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

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

uwrtey писал(а):как еще можно сократить объем данных записываемых в ОЗУ ?
ну в идеале можно генерить длительности на лету.. но вот насколько это будет тебе понятно - большой вопрос... так что пока не будем стремиться к экононии...

ты переписал код ? уже умещаешься в ОЗУ?

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

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

Сообщение uwrtey »

ВитГо писал(а):ты переписал код ? уже умещаешься в ОЗУ?
....код двумя постами выше
о размере....
мы кодируем и передаем ВЕСЬ Key_Buff ( а это 8 бит * 5 столбцов = 40 бит)
между каждыми 40 битами нужно передать импульс (40*2=80)
затем мы передаем бит четности (80+1=81)
всего 81 бит для кодирования
данные о каждом бите мы сохраняем в ОЗУ в виде одного (старшего) байта длительности(81*8=648 бит)
итого 648 бит + массив Key_Buff (который занимант 8*5=40 бит)
итого чуть больше 688 бит (РОН же еще...)
******** из даташита видно, что оперативки у нас 128 байт! (128*8=1024 бит) http://www.promelec.ru/pdf/ATTINY2313.pdf
теперь, теоретически должно уместиться :))
не зная броду не лезь к вольтмоду
Реклама
Эиком - электронные компоненты и радиодетали
ВитГо
Вымогатель припоя
Сообщения: 680
Зарегистрирован: Ср фев 24, 2010 19:16:07

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

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

гм..
опс.. ну да.. чтото этот момент я упустил.. действительно не влазием...

блин, неужели на лету придется кодировать :shock:

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

сейчас я напишу и кину тебе на разбор (сам ты вряд ли ее напишешь)
Последний раз редактировалось ВитГо Чт сен 20, 2012 22:05:47, всего редактировалось 1 раз.
Реклама
Аватара пользователя
uwrtey
Поставщик валерьянки для Кота
Сообщения: 2309
Зарегистрирован: Пт июл 17, 2009 07:34:07
Откуда: Свердловская обл.

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

Сообщение uwrtey »

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

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

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

что то вроде такого должно получиться в прерывании OCR1A_COMPare
Спойлер

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

;--------------------------------------------------------------------------------------

OCR1A_COMP:
; первоначальное значение R22 - 0
; таким образом сначала будет выполнена инициализации передачи

			;  проверяем фазу работы прерывания
					CPI R22, 1
					BREQ transmitt_byte          ; фаза передачи байта 

					CPI R22, 2
					BREQ transmitt_bite_imp      ; фаза передачи импульса бита в байте

					CPI R22, 3
					BREQ transmitt_bite_pause    ; фаза передачи паузы бита в байте

					CPI R22, 4
                    BREQ transmitt_imp_chetn	 ; фаза передачи импульса бита четности

					CPI R22, 5
                    BREQ transmitt_pausa_chetn	 ; фаза передачи паузы бита четности

					CPI R22, 6
                    BREQ transmitt_complete      ; передача завершена, выключение прерываний

			; инициализация передачи, (при R22=0)

   					ldi R21,0                 ; это будет счетчик единичек в передаче (четность)

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

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


transmitt_byte:   ; фаза начала передачи - передача байта
  
   					ld temp,y+         ; прочитаем байт для передачи

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


transmitt_bite_imp: ; фаза передачи импульса в передаваемом бите

   					LDI R19 ,high(ImpLen)      ; зададим фиксированную длительность импульса

   					OUT OCR1AH, R19            ; и выведем ее в порт сравнения

   					LDI R19,low(ImpLen)   

   					OUT OCR1AL ,R19       

                    LDI  R22, 3               ; в следующий раз передаем паузу

int_reti: 
                    RETI   ; точка выхода из прерывания


transmitt_bite_pause: ; фаза передачи паузы в передаваемом бите

                   ; здесь кодируем импульс для бита
   					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:
   					OUT OCR1AH,XH         ; установим длительность
   					OUT OCR1AH,XL         
					
					LDI  R22, 2    ; в следующий раз передадим импульс бита

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

                    LDI  R22, 1    ; в следующий раз передадим новый байт

   					dec R17            ; уменьшим счетчик байт для передачи
   					brne int_reti
                    
                    LDI R22, 4       ; в следующий раз передадим импульс бита четности

                    RJMP int_reti					     


transmitt_imp_chetn: ; передача импульса бита четности

   					LDI R19 ,high(ImpLen)      ; зададим фиксированную длительность импульса

   					OUT OCR1AH, R19            ; и выведем ее в порт сравнения

   					LDI R19,low(ImpLen)   

   					OUT OCR1AL ,R19       

                    LDI  R22, 5              ; в следующий раз передаем паузу бита четности

   					rjmp int_reti



transmitt_pausa_chetn: ; передача паузы импульса четности

                   ; здесь кодируем паузу для бита
   					LDI XL	,low(Nullen)      ; длительность для передачи нуля
   					LDI XH	,high(Nullen)

                    COM R21

					ROR R21

   					BRCC send_chetn      ; если "С"=0 то записываем нулевую длительность

   					LDI XL	,low(onelen)      ; длительность для передачи единицы
   					LDI	XH	,high(onelen)
   					INC R21            ; передаем единицу - увеличим счетчик 

send_chetn:

   					OUT OCR1AH,XH         ; установим длительность
   					OUT OCR1AH,XL         

                    LDI R22, 6             ; ОТКЛЮЧЕНИЕ ПРЕРЫВАНИЯ
                    rjmp  int_reti

transmitt_complete:
; ЗДЕСЬ ДОЛЖЕН БЫТЬ КОД ДЛЯ ОТКЛЮЧЕНИЯ ПРЕРЫВАНИЙ 
завтра еще на трезвую голову посмотрю :-) а ты пока попробуй понять алгоритм
еще раз повторяю это обработчик прерывания в который мы будем попадать каждый раз при совпадении TCNT1 и OCR1A
естественно что и прерывания должны быть разрешены и у счетчика задан и режим счета и предделитель (иначе счета не будет)

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

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

Сообщение uwrtey »

классный алгоритм! :) :beer:
я поражен тому - как Тебе это удалось написать за 45 минут :beer:
сейчас я напишу и кину тебе на разбор (сам ты вряд ли ее напишешь)
это точно - сам бы я очень долго мучился и то вряд ли бы написал такое
по коду мне, вроде, все понятно.
есть лишняя строчка
Спойлер

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

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


transmitt_pausa_chetn:			; передача паузы импульса четности

					; здесь кодируем длительность паузы для бита четности


	LDI XL,low(Nullen)		; длительность для передачи нуля
	LDI XH,high(Nullen)

	COM R21				; Побитная инверсия

	ROR R21				; Циклический сдвиг вправо

	BRCC send_chetn 		; если "С"=0 то записываем нулевую длительность

	LDI XL,low(onelen)		; длительность для передачи единицы
	LDI XH,high(onelen)

	INC R21				; если передаем единицу - увеличим счетчик//////////////////это тут не нужно скорее всего!!!!!



send_chetn:

	OUT OCR1AH,XH			; установим длительность
	OUT OCR1AH,XL         

	LDI R22,6			; ОТКЛЮЧЕНИЕ ПРЕРЫВАНИЯ
	rjmp int_reti

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

transmitt_complete:
					; ЗДЕСЬ ДОЛЖЕН БЫТЬ КОД ДЛЯ ОТКЛЮЧЕНИЯ ПРЕРЫВАНИЙ 
не зная броду не лезь к вольтмоду
ВитГо
Вымогатель припоя
Сообщения: 680
Зарегистрирован: Ср фев 24, 2010 19:16:07

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

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

да, INC R21 при передаче паузы в бите четности действительно можно выкинуть :-) простым копирование вставлял блоки..

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

еще где то есть одинаковости - которые тоже можно в подпрограмму выделить..


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

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

Сообщение uwrtey »

ВитГо писал(а):ты уже добавил в проект ?
пока нет.
могу попробовать все это запихать в единую программу...
:write: :write:
не зная броду не лезь к вольтмоду
Аватара пользователя
uwrtey
Поставщик валерьянки для Кота
Сообщения: 2309
Зарегистрирован: Пт июл 17, 2009 07:34:07
Откуда: Свердловская обл.

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

Сообщение uwrtey »

ну вот, что то вроде получилось
Спойлер

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

;*****************************************************************************
;передатчик
;*****************************************************************************

 	.def	Temp=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			;оперативка

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


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

.cseg
.org 0


					; СТАРТ
rjmp RESET				; External Pin, Power-on Reset, Brown-out Reset, and Watchdog Reset

.org	INT0addr;	= 0x0001	; External Interrupt Request 0
reti
.org	INT1addr;	= 0x0002	; External Interrupt Request 1
reti
.org	ICP1addr;	= 0x0003	; Timer/Counter1 Capture Event
reti
.org	OC1Aaddr;	= 0x0004	; Timer/Counter1 Compare Match A/////////////////////////
rjmp TIM1_COMPA
.org	OVF1addr;	= 0x0005	; Timer/Counter1 Overflow
reti
.org	OVF0addr;	= 0x0006	; Timer/Counter0 Overflow
reti
.org	URXCaddr;	= 0x0007	; USART, Rx Complete
reti
.org	UDREaddr;	= 0x0008	; USART Data Register Empty
reti
.org	UTXCaddr;	= 0x0009	; USART, Tx Complete
reti
.org	ACIaddr;	= 0x000a	; Analog Comparator
reti
.org	PCIBaddr;	= 0x000b	; Pin Change Interrupt Request B
reti
.org	OC1Baddr;	= 0x000c	;
reti
.org	OC0Aaddr;	= 0x000d	;
reti
.org	OC0Baddr;	= 0x000e	; 
reti
.org	USI_STARTaddr;	= 0x000f	; USI Start Condition
reti
.org	USI_OVFaddr;	= 0x0010	; USI Overflow
reti
.org	ERDYaddr;	= 0x0011	; 
reti
.org	WDTaddr;	= 0x0012	; Watchdog Timer Overflow
reti
.org	PCIAaddr;	= 0x0013	; Pin Change Interrupt Request A
reti
.org	PCIDaddr;	= 0x0014	; Pin Change Interrupt Request D
reti


;******************************************************************************
;старт
;******************************************************************************

reset:					; включение микроконтроллера

cli					; глобальный запрет на прерывания


ldi Temp,low(RamEnd)			; инициализации стека	
out SPL,Temp				;



ldi Temp,0b00001000			; настроили порт "В" (0-ввод, 1-вывод)
out DDRB,Temp				; 0000х000 - "вывод" на передатчик (PB3- 15 ножка)
					; хххх0000 - "ввод" для чтения строк клавиатуры
					; 
					 



ldi Temp,0b00001111			; настраиваем порт "D" (0-ввод, 1-вывод)
out DDRD,Temp 				; 0000хххх - на вывод столбцов клавы
					; 



ldi Temp,0b00000000			; выключено
out TCCR1A,Temp				;



ldi Temp,0b00000000			; установили тактовый сигнал = CK 0
out TCCR1B,Temp				; таймер выключен!!!
					; 


					; инициализация компаратора +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ldi Temp,0xFF				; наверно "0xFFFF"
out OCR1AH,Temp				; 
ldi Temp,0xFF				; 
out OCR1AL,Temp				; 


ldi Temp,(1<<OCIE1A)			; разрешить прерывание компаратора 
out TIMSK,Temp


;ldi Temp,0				; обнуление таймера при включении (здеь закоментировал т.к. перенес дальше по коду)
;out TCNT1H,Temp
;out TCNT1L,Temp


sei					; глобальное разрешение прерываний
        


ldi Temp,0b00000000			; выводим "0" в порт "Б" на "OC1A" +++++++++++++++++++++++++++++++++++++++++++++++++++++++
out PortB,Temp






;*******************************************************************************
; главный цикл
;*******************************************************************************


Main_cicle:



	rcall keyboardread		; вызов подпрограммы чтения клавиатуры

	rcall certain_buttons_keyboard	; вызов подпрограммы проверки нажатия

	
rjmp Main_cicle				; циклимся




;*******************************************************************************
;обработка прерывания
;*******************************************************************************

TIM1_COMPA:
					; включен режим CTC 
					; обнуление таймера  происходит автоматически
					; "OC1A" меняет свое логическое состояние автоматически


reti

;*******************************************************************************
; Чтение клавы и запись данных в ОЗУ
;*******************************************************************************

keyboardread:				; метка - опрос клавиатуры

          
	ldi Temp,5			; количество столбцов клавы = пять
         
	ldi Temp1,0b00000001		; первый столбец

          				; загружаем адрес метки (key_buff) находящейся в ОЗУ в регистровую пару X
	ldi XL,low(key_buff)		; младший байт адреса
	ldi XH,high(key_buff)		; старший байт адреса

keyboardread_loop:			; цикл опроса

	out PortD,Temp1			; выводим в порт "Д" значение "Temp1" для выбора столбца клавиатуры
	in Temp2,PinB			; прочитали состояние столбца
         
	st X+,Temp2			; сохраним в ОЗУ состояние столбца клавы, 
 					; адрес в регстровой паре "X" автоматом увеличится на 1

	lsl Temp1			; сдвинули единичку выбора столбца клавиатуры на 1
 					; позицию влево

	dec temp			; уменьшим счетчик
	brne keyboardread_loop		; если не все просканировали, то циклимся

ret




       
;******************************************************************************************
;проверка нажатия клавиатуры
;******************************************************************************************



certain_buttons_keyboard:
		

	ldi temp1,5			; УСТАНОВИМ СЧЕТЧИК столбцов клавы	

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


Certain_button:


	ld Temp,Z+			; загрузим данные в регистр из ОЗУ по адресу из регистровой пары "Z", 
					; и после этого адресс в регистровой паре автоматически увеличится на еденицу


	cpi Temp,0b00000000		; проверяем, нажата ли какая ни будь кнопка?
	brne inform			; если нажата то переходим на метку "inform"


	dec temp1			; уменьшим счетчик
	brne Certain_button		; если не все столбцы, то циклимся

metka:


ret

;***********************************************************************************************
;вывод информации о состоянии клавиатуры в порт "Б" 
;***********************************************************************************************

inform:


							; включаем таймер
	ldi Temp,(1<<COM1A0)				; переключать ножку "OC1A" по совпадению (PB3- 15 ножка)
	out TCCR1A,Temp					; *1


	ldi Temp,(1<<wgm12)|(1<<cs10)			; подключили режим "CTC" (вместе с *1) 
	out TCCR1B,Temp					; и установили тактовый сигнал = CK 1:1  ++++++++++++++++++++++++++++++++++++++
							; таймер начал считать!!!

	
	ldi Temp,0					; обнуление таймера 
	out TCNT1H,Temp
	out TCNT1L,Temp
						

;==========================
;начало передачи
;--------------------------------------------------------------------------------------------------------------------------------------

OCR1A_COMP:

					; первоначальное значение R22 - 0
					; таким образом сначала будет выполнена инициализации передачи



					; проверяем фазу работы прерывания



	CPI R22, 1
	BREQ transmitt_byte		; фаза передачи байта

	CPI R22, 2
	BREQ transmitt_bite_imp		; фаза передачи импульса бита в байте

	CPI R22, 3
	BREQ transmitt_bite_pause	; фаза передачи паузы бита в байте

	CPI R22, 4
	BREQ transmitt_imp_chetn	; фаза передачи импульса бита четности

	CPI R22, 5
	BREQ transmitt_pausa_chetn	; фаза передачи паузы бита четности

	CPI R22, 6
	BREQ transmitt_complete		; передача завершена, выключение прерываний


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

					; инициализация передачи, (при R22=0)



	ldi R21,0			; это будет счетчик единичек в передаче (четность)

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

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




transmitt_byte:				; фаза начала передачи - передача байта

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

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





transmitt_bite_imp:			; фаза передачи импульса в передаваемом бите


	LDI R19 ,high(ImpLen)		; зададим фиксированную длительность импульса
	OUT OCR1AH, R19			; и выведем ее в порт сравнения
	LDI R19,low(ImpLen)   
	OUT OCR1AL ,R19       

	LDI  R22, 3			; в следующий раз передаем паузу

;*********************************************************************************************************************\/*\/*\/

int_reti:

	RETI				; точка выхода из прерывания


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

transmitt_bite_pause:			; фаза передачи паузы в передаваемом бите


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


	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:

	OUT OCR1AH,XH			; установим длительность
	OUT OCR1AH,XL         
               
	LDI R22,2			; в следующий раз передадим импульс бита

	dec R18				; уменьшим счетчик бит на передачу
	brne int_reti			; если это непоследний бит в байте - то выход из прерывания

	LDI R22,1			; в следующий раз передадим новый байт

	dec R17				; уменьшим счетчик Байт для передачи
	brne int_reti			; если это не последний байт в массиве - то выход из прерывания
                   
	LDI R22,4			; в следующий раз передадим импульс бита четности

	RJMP int_reti			; выход из прерывания

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


transmitt_imp_chetn:			; передача импульса бита четности


	
	LDI R19 ,high(ImpLen)		; зададим фиксированную длительность импульса
	OUT OCR1AH, R19			; и выведем ее в порт сравнения
	LDI R19,low(ImpLen)   
	OUT OCR1AL,R19       


	LDI R22,5			; в следующий раз передаем паузу бита четности

	rjmp int_reti			; выход из прерывания

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


transmitt_pausa_chetn:			; передача паузы импульса четности

					; здесь кодируем длительность паузы для бита четности


	LDI XL,low(Nullen)		; длительность для передачи нуля
	LDI XH,high(Nullen)

	COM R21				; Побитная инверсия

	ROR R21				; Циклический сдвиг вправо

	BRCC send_chetn 		; если "С"=0 то записываем нулевую длительность

	LDI XL,low(onelen)		; длительность для передачи единицы
	LDI XH,high(onelen)

	INC R21				; если передаем единицу - увеличим счетчик//////////////////это тут не нужно скорее всего!!!!!!!!!



send_chetn:

	OUT OCR1AH,XH			; установим длительность
	OUT OCR1AH,XL         

	LDI R22,6			; ОТКЛЮЧЕНИЕ ПРЕРЫВАНИЯ
	rjmp int_reti

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

transmitt_complete:				; ЗДЕСЬ ДОЛЖЕН БЫТЬ КОД ДЛЯ ОТКЛЮЧЕНИЯ ПРЕРЫВАНИЙ 


	ldi Temp,0b00000000			; выключено
	out TCCR1A,Temp				;



	ldi Temp,0b00000000			; установили тактовый сигнал = CK 0  ++++++++++++++++++++++++++++++++++++++++++++++++++++
	out TCCR1B,Temp				; таймер выключен!!!
	


						; инициализация компаратора +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	ldi Temp,0xFF				; наверно "0xFFFF"
	out OCR1AH,Temp				; 
	ldi Temp,0xFF				; 
	out OCR1AL,Temp				; 
				

;*************************************************************************************************************************
;конец передачи
;=============


	ldi Temp,0b00000000			; выводим "0" в порт "Б" на "OC1A" +++++++++++++++++++++++++++++++++++++++++++++++++++++++
	out PortB,Temp


	rjmp metka

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

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

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

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

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

Сообщение uwrtey »

во первых забыл про константы с длительностью :oops:
вот
передатчик 1,1.txt
(12.46 КБ) 300 скачиваний
во вторых решил ужать кусочек кода с векторами прерываний (по совету DX168B )
вот
передатчик 1,2.txt
(11.5 КБ) 282 скачивания
а вот и проект в пятой студии
передатчик 1,2.rar
(21.47 КБ) 182 скачивания
не зная броду не лезь к вольтмоду
Аватара пользователя
uwrtey
Поставщик валерьянки для Кота
Сообщения: 2309
Зарегистрирован: Пт июл 17, 2009 07:34:07
Откуда: Свердловская обл.

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

Сообщение uwrtey »

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

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

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

бардак конечно..

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

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

Сообщение uwrtey »

разобрался в твоей программе - сразу видно руку мастера! :) :beer:
(Еще раз посмотрел свой предыдущий код - это не бардак - это галиматья ! аж стыдно стало, зато понял свои ошибки. Были подозрения конечно, и они оправдались)
есть пару вопросов
1) как таймер реагирует на то, что во время счета меняется число в OCR1A ? ( видимо его все устраивает ? )
2) и что будет, если во время обработки прерывания (где ни будь в середине подпрограммы обработки прерывания), произойдет совпадение таймера и OCR1A ?
Последний раз редактировалось uwrtey Пн сен 24, 2012 19:14:31, всего редактировалось 1 раз.
не зная броду не лезь к вольтмоду
Аватара пользователя
uwrtey
Поставщик валерьянки для Кота
Сообщения: 2309
Зарегистрирован: Пт июл 17, 2009 07:34:07
Откуда: Свердловская обл.

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

Сообщение uwrtey »

и еще один вопрос
допустим мы передали пакет информации и установленный бит четности,
выключили таймер,
и снова пошли опрашивать клаву
и у нас все это время на входе в передатчик будет висеть лог_1

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

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


transmitt_complete:			; КОД ДЛЯ ОТКЛЮЧЕНИЯ ПРЕРЫВАНИЙ 

	ldi Temp,0b00000000		; установили тактовый сигнал = CK 0  
	out TCCR1B,Temp			; таймер выключен!!!

	ldi Temp,0b00000000		; 
	out PORTB,Temp			; вывели лог_0 на вход передатчика!!! (добавлено)
	
	LDI R22, 7			; Признак окончания передачи
	rjmp int_reti				
???
не зная броду не лезь к вольтмоду
Аватара пользователя
uwrtey
Поставщик валерьянки для Кота
Сообщения: 2309
Зарегистрирован: Пт июл 17, 2009 07:34:07
Откуда: Свердловская обл.

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

Сообщение uwrtey »

(отредактировать предыдущий пост уже не получается, продолжу здесь)

.....это придется сделать, если на входе вч передатчика должен висеть лог_0, в то время, когда ни чего не передаем!

А если делать наоборот (лог_1 - во время отсутствия команд), тогда придется в начале программы вывести лог_0 на передатчик, для того что бы imp_len всегда был "импульсом"
Последний раз редактировалось uwrtey Ср сен 26, 2012 19:22:20, всего редактировалось 1 раз.
не зная броду не лезь к вольтмоду
Аватара пользователя
uwrtey
Поставщик валерьянки для Кота
Сообщения: 2309
Зарегистрирован: Пт июл 17, 2009 07:34:07
Откуда: Свердловская обл.

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

Сообщение uwrtey »

uwrtey писал(а):2) и что будет, если во время обработки прерывания (где ни будь в середине подпрограммы обработки прерывания), произойдет совпадение таймера и OCR1A ?
сам нашел ответ http://microsin.ru/content/view/1067/1/
- когда срабатывает любое прерывание, то сразу очищается флаг I (Global Interrupt Enable), и автоматически запрещаются все прерывания, пока не произойдет выход из обработчика прерывания. Если во время работы обработчика прерывания возникали условия, при которых должны были сработать другие прерывания, то эти другие прерывания не вызываются, а просто запоминаются соответсвующие им флаги (прерывания "откладываются" на будущее).
не зная броду не лезь к вольтмоду
Аватара пользователя
uwrtey
Поставщик валерьянки для Кота
Сообщения: 2309
Зарегистрирован: Пт июл 17, 2009 07:34:07
Откуда: Свердловская обл.

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

Сообщение uwrtey »

Попробую начать приемник

для начала нужно определится на какую ногу повесить выход передатчика
и на какие ноги повесить индикаторы

:write:
не зная броду не лезь к вольтмоду
Ответить

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