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

Temas similares

10/01/2015 #21


Gracias. Bueno, ahora me encuentro con otro problema.
Ya pude hacer uso de RS232 y de I2C.
El problema es que cuando se ejecuta una parte del código, éste se bloquea.

Está funcionando completamente bien hasta el punto en el que se ejecuta la parte de comparación de un valor para que haga otra tarea.

La parte en negrita del código es la que cuando se ejecuta, falla. Todo funciona bien hasta ese punto.
Debo decir que la función que ejecuta es una conexión por RS232 a un módem GSM.
Código:
while(TRUE){
      //-------------------- SELECCION PRODUCTO --------------------------------
         if((flag==1)&&(envio==1)){
            //printf(lcd_putc, "\f   Recibido ... \n");
            //printf(lcd_putc, "Pos.%d Dato= %u ", direccion, prod[direccion]);
            
            delay_ms(1000);
            //printf(lcd_putc, "\f\nPos.%d Copy= %u ", direccion, copy[direccion]);
            output_a(copy[direccion]);
            output_high(PIN_E0);
            delay_ms(2000);
            output_a(0x00);
            output_low(PIN_E0);
            copy[direccion]=copy[direccion]-1;
            //printf(lcd_putc, "\f\nPos.%d Copy2= %u ", direccion, copy[direccion]);
            delay_ms(100);
            
            if(prod[direccion]==3){
               for(i=0;i<NUMERO_MENSAJES;i++){
                   //Envio_SMS(); 
                   }
               output_high(PIN_E1);
               delay_ms(1000);
               output_low(PIN_E1);
               }
            
            if(prod[direccion]==0){
                  for(i=0;i<NUMERO_MENSAJES;i++){
                   Envio_SMS(); 
                   }
                  for(i=0;i<9;i++){
                  output_high(PIN_E1);
                  delay_ms(50);
                  output_low(PIN_E1);
                  delay_ms(50);
                  }
               }
            
            flag=0;
            envio=0;
            prod[0x1F]=0;
            }
          
          //------------------ CONFIGURACION DE ESCLAVO ------------------------
          if(cont==1){
            for(j=0;j<productos;j++){
                  if(j==0){
                     copy[j]=prod[j];}
                  else{
                     copy[j]=prod[j]+copy[j-1];}
                  }
                  
             //printcopy();
            //REESTABLECE LOS VALORES A 0
            cont=0;
            envio=0;
            prod[0x1E]=0;   
            }
      }
10/01/2015 #22
Moderador

Avatar de D@rkbytes

gatito11 dijo: Ver Mensaje
La parte en negrita del código es la que cuando se ejecuta, falla. Todo funciona bien hasta ese punto.
Entonces céntrate en la rutina Envio_SMS();
Es la rutina que está involucrada en un bucle de la parte que mencionas y que no incluyes.
Lo demás son instrucciones sencillas como retardos y activación de pines que podrían no afectar.
11/01/2015 #23


Pues lo que pasa es que la función envio_sms() hasta antes de agregar la interrupción RDA funcionaba perfectamente.
Cuando agregué todo el código de esta interrupción, la parte de envio_sms() empezó a fallar.
Digamos que cuando llega a esa parte del código el micro se traba o no sé.
Porque de ahí en adelante ya no hace nada y pues en sí, la funcion envio no tiene ciencia. Mira:

Código:
void Envio_SMS(){ 
      //char ctrlz = 26; //combinacion de teclas "ctrl+z"
      putc(0x0D);
      putc(0x0A);
      printf("AT+CMGS=\"%s\"\r\n",NUMERO);                           
      delay_ms(1000);
      printf("El prod[%i] tiene %i unidades\rLista total:\r",(direccion+1),prod[direccion]);
      printf("%i, %i, %i, %i, %i, %i, %i, %i, %i, %i\r",prod[0],prod[1],prod[2],prod[3],prod[4],prod[5],prod[6],prod[7],prod[8],prod[9]);//printf("%s",MENSAJE);                                       // 
      printf("estas son las cantidades de prod. restante");     
      delay_ms(500);
      putc(0x1A);//printf("%c",ctrlz); //se envia el mensaje
      putc(0x0D);
      putc(0x0A);
   }
No entiendo por qué se traba solo cuando llega a esa parte, si antes de agregar la interrupción funcionaba perfectamente.
11/01/2015 #24
Moderador

Avatar de D@rkbytes

