Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

07/05/2014 #21
Moderador

Avatar de D@rkbytes

Wever20 dijo: Ver Mensaje
D@rkbytes he probado tu programa y todo anda OK.
Mi programa ahora utilizando las funciones PRINTF, SPRINTF y STRCAT anda bien. Resulta que el problema era la versión del CCS. La versión en la que han arreglado todo ésto es a partir de la 5.013.
Sip, cada vez solucionan los bugs que tiene el compilador de CCS.
Ya tiene tiempo que no lo actualizo, ahora tengo la versión 5.021
Wever20 dijo: Ver Mensaje
Tengo otro pequeño o gran problema. Resulta que cuando envío primeramente un dato de solicitud del estilo "$ADQ,P01,CH0\r" o "$ADQ,P01,CH1\r" y luego un dato de solicitud del estilo "$TST,P01\r" SOLO ME RESPONDE SIEMPRE al primer dato.
Y si lo hago al revés primero le envío "$TST,P01\r" y luego "$ADQ,P01,CHx\r" solo me hace el primero.
Y siempre responde solo al primer tipo de dato que le envío.
Si luego le envío otro tipo de dato ya no responde.
Yo tuve un problema similar al trabajar con recepción de cadenas.
Utilice un buffer y las instrucciones gets y strcat.
El resultado fue que al recibir los datos, funcionaba inversamente.
Es decir, si yo mandaba "prender" se activaba la sentencia apagar.
Hasta ahora no lo he podido resolver.
Wever20 dijo: Ver Mensaje
¿Si te vuelvo a dar el código podrías ayudarme a solucionar ésto?
Yo ya no veo cual es el fallo, amigo.

La solución que he probado es meterle un reset_cpu() una vez envío los datos y entonces va bien. Pero no es la mejor solución esta.
Pues si quieres lo podría revisar para ver si encuentro algo raro.
Cuando comentan el código es más fácil entender que es lo que quieren hacer.
Espero que tengas comentados los bloques del programa.
07/05/2014 #22


Bueno YA HE LOGRADO solucionarlo. Resulta que al copilador en CCS no le gusta a veces éste tipo de definiciones variable[]="hola". Sustituyendo ese tipo de definiciones ahora el programa anda perfecto.

Conclusión, si alguien tiene muchos problemas con un programa que aparentemente está bien, primero que revise todo por si acaso y luego si siguen los problemas que cambie de compilador a una versión más reciente y definir en el programa las variables y demás de forma que el compilador sepa exactamente con que se está trabajando.

Tengo una duda respecto a la conexión de pics con MAX485 te podría consultar?

Quiero conectar tres pics. El pic principal interroga a los otros dos enviandoles una direccion y estos responden si esa direccion coincide con la suya.

Yo he conectado estos tres pics tal cual dice en las especificaciones. Pero solo me responde uno de ellos, el otro no me responde. Si vuelvo a conectar y desconectar todo a veces me responde el segundo pic pero el primero ya no.

¿Hay que elaborar algún tipo de protocolo para que cada MAX485 sepa cual es su función? o simplemente cambiando el estado de los pines RE/DE ya hay suficiente (porque ésto es lo que realizo en función de si escribo o escucho)?
15/05/2014 #23


D@rkbytes dijo: Ver Mensaje
Es mejor que adjuntes tu programa incluyendo librerías, dentro de un archivo comprimido, porque contiene código basura que agrega el navegador y lo hace casi incompresible.
Si tienes la simulación también es necesario que la incluyas.

Saludos.
te agrego todo el codigo, lo raro es que simulado funciona bien pero al momento de implementar no funciona correctamente la comunicacion por el puerto serie, en el archivo adjunto creo que va hasta la simulacion
Archivos Adjuntos
Tipo de Archivo: rar alarma.rar (800,7 KB (Kilobytes), 16 visitas)
15/05/2014 #24
Moderador

Avatar de D@rkbytes

felipeduarte1088 dijo: Ver Mensaje
lo raro es que simulado funciona bien pero al momento de implementar no funciona correctamente la comunicación por el puerto serie.
No pude compilar bien el código por falta de la librería lcd_flex.c, y las que hay por la red no tienen esta función: lcd_command(); "tuve que omitir la llamada a esas funciones."

