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

Temas similares

16/02/2017 #1


PIC16F886 a 125 Khz, no funciona conexión serie con PC
Hola a todos. Soy nuevo en el foro, aunque hace bastante que los sigo, es la primera vez que escribo.
Soy ingeniero electrónico y no hace mucho empecé a programar PIC.

Les cuento que estoy realizando un proyecto con PIC, el cual debe contar meses.

Utilizo un reloj de 125KHZ interno, ya que debo tener bajo consumo en el integrado, lo voy a alimentar con pilas.

Cada vez que pase algún día debo grabar en la memoria interna del PIC, la cantidad de días y meses que transcurrió.
La idea mía es que para corroborar el funcionamiento de que los días contados son los correctos, envié estos datos por la interfaz serie del PIC.
Para esto me compre un conversor USB- TTL para conectar el PIC directamente a la PC, sin utilizar el MAX232.
El problema que tengo, es que me envía basura el PIC, una vez que defino el oscilador interno. Esto me dí cuenta porque por cada línea puse un printf para saber en que momento falla.

Observen el código y me van a entender.
Código PHP:
#include <16f886.h>

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC                 //Internal RC Osc,CLKOUT
#FUSES PUT                    // Power Up Timer
#FUSES MCLR                   //Master Clear pin used for I/O
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOCPD                    //No EE protection
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOWRT                    //Program memory not write protected
#use delay(internal=125khz) //OSC interno
#use rs232(baud=1200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)// preguntar si esta bien la velocidad
#include <internal_eeprom.c>
#BYTE ADRESL = 0x9e 
#BYTE ADRESH = 0x1e
#BYTE ADCON0 = 0X1F
#BYTE ADCON1 = 0X9F
int1 flanco_detectormemoria=0,grabo=0;
int8 Segundos=0,Minutos=0Hora=0Dias=Mes=0,Mes_aux=0;

#int_timer1
void timer_1()
{
clear_interrupt(int_timer1);     // Limpiar flag por desborde del TMR1
Segundos++;
output_high(PIN_B0);
set_timer1(58550);               //Esto se hara cada 1 seg
//if(Segundos == 60){Segundos=0;Minutos++;}
}
void sonaralarma(){
   
int8 i=0;
   
output_high(PIN_A1);
   while(
i<10){
   
output_high(PIN_A2);
   
delay_ms(500);
   
output_low(PIN_A2);
   
i++;
   }
     
}