Bien. Como quiera la rutina contiene variables que no se sabe que valores contengan.
Pero puedes entrar en modo de depuración con ISIS colocando un punto de ruptura.
Por ejemplo, antes de: "printf("AT+CMGS=\"%s\"\r\n",NUMERO);"

De ahí te vas paso por paso hasta que en alguna ejecución ya no se consiga retornar, porque no veo llamadas a otras rutinas que puedan ocasionar el problema.
Y si quieres depurar el programa, comenta los delay_ms() para que el depurador no se detenga sobre esas instrucciones.

Estaría bien que subas el proyecto completo para poder ejecutarlo y ver mejor lo que sucede.
11/01/2015 #25


Lo mas raro es que en proteus no se traba, ahi si hace todo bien, el problema esta ya a la hora de probarlo fisicamente, porque en el simulador lo corre bien, no se a que se pueda deber ese problema
pero al parecer si recibe información porque el master no se traba entonces significa que el dato si llega pero el pic no hace ya nada despues de entrar a esa parte que describo
11/01/2015 #26
Moderador

Avatar de D@rkbytes

gatito11 dijo: Ver Mensaje
Lo más raro es que en proteus no se traba, ahí si hace todo bien.
El problema está ya a la hora de probarlo físicamente, porque en el simulador lo corre bien.
No sé a qué se pueda deber ese problema.
Pero al parecer si recibe información porque el master no se traba, entonces significa que el dato si llega pero el pic no hace ya nada después de entrar a esa parte que describo.
Cambia los %s, %i y %c por %u o %lu, dependiendo del tipo de variable que uses.
Yo he tenido problemas con %s principalmente y dejé de usar ese identificador por lo mismo.
11/01/2015 #27


acabo de encontrar el error, bueno mas bien le agregue dos lineas al codigo exactamente en la parte donde se trababa

if(prod[direccion]==3){
disable_interrupts(GLOBAL);
Envio_SMS();
enable_interrupts(GLOBAL);
output_high(PIN_E1);
delay_ms(500);
output_low(PIN_E1);
}

if(prod[direccion]==0){
disable_interrupts(GLOBAL);
Envio_SMS();
enable_interrupts(GLOBAL);
for(i=0;i<9;i++){
output_high(PIN_E1);
delay_ms(50);
output_low(PIN_E1);
delay_ms(50);
}
}

al parecer esas dos lineas solucionaron el problema, hare mas pruebas pero creo que algunas ocasiones si es necesario deshabilitar las interrupciones, jaja primera vez que tengo ese problema, para que tengan cuidado cuando usen interrupciones
23/05/2015 #28

Avatar de mendek

Buenas tardes compañeros del foro:

Estoy teniendo problemas con la comunicación y no sé si con la interrupción:

Código:
#include <16F887.h>

#fuses XT,NOWDT,NOPUT,NOPROTECT
#use delay(clock=4MHz)
#use     rs232(uart1, baud = 9600)
#include <string.h>           // Librería para usar strcmp
#include <stdlib.h>           // Librería para usar atoi
#use fast_io(all)       // Gestión de puertos

char dato=0;              // Valor leidd en el puerto serial

// Servicio de interrupción USART
#int_rda
void recepcion_serial (void)
{
   dato = getc();            // Guardar el dato recibido en "dato_serial"
}

/*----------------------------------------------------------------------------*/ 

void main() {            // Función principal

   set_tris_c(0b10000000);    // Se configura el puerto C cómo salida, menos el 
                              // puerto RX
   output_c(0);
   // Se configura el TMR2 con periodo de 249, prediv de 1:4 y postdiv de 1:1
   set_tris_d(0b00000000);
   setup_timer_2(T2_DIV_BY_4, 249, 1);

   set_pwm2_duty(0);  // Inicia la señal PWM en el pin C2




/*                Inicia la generación de la señal PWM.
                  Se configura el módulo CCP1 en modo PWM
                  con TPWM = 1 ms (FPWM = 1000 Hz)
*/

   setup_ccp2(CCP_PWM);       // La señal PWM se genera a partir de aquí

   enable_interrupts(int_rda);      // Habilitar interrupción USART
   enable_interrupts(global);       // Habilitar interrupciones gloabales.

dato=0;
while(1){

   set_pwm2_duty(dato);         // Inicia la señal PWM en el pin C2
   printf("\r %u ", dato);
}

}
Lo que pasa es que al enviarle un valor decimal al puerto, de por ejemplo 450, el valor que me devuelve el pic es 13, cuando me debería de devolver el mismo 450. Y el pic me devuelve el 13, independientemente de que valor le mande.

