# Programación en lenguaje ensamblador para AVR



## nogueda (Ago 27, 2008)

Estoy programando a los microcontroladores AVR en codigo ensamblador; este es el mismo tipo de programacion que use con los PIC; y he estado observando las diferencias de programacion entre los dos microcontroladores, nada mas que me quedan algunas dudas con los codigos en AVR. el siguiente codigo lo encontre en un libro, pero tengo algunas dudas.

pondre el siguiente codigo para ver si alguien sabe explicarlo mejor.


```
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;codigo que habilita interrupcion por sobre flujo del timer-counter1
;cada que se produce una interupcion, incrementa en PORTB.

;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
;definion de vectores y microcontrolador.

.include   "8515def.inc"                          ;librerias y caracteristicas del microcontrolador a usar
                                                              ;AT90S8515 microcntrolador usado
  
   .org         $0000                                  ;registro origen del programa en el microcontrolador
    rjmp        inicio                                   ;salto a inicio para evitar la interrupcion programada
 
   .org         $006                                    ;vector de interupcion de sobreflujo
   rjmp         interrupcion                        ;salta al codigo de interrupcion programada

inicio:                                                     ;etiqueta  de inicio

;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
;configurando puerto b como salida, el otro puerto no se usa

   ldi            R16,$FF                               ;carga el registro r16 a unos
   out          DDRB,R16                            ;pone r16 en ddrb, portb es salida

;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
;configurando la sram como stack pila

   ldi            R16,HIGH(RAMEND)             ;carga bytes altos de la sram en r16
   out          SPH,R16                               ;coloca el r16 en sph, byte alto de la pila
   ldi            R16,LOW(RAMEND)              ;carga bytes bajos de la sram en r26
   out          SPL,R16                               ;coloca el r16 en spl, byte bajo de la pila

;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
configurando las interrupciones y contador timer interno

   cli                                                        ;deshabilita las interrupciones
   
   ldi             R17,$00                              ;carga r17 con ceros
   out           TCNT1H,R17                        ;carga el registro tcnt1h a ceros, bytes altos
   out           TCNT1L,R17                        ;carga el registro tcnt1l a ceros, bytes bajos
 
   in              R17,TIMSK                           ;carga en r17 el registro timsk
   ori             R17,(1<<T0IE1)                  ;operacion or entre registro r17 con 1 del pin t0ie1
   out           TIMSK,R17                           ;habilita la interrupcion de sobreflujo, 1 en t0ie1
   
   in              R17,TIFR                              ;carga en r17 el registro tifr
   ori             R17,(1<<TOV1)                   ;operacion or entre registro r17 con 1 del pin tov1
   out            TIFR,R17                             ;limpia interrupcion anterior de sobreflujo

   ldi              R17,$01                              ;carga el registro con valor de $01
   out            TCCR1B                               ;configurando el reloj por cada pulso incrementar tcnt1

   sei                                                        ;habilitar interrupciones

;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
;programa en general, por lo mientras nada

bucle:
   nop                                                       ;nada
   nop                                                       ;nada
   nop                                                       ;nada
   rjmp            bucle                                  ;salta a bucle

;°°°°°°°°°°°°°°°°°°°°
;codigo de interrupcion

interrupcion:
   inc              R18                                     ;incrementa r18
   out             PORTB,R18                          ;muestra en puerto b las interrupciones
   reti                                                        ;regresa de interrupcion.

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
```

bueno en fin espero no confundirlos, pero asi hago mis programas para enternderlos mejor cuando los lea de nuevo. por eso mi dudas son las siguientes:

1.-  en el siguiente codigo ver abajo... en uno pone a 1 el bit para habilitar interrupcion, pero en el que sigue lo pone a cero para borrar interrupcion anterior...  pero es el mismo codigo con las mismas caracteristicas, no se si exista algun error... o alguien sea tan amable de explicarmelo detalladamente. lo he busacado y no encuentro respuesta.


```
in              R17,TIMSK                           ;carga en r17 el registro timsk
   ori             R17,(1<<T0IE1)                  ;operacion or entre registro r17 con 1 del pin t0ie1
   out           TIMSK,R17                           ;habilita la interrupcion de sobreflujo, 1 en t0ie1
   
   in              R17,TIFR                              ;carga en r17 el registro tifr
   ori             R17,(1<<TOV1)                   ;operacion or entre registro r17 con 1 del pin tov1
   out            TIFR,R17                             ;limpia interrupcion anterior de sobreflujo 0 pin tov1
```

2.- tambien programe otro, y use el puerto D como entrada y el puerto B como salida, pero en el pin (T0)  no me responde, como podria programarlo para que me funcione correctamente. 

si alguien es experto o sabe del tema por favor contestenme. gracias por su tiempo.


----------



## fitocondria (Sep 25, 2008)

Lo que entiendo de tú explicación, es que buscas que en el primer código ponga a uno y en el codigo a 2 ponga a 0. ¿Cierto? Si es así. Mejor lo copio.


```
1.- en el siguiente codigo ver abajo... en uno pone a 1 el bit para habilitar interrupcion, pero en el que sigue lo pone a cero para borrar interrupcion anterior... pero es el mismo codigo con las mismas caracteristicas, no se si exista algun error... o alguien sea tan amable de explicarmelo detalladamente. lo he busacado y no encuentro respuesta.

in R17,TIMSK ;carga en r17 el registro timsk
ori R17,(1<<T0IE1) ;operacion or entre registro r17 con 1 del pin t0ie1
out TIMSK,R17 ;habilita la interrupcion de sobreflujo, 1 en t0ie1

in R17,TIFR ;carga en r17 el registro tifr
ori R17,(1<<TOV1) ;operacion or entre registro r17 con 1 del pin tov1
out TIFR,R17 ;limpia interrupcion anterior de sobreflujo 0 pin tov1
```

Teoría: Página 113 del manual del ATmega32.
El TOV1: Timer/Counter1, Overflow flag ó Bandera de sobreflujo para el Contador/Temporizador 1.
La configuración de esta bandera es dependiente de la configuración de lo bits WGM13 al WGM10, los cuales se localizan en el registro TCCR!A[Pág. 107] y TCCR1B[Pág. 110].
En los modos CTC y normal, la bandera TOV1 es puesta a 1 cuando hay sobreflujo en el temporizador.

Y algo a tomar en cuenta es lo siguiente: 

El TOV1 es automaticamente puesto a 0 cuando el vector de interrupción por sobreflujo del temporizador/cotador 1 es ejecutado. Alternativamente, TOV1 puede ser puesto a 0 escribiendo un 1 lógico en esta locación del bit.

Lo único que queda es probarlo. Ante la duda, implementalo.


----------



## egofrn (Abr 17, 2010)

Hola, yo estoy iniciandome en la programacion de los AVR.
En esta pagina hay unos documentos interesantes que te explican desde cero la programacion de AVR...
http://tecnologicosucre.ning.com/ 
pero son para lenguaje Basic... Lo bueno es que te adjuntan el programador y el compilador....