Por lo que vi, estás tratando de usar una velocidad de 9600bps a 4MHz con el oscilador interno.
Te recomiendo que subas la frecuencia a 8MHz si piensas usar los 9600bps.
04/08/2015 #25

Avatar de Psyke

Hola, no quise abrir otro hilo porque me pareció mejor publicar acá. Disculpen si hice lo incorrecto.
Estoy trabajando con dos PICs, un 16f877a y un 18f4550. Los estoy comunicando por USART, y el primero es el emisor, y el 18f es el receptor. Bien, en el emisor hice una pequeña estructura para enviar datos constantemente, un while con un putc cada 250 ms, detallado a continuación.
Lo que deseo hacer es un protocolo de comunicación. No sé si se hacen así, pero es lo que se me ocurrió. La idea es tener un arreglo de 5 enteros en el emisor, y el 4 entero tiene el dato que utilizo para realizar acciones.

Código:
while(true)
{
   for(i=0;i<5;i++)
   {
   putc(DATOS[i]);
   delay_ms(250);
   }
}
El emisor ya comprobé que envía bien los datos.
El problema viene con el receptor. He hecho otros programas sencillos y recibía bien, pero con este no quiere funcionar, y lo necesito para continuar con el desarrollo. Lo dejo a continuación.

Código:
#include <18f4550.h> 
#fuses INTRC_IO,NOWDT,PLL1,CPUDIV1,NOFCMEN,NOPUT,BROWNOUT,NOLVP,NOMCLR,NOWRT,NOCPD
#use delay(clock=8000000) 
#use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7, bits=8, ERRORS)

int DATOS[5]; //0=SINCRO, 1=INICIO, 2=DIREC, 3=DATO, 4=CHECKSUM
int i,j;

#int_RDA
void RDA_isr()
{
   if (i<5)
   {
      DATOS[i] = getc();
      if (DATOS[0] == 0xAA)
      { 
         output_toggle(pin_b7);
         i++;
      }
      else
      {  
         output_toggle(pin_b6);
         i=0;
      }
      //printf("%u",DATOS[i]);
   }
}


void main()
{  
   setup_oscillator(OSC_8MHZ|OSC_INTRC|OSC_PLL_OFF);
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   while(1)
   {
   }
}
Poniendo además un output_toggle(pin_b7) dentro de la interrupcion, tampoco producía nada. Lo que me llamaba la atención es que al alimentar el circuito, el LED comenzaba encendido. Así que presumo que entra a la interrupción por una vez y no sale. Y ya estoy tomando el dato que llega, por lo que descarto que el error sea que no se quita el flag de la interrupción. Tambien probé con clear_interrupt(int_rda) y nada.



EDITO:
Si quito el if(i<5) en la interrupcion, funcionan los LEDs. Pero obviamente deja de cumplir la función que quiero que haga. Resumiendo, se ve que el if(i<5) "no le gusta", pero ya probe con un while(i<5) y tampoco. así que ya no se. Quedaría así

Código:
#int_RDA
void RDA_isr()
{
      DATOS[i] = getc();
      if (DATOS[0] == 0xAA)
      { 
         output_toggle(pin_b7);
         i++;
      }
      else
      {  
         output_toggle(pin_b6);
         i=0;
      }
      //printf("%u",DATOS[i]);
   clear_interrupt(INT_RDA);
}
04/08/2015 #26
Moderador

Avatar de D@rkbytes

Psyke dijo: Ver Mensaje
La idea es tener un arreglo de 5 enteros en el emisor, y el 4 entero tiene el dato que utilizo para realizar acciones.
Es mejor que adquieras los datos con gets() y después separes el valor del búfer.

Por ejemplo:
Código:
#INT_RDA
void SDI_RS232 (void)
{
// La instrucción gets() retorna hasta que se reciba un Car Return (\r o el ASCCI 13)
   gets(buffer);            // Se guardan los datos recibidos en el arreglo.
   
   flag_rx = 1;             // Indicar recepción (Búfer leído)
}
Y después obtienes el valor que te interesa: var_main = buffer[3]; // Cuarta posición del buffer.
04/08/2015 #27

Avatar de Psyke