Adjunto mi simulación.

Sin más de momento me gustaría ver qué es lo que estoy haciendo mal.

De antemano muchas gracias.
23/05/2015 #29

Avatar de Gudino Roberto duberlin

Hola, bueno tú declaras la variable "dato" con formato caracter, pero la manipulas cómo de tipo numérica.
23/05/2015 #30
Moderador

Avatar de D@rkbytes

mendek dijo: Ver Mensaje
Lo que pasa es que al enviarle un valor decimal al puerto, de por ejemplo 450, el valor que me devuelve el PIC es 13, cuando me debería de devolver el mismo 450.
Y el PIC me devuelve el 13, independientemente de que valor le mande.
Recuerda que por el puerto serial únicamente puedes enviar un Byte (8 bits) o sea, hasta 255
La variable Char que estás usando es correcta al igual que INT8, pero ambas son de 8 bits.

Así que no puedes recibir ni enviar valores superiores a 255 por el puerto serie aunque uses variables de 16 bits.
24/05/2015 #31

Avatar de Scooter

Claro que se puede, pero no de golpe.
Si el valor es de 16 bits hay que enviar dos bytes etc...
24/05/2015 #32
Moderador

Avatar de D@rkbytes

Scooter dijo: Ver Mensaje
Claro que se puede, pero no de golpe.
Si el valor es de 16 bits hay que enviar dos bytes etc...
Obvio. Pero primero lo básico y después ya entramos en ese tema.
03/02/2016 #33


Consulata para enviar y recibir trama de datos por rs232
Hola amigos

Quería consultarles como se puede enviar y leer una trama de datos por rs232, quiero enviar una trama de dos cifras decimales , por ejemplo quiero enviar la siguiente trama :

MAESTRO PIC16F628A ===> 85 & 25
ESCLAVO ===> 85 & 25 PIC16F628A

Despues de recibir la trama tengo que mostrarlos por el Display de 16x2
____________________
| Decimal 1 : 85 |
| Decimal 2 : 25 |
____________________


Hasta ahora solo he podido enviar el dato 85 y mostarlos por el display, estoy ocupando el CCS Compiler
04/02/2016 #34

Avatar de TRILO-BYTE

muy facil

debes hacer un printf mas o menos asi:

printf("%d,%d@"decimal1,decimal2);

y se imprimira algo asi:

85,25@

ahora el receptor leera la cadena de texto

85,25@

donde mis 2 decimales estan separados por una coma y el @ "puede ser cualquier simbolo"
indica que la cadena termino

si es que envias mas decimales.

ahora con un token separas el texto indicando al STRTOK la ","

y asi de facil

ya con atoi conviertes a decimal el texto

no te dire exactamente como por que seria hacerte tu tarea

pero si dije basicamente como se hace
04/02/2016 #35


Gracias , trilo-byte
TRILO-BYTE, gracias por la respuesta que me enviaste !!!!!

Estoy haciendo dos programas, uno que me envié números desde 0 al 99 en una trama y enviarlo por RS-232. Por ejemplo; 88 & 99 y mostrar lo que envié por un LCD

Y el otro es el que recepciona los datos enviados.
Mi duda es ¿cómo puedo separar eso datos para mostrarlos?

Esto es lo que he programado:
Éste programa estará recibiendo constantemente números desde el 0 a 99
Por ejemplo; 88 & 50 o puede ser 05 & 08, los números decimales están separados por "&" = (números 0 al 99) & (números 0 al 99)...

Hasta ahora estoy recibiendo solo un dato que lo envió desde otro micro controlador.
El programa lee el numero y lo muestra en dos display, si me llega el otro dato lo mostraría en otros 2 displays

Código PHP:
///////////////////////////////////////////////////////////////////////////

#use rs232(baud=9600,xmit=pin_b1,rcv=pin_b2,bits=8)

#define COMUN_1     PIN_b4
#define COMUN_2     PIN_b5
#define COMUN_3     PIN_b6
#define COMUN_4     PIN_b7



int digito[10]  = {0X00,0X01,0X02,0x03,0x04,0x05,0X06,0x07,0X08,0x09};
unsigned int UnidadDecena;
int8 valor;

#int_rda
void rda_isr(void){
valor getc();
}

void main(void){
int8 unidades,decenas;
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);

