Webcampista.com

mucho más que un foro

Dmx

Otra opción sería subir la frecuencia del PIC a lo maximo que de, con cristal y todo. Eso sí, tocaría tocar todo el codigo de la USART para que leyese el DMX como debe. Pero en ese caso tendría que documentarme.
 
A ver ahora, Tiene como pega que el último bit de los 256 siempre está a cero, aunque el dato sea FFh (255d) y si en vez de poner < en los if, pones <=, entonces el primer bit de los 256 estará siempre a 1, aunque el dato sea 00h.


PHP:
// PWM Versión mejorada. 

byte contador;
byte[8] dato;  //aquí van a parar los datos recibidos en la rutina de DMX

while (true)
{
	PortB= 00h;
	if (contador<dato[0]) then
		PortB0=1;
	
	if (contador<dato[1]) then
		PortB1=1;
	
	if (contador<dato[2]) then
		PortB2=1;	
.
.
.

	if (contador<dato[7]) then
		PortB7=1;

	contador++; // como es un byte, el solo desborda y se pone a cero. 

} // del while


// En este caso el if se puede sustituir, pero dependiendo del compilador, podría no ser tan rápido.
// PortB[x]= (Contador<=dato[x]);


Esta versión además tiene como "ventaja" el que, según el compilador, ahorrará un salto por "if" y atención por que en cuanto a la rapidez, a lo mejor es preferible hacer la comparación al revés
if (dato[X]>=contador)
hablamos de acelerarlo "mucho", todo dependerá del como lo interprete el compilador y como sea de bueno...
 
Otra opción sería subir la frecuencia del PIC a lo maximo que de, con cristal y todo. Eso sí, tocaría tocar todo el codigo de la USART para que leyese el DMX como debe. Pero en ese caso tendría que documentarme.

Eso es lo primero :D según la versión, puedes llegar a 24Mhz, me parece...
 
Me cuesta entender la idea de que haya diferentes compiladores, sintaxis y demás, ya que viniendo de Java, donde todo es siempre lo mismo, alto nivel y excepciones. Solo es un comentario.
 
Me cuesta entender la idea de que haya diferentes compiladores, sintaxis y demás, ya que viniendo de Java, donde todo es siempre lo mismo, alto nivel y excepciones. Solo es un comentario.

El Java... ¿no es parecido al C? al menos al C# y este al C... ¿o ya estoy desfasado incluso en eso? :(
 
Noooooooooooo. Dios vaya desfase. Java corre sobre una máquina virtual y está orientado a objetos. La sintaxis básica y la forma de enfocar los programas es similar pero digamos que la máquina y la memoria son transparentes para el usuario y que tu solo trabajas con encapsulamiento en clases y objetos, todo de alto nivel. No hay, por ejemplo, punteros, sino referencias a objetos. Los objetos son dinámicos y se muren si se quedan sin referencias. Y si por ejemplo intentas acceder a la posición -1 de un array, el programa lanza una excepción (error) y se para, no lee la posicion relativa de memoria -1.

Más en http://es.wikipedia.org/wiki/Java_(lenguaje_de_programación)

Y micros en Java como que no.
 
Oye, pues no estaba tan mal encaminado, lo que es lo de la programación a objetos de toda la vida...

Sospecho que si te metes en la programación de micros te tocará aprender C...
 
Si en el fondo me apetecería. Tengo intenciones de en su día coger un programador de lavadora de carraca y levantarle todos los cronogramas de todos los pines con ayuda de Matlab y Arduino (activa un pin, comprueba con cuales de los otros tiene continuidad, lo almacena y pasa al siguiente, y luego con Matlab hacer los plots) y luego pasarlos a un micro. Es solo experiental, por hacerlo y aprender. Lo jodido sería luego digitalizar la temperatura de la lavadora. Requeriría cambiar termostato por NTC (uno cualquiera de lavadora, teniendo su curva sería suficiente, y si no se levanta) o dejar el mando termostático antiguo, y también cambiar la electoválvula de un cuerpo por otra de 4 cuerpos (o 4 simples empalmadas) para las 4 jaboneras, porque las de carraca distribuyen el agua con una varilla desde el programador.
Ya te digo, no creo que lo haga por necesidad, pero sí para aprender a usar C en serio.
 