Si pongo
Código:
#int_RDA
void RDA_isr()
{
      gets(DATOS);
      if (DATOS[0] == 0xAA && i<5)
      { 
         output_toggle(pin_b7);
         i++;
      }
      else
      {  
         output_toggle(pin_b6);
         i=0;
      }
}
Deja de funcionar
05/08/2015 #28
Moderador

Avatar de D@rkbytes

Para que la instrucción gets() retorne, debe recibir la cadena con un \r al final.
Esto es lo que le indica a la instrucción el final de la cadena, si no se recibe permanece en un bucle de espera.

CCS Help dijo:
Reads characters (using getc()) into the string until a RETURN (value 13) is encountered.
Esto lo comenté en el fragmento de código de ejemplo.
D@rkbytes dijo: Ver Mensaje
// La instrucción gets() retorna hasta que se reciba un Car Return (\r o el ASCII 13)
05/08/2015 #29

Avatar de Psyke

D@rkbytes dijo: Ver Mensaje
Para que la instrucción gets() retorne, debe recibir la cadena con un \r al final.
Esto es lo que le indica a la instrucción el final de la cadena, si no se recibe permanece en un bucle de espera.



Esto lo comenté en el fragmento de código de ejemplo.
Acabo de hacerlo, poniendo un además un "putc(13);" en el emisor, luego de cada dato que envío, pero funciona más feo jajaja, con el getc no he tenido problemas. De todos modos, cuando pueda solucionar el problema que planteé al principio, tendré en cuenta este consejo que me has dado y lo implementaré! Gracias D@rk
05/08/2015 #30
Moderador

Avatar de D@rkbytes

Pues debe funcionar, ya que no tiene por qué no hacerlo.

Lo que no entiendo es, ¿por qué esperas el valor 170 (0xAA) si sólo mandas valores del 0 al 5?
05/08/2015 #31

Avatar de Psyke

No,no, estoy mandando los valores del arreglo en la posicion del 0 al 4.

Código:
#include <16f877a.h>
#fuses XT,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT,NOPROTECT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit= pin_c6, rcv=pin_c7, bits=8)

#define SINCRO    0
#define INICIO    1
#define DIREC     2
#define DATO      3
#define CHECKSUM  4

//int8 DATOS[5] 0=SINCRO, 1=INICIO, 2=DIREC, 3=DATOS, 4=CHECKSUM

int DATOS[5] = {0xAA, 0x7E, 0x66, 0x66};

void main()
{

int i;
DATOS[CHECKSUM] = DATOS[DIREC] + DATOS[DATO];

while(true)
{
   for(i=0;i<5;i++)
   {
   putc(DATOS[i]);
   putc(13);
   delay_ms(250);
   }
}
}
05/08/2015 #32
Moderador

Avatar de D@rkbytes

OK. Me faltó ver esa estructura.

Mira este sencillo ejemplo para que veas que si funciona lo que te menciono.
Tal vez viéndolo puedas encontrar lo que te hace falta.
Archivos Adjuntos
Tipo de Archivo: rar 16F628A Recibir y separar cadena.rar (59,9 KB (Kilobytes), 37 visitas)
05/08/2015 #33

Avatar de Psyke

D@rkbytes dijo: Ver Mensaje
OK. Me faltó ver esa estructura.

Mira este sencillo ejemplo para que veas que si funciona lo que te menciono.
Tal vez viéndolo puedas encontrar lo que te hace falta.
Me parece bastante fácil ese método D@rk. Ahora quiero explicarte algo. Quiero hacer una especie de protocolo (nunca vi como se hace uno, pero me parece que así debería funcionar). La idea es que el emisor envie un 5 enteros, en un arreglo de enteros localizado en el.
Los tres primeros enteros contienen un valor fijo.

//int8 DATOS[5] 0=SINCRO, 1=INICIO, 2=DIREC, 3=DATOS, 4=CHECKSUM