while (
true){
unidades = (valor 10); // Se extraen las unidades.
decenas = (valor 100)/10// Se extraen las decenas.

output_low(COMUN_2);
output_high(COMUN_1);
output_a(digito[unidades]); .
delay_ms(2); 
output_low(COMUN_1);
output_high(COMUN_2)
output_a(digito[decerna]);
delay_ms(2); 

}

04/02/2016 #36

Avatar de TRILO-BYTE

es que estas MAL

en getc solo recibes un caracter de 8 bits

una trama es una linea de texto

ejemplo

trilobyte#123#perro#567#perico@

donde tengo en mi trama texto , numeros en texto seprarados por un simbolo y la trama termina con un simbolo diferente

para enviar una trama se envia con printf el texto con mi formato

cadena#numero#cadena#numero#cadena@

seria asi:

printf("%s#%d#%s#%d@",cadena1,numero1,cadena2,nume ro2);

te das cuenta que envie un formato para mi trama "mi trama es ejemplo como se hace".

ahora de parte del receptor debemos leer toda la cadena.

no sabemos de que tamaño la va enviar el transmisor

podemos usar un apuntador
char *trama;

o podemos usar una cadena definida
char trama[15];

ahora necesitamos 2 cadenas para que reciban los numeros

char numero1[4];
char numero2[4];

y 2 variables tipo entero que reciban el valor de esos numeros

int valor1;
int valor2;

hasta aqui todo debe ser mas claro que una taza de cafe.

luego debemos recibir toda la cadena leida por el transmisor con un gets

char trama[10];

#int_rda
void rda_isr(void){
gets(trama);
}

una vez leida toda la cadena ahora debes aplicar STRTOK();

lo que vaz a hacer es separar con tokens

este es un ejemplo del CCS del token

se ve que no sabes buscar pues el CCS lo da como ejemplo

char string[30], term[3], *ptr;

strcpy(string,"one,two,three;");
strcpy(term,",;");

ptr = strtok(string, term);

while(ptr!=0) {
puts(ptr);
ptr = strtok(0, term);
}

// Prints:
one
two
three

lo que debes hacer es separar tu trama por los simbolos usados &

y cada pedacito de texto lo debes guardar en las cadenas que defini

luego para que esas cadenas de texto se conviertan en un valor numerico debes aplicar atoi
que tambien hay muchos ejemplos no me desgastare en explicar.

ese valor en atoi se convierte en numerico y se puede ya guardar en los registros tipo int

bien facil
04/02/2016 #37
Moderador

Avatar de D@rkbytes

ciberick dijo: Ver Mensaje
Estoy haciendo dos programas, uno que me envié números desde 0 al 99 en una trama y enviarlo por RS-232. Por ejemplo; 88 & 99 y mostrar lo que envié por un LCD

Y el otro es el que recepciona los datos enviados.
Mi duda es ¿cómo puedo separar eso datos para mostrarlos?
Es sencillo. Te adjunto unos programas de ejemplo comentados, para que entiendas el proceso.

PD: El ejemplo puede usar cifras con decimales o números enteros.
Si se desea, también se puede enviar el Checksum para comprobar errores de envío.
Archivos Adjuntos
Tipo de Archivo: rar 16F628A Cadenas RS-232.rar (32,0 KB (Kilobytes), 28 visitas)
05/02/2016 #38


D@rkbytes

se agradece el gesto, revisare el archivo y te comento como me va

muchas gracias!!!!!

---------- Actualizado después de 2 minutos ----------

TRILO-BYTE

también se agradece el gesto, pero me complique mas ...empece a buscar las instrucciones que me indicaste pero por el momento aun estoy en blanco...revisare el archivo que me enviaron y les comento como va resultando todo...

saludos
muchas gracias!!!!!
05/02/2016 #39


D@rkbyte

Podrías ayudarme porfavor a corregir el programa para ver en que estoy equivocado, me estoy basando en el ejemplo que me enviaste pero aun no logro hacerlo funcionar.

te envie el archivo completo

saludos
Archivos Adjuntos
Tipo de Archivo: rar CONTADOR DUPLEX.rar (169,2 KB (Kilobytes), 3 visitas)
05/02/2016 #40
Moderador

Avatar de D@rkbytes

ciberick dijo: Ver Mensaje
Me estoy basando en el ejemplo que me enviaste pero aún no logro hacerlo funcionar.
En los archivos que adjuntas no veo que estés aplicando los procedimientos de los ejemplo que subí.

¿Podrías explicar detalladamente qué es lo que quieres hacer?
¿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.