De genio nada, sólo un poco cabezota. Me alegro que te haya servido.
Caro amigo Nocturno !
Usei o seu codigo para adaptar no pic16f877 com 12canais led rgb e funcionou perfeitamente,porem não conseguir colocar toda a trama de canais (512) pois não tinha espaço suficiente na RAM do pic então resolvi comprar o pic18f4525 ai começou minha dor de cabeça pois não entendo muito bem os registro do mesmo ,conseguir colocar toda a trama dmx neste pic porem
só que funcionar em 16bits então quando tento controlar os leds ele vai aumentado a intensidade e quando chega na metade do controle zera e começa tudo denovo ,acho que ele não esta lendo de 0 a 255 e sim de -127 0 127 (16bits)
ai entra Vc grande MESTRE, como faço para eliminar este problema? teria como vc analisar isso para mim pois tenho pouco conhecimento em programação e não consigo resolver.
Por favor me ajude pois já estou ficando careca com isso.
segue o codigo para analise.
#include <18F4525.h>
#device adc=8
#FUSES WDT
#FUSES WDT128 //Watch Dog Timer uses 1:1 Postscale
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOIESO //Internal External Switch Over mode enabled
#FUSES NOBROWNOUT //No brownout reset
#FUSES BORV46 //Brownout reset at 4.6V
#FUSES PUT //Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOFCMEN //Fail-safe clock monitor enabled
#FUSES NOXINST //Extended set extension and Indexed Addressing mode enabled
#FUSES NOPBADEN //PORTB pins are configured as digital I/O on RESET
#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES NOMCLR //Master Clear pin used for I/O
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,restart_wdt)
#use delay(clock=20000000,RESTART_WDT) // Utilizo clock de 20MHz porque me facilita la elección exacta del baudrate a 250k y tenia el cristal
/************************************************************************
* Registros USART *
************************************************************************/
#byte SPBRG= 0xFAF // Registros para establecer la velocidad
#byte SPBRGH= 0xFB0 // de la USART
#byte RCSTA= 0xFAB // Registro de recepcion de la usart
#byte TXSTA= 0xFAC // Registro de emisión de la usart
#byte RCREG= 0xFAE // Aquí se recibe el dato de la usart
#byte PIR1= 0xF9E // Estado de interrupciones de periféricos
#byte PIE1= 0xF9D // Activación de interrupciones de periféricos
#byte BAUDCON= 0xFB8 // Control de la velocidad en baudios
#bit SPEN= RCSTA.7 // Bit activación puerto serie
#bit RX9= RCSTA.6 // Activación de recepción de 9 bits
#bit SREN= RCSTA.5 // Se activa para recibir un sólo byte
#bit CREN= RCSTA.4 // Se activa para recepción continua
#bit ADDEN= RCSTA.3 // Autodetección de dirección
#bit FERR= RCSTA.2 // Error de Frame
#bit OERR= RCSTA.1 // Error de Overrun
#bit RX9D= RCSTA.0 // El noveno bit
#bit BRGH= TXSTA.2 // Selección de alta velocidad
#bit BRG16= BAUDCON.3 // Uso de un valor baudrate de 16 bits
#bit SYNC= TXSTA.4 // Selección de modo síncrono o asíncrono
#bit RCIF= PIR1.5 // Señalizador de byte recibido en USART
#bit RCIE= PIE1.5 // Activación de la interrupción USART
/************************************************************************
* Estados protocolo DMX *
************************************************************************/
#define DMX_ESPERA_BYTE 0
#define DMX_ESPERA_BREAK 1
#define DMX_ESPERA_START 2
#define DMX_ESPERA_DATO 3
#define DMX_RECEPCION_DATOS 4
//#define HS 0xFAFF
/************************************************************************
* Variables globales y constantes *
************************************************************************/
//--------------------Se han quitado las variables que no utilizo--------------------------------------
int8 DMX_Estado = DMX_ESPERA_BREAK; // Estado de la máquina de estados
int8 DatoRX; // Dato genérico recibido en USART
int8 DMX_Indice = 0; // Apuntador a una posición de la trama DMX
#define liga output_low
#define off output_high
#define TotalCanales 50 // Total canales a almacenar en este caso solo interesan los 3 primeros int16 tramadmx[totalcanales]; //={0,0,0,0,0,0,0,0,0,0,0,0}; // Trama completa de valores DMX
int8 TramaDMX[totalcanales];
int8 r1,g1,b1,r2,g2,b2,r3,g3,b3,r4,g4,b4;
int8 a,b,c,d,e,f,g,h,i,j,l,m;
int8 x;
int8 Ticks = 0;
union // Estructura para hacer una copia del registro RCSTA
{
unsigned char registro;
struct {
unsigned char RX9D:1;
unsigned char OERR:1;
unsigned char FERR:1;
unsigned char ADDEN:1;
unsigned char CREN:1;
unsigned char SREN:1;
unsigned char RX9:1;
unsigned char SPEN:1;
} bits ;
}Copia_RCSTA;
/************************************************************************
* Interrupción Timer 0: *
************************************************************************/
#int_Timer0
TIMER0_isr()
{
(a = x=0);
(b = a+1);
(c = b+1);
(d = c+1);
(e = d+1);
(f = e+1);
(g = f+1);
(h = g+1);
(i = h+1);
(j = i+1);
(l = j+1);
(m = l+1);
ticks++;
if (Ticks==0)
{
r1 = TramaDMX[a];
g1 = TramaDMX
;
b1 = TramaDMX[c];
r2 = TramaDMX[d];
g2 = TramaDMX[e];
b2 = TramaDMX[f];
r3 = TramaDMX[g];
g3 = TramaDMX[h];
b3 = TramaDMX;
r4 = TramaDMX[j];
g4 = TramaDMX[l];
b4 = TramaDMX[m];
off(pin_b1);
off(pin_b2);
off(pin_b3);
off(pin_b4);
off(pin_b5);
off(pin_b6);
off(pin_b7);
off(pin_d0);
off(pin_d1);
off(pin_d2);
off(pin_d3);
off(pin_d4);
}
if(Ticks==r1)
liga(pin_b1);
if(Ticks==g1)
liga(pin_b2);
if(Ticks==b1)
liga(pin_b3);
if(Ticks==r2)
liga(pin_b4);
if(Ticks==g2)
liga(pin_b5);
if(Ticks==b2)
liga(pin_b6);
if(Ticks==r3)
liga(pin_b7);
if(Ticks==g3)
liga(pin_d0);
if(Ticks==b3)
liga(pin_d1);
if(Ticks==r4)
liga(pin_d2);
if(Ticks==g4)
liga(pin_d3);
if(Ticks==b4)
liga(pin_d4);
set_timer0(128);
}
/************************************************************************
* Interrupción RDA: dato recibido por la USART *
* Esta interrupción se activa cada vez que se recibe un dato en la *
* USART. Mediante el control de una máquina de estados se determina *
* la validez y el significado del dato recibido, y se obra en *
* consecuencia. *
************************************************************************/
//--------La interrupción de la USART no se ha modificado, esta tal cual el receptor de Nocturno----------------
//--------solo cambia el hecho de que TotalCanales vale 3 en lugar de 512----------------------------------------
#int_rda
void Dato_Recibido_USART(void)
{
while (RCIF) // ejecutamos mientras haya un dato pendiente de procesar
{
// Hacemos una copia del registro RCSTA porque sus bits cambian de valor
// al leer RCREG y modificar CREN
Copia_RCSTA.registro = RCSTA;
// En RCREG está el dato que acaba de recibir la USART
DatoRX = RCREG;
// Si se reciben más de 3 bytes sin haberlos procesado, se produce un error
// de Overrun. En este caso, se borra el error reiniciando CREN y dejamos
// la interrupción preparada para procesar la siguiente trama DMX
if (Copia_RCSTA.bits.OERR)
{
CREN=0;
CREN=1;
DMX_Estado = DMX_ESPERA_BYTE;
return;
}
// Máquina de estados
switch (DMX_Estado)
{
case DMX_ESPERA_BYTE: // si estamos en este estado y hay error FRAME
// es que nos ha pillado en medio de un Byte. Hay que seguir esperando
// hasta que desaparezca el error.
if (!Copia_RCSTA.bits.FERR)
// Ha llegado un byte. Ahora esperaremos la señal Break
DMX_Estado = DMX_ESPERA_BREAK;
break;
case DMX_ESPERA_BREAK: // estamos esperando la señal Break
// Esta señal se identifica porque aparece el error de Frame
if (Copia_RCSTA.bits.FERR)
// Tras recibir el error de Break, hay que esperar un byte de valor 0
if (!DatoRX)
DMX_Estado = DMX_ESPERA_START;
break;
case DMX_ESPERA_START: // ya hemos recibido el Break y ahora hay que
// esperar un Byte con valor 0, que será la señal de Start
// Mientras tanto, si recibimos un error de Frame, hay que volver a
// empezar para recibir la señal de comienzo de trama.
if (Copia_RCSTA.bits.FERR)
DMX_Estado = DMX_ESPERA_BYTE;
else {
if (!DatoRX)
{
// Llegados a este punto, ya hemos recibido el Byte Start=0
// y comenzamos la trama de valores DMX.
DMX_Indice = 0;
DMX_Estado = DMX_RECEPCION_DATOS;
} else
// Si el dato recibido no es 0, volvemos a empezar
DMX_Estado = DMX_ESPERA_BREAK;
}
break;
case DMX_RECEPCION_DATOS:
// En este estado estamos recibiendo la trama de datos DMX
// Si se detecta un error de Frame es que ha habido un error y estamos
// al principio
if (Copia_RCSTA.bits.FERR)
if (!DatoRX)
DMX_Estado = DMX_ESPERA_START;
else
DMX_Estado = DMX_ESPERA_BYTE;
else
{
// Almacenamos el dato recibido en nuestro array
TramaDMX[DMX_Indice++] = DatoRX;
// Si ha llegado al final de la capacidad, cambiamos al estado de espera
// de nueva trama
if (DMX_Indice >= TotalCanales)
DMX_Estado = DMX_ESPERA_BREAK;
}
break;
}
}
return;
}
void main()
{
setup_oscillator(TRUE); //(OSC_8MHZ|OSC_INTRC|OSC_PLL_ON);
port_b_pullups(TRUE);
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF|ADC_TAD_MUL_0);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_wdt(WDT_ON);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1|RTCC_8_BIT);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_4);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
// Configuración de la USART
BRGH=1; // Alta velocidad seleccionada.
BRG16=1; // Baudrate de 16 bits
SYNC=0; // Seleccionamos transmisión asíncrona
SPBRG=17; // A 8MHz representa Baudios = 250KHz
SPBRGH=0;
RX9=1; // Activada la recepción a 9 bits
SREN=0; // Desactivada la recepción de un sólo byte
ADDEN=0; // Desactivada la autodetección de dirección
FERR=0; // No hay error de frame
OERR=0; // No hay error de overrun
SPEN=1; // USART activada
CREN=1; // Recepción activada
// Activamos las interrupciones de recepción de la USART y del Timer0
enable_interrupts(INT_RDA);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
//-----------------------------------------------------------
set_timer0(128);
while(1){delay_ms(5000); }
}