----------



## Daniel Meza (Sep 8, 2014)

Saludos y una disculpa por revivir éste viejo post pero es que no encuentro solución.

Me he decidido por iniciarme en el mundo de los AVR's desde 0, es decir desde su ensamblador.  Ando haciendo mis primeros programas pero me salta la duda ¿es posible utilizar el símbolo "$" para definir el contador de programa en la instrucción actual?, por ejemplo: en el asm de los PIC y MSP430 podemos hacer:


```
lolo
    bcf   INTCON,INTF
    bra  lolo     ;Regresa a la etiqueta "lolo"
```

Pero se me hace más cómodo, para no abusar de las etiquetas, hacer esto:


```
bcf   INTCON,INTF
  bra  $-.2         ;2 porque se trata de asm para el PIC18 y cada instrucción ocupa 2 bytes
```

Ese símbolo si es reconocido en el MPLAB y el IAR (MSP430) pero ahora que lo quiero poner en el AVRStudio me da error de sintáxis, ¿es posible usar algo semejante en éste IDE?


----------



## Miembro eliminado 356005 (Sep 9, 2014)

Según lo que viene en el AVR Assembler User Guide, la única forma de referirse al contador de programa es con el identificador PC (página 4-17, apartado 4.6.1), así que quedaría así (no probado):


```
rjmp    PC-2
```

De todas maneras, todos los códigos y ejemplos que vas a ver van a usar etiquetas.


----------



## Daniel Meza (Sep 13, 2014)

ohh muy cierto, olvidaba esa forma , es que trato de meterme lo menos posible con el contador de programa en los micros. 
He compilado el código y simulado y funciona correctamente. Gracias compañero Joaquín
PD: pido perdón por la demora en mi respuesta


----------



## locodelafonola (Sep 20, 2014)