void main()
{
   
printf("comienso11\n\r");
   
setup_oscillator(OSC_125KHZ); //OSC_31KHZ
   
printf("comienso22\n\r");
   
setup_oscillator(OSC_INTRC);  //OSCCON = 00000011;
   
printf("comienso33\n\r");
   
set_tris_a(0b11111000);          // ENTRADAS= RA7 RA6 RA5 RA4 RA3 SALIDAS= RA2 RA1 RA0
   
printf("comienso44\n\r");
   
set_tris_b(0b11110000);          // ENTRADAS= RB7 RB6 RB5 RB4 SALIDAS= RB3 RB2 RB1 RB0
   
printf("comienso55\n\r");
   
setup_adc(ADC_CLOCK_INTERNAL);
   
printf("comienso66\n\r");
   
setup_adc_ports(sAN8);// VER!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   
printf("comienso77\n\r");
   
output_b(0b0); //Se inicializa en 0
   
printf("comienso88\n\r");
   
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
   
printf("comienso99\n\r");
   
enable_interrupts(int_timer1); //Habilita interrupcion del Timer 1
   
printf("comienso100\n\r");
   
enable_interrupts(global); // Habilita interrupcion Global
   
printf("comienso110011\n\r");
   
set_timer1(58550); // Carga el TMR1 con 57786
   
output_low(PIN_A2);  
   
//-----------------Comienzo Programa--------------------
   
printf("hola mundooo11\n\r");
   if (
input(PIN_B4) == && input(PIN_B5) ==&& input(PIN_B6) ==&& input(PIN_B7) ==0){ flanco_detectormemoria=0setup_timer_1(T1_DISABLED);grabo=0//Reinicio Memoria del contador.
   
}
   else{       if(
input(PIN_B4) == && input(PIN_B5) ==&& input(PIN_B6) ==&& input(PIN_B7) ==1){flanco_detectormemoria=1;Mes_aux =1;}            //1 Mes
               
if(input(PIN_B4) == && input(PIN_B5) ==&& input(PIN_B6) ==&& input(PIN_B7) ==0){flanco_detectormemoria=1;Mes_aux =2;}            //2 Meses  
               
if(input(PIN_B4) == && input(PIN_B5) ==&& input(PIN_B6) ==&& input(PIN_B7) ==1){flanco_detectormemoria=1;Mes_aux =3;}            //3 Meses 
               
if(input(PIN_B4) == && input(PIN_B5) ==&& input(PIN_B6) ==&& input(PIN_B7) ==0){flanco_detectormemoria=1;Mes_aux =4;}            //4 Meses
               
if(input(PIN_B4) == && input(PIN_B5) ==&& input(PIN_B6) ==&& input(PIN_B7) ==1){flanco_detectormemoria=1;Mes_aux =5;}            //5 Meses
               
if(input(PIN_B4) == && input(PIN_B5) ==&& input(PIN_B6) ==&& input(PIN_B7) ==0){flanco_detectormemoria=1;Mes_aux =6;}            //6 Meses
               
if(input(PIN_B4) == && input(PIN_B5) ==&& input(PIN_B6) ==&& input(PIN_B7) ==1){flanco_detectormemoria=1;Mes_aux =7;}            //7 Meses
               
if(input(PIN_B4) == && input(PIN_B5) ==&& input(PIN_B6) ==&& input(PIN_B7) ==0){flanco_detectormemoria=1;Mes_aux =8;}            //8 Meses
               
if(input(PIN_B4) == && input(PIN_B5) ==&& input(PIN_B6) ==&& input(PIN_B7) ==1){flanco_detectormemoria=1;Mes_aux =9;}            //9 Meses
               
if(input(PIN_B4) == && input(PIN_B5) ==&& input(PIN_B6) ==&& input(PIN_B7) ==0){flanco_detectormemoria=1;Mes_aux =10;}            //10 Meses
               
if(input(PIN_B4) == && input(PIN_B5) ==&& input(PIN_B6) ==&& input(PIN_B7) ==1){flanco_detectormemoria=1;Mes_aux =11;}            //11 Meses
               
if(input(PIN_B4) == && input(PIN_B5) ==&& input(PIN_B6) ==&& input(PIN_B7) ==0){flanco_detectormemoria=1;Mes_aux =12;}            //12 Meses
               
if(input(PIN_B4) == && input(PIN_B5) ==&& input(PIN_B6) ==&& input(PIN_B7) ==1){flanco_detectormemoria=1;Mes_aux =13;}            //13 Meses
               
if(input(PIN_B4) == && input(PIN_B5) ==&& input(PIN_B6) ==&& input(PIN_B7) ==0){flanco_detectormemoria=1;Mes_aux =14;}            //14 Meses
               
if(input(PIN_B4) == && input(PIN_B5) ==&& input(PIN_B6) ==&& input(PIN_B7) ==1){flanco_detectormemoria=1;Mes_aux =15;}            //15 Meses
   
}
   
printf("hola mundooo22\n\r"); 
   
grabo=read_int1_eeprom(0x0,00);// acomodomar para leer 1 bit
   
if (grabo ==0){
    
Mes=read_eeprom(0x02);
    
Dias=read_eeprom(0x03);
    }
 
//if (Mes_aux < Mes){ sonaralarma();
 //}
 
printf("hola mundooo33\n\r");
 while(
flanco_detectormemoria==1)                                       // Comienza solo si se selecciono un mes
  
{  
   
output_high(PIN_A0);
   
output_low(PIN_B0);
   
output_low(PIN_A1);
   if (
Segundos == 60){Minutos++;Segundos=0;sonaralarma();}
   if (
Minutos == 60){Hora++;Minutos=0;}
   if(
Hora == 24){Dias++;Hora=0;grabo=1;write_int1_eeprom(0x0,00,grabo);write_eeprom(0x02,Mes);write_eeprom(0x03,Dias);}// write_eeprom(0x50, Dias); Cuando pase un dia debo grabar. cuando se corte y vuelva a conectar debo ver estado de swicht 
   
if(Dias ==30){Mes++;Dias=0;}
   if(
Mes == Mes_aux){   sonaralarma();
   }
  }
  

Me parece que el problema es la velocidad de reloj interno, que no llega a transmitir.

¿Alguien pudo hacer funcionar con el reloj de 125khz el puerte serie?
Utilizo Hyperterminal, con la velocidad de 1200. Probé también con velocidad de 300 y no funcionó.

Captura de lo que recibo.

Gracias y saludos.
16/02/2017 #2
Moderador

Avatar de D@rkbytes

No es excesivo el consumo del oscilador interno.
En la hoja de datos no está especificado el consumo a 125 KHz, pero a 8 MHz, el consumo es de 1.3 mA típico y a un máximo de 1.8 mA. @ 5 V.

Y si quieres ahorrar batería, entra en modo de bajo de consumo usando Sleep, y el microcontrolador despertará cuando ocurra una interrupción.
17/02/2017 #3

Avatar de ruben90

Creo que el problema es la velocidad de transmisión (baudios por segundo). Con 125kHz tienes un ciclo máquina de 8us, pero como cada instrucción necesita 4 ciclos máquina, entonces el tiempo de ejecución por instrucción es de 32us. Debes comprobar que el tiempo de transmisión es suficiente para enviar el paquete de datos. Prueba aumentando el valor del oscilador a 1 o 4 MHz, o también mandando una sola letra y luego una palabra.
17/02/2017 #4

Avatar de Nuyel

Se supone que desde que pones #use*delay(internal=125khz) el compilador ajusta el oscilador por su cuenta, por otra parte, si marcas **setup_oscillator(OSC_125KHZ); y luego usas nuevamente **setup_oscillator(OSC_INTRC);**ahí sobrescribes una con otra. Aquí se me hace confuso el manual de tu compilador, según deberías usar*setup_oscillator(OSC_125KHZ|OSC_INTRC); pero tu valor debería ser OSCCON=0x15, yo honestamente prefiero leer la hoja de datos y cargar el registro directamente.
17/02/2017 #5


Buenas, gracias por la pronta respuesta.

Voy a probar una vez mas como menciono Nuyel. Y sino funciona subo el clock a 4mhz.

Por otro lado pensaba, ya que la comunicación serie es para corroborar el funcionamiento, no utilizarla.
Sino que directamente una vez que grabe el día y mes, leer la memoria del pic con el programador.

Les escribo con los resultados mas tarde..

Saludos y gracias nuevamente!
02/03/2017 #6


Disculpen por la demora

Ni con 125khz, 500khz y 1mhz puede hacer funcionar la comunicación serial.
Probé también configurando el registro OSCCON, sin utilizar las funciones definidas en el CCS, pero no funciono.
En 4mhz funciono todo, cosa que tendré que ver el tema del consumo. Creo que con el SLEEP va a ir bien.

Gracias a todos por la respuesta.
02/03/2017 #7
Moderador

Avatar de D@rkbytes

Yo sí pude hacer funcionar la comunicación con 125 KHz. @ 2400 Bps.
No más, porque el compilador no me lo permitía y con lógica razón.

No tengo un PIC16F886, pero usé un PIC16F887, que es lo mismo pero con más puertos.

Aquí unas muestras de las pruebas en físico:

Montaje básico en protoboard con un módulo que usa el C.I. FT232RL.






Envío y recepción de mensajes, usando mi Interfaz RS-232


El código usado:
Código PHP:
#include <16f887.h>
#use     delay(internal = 125 KHz)  // Usar Oscilador interno.

#use     rs232(UART1, baud = 2400)  // Usar RS-232 por hardware.

#define  pin_led  PIN_D1

int8 buffer[20];
int1 flag_rx 0;

// Servicio de interrupción por recepción del módulo USART.
#INT_RDA
void sdi_recepcion_usart (void)
{
   
gets (buffer);                // Adquirir los datos. (gets espera un 13 al final de la cadena)
   
output_high (pin_led);        // Encender el LED.
   
flag_rx 1;                  // Indicar que hay datos en el buffer.
}

void main (void)
{
   
enable_interrupts (INT_RDA);
   
enable_interrupts (GLOBAL);
   
   
output_low (pin_led);
   
   
putc (0x00);   // Inicializar la transmición RS-232. (Evita primer envío con basura)
   
   
while (true)
   {
      if (
flag_rx)
      {
// Si hay datos en el buffer...
         
printf (buffer);        // Retransmitir los datos del buffer.
         
puts ("\n");            // Enviar comando de línea nueva.
         
output_low (pin_led);   // Apagar el LED
         
flag_rx 0;            // Limpiar la bandera de indicación de datos en buffer.
      
}
   }

Imágenes Adjuntas
Tipo de Archivo: jpg Dsc01990.jpg (97,3 KB (Kilobytes), 24 visitas)
Tipo de Archivo: jpg SPCTRL - Tx & Rx @ 2400 Bps.jpg (141,1 KB (Kilobytes), 21 visitas)
Respuesta
¿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.