El primer dato y segundo dato es para indicar que se comenzará el envío. El tercer dato es el de dirección, que si existieran mas PICs recibiendo, cada uno se identificaría por un código diferente. El 4 dato contiene la info, es decir, si recibo (por ejemplo) un "0x56", que el receptor encienda tal cosa, si recibo otra cosa, que haga otra cosa. Y el 5 dato, el checksum, que me permite verificar que se haya recibido bien el arreglo, este lo obtengo haciendo la suma entre el entero de DIRECCION y el de DATOS.
En cualquier instancia, cuando se reciba un valor que no corresponde con los que deberían llegar, se descarta la cadena entera. Y para no recibir datos de gusto, en el receptor coloco

Código:
...
void RDA_isr()
{
      gets(DATOS);
      if (DATOS[0] == 0xAA && i<5)
...
para que esté esperando datos hasta recibir un OxAA y ahí continuar la recepción de más datos.

Escribo esto para comentarte, que hasta este momento no quiero cambiar las estructuras que utilizo, porque creo que debería funcionar con un getch, o al menos así lo hizo. Como comentaba anteriormente, solo aparece el problema cuando pongo el if(i<5) dentro de la interrupción. Parezco medio tonto solicitando ayuda y rechazando tu solicitud, pero te agradezco de todas formas, y en caso de que no quede otra solución, haré lo que tú me dices. Lo que no me convence es que debe recibir todo el buffer de una, y si se llega a colar algun dato de alguna interferencia ahi, pierdo toda la cadena de gusto.

---------- Actualizado después de 1 hora ----------

Asunto solucionado. La interrupción no entraba en la estructura if(i<5).... El poco inteligente no inicializó i! Ahora aprendí qué tan importante es hacerlo. Gracias D@rk por tu apoyo. Como te comenté, ahora procederé a intentar utilizar la estructura que propones para continuar el proyecto
20/08/2015 #34


Podrias intentar con esto
Código:
#include <18f4550.h> 
#fuses INTRC_IO,NOWDT,PLL1,CPUDIV1,NOFCMEN,NOPUT,BROWNOUT,NOLVP,NOMCLR,NOWRT,NOCPD
#use delay(clock=8000000) 
#use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7, bits=8, ERRORS)

int DATOS[5]; //0=SINCRO, 1=INICIO, 2=DIREC, 3=DATO, 4=CHECKSUM
int j;
int8 i;
int1 hay_dato;

#int_RDA
void RDA_isr()
{
   DATOS[i++]=getc();
   if(i==5){
      i=0;
      hay_dato=1;
   }
}

void main()
{  
  // setup_oscillator(OSC_8MHZ|OSC_INTRC|OSC_PLL_OFF);
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   while(1)
   {
   if(hay_dato==1){
      hay_dato=0;
      
      if (DATOS[0] == 0xAA)
      { 
        //se sigue la comparacion de los demas caracteres esperados
      }
      else
      {  
         output_toggle(pin_b6);
      }
   }
   }
}
Leyendo bien seria algo asi, solo cambias por los valores que quieres

Código:
#include <18f4550.h> 
#fuses INTRC_IO,NOWDT,PLL1,CPUDIV1,NOFCMEN,NOPUT,BROWNOUT,NOLVP,NOMCLR,NOWRT,NOCPD
#use delay(clock=8000000) 
#use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7, bits=8, ERRORS)

int DATOS[5]; //0=SINCRO, 1=INICIO, 2=DIREC, 3=DATO, 4=CHECKSUM
int j;
int8 i;
int1 hay_dato;

#int_RDA
void RDA_isr()
{
   DATOS[i++]=getc();
   output_toggle(pin_b7);
   if(i==5){
      i=0;
      hay_dato=1;
   }
}

void main()
{  
  // setup_oscillator(OSC_8MHZ|OSC_INTRC|OSC_PLL_OFF);
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   while(1)
   {
   if(hay_dato==1){
      hay_dato=0;
      
      if (DATOS[0] == 0xAA && DATOS[1] == INICIO &&  DATOS[2] == DIREC && DATOS[3] == DATO && DATOS[4] == CHECKSUM )
      { 
        //Ejecutar accion1
      }
      else if (DATOS[0] == 0xAA && DATOS[1] == INICIO &&  DATOS[2] == DIREC && DATOS[3] == DATO2 && DATOS[4] == CHECKSUM2 )
      { 
        //Ejecutar accion2
      }
      else
      {  
         output_toggle(pin_b6);
      }
   }
   }
}
Pero veo mal tu trasmisor

#include <16f877a.h>
#fuses XT,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT,NOPROTECT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit= pin_c6, rcv=pin_c7, bits=8)

#define SINCRO 0
#define INICIO 1
#define DIREC 2
#define DATO 3
#define CHECKSUM 4

//int8 DATOS[5] 0=SINCRO, 1=INICIO, 2=DIREC, 3=DATOS, 4=CHECKSUM

int DATOS[5] = {0xAA, 0x7E, 0x66, 0x66}; //Solo tienes 4 valores

void main()
{

int i;
DATOS[CHECKSUM] = DATOS[DIREC] + DATOS[DATO];//Este arreglo no lo usas

while(true)
{
for(i=0;i<5;i++) //Mandas 5 datos Pero solo le diste valor a los primeros 4 no hay un quinto
{
putc(DATOS[i]);
putc(13); //Con getc no seria necesario enviarlo
delay_ms(250);
}
}
}
Segun yo..

Saludos!!
20/08/2015 #35
Moderador

Avatar de D@rkbytes

Si miras el tema anterior, el problema ya fue solucionado.
Psyke dijo: Ver Mensaje
Asunto solucionado. La interrupción no entraba en la estructura if(i<5).... El poco inteligente no inicializó i! Ahora aprendí qué tan importante es hacerlo.
Pero te explico lo siguiente...

int DATOS[5] = {0xAA, 0x7E, 0x66, 0x66}; //Solo tienes 4 valores

Aquí mencionas que sólo existen 4 valores.
En los arreglos siempre se debe declarar uno más.
Si declaras 4, el compilador dará la advertencia 229: (Subscript out of range) "Subíndice fuera de rango".


DATOS[CHECKSUM] = DATOS[DIREC] + DATOS[DATO];//Este arreglo no lo usas

Esto no es un arreglo. Es una adquisición de datos sobre una variable que forma parte de un arreglo.
DATOS[CHECKSUM] tendrá la suma de
DATOS[DIREC] + DATOS[DATO]

for(i=0;i<5;i++) //Mandas 5 datos Pero solo le diste valor a los primeros 4 no hay un quinto

Esto es debido a la primer explicación.
El valor máximo del bucle "For" debe ser igual a la dimensión del arreglo para que se procesen todos los datos.

putc(13); //Con getc no seria necesario enviarlo

En esto tienes razón, al parecer es algo que a Psyke no le quedó muy claro.

Saludos.
20/08/2015 #36


D@rkbytes dijo: Ver Mensaje
Si miras el tema anterior, el problema ya fue solucionado.

Pero te explico lo siguiente...
Una disculpa la verdad no lei el tema completo, al igual solo es una respuesta con el fin de ayudar.


int DATOS[5] = {0xAA, 0x7E, 0x66, 0x66}; //Solo tienes 4 valores
Aquí mencionas que sólo existen 4 valores.
En los arreglos siempre se debe declarar uno más.
Si declaras 4, el compilador dará la advertencia 229: (Subscript out of range) "Subíndice fuera de rango".


a lo que me referia no es al tema de la advertencia 229 si no que solo le da valor a los 4 primeros, es decir dato0,dato1,dato2,dato3, pero en el for hace un conteo de
for(i=0;i<5;i++) es decir de dato0 a dato4, manda 5 valores pero en la declaracion solo tiene 4 es decir que la condicion del receptor recibia 5 datos no 4 por eso i<5 no se cumple, segun mi logica, enviaria 4datos que el tiene mas uno extraño o repetido al final.



DATOS[CHECKSUM] = DATOS[DIREC] + DATOS[DATO];//Este arreglo no lo usas

Esto no es un arreglo. Es una adquisición de datos sobre una variable que forma parte de un arreglo.
DATOS[CHECKSUM] tendrá la suma de
[COLOR=Red][COLOR=Black]DATOS[DIREC] + DATOS[DATO]
si esto ya lo se pero a lo que me refiero es que el envia, dato[i] en el for que es la cadena de 5 datos que discutimos anteriormente, no envia datos[checksum], es verdad que me pude haber equivocado tambien.

Saludos Master D@RKbytes.
20/08/2015 #37
Moderador

Avatar de D@rkbytes

Nop. No prestaste atención a lo que expliqué.
Si existen 4 valores, el arreglo debe tener uno más, o sea; 5 locaciones.
Y si en el bucle "For" no se coloca el valor de la dimensión del arreglo, el 4 valor no será procesado.

En C, la terminación de un arreglo o cadena debe terminar con "Null" ('\0') y este carácter debe ser considerado dentro del arreglo.
Por lo tanto, cuando se declara un arreglo, siempre se debe considerar ese carácter extra.
16/10/2015 #38


duda capturar almacenar cadena por interrupcion
hola, una consulta yo tengo implementado el siguiente codigo, pero al simular en proteus, el do while de la interrupcion RDA solo me esta capturando el valor del caracter que llega, la variable data se esta actualizando pero no se adiciona a la variable cadena, es decir no se esta juntando los caracteres en el array cadena. podrian ayuarme con esta duda por favor, lo probe en proteus simulando paso a paso y se ve el array cadena nunca se llena de algun valor. adjunto el codigo y el diagrama en proteus. por fa ayuda.

Código:
#include <16f877a.h>
#include <string.h>
#include <stdlib.h>
#fuses NOWDT,HS,NOLVP
#use delay(clock=10M)

#use RS232(baud=9600,XMIT=PIN_C6,RCV=PIN_C7,stream=receptor)

#bit RB0=0x06.0
#bit RB1=0x06.1
#bit RC3=0x07.3
#bit RC4=0x07.4
#bit RC7=0x07.7

int i;
int const length=10;
char data;
char cadena[length];
short flagcomand=0;
signed int16 p=0;

#int_RDA
void  RDA_isr(void) 
{
   do
   {
    data=fgetc(receptor);
    if(data=='\0')
      {
       break;
      }
    else
      {
       cadena[i]=data;
       i++;
      }
   }while(kbhit(receptor));
  flagcomand=1; 
}


void limpiar_buffer()
 {
  int j;
  for(j=0;j<length;j++)
   {
    cadena[j]=0x00;
   }
 }

#INT_EXT                    // directiva de interrupcion por cambio de estado en RB0
void interrupcion_RB0()
{
 if(RB0==1)
   {
    ext_int_edge(H_TO_L);
    if(RB1==1)
      {
       p=p+1;
      }
   }
 else
   {
    ext_int_edge(L_TO_H);
    if(RB1==1)
      {
       p=p-1;
      }
   }
 //putc(p);
 //puts(p);
 printf("\r%Ld",p);
}

void main()
{
  //char valorRec[4];          //variable donde se recibira desde la cadena
  char c;
  int d;
 
 set_tris_b(0xFF);               //configuro portb=in
 set_tris_c(0x80);               //solo el Rx esta como entrada
 RC3=0;
 RC4=0;
 //configuracion pwm
 setup_ccp1(CCP_PWM);
 setup_timer_2(T2_DIV_BY_16,255,1);      //Tpwm=1.63ms--->el ciclo de trabajo sera de 0-255
 set_timer2(0);
 set_pwm1_duty(0);
 enable_interrupts(INT_RDA);
 enable_interrupts(INT_EXT);     //habilito interrupcion RB0
 ext_int_edge(L_TO_H);           //configuro interrupcion por flanco de subida
 enable_interrupts(GLOBAL);      // habilito interrupcion global
 
 
 while(TRUE)
  {
   //gets(valorRec);
   c=cadena[0];
   if(flagcomand==1)
    {
    flagcomand=0;
   switch(c)
     {
      case 's':
        {
         //printf("%3Lu",p);
         //putc(p);
         //printf("%3u",pv);
         //delay_ms(500);
         break;
        }
      case 'i':
         {
          RC3=0;
          RC4=1;
          break;
         }
      case 'd':
         {
          RC3=1;
          RC4=0;
          break;
         }
      default:
         {
          d=atoi(cadena);
          set_pwm1_duty(d);
          //putc(p);
          //printf("%3Lu",p);
          break;
         } 
     }
   limpiar_buffer();
   } 
 }

}
Archivos Adjuntos
Tipo de Archivo: rar Programa Control.rar (71,7 KB (Kilobytes), 6 visitas)
17/10/2015 #39

Avatar de Saint_

Hola unifim, lo que pasa es que cuando la interrupción RDA se activa el dato llegado por el puerto serie se guarda en el vector cadena, luego sale de la interrupción y antes de que llegue el o los nuevos datos la subrutina limpiar_buffer() limpia el dato almacenado en el vector cadena. Esto sucede para cada uno de los datos que llegan al puerto serie y por eso sucede el problema que comentas.
Una solución al problema sin hacer mucho parche es usar un fin de cadena, por ejemplo '\r'(0x0d):

Código:
#include <16f877a.h>
#include <string.h>
#include <stdlib.h>
#fuses NOWDT,HS,NOLVP
#use delay(clock=10M)

#use RS232(baud=9600,XMIT=PIN_C6,RCV=PIN_C7,stream=receptor)

#bit RB0=0x06.0
#bit RB1=0x06.1
#bit RC3=0x07.3
#bit RC4=0x07.4
#bit RC7=0x07.7


int const length=10;
char data;
char cadena[length];
short flagcomand=0;
signed int16 p=0;

#int_RDA
void  RDA_isr(void) 
{
   static unsigned int8 i;
   data=fgetc(receptor);
   if(data=='\r')
   {
      cadena[i]=0; //fin de cadena de texto
      i=0;
      flagcomand=1;
   }
   else
   {
      cadena[i++]=data;
   }
}


void limpiar_buffer()
{
   int j;
   for(j=0;j<length;j++)
   {
      cadena[j]=0x00;
   }
}

#INT_EXT                    // directiva de interrupcion por cambio de estado en RB0
void interrupcion_RB0()
{
   if(RB0==1)
   {
      ext_int_edge(H_TO_L);
      if(RB1==1)
      {
         p=p+1;
      }
   }
   else
   {
      ext_int_edge(L_TO_H);
      if(RB1==1)
      {
         p=p-1;
      }
   }
 //putc(p);
 //puts(p);
 printf("\r%Ld",p);
}

void main()
{
  //char valorRec[4];          //variable donde se recibira desde la cadena
   char c;
   int d;
 
   set_tris_b(0xFF);               //configuro portb=in
   set_tris_c(0x80);               //solo el Rx esta como entrada
   RC3=0;
   RC4=0;
   //configuracion pwm
   setup_ccp1(CCP_PWM);
   setup_timer_2(T2_DIV_BY_16,255,1);      //Tpwm=1.63ms--->el ciclo de trabajo sera de 0-255
   set_timer2(0);
   set_pwm1_duty(0);
   enable_interrupts(INT_RDA);
   enable_interrupts(INT_EXT);     //habilito interrupcion RB0
   ext_int_edge(L_TO_H);           //configuro interrupcion por flanco de subida
   enable_interrupts(GLOBAL);      // habilito interrupcion global
  
   while(TRUE)
   {
      //gets(valorRec);
      c=cadena[0];
      if(flagcomand==1)
      {
         flagcomand=0;
         switch(c)
         {
            case 's':
            {
            //printf("%3Lu",p);
            //putc(p);
            //printf("%3u",pv);
            //delay_ms(500);
               break;
            }
            case 'i':
            {
               RC3=0;
               RC4=1;
               break;
            }
            case 'd':
            {
               RC3=1;
               RC4=0;
               break;
            }
            default:
            {
               d=atoi(cadena);
               set_pwm1_duty(d);
             //putc(p);
             //printf("%3Lu",p);
               break;
            } 
         }
         limpiar_buffer();
      } 
   }
}
10/11/2015 #40


hola Saint_, muchas gracias por responder. estara atareado con otras cosas y recien me di tiempo para probarlo con lo que mencionas, es correcto tal como indicas, funciona bien muchas gracias por la ayuda. una consulta has hecho comunicacion bluetooth con android studio y el modulo HC-05?? yo realice una app en app inventor y me logro comunicar con mi modulo bluetooth y controlo un pwm y envio de datos, pero ahora intento hacerlo con android studio pero no se bien como hacerlo. adjunto la imagen que hice en app inventor y pretendo hacer la misma funcionalidad pero en android studio, agradeceria si pudieras ayudarme.
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.