hola genete ...bueno siguiendo el consejo de el amigo D@rkbytes publico por aca ..creo que al amigo meza tambien le va a servir ...yo deprogamacion en ASM ..no se nada ( solo lo que leei ..pero no estoy seguro que aprendi algo .... bueno como se un poco de compilar en C ...( me enseño cosmefulanito04) ...me decidi aprobar estas libreris que en contre en este foro .... http://www.mikrocontroller.net/forum/mikrocontroller-elektronik?filter=Henne´s+DMX+Transceiver ..  y bueno parece que estan bien ...porque arme el proyecto en avr studio 4 ... y compilo muy bien    ....y al parecer hace lo que dicen ...ya lo tengo montado y funcionando .....  mi idea es reformarlo ..y aclaro que como esta ...... funciona perfectamente en DMX y en modo manual ( llaves minidips).. la cosa es que en el post de las luces hace rato que piden algo como los tachos comerciales ... y mi idea es hacer algo que sirva para DMX o sin DMX (audioritmico ) .... para aquellos que no saben o no tiene DMX basicamente tome el ejemplo de este "tacho" comercial 



 .... que se usa muchisimo en ambientacion de fiestas  lo que tendia que reformar sun algunos comandos y agregar algunos mas para que quede funcionalmente igual ..  pero como no se mucho de ASM recurro a ustedes ... el codigo es este 
	
	



```
.include "m8515def.inc"

;Register and Pin definitions

.def tempL 			= r16
.def tempH				= r17
.def Flags				= r18
.def DMXstate			= r19
.def null				= r2
.def status			= r21
.def ind_count			= r3
.def blink				= r4
.def PwmCnt			= r20
.def SREGbuf			= r5
.def ChaseFine			= r6
.def ChaseRes			= r7

.equ StrobeFreqH		     = 0x80
.equ StrobeFreqL		     = 0x81
.equ StrobeBuf			= 0x82

.equ OldStepH			= 0x83
.equ OldStepL			= 0x84
.equ NewStepH			= 0x85
.equ NewStepL			= 0x86
.equ StepCnt			= 0x87
.equ ChaseCnt			= 0x88
.equ ChaseSeed			= 0x89

.equ LED1= PD7
.equ LED2= PE0
.equ BIT9= PE2

.equ DMX_FIELD=      0x60 		;Inicio SRAM
.equ DMX_CHANNELS=   10
.equ PWM_FIELD=      0x70		
.equ F_OSC=          8000
.equ FLASH_DURATION= 400
.equ IND_OFFSET=     12	 	;Offset para el indicador del disparador automático(14Hz)

#define CHS_SPD		 (0x600)
#define RATE         (0x500)
#define PAT0		 (0x400)
#define PAT1         (PAT0 +0xA)
#define PAT2		 (PAT1 +0xA)
#define PAT3		 (PAT2 +0xA)
#define PAT4		 (PAT3 +0xA)
#define PAT5         (PAT4 +0xA)
#define PAT6         (PAT5 +0xA)
#define PAT7         (PAT6 +0xA)


;***** banderas especiales

#define  VALID_DMX 	       (0)
#define  SIGNAL_COMING      (1)

#define  doIND			 (5)
#define  BLACK_OUT		 (6)
#define  DATA_REFRESHED     (7)


;vectores de interrupción
.org 0	
	rjmp init 		;restablecer la dirección del vector
	reti			;Interrupción externa 0 Vector Dirección
	reti			;Interrupción externa Vector Dirección 1
	reti			;Captura Introducir dirección de vector de interrupción 1
	rjmp strobe	;Salida Comparar vector de interrupción Dirección 1A
	reti			;Salida Comparar vector de interrupción Dirección 1B
	reti			;Desbordamiento de interrupción vectorial Dirección 1
	rjmp pwm		;Desbordamiento de interrupción vectorial Dirección 0
	reti			;SPI vector de interrupción Dirección
	rjmp get_byte	;UART Recibe completa interrupción vectorial Dirección
	reti			;UART registro de datos vacío vector de interrupción Dirección
	reti			;UART transmisión completa interrupción vectorial Dirección
	reti			;Comparador analógico vector de interrupción Dirección
	reti			;Interrupción externa Vector Dirección 2
	reti			;Salida Comparar 0 vector de interrupción Dirección
	reti			; EEPROM Interrupt Vector Dirección
	reti			; SPM interrupción completa Vector Dirección
	reti			; SPM interrupción completa Vector Dirección

; INIT

init:

; Stack
	ldi		tempH,high(RAMEND)
	ldi		tempL,low(RAMEND)
	out		SPH,tempH
	out		SPL,tempL

; WATCHDOG
	wdr
	ldi 	tempL, (1<<WDE)|(1<<WDCE)
	out 	WDTCR, tempL
	ldi 	tempL, (1<<WDE)|(1<<WDCE)|(1<<WDP2)|(1<<WDP1)
	out 	WDTCR, tempL
	wdr												;set prescaler @0,5s

; PortA
	ser 	tempL
	out 	DDRA, tempL
	clr 	tempL
	out 	PortA, tempL 			;low Outputs

; PortB
	ldi		tempL, 0b00000011
	out		DDRB, tempL
	ldi		tempL, 0b11110100
	out		PortB, tempL

; PortD
	ldi 	tempL, 0b10000100
	out 	DDRD, tempL
	ldi 	tempL, 0b01111000
	out 	PortD, tempL 			;DMX & Spare , LED1 on

; PortE
	ldi 	tempL, 0b00000001
	out 	DDRE, tempL
	ser		tempL
	out 	PortE, tempL 				;LED2 off,          BIT9 & OPTION Pullup             ; Timers
	ldi 	tempL, (1<<CS01)	;set counter0 @clock/8 frequency
	out 	TCCR0, tempL
	clr		tempL
	out		TCCR1A, tempL
	ldi 	tempL, (1<<CS12)|(1<<WGM12) 	;set counter1 @clock/256 frequency, CTCmode
	out 	TCCR1B, tempL
	ldi 	tempL, 	(1<<TOIE0)	 ;aktivate overflow interrupt
	out 	TIMSK, tempL
		
	rcall	init_dmx  ; set Register
	clr null
	clr blink
	com blink
	mov	ChaseFine, blink
	ldi tempL, IND_OFFSET
	mov ind_count, tempL
	ldi PwmCnt, 0xFF
	ldi	Flags, 0									;clear Flags
	
	sts StepCnt, null
	sts	NewStepH, null
	sts NewStepL, null
	ldi	tempL, 1
	sts ChaseCnt, tempL
	sts ChaseSeed, tempL
	mov	ChaseRes, tempL		

	wdr
	sei

main: 	sbrc	Flags, doIND
		rcall	indicate

		rcall   eval_strobe_freq ;rcall chase
		rjmp	main



;****************************** LED INDICATOR ***********************************
indicate:
		cbr		Flags, (1<<doIND)	;clear flag
		rcall	chase
		dec		ind_count
		breq	ind_a
		ret
      
	  ind_a:
		wdr			;reset Watchdog
        ;working LED
		sbrc	Flags, DATA_REFRESHED	;should flash?
		rjmp	data_flash	
		sbi		PortE, LED2			; LED off

Error_LED:
		sbrc  	blink, 0			;wenn erstes bit HI
		rjmp  	on
		sbi   	PortD, LED1
		rjmp  	ind_tst
	 on:
	 	cbi  	PortD, LED1

     ind_tst:
	    lsr   	blink
		ldi		tempL, 1
		cp		blink, tempL
		brne	no_ind   ;wenn durchrotiert (blink = 0)
		ldi		tempL, 0b10000000		
		sbrs 	Flags, VALID_DMX
		ldi	 	tempL, 0b10001010
		sbrs 	Flags, SIGNAL_COMING
		ldi	 	tempL, 0b10000010
		mov  	blink, tempL

		cbr 	Flags, (1<<VALID_DMX)|(1<<SIGNAL_COMING)
	
	no_ind:
		ldi		tempL, IND_OFFSET
		mov		ind_count, tempL		;plant prescaler
		ret
	data_flash:
		cbr		Flags, (1<<DATA_REFRESHED)
	    sbis 	PortE,LED2				;blinken grün
		rjmp 	off
		cbi		PortE,LED2
		rjmp 	Error_LED
		off:
		sbi 	PortE,LED2
		rjmp 	Error_LED 




;****************************** strobe frequency ***********************************
eval_strobe_freq:
		lds		tempL, DMX_FIELD					;get 1st DMX ch
		cpi		tempL, 246
		brlo	esf_1
		ldi		tempL, 245
       esf_1:
		lds		tempH, StrobeBuf
		cp		tempL, tempH
		brne	esf_2					;only eval if changed
		ret
	esf_2:
		sts		StrobeBuf, tempL
		cpi		tempL, 30
		brlo	esf_no_strobe
		cpi		tempL, 245
		brsh	esf_sync

		subi	tempL, 30				;0-200 allowed
		ldi		ZL, low(RATE*2)		;get freq from table
		ldi		ZH, high(RATE*2)
		add		ZL, tempL
		adc		ZH, null
		add		ZL, tempL
		adc		ZH, null
		lpm		tempL, Z+
		lpm		tempH, Z
		cli
		sts		StrobeFreqL, tempL		;atomic store
		sts		StrobeFreqH, tempH
		
		in		tempL, TIMSK
		sbr		tempL, (1<<OCIE1A)	;enable irq
		out		TIMSK, tempL
		in		tempL, TIFR
		sbr		tempL, (1<<OCF1A)	;enable irq
		out		TIFR, tempL
		reti	


	esf_no_strobe:
		in		tempL, TIMSK
		cbr		tempL, (1<<OCIE1A)		;disable irq
		out		TIMSK, tempL
		cbr		Flags, (1<<BLACK_OUT)		;enable pwm
		ret
	
	esf_sync:
		in		tempL, TIMSK
		sbrs	tempL, OCIE1A			;only when strobing
		ret
		cli
		sbr		Flags, (1<<BLACK_OUT)		;blank!
		lds		ZH, StrobeFreqH
		lds		ZL, StrobeFreqL
		out		OCR1AH, ZH
		out		OCR1AL, ZL
		sbiw	ZH:ZL, 20
		out		TCNT1H, ZH
		out		TCNT1L, ZL 		
		reti


;****************************** manual chaser mode ***********************************
chase:							;called by indicator
		sbis	PinE, PE1
		rjmp	chs_a
		sbic 	UCSRB,RXEN
		ret				;enable DMX reception
		sbi		UCSRB, RXEN
		clr		DMXstate
		ret

	chs_exit:
		sts		ChaseCnt, tempH
		ret

    chs_a:
		cbi		UCSRB,RXEN			;disable DMX
		sbr		Flags, (1<<VALID_DMX)|(1<<SIGNAL_COMING)
		lds		tempH, ChaseCnt		;load prescaler
		dec		tempH
		brne	chs_exit
		lds		tempL, ChaseSeed	;reseed prescaler
		sts		ChaseCnt, tempL

		add		ChaseFine, ChaseRes		;up-fade val
		adc		tempH, null	;(tempH was 0)
		mov		tempL, ChaseFine
		com		tempL			;down-fade val

		tst		tempH
		brne	chs_step
	  chs_step_ret:
		ldi		XL, low(DMX_FIELD +1)
		ldi 	XH, high(DMX_FIELD)
		ldi		ZL, 1
	   chase_fade:				;ch1..8
		clr		tempH
		lds		ZH, OldStepL
		and		ZH, ZL
		breq	cf_no_old
		mov		tempH, tempL
	   cf_no_old:
	    lds		ZH, NewStepL
		and		ZH, ZL
		breq	cf_no_new
        add		tempH, ChaseFine
       cf_no_new:
	    st		X+, tempH
		lsl		ZL
		brne	chase_fade
		
		clr		tempH			;9th ch
		lds		ZH, OldStepH
		sbrc	ZH, 0
		mov		tempH, tempL
		lds		ZH, NewStepH
		sbrc	ZH, 0
		add		tempH, ChaseFine
		st		X, tempH

		ret
		
		
	chs_step:
		sbr		Flags, (1<<DATA_REFRESHED)
		clr		ChaseFine		;reset fader
		ser		tempL

		lds		tempH, NewStepL		;change steps
		sts		OldStepL, tempH
		lds		tempH, NewStepH
		sts		OldStepH, tempH

		ldi		ZH, high(CHS_SPD*2)		;get speed
		in		ZL, PinC
		com		ZL
		swap	ZL
		andi	ZL, 0b00001111		;isolate pattern
		lpm		ZH, Z
		ldi		tempH, 1
		
		cpi		ZL, 5	 ;switch between resolution and prescale
		brsh	chs_decres
		mov		ChaseRes, tempH
		sts		ChaseSeed, ZH
		rjmp	chs_strb
       chs_decres:
	    mov		ChaseRes, ZH
		sts		ChaseSeed, tempH
	   chs_strb:

		clr		ZH			;add strobe
		sbis	PinE, PE2
		ldi		ZH,  220
		sts		DMX_FIELD, ZH

		ldi		ZH, high(PAT0*2)	;get next step
		lds		tempH, StepCnt
		mov		ZL, tempH
		lsl		ZL
		inc		tempH
		sts		StepCnt, tempH
		lpm		tempH, Z+
		sts		NewStepL, tempH
		lpm		tempH, Z
		sts		NewStepH, tempH
		
		sbrs	tempH, 1			;reset pattern?	
		rjmp	chs_step_ret
		
		in		ZL, PinC
		com		ZL
		andi	ZL, 0b00000111		;isolate pattern
		ldi		tempH, 10
		mul		ZL, tempH	
		sts		StepCnt, r0		;save pattern

		rjmp	chs_step_ret		
		
		
		
			


; ***************************9ch 8bitpwm-Ausgabe ****************************************
pwm:						
		in      SREGbuf, SREG
		push	tempL

	  	sbrc	Flags, BLACK_OUT		;blanked by strobe?
		rjmp	pwm_bo_exit
			
		lds		tempL, PWM_FIELD
		cp		tempL, PwmCnt
		ror		status
	  
	  	lds		tempL, (PWM_FIELD+1)
		cp		tempL, PwmCnt
		ror		status

	 	lds		tempL, (PWM_FIELD+2)
		cp		tempL, PwmCnt
		ror		status
		 	
		lds		tempL, (PWM_FIELD+3)
		cp		tempL, PwmCnt
		ror		status

		lds		tempL, (PWM_FIELD+4)
		cp		tempL, PwmCnt
		ror		status

	  	lds		tempL, (PWM_FIELD+5)
		cp		tempL, PwmCnt
		ror		status
	  	
		lds		tempL, (PWM_FIELD+6)
		cp		tempL, PwmCnt
		ror		status

	  	lds		tempL, (PWM_FIELD+7)
		cp		tempL, PwmCnt
		ror		status
								.;9th bit
	   	sbis	PinD, PD4				;invert option
  		rjmp	pwm9_pos				; no invert
		
		lds		tempL, (PWM_FIELD+8)
		sbi		PortB, 0
		cp		tempL, PwmCnt
		brlo	pwm_exit
		cbi		PortB, 0
		rjmp	pwm_exit

	   pwm9_pos:
	    com		status
	  	lds		tempL, (PWM_FIELD+9)
		cbi		PortB, 0
		cp		tempL, PwmCnt
		brlo	pwm_exit
		sbi		PortB, 0
		rjmp	pwm_exit

	pwm_bo_exit:
		sbis	PinD, PD4				;invert option
  		rjmp	pwm_bo_pos				; no invert
		ser		status		;all ch off (inverted)
		sbi		PortB, 0
		rjmp	pwm_exit
	   pwm_bo_pos:
	   	clr		status		;all ch off
		cbi		PortB, 0	

	pwm_exit:
		out		PortA, status			;output
		mov		tempL, PwmCnt	;set next compare time
		lsr		tempL
		lsr		tempL
		lsr		tempL
		ldi		status, 250
		sub		status, tempL
		out		TCNT0, status

		inc		PwmCnt
		tst		PwmCnt
		brne	pwm_no_reload
		lds		tempL, (DMX_FIELD+1)	;refresh channels
		sts		PWM_FIELD, tempL
		lds		tempL, (DMX_FIELD+2)
		sts		(PWM_FIELD+1), tempL
		lds		tempL, (DMX_FIELD+3)
		sts		(PWM_FIELD+2), tempL
		lds		tempL, (DMX_FIELD+4)
		sts		(PWM_FIELD+3), tempL
		lds		tempL, (DMX_FIELD+5)
		sts		(PWM_FIELD+4), tempL
		lds		tempL, (DMX_FIELD+6)
		sts		(PWM_FIELD+5), tempL
		lds		tempL, (DMX_FIELD+7)
		sts		(PWM_FIELD+6), tempL
		lds		tempL, (DMX_FIELD+8)
		sts		(PWM_FIELD+7), tempL
		lds		tempL, (DMX_FIELD+9)
		sts		(PWM_FIELD+8), tempL
		ldi		PwmCnt, 1				;reseed counter
		sbr		Flags, (1<<doIND)	;indicate in main
	  
	  pwm_no_reload:
	  	pop		tempL
		out     SREG, SREGbuf
		reti



; ***************************Strobo function ****************************************
strobe:	
		in      SREGbuf, SREG
		push	tempL
		push	tempH

		sbrs	Flags, BLACK_OUT
		rjmp	str_blank
		cbr		Flags, (1<<BLACK_OUT)				;enable pwm
		ldi		tempL,  low(FLASH_DURATION)			;load flash time
		ldi		tempH, high(FLASH_DURATION)
		rjmp	str_exit

	str_blank:
		sbr		Flags, (1<<BLACK_OUT)
		lds		tempL, StrobeFreqL
		lds		tempH, StrobeFreqH

	str_exit:
		out		OCR1AH, tempH
		out		OCR1AL, tempL
		pop		tempH
		pop		tempL
		out     SREG, SREGbuf
		reti	


.include "lib_dmx_in.asm"

nix: rjmp nix

// Strobo frequency table (damped logarithmic)
.org RATE
.dw 65532, 60407, 56368, 53017, 50170, 47708, 45546, 43626, 41904, 40345, 38925, 37623, 36423, 35311, 34277, 33311 
.dw 32406, 31555, 30753, 29996, 29278, 28596, 27948, 27331, 26741, 26177, 25637, 25120, 24623, 24145, 23685, 23242 
.dw 22814, 22402, 22003, 21617, 21244, 20882, 20531, 20191, 19861, 19540, 19228, 18924, 18629, 18341, 18061, 17788 
.dw 17521, 17261, 17007, 16760, 16517, 16281, 16049, 15823, 15601, 15384, 15172, 14964, 14760, 14560, 14364, 14172 
.dw 13983, 13798, 13617, 13438, 13263, 13091, 12922, 12756, 12593, 12432, 12274, 12119, 11966, 11815, 11667, 11522 
.dw 11378, 11237, 11098, 10960, 10825, 10692, 10561, 10431, 10304, 10178, 10054, 9931,  9811,  9691,  9574,  9458 
.dw 9343,  9230,  9119,  9008,  8899,  8792,  8686,  8581,  8477,  8375,  8273,  8173,  8074,  7976,  7880,  7784 
.dw 7690,  7596,  7504,  7412,  7322,  7232,  7144,  7056,  6969,  6884,  6799,  6715,  6631,  6549,  6467,  6387 
.dw 6307,  6227,  6149,  6071,  5994,  5918,  5843,  5768,  5694,  5620,  5548,  5475,  5404,  5333,  5263,  5193 
.dw 5125,  5056,  4988,  4921,  4855,  4789,  4723,  4658,  4594,  4530,  4466,  4404,  4341,  4279,  4218,  4157 
.dw 4097,  4037,  3978,  3919,  3860,  3802,  3744,  3687,  3631,  3574,  3518,  3463,  3408,  3353,  3299,  3245
.dw 3191,  3138,  3085,  3033,  2981,  2929,  2878,  2827,  2777,  2726,  2677,  2627,  2578,  2529,  2480,  2432
.dw 2384,  2337,  2289,  2242,  2196,  2149,  2103,  2057,  2012,  1967,  1922,  1877,  1833,  1789,  1745,  1701 
.dw 1658,  1615,  1572,  1530,  1488,  1446,  1350,  1250,  1100,  1050,  1000,  950,   900,   850,   800,   750
.dw 700,   650,   600,   550,   500,   450,   400,   350,   300,   250,   200,   150


.org PAT0					;on
.dw 0b0111111111
.dw 0b1111111111

.org PAT1					;Lauflicht
.dw 0b0000000001
.dw 0b0000000010
.dw 0b0000000100
.dw 0b0000001000
.dw 0b0000010000
.dw 0b0000100000
.dw 0b0001000000
.dw 0b0010000000
.dw 0b1100000000

.org PAT2					;ping pong
.dw 0b0000010000
.dw 0b0000100000
.dw 0b0000001000
.dw 0b0001000000
.dw 0b0000000100
.dw 0b0010000000
.dw 0b0000000010
.dw 0b0100000000 
.dw 0b1000000001

.org PAT3					;ping pong
.dw 0b0000011000
.dw 0b0000100100
.dw 0b0001000010
.dw 0b1010000001

.org PAT4					;pfeil
.dw 0b0000011000
.dw 0b0000111100
.dw 0b0001111110
.dw 0b0011111111
.dw 0b0011100111
.dw 0b0011000011
.dw 0b1010000001

.org PAT5					;RGB
.dw 0b0001001001
.dw 0b0011011011
.dw 0b0010010010
.dw 0b0110110110
.dw 0b0100100100
.dw 0b1101101101

.org PAT6					;RGB spread
.dw 0b0100010001
.dw 0b0101110011
.dw 0b0001100010
.dw 0b0011101110
.dw 0b0010001100
.dw 0b1110011101

.org PAT7
.dw 0b0001001001			;RGB single change
.dw 0b0001001011
.dw 0b0001011011
.dw 0b0011011011
.dw 0b0011011010
.dw 0b0011010010
.dw 0b0010010010
.dw 0b0010010110
.dw 0b0010110110
.dw 0b0110110110
.dw 0b0110110100
.dw 0b0110100100
.dw 0b0100100100
.dw 0b0100100101
.dw 0b0100101101
.dw 0b0101101101
.dw 0b0101101001
.dw 0b1101001001


.org CHS_SPD
.db 25, 10, 3, 2, 1, 2, 3, 5, 8, 12, 17, 22, 27, 35, 40, 48
```
 bueno si tienen mas preguntas ..... con respecto alguna cosa que nesesite aportar avicen ..y trato de subirlas ...ya en otro mensaje explico con mas claridad por donde empezar ....juan


----------



## locodelafonola (Sep 22, 2014)

hola gente ...bueno una de las cosa que qiero reformar es el cambio del cristal .... tiene de 8 MHZ y quiero cambiarlo por uno de 16MHZ .... y no se donde esta la sentencia para hacerlo .....ni como hacerlo en ASM  edito mensaje bueno acabo de darme cuenta que en la otra libreria que se compila junto con la anterior ....... hay algunas sentencias de el cristal .... pero no entiendo como cambiarlo 
	
	



```
//Definitions in main source ****************** //
		
 //#define DMX_FIELD	 0x60	//base address of DMX array
//#define DMX_CHANNELS 10		//no. of channels
#define DMX_CHANGED  0		//DMX flag: indicates ch changes
#define DMX_BT_CH	 1		//internal flag
#define DMXstate	 R18	//status reg for DMX-ISR (r16-r31)
	  //X-Pointer reserved for DMX ISR!!

//#define F_OSC		 8000  	//oscillator freq. in kHz (typical 8MHz or 16MHz)


	
init_dmx:
	;**** PortD
		in		tempL, DDRD
		sbr		tempL, (1<<2)
		out		DDRD, tempL
		in		tempL, PortD
		cbr		tempL, (1<<2)		;enable reception
		out		PortD, tempL		
	;**** USART
    	ldi 	tempL, ((F_OSC/4000)-1) ;set Usart to 250 kbaud
    	out 	UBRRL, tempL
    	clr 	tempL
    	out 	UBRRH, tempL
    	ldi 	tempL, (1<<URSEL)|(3<<UCSZ0)|(1<<USBS)
    	out 	UCSRC, tempL			
		in		tempL,UDR
 		clr		tempL
		out		UCSRA,tempL		
		sbi 	UCSRB,RXCIE
		sbi 	UCSRB,RXEN			

#ifndef USE_ADR
	;**** PortC
		clr 	tempL
		out 	DDRC, tempL
		ser 	tempL
		out 	PortC, tempL  		;Inputs with PullUp for DipSwitch
	;**** PortE
		in		tempL, DDRE
		cbr	 	tempL, (1<<1)|(1<<2)
		out 	DDRE, tempL
		in		tempL, PortE
		sbr	 	tempL, (1<<1)|(1<<2)
		out 	PortE, tempL 		;PE2 & OPTION Pullup
#endif

	;**** memory
		ldi		XH, high(DMX_FIELD)
		ldi		XL,  low(DMX_FIELD)
		ldi		tempL,0x00			;set all channels to 0
		ldi 	DMXstate, DMX_CHANNELS
	write_RxD:	
		st 		X+,tempL
		dec		DMXstate
		brne	write_RxD

		clr 	DMXstate			;set DMXstate to 'wait for Reset' (done by counting ;-)
		ret


/* ***********************************************************************************************************
 *					DMX reception ISR
 ************************************************************************************************************/
get_byte:
		in      SREGbuf, SREG
		push	tempH
		push	tempL		

		in		tempL,UCSRA		;get status register before data register
		in		tempH,UDR
#ifdef SIGNAL_COMING
		sbr		Flags, (1<<SIGNAL_COMING)	;indicator flag: USART triggered
#endif	
		sbrc	tempL,DOR		;check for overrun -> wait for reset
		rjmp	overrun	

		sbrc	tempL,FE		;check for frame error -> got reset
		rjmp	frame_error	
		
		cpi		DMXstate, 1   	;check for startbyte (must be 0)
		breq	startbyte

  		cpi 	DMXstate, 2   	;check for start adress
		breq    startadr
  		
 		cpi 	DMXstate, 3	
  		brsh	handle_byte

	gb_finish:
		pop		tempL
		pop		tempH
		out     SREG, SREGbuf	
		reti			

	startbyte:
		tst 	tempH	 				;if null-> Startbyte
		brne 	overrun
		inc  	DMXstate 				;next -> start address

#ifndef USE_ADR
		in 		XL, PinC 				;get start address
		com     XL
		clr		XH
		sbis	PinE, PE2				;9th bit
		inc		XH
#endif
#ifdef USE_ADR
		rcall	get_address
#endif
		rjmp	gb_finish

 	startadr:
		sbiw	XH:XL, 1
		brne	gb_finish
		ldi 	XH, high(DMX_FIELD)
		ldi		XL,  low(DMX_FIELD)
		inc  	DMXstate 				;next-> data handler
		
	handle_byte:
#ifdef DMX_EXT							;external manipulation of DMX data?
		rcall	clc_dmx
#endif			
		ld		tempL, X				;get old val
		cp		tempL, tempH
		breq	gb_noChange
		st		X, tempH
#ifdef DATA_REFRESHED
		sbr		Flags, (1<<DATA_REFRESHED) ;indicator flag: ch changed
#endif
       gb_noChange:
	    adiw	XH:XL, 1

		cpi		XL, low(DMX_FIELD +DMX_CHANNELS)
		brne	gb_finish
		cpi		XH, high(DMX_FIELD +DMX_CHANNELS)
		brne	gb_finish
#ifdef VALID_DMX
		sbr		Flags, (1<<VALID_DMX)	;indicator flag: all ch received
#endif	
		clr		DMXstate
		rjmp	gb_finish
	
 	frame_error:
		ldi 	DMXstate, 1				;FE detected as break
		cbi		UCSRA,FE				;further framing errors, caused by longer breaks
		rjmp	gb_finish

	overrun:
	 	clr 	DMXstate				;wait for frame-error
		cbi		UCSRA,DOR				
		rjmp	gb_finish
```


----------



## Miembro eliminado 356005 (Sep 22, 2014)

En principio, no pasa nada por que le pongas un cristal más rápido.

Lo que sí cambia es si en tu programa hay instrucciones de retraso (_delay_) o haces uso de los temporizadores (con o sin interrupciones asociadas).

En ese caso, tienes que volver a hacer los cálculos para tener los nuevos argumentos a esas subrutinas y temporizadores. Digamos que hay que ajustar el número de instrucciones del programa a la nueva situación de que el reloj ahora va el doble de velocidad, y solo en las partes del programa que dependen de esa situación externa.

En tu programa, por ejemplo, tienes definido* F_OSC con la velocidad en khz del cristal. Si el programa está bien escrito, solo tendrás que cambiar esa línea.

(*) en realidad, esa línea está comentada, así que no la estás usando (?).


----------



## locodelafonola (Sep 22, 2014)

hola amigo ... gracias por condestar .... bueno esa es la idea .... aumentar la velocidad del reloj .... aunque al cambiarla ...se me escapo lo de los tiempos ......   en la segunda libreria que subi  sip ...la sentencia esta sin activarce ... .. pero en la pirimera libreria si esta actvado 
	
	



```
.equ DMX_FIELD=      0x60 		;Inicio SRAM
.equ DMX_CHANNELS=   10
.equ PWM_FIELD=      0x70		
[COLOR="Red"].equ F_OSC=          8000[/COLOR]
.equ FLASH_DURATION= 400
.equ IND_OFFSET=     12	 	;Offset para el indicador del disparador automático(14Hz)
```
 bueno si me explicas como hacerlo lo hago .. ...porque sobre todo quiero aprender este lenguaje .... que desconozco absolutamente ...gracias amigo ... juan


----------



## Daniel Meza (Sep 22, 2014)

Adelantándome al amigo Joaquín, prevalecerá la librería que tenga el fuse de cristal activado... fuera de eso, veo que en la rutina de gestión del puerto UART se hace el cálculo de los bdps directamente con el dato de F_OSC así que un cambio en él automáticamente calculará el nuevo valor para los registros del generador de baudios.
No veo, además, rutinas de tiempo que dependan directamente de la FOSC

Saludos


----------



## locodelafonola (Sep 22, 2014)

gracias amigo meza .... publique la segunda libreria poque vi esto 
	
	



```
;**** USART
    	[COLOR="Red"]ldi 	tempL, ((F_OSC/4000)-1) ;set Usart to 250 kbaud[/COLOR]
    	out 	UBRRL, tempL
    	clr 	tempL
    	out 	UBRRH, tempL
    	ldi 	tempL, (1<<URSEL)|(3<<UCSZ0)|(1<<USBS)
    	out 	UCSRC, tempL			
		in		tempL,UDR
 		clr		tempL
		out		UCSRA,tempL		
		sbi 	UCSRB,RXCIE
		sbi 	UCSRB,RXEN
```
 entose razono que debe ser lo que tu dices ya que detecta la trama de DMX que trabaj a 250 kb ...ahora la duda es que hace una divicion y si cambio el cristal  ..supongo que eso lo tengo que cambiar tambien  ¿¿¿ o no ???


----------



## Daniel Meza (Sep 22, 2014)

Así es, te sugiero que revises la hoja de datos del micro, en ella encontrarás una tabla con los valores ya calculados que tienes que cargarle a UBRRL y UBRRH para lograr los bdps deseados. En este momento veo la hoja de datos del ATMEGA328 (supongo a de ser similar) y dice que para lograr 250K es necesario cargar en UBRRn un 3 si el bit U2Xn=1 o un 1 si U2Xn =0


----------



## locodelafonola (Sep 22, 2014)

Daniel Meza dijo:


> Así es, te sugiero que revises la hoja de datos del micro, en ella encontrarás una tabla con los valores ya calculados que tienes que cargarle a UBRRL y UBRRH para lograr los bdps deseados. En este momento veo la hoja de datos del ATMEGA328 (supongo a de ser similar) y dice que para lograr 250K es necesario cargar en UBRRn un 3 si el bit U2Xn=1 o un 1 si U2Xn =0


 gracias de nuevo amigo .... como dije ....estoy tocando de oido ... solo son cosas que supongo ..yy... apaaa sip tengo la hoja de datos del 8515 ...vere si encuentro eso que dices ...... y si supongo que trabaja asi por esto (con cristal de 8mhz)  ya veo que al menos entienden mejor que yo .... lo de estas librerias


----------



## locodelafonola (Sep 25, 2014)

hola gente ...hice los cambios asi 
	
	



```
.equ LED1= PD7
.equ LED2= PE0
.equ BIT9= PE2

.equ DMX_FIELD=      0x60 	;Inicio SRAM
.equ DMX_CHANNELS=   10
.equ PWM_FIELD=      0x70		
[COLOR="Red"].equ F_OSC=          16000[/COLOR]
.equ FLASH_DURATION= 400
.equ IND_OFFSET=     12	 	;Offset para el indicador del disparador automático(14Hz)
```
 en esa parte y en la otra marcada por el amigo meza asi 
	
	



```
;**** USART
    	[COLOR="Red"]ldi 	tempL, ((F_OSC/4000)-2) ;set Usart to 250 kbaud[/COLOR]
    	out 	UBRRL, tempL
    	clr 	tempL
    	out 	UBRRH, tempL
    	ldi 	tempL, (1<<URSEL)|(3<<UCSZ0)|(1<<USBS)
    	out 	UCSRC, tempL			
		in		tempL,UDR
 		clr		tempL
		out		UCSRA,tempL		
		sbi 	UCSRB,RXCIE
		sbi 	UCSRB,RXEN
```
 la compilacion esta perfecta no larga error ..pero al grabar el hex en el montaje ..no funciona aclaro que cambio el cristal por uno de 16mhz y la configuracin de los fusebit ......  hay error en la deteccion de la trama dmx ....  o tal vez otro error que no puedo determinar ....


----------



## Daniel Meza (Sep 25, 2014)

La primera parte ok, pero en la segunda intenta así

```
ldi tempL,3
out UBRRL,tempL
clr tempL
out URRH,tempL
```

Saludos


----------



## locodelafonola (Sep 26, 2014)

hola  amigos ...bueno segui las indicaciones y alli esta andando ...veo que hay una notable mejora en el proceso de DMX ..... en modo autonomo . cambio los ciclos de trabajo (lo hace mas rapido) ......   aunque sigo confundido con la configuracion de fuces-bit del pony prog ...bueno ahora la parte que quiero reformar es la siguiente ..... aca esta  la generacion del pwm 
	
	



```
; ***************************9ch 8bitpwm-Ausgabe ****************************************
pwm:						
		in      SREGbuf, SREG
		push	tempL

	  	sbrc	Flags, BLACK_OUT		;blanked by strobe?
		rjmp	pwm_bo_exit
			
		lds		tempL, PWM_FIELD
		cp		tempL, PwmCnt
		ror		status
	  
	  	lds		tempL, (PWM_FIELD+1)
		cp		tempL, PwmCnt
		ror		status

	 	lds		tempL, (PWM_FIELD+2)
		cp		tempL, PwmCnt
		ror		status
		 	
		lds		tempL, (PWM_FIELD+3)
		cp		tempL, PwmCnt
		ror		status

		lds		tempL, (PWM_FIELD+4)
		cp		tempL, PwmCnt
		ror		status

	  	lds		tempL, (PWM_FIELD+5)
		cp		tempL, PwmCnt
		ror		status
	  	
		lds		tempL, (PWM_FIELD+6)
		cp		tempL, PwmCnt
		ror		status

	  	lds		tempL, (PWM_FIELD+7)
		cp		tempL, PwmCnt
		ror		status
								.;9th bit
	   	sbis	PinD, PD4				;invert option
  		rjmp	pwm9_pos				; no invert
		
		lds		tempL, (PWM_FIELD+8)
		sbi		PortB, 0
		cp		tempL, PwmCnt
		brlo	pwm_exit
		cbi		PortB, 0
		rjmp	pwm_exit

	   pwm9_pos:
	    com		status
	  	lds		tempL, (PWM_FIELD+9)
		cbi		PortB, 0
		cp		tempL, PwmCnt
		brlo	pwm_exit
		sbi		PortB, 0
		rjmp	pwm_exit

	pwm_bo_exit:
		sbis	PinD, PD4				;invert option
  		rjmp	pwm_bo_pos				; no invert
		ser		status		;all ch off (inverted)
		sbi		PortB, 0
		rjmp	pwm_exit
	   pwm_bo_pos:
	   	clr		status		;all ch off
		cbi		PortB, 0
```
  que en DMX va de 0 a 255 ..... y aca esta la parte me maneja los canales definidos en este caso son 9  
	
	



```
pwm_bo_exit:
		sbis	PinD, PD4				;invert option
  		rjmp	pwm_bo_pos				; no invert
		ser		status		;all ch off (inverted)
		sbi		PortB, 0
		rjmp	pwm_exit
	   pwm_bo_pos:
	   	clr		status		;all ch off
		cbi		PortB, 0	

	pwm_exit:
		out		PortA, status			;output
		mov		tempL, PwmCnt	;set next compare time
		lsr		tempL
		lsr		tempL
		lsr		tempL
		ldi		status, 250
		sub		status, tempL
		out		TCNT0, status

		inc		PwmCnt
		tst		PwmCnt
		brne	pwm_no_reload
		lds		tempL, (DMX_FIELD+1)	;refresh channels
		sts		PWM_FIELD, tempL
		lds		tempL, (DMX_FIELD+2)
		sts		(PWM_FIELD+1), tempL
		lds		tempL, (DMX_FIELD+3)
		sts		(PWM_FIELD+2), tempL
		lds		tempL, (DMX_FIELD+4)
		sts		(PWM_FIELD+3), tempL
		lds		tempL, (DMX_FIELD+5)
		sts		(PWM_FIELD+4), tempL
		lds		tempL, (DMX_FIELD+6)
		sts		(PWM_FIELD+5), tempL
		lds		tempL, (DMX_FIELD+7)
		sts		(PWM_FIELD+6), tempL
		lds		tempL, (DMX_FIELD+8)
		sts		(PWM_FIELD+7), tempL
		lds		tempL, (DMX_FIELD+9)
		sts		(PWM_FIELD+8), tempL
		ldi		PwmCnt, 1				;reseed counter
		sbr		Flags, (1<<doIND)	;indicate in main
	  
	  pwm_no_reload:
	  	pop		tempL
		out     SREG, SREGbuf
		reti
```
  ahora paso a explicarles .... mi idea es repartir esa 9 salidas en 3 grupos de 3 RGB .... para que siga la normas de los "tachos" .... en DMX .... ya sea una consola virtual (computadora con interfaz .... o sea  una consola manual ( clasica a potenciometros) se asignan 3 canales solamente ..y el orden se respeta ..o sea RGB ..el primero es siempre el rojo (red) el que sigue es verde (green) ... y el ultimo es azul ( blue) ... bueno para que pueda respetarce la mezcla de colores nesesito que trabaje de esta manera ....  les cuento que originalmente ( como esta ) .... son 10 canales .... y el primero es strobe o flash ...entonces comenzamos a contar desde el 2 ...... los tres primeros canales  que se activen como esta  o sea desde 0 a 255 ... serian 2 , 3 y 4 ... el segundo grupo RGB serian 5 ,6 y 7 desde 85 a 255 y el ultimo grupo RGB 8 , 9 y 10 desde 170 a 255  ...de esta manera ...... con cuatro potenciometros asignados manejo la mezcla de los colores ...... y en la consola  me quedan 1 strobe .... 2 rojo... 3 verde ....y 4 azul ... en la practica trabajan asi ....tomemos el primer potenciometro (virtual o ficico trabajan igual ) ... que es el rojo y recordemos que este va desde 0 a 255 ...  a medida que voy subiendo va aumetando la intencidad (brillo) ..... y se enciende la primer hilera de led rojos .... cuando llegue a los 85 se encendera la segunda hilera de led rojos ( y por lo tanto aumenta su color ) ....... y si se sigue subiendo se llega a los 170 ........ y alli se enciende la tercera hilera de rojos ..... hasta los 255 ........ que es pleno brillo ...... en resumida cuenta nesesito ...... que los otros 6 canales sean el "reflejo" de las primeras tres salidas y que enciendan en los valores indicados (85 y 170 ) ...... si no lo entienden  avicen .... y trato de explicarlo de otra manera (pensare como )  gracias ... juan


----------



## locodelafonola (Sep 28, 2014)

hola gente ........ bueno pude cambiar las sentencias para el manejo de los potenciometros (virtuales y fisicos ) y aclaro que pude probar con los dos casos ..... con el freestyler y con una cosola DMX de 9 canales .......  bueno el montaje funciona .... los tres  primeros canales de color RGB ........ manejan a los otros dos grupos restantes ....  pero no se como hacer para que el segundo grupo arranque a los 85 .... y el tercero a los 170 .... aca muestro como hice 
	
	



```
inc		PwmCnt
		tst		PwmCnt
		brne	pwm_no_reload
		lds		tempL, (DMX_FIELD+1)				;canales de actualización
		sts		PWM_FIELD, tempL
		lds		tempL, (DMX_FIELD+2)
		sts		(PWM_FIELD+1), tempL
		lds		tempL, (DMX_FIELD+3)
		sts		(PWM_FIELD+2), tempL
		lds		tempL, (DMX_FIELD+1)
		sts		(PWM_FIELD+3), tempL
		lds		tempL, (DMX_FIELD+2)
		sts		(PWM_FIELD+4), tempL
		lds		tempL, (DMX_FIELD+3)
		sts		(PWM_FIELD+5), tempL
		lds		tempL, (DMX_FIELD+1)
		sts		(PWM_FIELD+6), tempL
		lds		tempL, (DMX_FIELD+2)
		sts		(PWM_FIELD+7), tempL
		lds		tempL, (DMX_FIELD+3)
		sts		(PWM_FIELD+8), tempL
		ldi		PwmCnt, 1							;reseed counter
		sbr		Flags, (1<<doIND)					;indicate in main
	  
	  pwm_no_reload:
	  	pop		tempL
		out     SREG, SREGbuf
		reti
```


----------



## locodelafonola (Sep 29, 2014)

buenas ...... mi gente ... bueno sigo peliando con mi codigo ...bueno descubri algo guiandome por el instinto .. (y razonamiento de ignorante) .... me fije que esta sentencia 
	
	



```
[COLOR="Blue"]ldi		PwmCnt, 1[/COLOR]
```
 es la que define el valor de lectura de los potenciometros virtuales o fisicos ...... yo cambie la libreria ..... agregandola en cada uno de los potenciometros ........ con el valor que pretendo que actuen .... pero no paso eso ..... en realidad  ....... toma todas las salidas ese valor de 170 o sea que por un lado descubri ...... que de esa manera toma el valor que yo quiero ....pero  no en forma individual ........... las sentencias anteriores .las desconoce  ...... solo toma la ultima 170  si yo la cambio por cualquier otro valor ......todo el conjunto toma ese EJ: 85 .......  la verdad que he buscado tutos o guias de ASM par AVR ..... pero sigo en la ignorancia total ...... los tutos me confunden mas .... debido a las etiquetas ... y si comparo estas librerias con lo que hay ...... peor todavia ...... sigo sin aprender nada  ....  
	
	



```
pwm_exit:
		out		PortA, status						;de salida
		mov		tempL, PwmCnt						;set próxima vez comparar
		lsr		tempL
		lsr		tempL
		lsr		tempL
		ldi		status, 255
		sub		status, tempL
		out		TCNT0, status

		inc		PwmCnt
		tst		PwmCnt
		brne	pwm_no_reload
		lds		tempL, (DMX_FIELD+1)				;canales de actualización
		sts		PWM_FIELD, tempL                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      																																																																																																																																																																																																																																																																																																																																																																																							
		[COLOR="Red"]ldi		PwmCnt, 1[/COLOR]
		lds		tempL, (DMX_FIELD+2)
		sts		(PWM_FIELD+1), tempL 																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																			
		[COLOR="Red"]ldi		PwmCnt, 1[/COLOR]
		lds		tempL, (DMX_FIELD+3)
		sts		(PWM_FIELD+2), tempL                               																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																												
		[COLOR="Red"]ldi		PwmCnt, 1[/COLOR]
		lds		tempL, (DMX_FIELD+1)
		sts		(PWM_FIELD+3), tempL                                                      																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																						
		[COLOR="Red"]ldi		PwmCnt, 85[/COLOR]
		lds		tempL, (DMX_FIELD+2)
		sts		(PWM_FIELD+4), tempL                                                 																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																							
		[COLOR="Red"]ldi		PwmCnt, 85[/COLOR]
		lds		tempL, (DMX_FIELD+3)
		sts		(PWM_FIELD+5), tempL 																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																			
		[COLOR="Red"]ldi		PwmCnt, 85[/COLOR]
		lds		tempL, (DMX_FIELD+1)
		sts		(PWM_FIELD+6), tempL 																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																			
		[COLOR="Red"]ldi		PwmCnt, 170[/COLOR]
		lds		tempL, (DMX_FIELD+2)
		sts		(PWM_FIELD+7), tempL 																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																			
		[COLOR="Red"]ldi		PwmCnt, 170[/COLOR]
		lds		tempL, (DMX_FIELD+3)
		sts		(PWM_FIELD+8), tempL 
		[COLOR="Red"]ldi		PwmCnt, 170[/COLOR]						;reseed counter
		sbr		Flags, (1<<doIND)					;indicate in main
	  
	  pwm_no_reload:
	  	pop		tempL
		out     SREG, SREGbuf
		reti
```


----------