Si en el fondo me apetecería. Tengo intenciones de en su día coger un programador de lavadora de carraca y levantarle todos los cronogramas de todos los pines con ayuda de Matlab y Arduino (activa un pin, comprueba con cuales de los otros tiene continuidad, lo almacena y pasa al siguiente, y luego con Matlab hacer los plots) y luego pasarlos a un micro. Es solo experiental, por hacerlo y aprender. Lo jodido sería luego digitalizar la temperatura de la lavadora. Requeriría cambiar termostato por NTC (uno cualquiera de lavadora, teniendo su curva sería suficiente, y si no se levanta) o dejar el mando termostático antiguo, y también cambiar la electoválvula de un cuerpo por otra de 4 cuerpos (o 4 simples empalmadas) para las 4 jaboneras, porque las de carraca distribuyen el agua con una varilla desde el programador.
Ya te digo, no creo que lo haga por necesidad, pero sí para aprender a usar C en serio.

Tú ríete, pero en el pueblo tengo una lavadora de los 70 que funciona de cine... salvo el programador, que de un tiempo a esta parte se para en un punto y no pasa.... Compré una placa de relés en ebay y en algún movil tengo apuntados las entradas, las salidas, algunos tiempos... :D no sé como acabará la cosa por que la tengo lejos y no somos los que más la usamos (hay más presión por acabarla pronto una vez empiece) pero... está to' preparado para cuando llegue el momento :D
 
¿La del R6? Algo habia oido tuyo de una lavadora y relés pero pensaba que era la del boquete. En cualquier caso si se te para el programador es que no le llega corriente al motor de arrastre o que hay un engranaje tocado. ¿Cómo saberlo? Neon soldado en paralelo con el motor de arrastre del programador. Cuando se pare el programador, si el neón está encendido es fallo mecánico =>Planteate levantar el programa y hacer el código en ese momento. Si no le llega corriente al motor es que algo que no hace contacto. Normalmente llevan un contacto para el motor de arrastre, y dependiendo del diseño, el motor de arrastre se parará cuando acabe el ciclo o también en las fases de carga y calentamiento, pasando a depender del presostato y del termostato, aunque normalmente no dependen de ello por seguridad con el agua. Eso sí, seguro que es bitemperatura: o frio o caliente con termostato por botón, y presostato de un nivel . No creo que lleve muchos contactos el programador, y por no tener no tendrá ni micro de puerta (blocapuertas ni lo pienso). En cualquier caso si te aburres, levanta el cronograma y haz la placa, y ya lo tienes.

Por cierto, vi por ahí un esquema super interesante para manejar un motor asíncrono de lavadora sacando los 3 modos de funcionamiento con un condensador. A ver si lo encuentro. Hubo suerte: http://cdn3.grupos.emagister.com/imagen/circuito_para_probar_motor_lavarropas_538723_t0.jpg Eso sí, yo en vez de poner una conmutador doble con parada para el lavado ponía uno doble sin parada y los comunes en vez de ir directos a fase y condensador los ponia en los otros bornes libres del de centrifugado. Así con 2 conmutadores dobles o relés gestionaba el sentido de giro y velocidad, e interrumpiendo la fase el encendido.
 
¿La del R6? Algo habia oido tuyo de una lavadora y relés pero pensaba que era la del boquete. En cualquier caso si se te para el programador es que no le llega corriente al motor de arrastre o que hay un engranaje tocado. ¿Cómo saberlo? Neon soldado en paralelo con el motor de arrastre del programador. Cuando se pare el programador, si el neón está encendido es fallo mecánico =>Planteate levantar el programa y hacer el código en ese momento. Si no le llega corriente al motor es que algo que no hace contacto. Normalmente llevan un contacto para el motor de arrastre, y dependiendo del diseño, el motor de arrastre se parará cuando acabe el ciclo o también en las fases de carga y calentamiento, pasando a depender del presostato y del termostato, aunque normalmente no dependen de ello por seguridad con el agua. Eso sí, seguro que es bitemperatura: o frio o caliente con termostato por botón, y presostato de un nivel . No creo que lleve muchos contactos el programador, y por no tener no tendrá ni micro de puerta (blocapuertas ni lo pienso). En cualquier caso si te aburres, levanta el cronograma y haz la placa, y ya lo tienes.

Por cierto, vi por ahí un esquema super interesante para manejar un motor asíncrono de lavadora sacando los 3 modos de funcionamiento con un condensador. A ver si lo encuentro. Hubo suerte: http://cdn3.grupos.emagister.com/imagen/circuito_para_probar_motor_lavarropas_538723_t0.jpg Eso sí, yo en vez de poner una conmutador doble con parada para el lavado ponía uno doble sin parada y los comunes en vez de ir directos a fase y condensador los ponia en los otros bornes libres del de centrifugado. Así con 2 conmutadores dobles o relés gestionaba el sentido de giro y velocidad, e interrumpiendo la fase el encendido.


Sí, es la del R6, pero no la del boquete :D jo, después dicen de dar información por la red...

Un respeto para la lavadora ¿eh? que es de las primeras automáticas :D la temperatura se controla linealmente, todo/nada pero con su mando de ajuste, entre "0" y 90º sí, es el motor de arrastre, le das un toquecito y vuelve a funcionar, de los esquemas he mirado un montón, y tengo ya pensado como poner los relés para el tema del motor :D

Incluso recuerdo haber visto que lo controla con un PLC.

Vamos que tengo ideas a mogollón, lo malo será que el día que se estropee definitivamente no estaré para hacer el cambio (ni tendré el programa hecho :( ) y mi hermana, que es la que la usa pues va más veces, irá a la tienda y comprará una... :(
 
¡Lo encontré!

Lo pongo tal cual, está. Tiene control de paso por cero, por que es la última versión en la que tenía que controlar 3 leds solo (por eso están comentados los otros) y como la tensión de red no estaba filtrada, solo rectificada, pues había que sincronizar para evitar parpadeos. También está la rutina para recibir DMX y el código relativo a un controlador DA de dos canales por SPI, que luego no se usó, pero la idea era que la misma programación sirviera para dos cosas, configurable mediante un jumper-soldadura.

PHP:
asm:
;; De bit
DMXok		EQU 00H	; PARA LA RUTINA SERIE
Input		EQU 02H	; para serie
Conf		EQU 03h ; para serie
bloquenuevo	EQU 05h 	
HADR		EQU 06h	; para llegar a los 512 
Pata256		EQU 07h ; Esta es para llegar a los 256, lo dejaremos a cero de momento
ms20		EQU 08h	; Si han pasado 20 ms
SalvaRB8	EQU 0d5h ; es F0,  de proposito general,  para recibir DMX si esta a uno

; De Byte
DecDirDMX	EQU 08H ; Para no cambiar la dirección, la ponemos aqui y contamos
Direccion	EQU 09h	; para guardar la dirección de los interruptores
GuardaASerie	EQU 0Ah	; para guardar A en la interrupción serie
GuardaPSWSerie	EQU 0Bh ; para guardar la palabra de estado en IRQ serie
DAtoDACA	EQU 0Ch	; Dato que coge la rutina para el canal A
DAtoDACB	EQU 0Dh ; Dato que coge la rutina para el canal B
DatoAnterior01	EQU 0Eh	; Para saber si hay que mandar o no
DatoAnterior02	EQU 0Eh	; Para saber si hay que mandar o no
DatoAnterior03	EQU 0Eh	; Para saber si hay que mandar o no

; Puertos
DOUT		EQU	P3.7
CLKDAC		EQU	P3.4
CSDAC		EQU	P3.5


PWM01	EQU 50h	;  // Primer byte para PWM
PWM02	EQU 51h	;  // Primer byte para PWM
PWM03	EQU 52h	;  // Primer byte para PWM
PWM04	EQU 33h	;  // Primer byte para PWM
PWM05	EQU 34h	;  // Primer byte para PWM
PWM06	EQU 35h	;  // Primer byte para PWM
PWM07	EQU 36h	;  // Primer byte para PWM
PWM08	EQU 37h	;  // Primer byte para PWM
PWM09	EQU 38h	;  // Primer byte para PWM
PWM10	EQU 39h	;  // Primer byte para PWM
PWM11	EQU 3Ah	;  // Primer byte para PWM
PWM12	EQU 3Bh	;  // Primer byte para PWM
PWM13	EQU 3Ch	;  // Primer byte para PWM
PWM14	EQU 3Dh	;  // Primer byte para PWM
PWM15	EQU 3Eh	;  // Primer byte para PWM
PWM16	EQU 3Fh	;  // Ultimo byte para PWM

DMX01	EQU 40h	;   // Primer byte que recibe DMX
DMX02	EQU 41h	;  // 
DMX03	EQU 42h	;  // 
DMX04	EQU 43h	;  // 
DMX05	EQU 44h	;  // 
DMX06	EQU 45h	;  // 
DMX07	EQU 46h	;  // 
DMX08	EQU 47h	;  // 
DMX09	EQU 48h	;  // 
DMX10	EQU 49h	;  // 
DMX11	EQU 4Ah	;  // 
DMX12	EQU 4Bh	;  // 
DMX13	EQU 4Ch	;  // 
DMX14	EQU 4Dh	;  // 
DMX15	EQU 4Eh	;  // 
DMX16	EQU 4Fh	;  // Ultimo byte que recibe DMX

;DatoRecibido	EQU 50H ; aqui esta el dato real, lo siguiente es "un puntero"
PrimeroDMX	EQU 50H	; es para poner un inmediato, asi siempre apunta bien
UltimoDMX	EQU 50H+3	; es para poner un inmediato, asi siempre apunta bien

ContadorPWM	EQU 60h	; Es el que lleva la cuenta de hasta donde debe llegar

Pila 		EQU 68h ; Es para dejar sitio

DatoA		EQU	00100001b
DAtoB		EQU	00100010b
RecargaTH0	EQU	256-55


	ORG 0000h
	LJMP INICIO


	ORG 00BH	; timer 0, se encargara de contar los 255 hasta llegar a 20 ms
	LJMP BuclePWM	; Mide el minimo pulso 20 / 256

	ORG 0013H	; Externa 0, pata 12
	RETI
;	CLR IE1
	LJMP Externa1_PasoPorCero	; Paso Por 0 de la tensión

	ORG 0023h
Serie: 
       MOV GuardaAserie, A
       MOV GuardaPSWSerie, PSW
;	SETB RecibiDMX
; 	LJMP LRecepDMX 

; *************************************************** RUTINA SERIE

LRecepDMX: 
       MOV A, SBUF                ;RECEPCION      : 1EAD
       MOV C, RB8
       MOV SalvaRB8, C
       CLR RI
       JB Bloquenuevo, LDMXOFF 	; Si aun no se ha hecho caso del otro, no recibas nada
       JB DMXok, rec1old
       CJNE A, #00H, LDMXOFF    
       JB SalvaRB8, LDMXOFF
       SETB DMXok
       SJMP LRETORNO
 
rec1old: JB Conf, Rec2old
       CJNE A, #00H, LDMXOFF    
       JNB RB8, LDMXOFF
       SETB Conf
       MOV DecDirDMX, Direccion
       MOV C, Pata256		; Para que el DMX sea a partir de 256
       CPL C			
       MOV HADR, C		
       SJMP LRETORNO
 
rec2old: JB Input, L1EF2
       JNB SalvaRB8, LDMXOFF
       DJNZ DecDirDMX, LRETORNO
       JBC HADR, LRETORNO
       SETB Input
 
L1EF2: JNB SalvaRB8, LDMXOFF
       MOV @R0, A                
Lnadas: INC R0
Lnadar: CLR C
       CJNE R0, #UltimoDMX, L1F05       ;; Antes #6bH
       SETB Bloquenuevo
	CPL P3.5
       SJMP LDMXOFF

L1F05: JC LRETORNO

LDMXOFF: 
       MOV R0, #PrimeroDMX
       CLR DMXok
       CLR Conf
       CLR Input
 
LRETORNO:                       ; 1F17
       MOV A, GuardaAserie
       MOV PSW, GuardaPSWSerie
       RETI


; ***************************************************************************************
INICIO:
	ANL P3, #E9h	;; Solo P3.4, P3.2 y P3.1  a cero
       MOV R0, #00H
Lacero: INC R0                  ; Este bucle es para poner TODA la memoria 
       MOV @R0, #00H             ; interna a 00H
       CJNE R0, #7FH, Lacero
yaacero:
       MOV P1, #0FFH 	;; Aqui P1 sirvira para la salida de datos por display
       MOV R0, #PrimeroDMX	;; para la recepcion serie
;       MOV R1, #PrimeroDMX
       MOV SP, #Pila             ;; La pila solo va a tener 16 posiciones 
       

       MOV SCON, #090H       ;; SCON Modo 2 ( 9 bits ); REN =1,  Preparado 
       MOV PCON, #00H        ;; SMOD = 0
       MOV TMOD, #00100010B    ;; TMOD Timers 0 y 1 en modo 2 ( 8 bits CON )
	MOV TCON, #04H		;; Externa 1 por flanco
	MOV TH0, #RecargaTH0
	MOV TL0, TH0	
;	SETB TR0

       MOV IP, #10H      ;; IP, Prioridad serie
       SETB ES
       SETB EA
	SETB ET0	; tIMER 0
;	SETB EX1	; eXTERNA 1
       SETB PS		; Prioridad serie, de momento
;	SETB PX1	; Y Tambien Externa 1
;	MOV Direccion, #1	;; Aunque sea el canal 0, es el 1
	SETB Pata256	; Simula la pata del puerto a 1
	
	



;TARDAMASPWM:
;	SETB BloqueNuevo
;BUCLEDAC:
;	NOP
;	NOP
;	NOP
;	NOP
;	NOP
SIMISMO:
	JB P3.6, SiMismo	; P1.0 es la + y P1.1 - del operacional, P3.6 es la salida
	ANL P3, #E9h	;; Solo P3.4, P3.2 y P3.1  a cero
	CLR TR0
Esperaeluno:	; 
	JNB P3.6, Esperaeluno	; Asi esperamos que se ponga a uno, y ahora si que entramos
	SETB P3.3
	CLR Bloquenuevo		; Para Poder recibir más datos
	MOV COntadorPWM, #0	;; No tenemos externa 1
	MOV TL0, TH0
	SETB TR0
	MOV A, P1	; Esperamos que se ponga abajo
	RRC A		; Pasamos de lo que diga P1.0 en la direccion
	RRC A
	ORL A, #C0H	;; Pasamos de P1.0 y P1.1
	CPL A
	JNZ YaEsta
	INC A		; Para que el cero sea 1
YaEsta:
	MOV Direccion, A
	CLR P3.3
	ANL P3, #E9h	;; Solo P3.4, P3.2 y P3.1  a cero
	SJMP SiMismo
;	JNB BloqueNuevo, BUCLEPWM 	;BUCLEDAC
;	MOV A, DatoDACA
;	CJNE A, PWM01, MandaDato
;	MOV A, DatoDACB
;	CJNE A, PWM02, MandaDato
;	SJMP BuclePWM	;BucleDAC
;MandaDato:
;	MOV DatoDACA, PWM01
;	MOV DatoDACB, PWM02
;	LCALL LMandar
;;	CLR BloqueNuevo
;;	SJMP BUCLEDAC

; **************************************	Cada Cierto Tiempo
BUCLEPWM:

	MOV A, ContadorPWM
	CJNE A, PWM01, P01
P01:
	MOV P3.1, C
	CJNE A, PWM02, P02
P02:
	MOV P3.2, C
	CJNE A, PWM03, P03
P03:
	MOV P3.4, C
;	CJNE A, PWM04, P04
;P04:
;	MOV P1.3, C
;	CJNE A, PWM05, P05
;P05:
;	MOV P1.4, C
;	CJNE A, PWM06, P06
;P06:
;	MOV P1.5, C
;	CJNE A, PWM07, P07
;P07:
;	MOV P1.6, C
;	CJNE A, PWM08, P08
;P08:
;	MOV P1.7, C
;	CJNE A, PWM09, P09
;P09:
;	MOV P2.0, C
;	CJNE A, PWM10, P10
;P10:
;	MOV P2.1, C
;	CJNE A, PWM11, P11
;P11:
;	MOV P2.2, C
;	CJNE A, PWM12, P12
;P12:
;	MOV P2.3, C
;	CJNE A, PWM13, P13
;P13:
;	MOV P2.4, C
;	CJNE A, PWM14, P14
;P14:
;	MOV P2.5, C
;	CJNE A, PWM15, P15
;P15:
;	MOV P2.6, C
;	CJNE A, PWM16, P16
;P16:
;	MOV P2.7, C
FindelBucle:
;	ADD A, #4	;; Voy de 4 en 4 para no tener que dividir por 4 todos los demas
;	MOV ContadorPWM, A
	SETb P3.7
	INC ContadorPWM
	MOV A, ContadorPWM
	JNZ FinBuclePWM
	ANL P3, #E9h	;; Solo P3.4, P3.2 y P3.1  a cero
	CLR TR0
;	CLR ms20	
;	MOV P1, #0
;	MOV P2, #0
;	MOV PWM01, DatoRecibido
;	CLR Bloquenuevo		; Para Poder recibir más datos sino lo resetea el paso por cero
FinBuclePWM:	
	CLR P3.7
	RETI

; ***********************************************	Se produce una interrupción en el paso por cero
Externa1_PasoPorcero:
	ANL P3, #E9h	;; Solo P3.4, P3.2 y P3.1  a cero
	MOV ContadorPWM, #0
	CLR Bloquenuevo		; Para Poder recibir más datos
	CPL P3.5
	RETI


; ****************************************    	RUTINA DAC *************

LMandar:
	MOV	A, #DatoA	;; Primero le decimos el canal, Ahora El A
	CLR	CSDAC
	RLC	A
	MOV	Dout, C
1bit:	SETB	CLKDAC
	RLC	A
	CLR	CLKDAC
	MOV	Dout, C
2Bit	SETB	CLKDAC
	RLC	A
	CLR	CLKDAC
	MOV	Dout, C
3Bit	SETB	CLKDAC
	RLC	A
	CLR	CLKDAC
	MOV	Dout, C
4Bit	SETB	CLKDAC
	RLC	A
	CLR	CLKDAC
	MOV	Dout, C
5Bit	SETB	CLKDAC
	RLC	A
	CLR	CLKDAC
	MOV	Dout, C
6Bit	SETB	CLKDAC
	RLC	A
	CLR	CLKDAC
	MOV	Dout, C
7Bit	SETB	CLKDAC
	RLC	A
	CLR	CLKDAC
	MOV	Dout, C
8Bit	SETB	CLKDAC

	MOV	A, DatoDACA	; Ahora el DATO De A
	CLR	C		; Para meter un cero
;	RLC	A		; Para poner ACC.7 en C
;	MOV	FaseA, C	; y mandarlo a la fase
	CLR	CLKDAC
	RLC	A
	MOV	Dout, C		
1bit2:	SETB	CLKDAC
	RLC	A
	CLR	CLKDAC
	MOV	Dout, C
2Bit2	SETB	CLKDAC
	RLC	A
	CLR	CLKDAC
	MOV	Dout, C
3Bit2	SETB	CLKDAC
	RLC	A
	CLR	CLKDAC
	MOV	Dout, C
4Bit2	SETB	CLKDAC
	RLC	A
	CLR	CLKDAC
	MOV	Dout, C
5Bit2	SETB	CLKDAC
	RLC	A
	CLR	CLKDAC
	MOV	Dout, C
6Bit2	SETB	CLKDAC
	RLC	A
	CLR	CLKDAC
	MOV	Dout, C
7Bit2	SETB	CLKDAC
	RLC	A
	CLR	CLKDAC
	MOV	Dout, C
8Bit2	SETB	CLKDAC
	NOP
	CLR	CLKDAC
	NOP	
	SETB	CSDAC	
	NOP
	CLR	CSDAC	
	MOV	A, #DatoB	;; Ahora le decimos el canal B
	RLC	A
	MOV	Dout, C
1bitB:	SETB	CLKDAC
	RLC	A
	CLR	CLKDAC
	MOV	Dout, C
2BitB	SETB	CLKDAC
	RLC	A
	CLR	CLKDAC
	MOV	Dout, C
3BitB	SETB	CLKDAC
	RLC	A
	CLR	CLKDAC
	MOV	Dout, C
4BitB	SETB	CLKDAC
	RLC	A
	CLR	CLKDAC
	MOV	Dout, C
5BitB	SETB	CLKDAC
	RLC	A
	CLR	CLKDAC
	MOV	Dout, C
6BitB	SETB	CLKDAC
	RLC	A
	CLR	CLKDAC
	MOV	Dout, C
7BitB	SETB	CLKDAC
	RLC	A
	CLR	CLKDAC
	MOV	Dout, C
8BitB	SETB	CLKDAC

	MOV	A, DatoDACB
	CLR	CLKDAC
	CLR	C		; Para meter un cero
;	RLC	A		; Para poner ACC.7 en C
;	MOV	FaseB, C	; y mandarlo a la fase
	RLC	A
	MOV	Dout, C
1bitB2:	SETB	CLKDAC
	RLC	A
	CLR	CLKDAC
	MOV	Dout, C
2Bit2B	SETB	CLKDAC
	RLC	A
	CLR	CLKDAC
	MOV	Dout, C
3Bit2B	SETB	CLKDAC
	RLC	A
	CLR	CLKDAC
	MOV	Dout, C
4Bit2B	SETB	CLKDAC
	RLC	A
	CLR	CLKDAC
	MOV	Dout, C
5Bit2B	SETB	CLKDAC
	RLC	A
	CLR	CLKDAC
	MOV	Dout, C
6Bit2B	SETB	CLKDAC
	RLC	A
	CLR	CLKDAC
	MOV	Dout, C
7Bit2B	SETB	CLKDAC
	RLC	A
	CLR	CLKDAC
	MOV	Dout, C
8Bit2B	SETB	CLKDAC
	NOP
	CLR	CLKDAC
	NOP
	SETB	CSDAC
FinMandar:
	RET
 
Me sorprende la facilidad que manejas ASM, eso es que le has echado muchas horas. Me hablas de la CJNE como si fuese en vez de una instrucción de ensamblador un sindicato, algo corriente. Entenderlo me llevaría su tiempo, y solo la parte que me interesa, pero no dudes que lo probaré. Digamos que tu pwm se basa en un bucle con un contador de 256 pasos autoreiniciable (overflown), que compara el contador con el valor DMX, poniendo la salida en alto si el contador supera el DMX, esto para los 8 canales, y luego se reinicia. Desde luego lo probaré a ver como resulta y qué frecuencia me da. Ten en cuenta que la frecuencia de reloj mia son 4 Mhz y creo que era 4 ciclos x instrucción, a ver si con suerte llego al Khz (considerando interrupciones y demás no creo que se ejecuten 1000 instrucciones entre paso y paso del PWM, a lo mejor me equivoco) y el filtro mejora.

Por cierto, lo del cruce por cero como lo haces. Es porque eso es lo que necesitaría ya para hacer un dimmer n-fásico microcontrolado analógico-digital, y lo del cruce por cero es algo imprescindible. Eso sí, hardware optoaislado.
 
Me sorprende la facilidad que manejas ASM, eso es que le has echado muchas horas. Me hablas de la CJNE como si fuese en vez de una instrucción de ensamblador un sindicato, algo corriente. Entenderlo me llevaría su tiempo, y solo la parte que me interesa, pero no dudes que lo probaré. Digamos que tu pwm se basa en un bucle con un contador de 256 pasos autoreiniciable (overflown), que compara el contador con el valor DMX, poniendo la salida en alto si el contador supera el DMX, esto para los 8 canales, y luego se reinicia. Desde luego lo probaré a ver como resulta y qué frecuencia me da. Ten en cuenta que la frecuencia de reloj mia son 4 Mhz y creo que era 4 ciclos x instrucción, a ver si con suerte llego al Khz (considerando interrupciones y demás no creo que se ejecuten 1000 instrucciones entre paso y paso del PWM, a lo mejor me equivoco) y el filtro mejora.

Por cierto, lo del cruce por cero como lo haces. Es porque eso es lo que necesitaría ya para hacer un dimmer n-fásico microcontrolado analógico-digital, y lo del cruce por cero es algo imprescindible. Eso sí, hardware optoaislado.


Uf, a 4Mhz sí que lo tienes chungo...

El paso por cero, sencillo: aparte del puente rectificador, pones un par de diodos que lleven los semiciclos positivos del secundario del transformador a una resistencia a la base de un transistor NPN, el emisor a masa (negativo del puente) en colector con una resistencia de pull up ya lo tienes.

Hablamos de un transformador normal, no de una fuente conmutada, ahí está más chungo y habría que sacarlo de la parte de 220V...




Con el ensamblador todo es ponerse :D

Algunas pistas.


CJNE Compara y Jump si No es Equal.
CJNZ Compara y Jump si No es 0

Estás dos instrucciones lo que hacen en realidad es una resta pero sin guardar el resultado, solo cambian el carry, lo que da como resultado que sabes si es mayor o menor e igual

JC/JNC Jump if Carry / if Not Carry
JB/JNB Jump if Bit / if Not Bit
JZ/JNZ Jump if Zero / if Not Zero (siempre referido al acumulador)

EQU Equal, igual, asignación.

CLR Clear (bit o byte)
SETB Set bit

RETI Retorno Interrupción

MOV Mueve del segundo al primero

INC Incrementa
DEC Decrementa

ADD Suma (al acumulador) X (o dato)

RL Rota el acumulador hacia la Left (izquierda)
RR Rota el acumulador hacia la Rigth (derecha)
RLC Lo mismo que RLC, pero pasando por el Carry
RRC Lo mismo que RRC, pero pasando por el Carry.

ANL And Lógico del dato con lo que sea
ORL Or Lógico ...
CPL Complementa, los ceros los vuelve unos y al revés.

NOP Not Operation.


A Acumulador.

C Carry (Acarreo)

B Un registro que tiene el 8051 por ahí... :dontknow: diferente del resto de la memoria.

RX Registros del 0 al 8 que tiene el 8051
SP Stack Pointer, Puntero de pila, importante para los saltos, se guarda la dirección de vuelta cuando se salta a una interrupción, en los lenguajes de alto nivel también se pasan los parámetros por ahí. Cuando algún programa da un "Desbordamiento de pila/Stack Overflow" es que este puntero se ha salido de la memoria que tenías reservada, y, lo más seguro es que te la va a liar... por que ha machacado una dirección que no tocaba, si es circular (como en los primeros PIC), acabas de machacar la dirección de vuelta a algún sitio, cuando toque volver... lo más probable es que caigas en un bucle infinito... en el caso del 8051, no es circular, pero si te pasas vuelve a cero, y empiezas a machacar lo que haya por allí...


PX Puertos, del 0 al 3
PX.Y Bit de un puerto.

PSW Program Status Word, Palabra de estado, en ella están el Carry, el carry "del medio", el Zero, un bit de propósito general, dos bits de selección de Banco de Registros y el de paridad, básicamente, hay que salvarlo casi siempre que tratas una interrupción.

IE Interrupt Enable, se permiten las interrupciones activas o no se permite ninguna.
EX1 Enable (Interrupt) External 1 Enable (a 1 permite, a 0 no)
ES Enable Serie


RI Receive Interrupt, Flag de interrupción de recepción serie
IP Prioridad Interrupción.

SCON, PCON, TCON, registros de configuración Serie

TMX TimerX
THX, TLX TimerX byte alto y byte bajo (son configurables, pero pueden ser de 16 bits)


ORG Dirección donde poner el código. En el 8051 los vectores de interrupción son fijos.


Puf, seguro que me olvido alguno

Ah, todo pin puesto a 1 es entrada, puesto a 0 es salida, concretamente a 0.
 
Ya no edito más...

Menos eficiente, entre el puente y el condensador de filtro, un diodo bien polarizado, la señal de antes del diodo, a la base del transistor.
 
Ahora veo uno importante

RB8, es el noveno bit que se recibe/manda por el puerto serie. Creo que aquí se usa para hacer los dos bits de parada a 1.
 
Con lo del cruce por cero me refería al software, el hardware +- lo controlo.
 
Con lo del cruce por cero me refería al software, el hardware +- lo controlo.

:oops: Ah, vale...

Bueno, yo lo metí a una pata que genera interrupción, en este caso la que llama Externa1, por un tema de prioridades, aunque al final creo no fue determinante. Bueno, decía, que a una pata que genera la interrupción, a partir de ahí, hago lo tengo que hacer, que es poner el contador PWM a cero, así como los pines que toquen

Está aquí:

PHP:
; ***********************************************    Se produce una interrupción en el paso por cero
Externa1_PasoPorcero:
    ANL P3, #E9h                  ;; Solo P3.4, P3.2 y P3.1  a cero
    MOV ContadorPWM, #0   ;; Pongo a cero el contador
    CLR Bloquenuevo   ; Para Poder recibir más datos, Así evito que el dato cambie cuando estoy formando el PWM
    CPL P3.5          ; En el código es la pata CS del controlador DA, pero no estoy seguro de lo que hace ahora, *
    RETI                ; retorno de interrupción, es decir, vuelve a lo que estuvieras haciendo.

* puede que lo usará como chivato, para saber cuando empiezan y acaban las cosas, sospecho que este es un código de transición a la última versión

Por si no se ha deducido, # implica "dato inmediato", es decir, una constante, frente a cuando no lleva, que sería un dato de memoria.
 
No lo he deducido. Vaya triples que te tiras, como dice un amigo mio.
En mi caso no me valdría mucho porque lo que he de hacer es hacer que cuando la fracción del timer supere la fracción del DMX (o su equivalente modificando la respuesta con una curva de dimerizado) dispare. Es evidente que antes de dimerizar he de medir la frecuencia de la red (o hardcodearla, pero prefiero no hacerlo) y luego actualizarla en cada ciclo. La idea sería: arranca el sistema, espera a que haya un cruce por cero, se reinicia el timer y empieza a contar hasta el siguiente cruce por cero, siendo ese valor la duración del ciclo de red (1/(2*Freq-AC)), llamemoslo timer_total. Luego entraría en el main, de tal modo cada vez que suba el timer se compara la ratio timer_actual/timer_total con el parámetro dmx_canal/256 (o incluso analog_read/analog_max) y en ese momento se pone ese pin a alto hasta que el cruce por cero cae de nuevo (ojo con que tarde más en apagar la salida que en que se cambie de semiciclo porque el triac se reactivaría). Además en ese instante volvería a recalcularse el timer total, actualizandose en cada ciclo (o sea se lee una vez antes de empezar a funcionar y se actualiza en cada ciclo). En este caso la frecuencia no sería tan problemática (100Hz de nada...)

Esta es mi idea pero necesito tiempo para ponerme en serio.

Gracias por todo.
 
:scratch: El ciclo de red ya lo sabes... creo que no lo he entendido, a ver cuando vea el código, pero si esto no es importante, dedícate a estudiar, que sin darte cuenta, se te pasa el tiempo, como me ha pasado a mi "recopilando" instrucciones... :(


Creo que no piensas usar instrucciones ¿puede ser? este es un caso típico para usarlas, por que además son cada mucho, bueno, ahora que lo pienso, si vas a recibir DMX las necesitas ¿no?
 
De esto que te levantas de siesta y te duele toda la cabeza que eres incapaz de tocar apuntes. Pues eso. No me ha rendido nada la tarde. Ya contaba con ello. Probaré lo de ASM, pero no se hasta que nivel llegaré, pero me ayuda mucho a entender como funcionan todos estos chismes.
 
Arriba
© 2004-2024 Webcampista.com