Autor Tema: UNIR DOS PROGRAMAS EN UNO  (Leído 5226 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado p_starkon

  • PIC10
  • *
  • Mensajes: 7
UNIR DOS PROGRAMAS EN UNO
« en: 04 de Diciembre de 2016, 17:17:29 »
Hola amigos
Estoy programando un control de potencia y lamentablemente  tengo separado el funcionamiento en dos Microcontroladores, mi idea que funcione en un solo microcontrolador de 40 patas , el PIC16F887A...., hasta no he podido hacerlo !!!! :-/

esta separado para que funcionara mejor....pero lamentablemete el pic16f88 esta descontinuado , lo intente  montar  en otro microcontrolador.... lo intente en un PIC16F628A . pero no me resulto

detalles :
PIC16F87A : lee la temperatura del lm 35 y la muestra en un lcd 16x2 y y manda un señal serial al pic16f88 dependiendo de la temperatura
PIC16F88 :   toma la señal serial del pic16f887a y la compara con el lm34 , dependiendo el resultado manda la señal para activar la opctocupla... para variar la intensidad le luz de la ampolleta

programa 16f887a

Código: C
  1. #include <16f887.h>                 //pic a utilizar
  2. #FUSES XT //Crystal osc <= 4mhz
  3. #device adc=10
  4. #use delay(clock=4000000)
  5. #use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7)
  6. #FUSES NOWDT,NOPUT,NOPROTECT,NODEBUG,NOBROWNOUT,NOLVP,NOWRT
  7. #define use_portb_kbd true
  8. #include <kbd.c>
  9. #define LCD_ENABLE_PIN PIN_D2
  10. #define LCD_RS_PIN PIN_D0
  11. #define LCD_RW_PIN PIN_D1
  12. #define LCD_TYPE 2
  13. #include <lcd.c>                   //libreria manejo lcd
  14.  
  15.  
  16.  
  17. void main (void)
  18. {
  19. float temp,medicion,res_1,res_2,serial;
  20. float n_sumar = 244;
  21. lcd_init();
  22. printf(lcd_putc,"\f");
  23.  
  24. while (true)
  25. {
  26. setup_adc (adc_clock_internal);
  27. setup_adc_ports (all_analog);
  28. set_adc_channel (0);                // Elige canal a medir RA0
  29. delay_us (1);
  30. medicion=read_adc ();              // Hace conversión AD
  31. setup_adc (adc_off);                 // Apaga ADC
  32. temp=medicion*(0.4594);     // Pasa binario a °C
  33.  
  34. res_1=(30-temp);
  35. res_2=(12.75*res_1);
  36. serial=(255+res_2);
  37. if (serial > (n_sumar-1))
  38. {serial = 244;}
  39.  
  40. if (serial<50){serial = 0;}
  41. lcd_gotoxy(1,1);printf(lcd_putc,"Tem =%2.0f\337C",temp);
  42. lcd_gotoxy(1,2);printf(lcd_putc,"Serial =%2.0f%%",Serial);
  43. printf ("%0.0f\r" ,serial );
  44. delay_ms(1000);
  45. }
  46. }

Programa 2, este programa esta hecho en el pic16f88 y su funcion es detectar las señales del lm324 y envia la señal a la autocupla

Código: C
  1. #include <16F88.h>
  2. #device adc = 8
  3. #FUSES NOWDT //No Watch Dog Timer
  4. #FUSES XT //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
  5. #FUSES NOPUT //No Power Up Timer
  6. #FUSES MCLR //Master Clear pin enabled
  7. #FUSES NOBROWNOUT //No brownout reset
  8. #FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for #FUSES NOCPD //No EE protection
  9. #FUSES NOWRT //Program memory not write protected
  10. #FUSES NODEBUG //No Debug mode for ICD
  11. #FUSES NOPROTECT //Code not protected from reading
  12. #FUSES NOFCMEN //Fail-safe clock monitor enabled
  13. #FUSES NOIESO //Internal External Switch Over mode enabled
  14. #FUSES RESERVED //Used to set the reserved FUSE bits
  15. #use delay ( clock = 4000000 )
  16. #use rs232 ( baud = 9600 , parity = N , xmit = PIN_B5 , rcv = PIN_B2 , bits = 8 )
  17. #BYTE TRISB = 0x86
  18. #BYTE PORTB = 0x06
  19. #BYTE TRISA = 0x85
  20. #BYTE PORTA = 0x05
  21. int16 tiempoalto ;
  22. int16 tiempobajo = 0x4A38 ;
  23. int16 potencia = 0x00 ;
  24. #int_RDA
  25. void RDA_isr ( void )
  26. {
  27. potencia = getc ();
  28. tiempobajo = potencia * 78 ;
  29. if ( tiempobajo > 19400 ){
  30. tiempobajo = 19400 ;
  31. }
  32. tiempoalto = 19400 - tiempobajo ;
  33. }
  34. void main ()
  35. {
  36. setup_adc_ports ( NO_ANALOGS | VSS_VDD );
  37. setup_adc ( ADC_CLOCK_DIV_2 );
  38. //setup_spi(SPI_SS_DISABLED);
  39. setup_timer_0 ( RTCC_INTERNAL | RTCC_DIV_1 );
  40. setup_timer_1 ( T1_DISABLED );
  41. setup_timer_2 ( T2_DISABLED , 0 , 1 );
  42. setup_comparator ( NC_NC_NC_NC );
  43. setup_vref ( FALSE );
  44. enable_interrupts ( INT_RDA );
  45. enable_interrupts ( GLOBAL );
  46. bit_set ( TRISB , 7 ); //B7 como entrada
  47. bit_clear ( TRISB , 6 ); //B6 como salida
  48. while ( true ){
  49. if ( bit_test ( PORTB , 7 ) == 1 ){
  50. bit_clear ( PORTB , 6 );
  51. delay_us ( tiempobajo );
  52. bit_set ( PORTB , 6 );
  53. delay_us ( tiempoalto );
  54. }
  55. }
  56. }




Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:UNIR DOS PROGRAMAS EN UNO
« Respuesta #1 en: 04 de Diciembre de 2016, 19:27:22 »
El PIC1688 está todavía en producción. Y por lo que yo sé todavía no es obsoleto:
http://www.microchip.com/wwwproducts/en/PIC16F88

Un saludo.

Desconectado p_starkon

  • PIC10
  • *
  • Mensajes: 7
Re:UNIR DOS PROGRAMAS EN UNO
« Respuesta #2 en: 04 de Diciembre de 2016, 19:38:19 »
puede ser, que aun este a la venta , pero yo quiero hacer todo en ese control en un solo microcontrolador,, hasta ahora solo me arroja error, mi idea es de incorporar el programa del 16f88 al pic16f887a

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:UNIR DOS PROGRAMAS EN UNO
« Respuesta #3 en: 04 de Diciembre de 2016, 20:24:31 »
Tu problema son los delays, obaviamente no te va a funcionar.

Soluciones:

en el programa del PIC16F88 deberias usar el PWM por hardware, setear la frecuencia del mismo ( ya que veo que los delays son microsegundos ) y luego unicamente cambiar el duty. Si estoy hablando de usar el modulo CCP.
Obviamente vas a tener que cambiar la formula. Cuando actualizar el duty? eso va a depender de vos,  y cuando actualizar el LCD tambien.

Al menos usando el PWM por hardware si no lo actualizas va a mantener el duty, por lo cual vas a tener menos problemas. Intentalo y luego si ya no funciona vemos como podemos seguir.

PD: Por que tenes incorporado el kbd.c si no lo usas e.e
« Última modificación: 04 de Diciembre de 2016, 21:00:31 por KILLERJC »

Desconectado p_starkon

  • PIC10
  • *
  • Mensajes: 7
Re:UNIR DOS PROGRAMAS EN UNO
« Respuesta #4 en: 09 de Diciembre de 2016, 18:59:26 »
pude unir los dos programas ...  tambien pude lograr controlar la potencia de la ampolleta y mostrar la lectura en el lcd...pero el problema ahora , es que el lcd se ve parpadeante creo que es por la programacion...

no le encuentro la falla aun.....pero algo he avanzado

Código: C
  1. #include <16f877.h>
  2. #FUSES XT //Crystal osc <= 4mhz
  3. #device adc=10
  4. #use delay(clock=4000000)
  5. #use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7)
  6. #FUSES NOWDT,NOPUT,NOPROTECT,NODEBUG,NOBROWNOUT,NOLVP,NOWRT
  7. #define use_portb_kbd true
  8. #include <kbd.c>
  9. #define LCD_ENABLE_PIN PIN_D2
  10. #define LCD_RS_PIN PIN_D3
  11. #define LCD_RW_PIN PIN_D1
  12. #define LCD_TYPE 2
  13. #include <lcd.c>
  14. //libreria manejo lcd
  15. #byte trisa=0x85
  16. #byte porta=0x05
  17. #byte trisb=0x86
  18. #byte portb=0x06
  19. #byte trisd=0x88
  20. #byte portd=0x08
  21.  
  22. #bit flanco=0x81.6
  23. int16 an;
  24. int16 pausa;
  25. int1 control=0;
  26. #int_ext
  27. void int_ex(){
  28. control=1;
  29. flanco=!flanco;
  30. }
  31. void main (void)
  32. {
  33. float temp,medicion,res_1,res_2,serial;
  34. float n_sumar = 244;
  35. lcd_init();
  36. printf(lcd_putc,"\f");
  37. lcd_gotoxy(1,1); printf(LCD_PUTC, "  control ");
  38.    lcd_gotoxy(1,2); printf(LCD_PUTC, "   bombillo   ");
  39.  
  40. while (true)
  41. {
  42. setup_adc (adc_clock_internal);
  43. setup_adc_ports (all_analog);
  44. set_adc_channel (0);                // Elige canal a medir RA0
  45. delay_us (1);
  46. medicion=read_adc ();              // Hace conversión AD
  47. setup_adc (adc_off);                 // Apaga ADC
  48. temp=medicion*(0.4594);     // Pasa binario a °C
  49.  
  50. res_1=(30-temp);
  51. res_2=(12.75*res_1);
  52. serial=(255+res_2);
  53. trisb=0x01;
  54. portb=0x00;
  55. trisa=0x01;
  56. porta=0x00;
  57. trisd=0x00;
  58. portd=0x00;
  59.  
  60. setup_adc(ADC_clock_div_8);//trabaja con 4MHZ (fosc/8)
  61. setup_adc_ports(an0);
  62. enable_interrupts(int_ext);
  63. flanco=1;
  64. enable_interrupts(global);
  65. while(true){
  66. SET_ADC_CHANNEL(0);
  67.  
  68. if (control==1){
  69.    an=read_adc();
  70.    pausa=an*7;
  71.    delay_us(pausa+400);//desplaza el pulso
  72.    bit_set(portd,0);
  73.    delay_us(100);
  74.    bit_clear(portd,0);
  75.    control=0;
  76.  
  77.    
  78. }
  79.  printf(lcd_putc,"\f");
  80. lcd_gotoxy(1,1); printf(LCD_PUTC, "  lectura  ");
  81.    lcd_gotoxy(1,2);printf(lcd_putc,"Serial=%ld",an);
  82. }}
  83. }

Desconectado p_starkon

  • PIC10
  • *
  • Mensajes: 7
control de potencia
« Respuesta #5 en: 14 de Diciembre de 2016, 21:29:23 »
Modifique, pero si9go con el problema


Código: C
  1. #include <16f877.h>
  2. #FUSES XT //Crystal osc <= 4mhz
  3. #device adc=10
  4. #use delay(clock=4000000)
  5. #use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7)
  6. #FUSES NOWDT,NOPUT,NOPROTECT,NODEBUG,NOBROWNOUT,NOLVP,NOWRT
  7. #define use_portb_kbd true
  8. #include <kbd.c>
  9. #define LCD_ENABLE_PIN PIN_D2
  10. #define LCD_RS_PIN PIN_D3
  11. #define LCD_RW_PIN PIN_D1
  12. #define LCD_TYPE 2
  13. #include <lcd.c>
  14. //libreria manejo lcd
  15. #byte trisa=0x85
  16. #byte porta=0x05
  17. #byte trisb=0x86
  18. #byte portb=0x06
  19. #byte trisd=0x88
  20. #byte portd=0x08
  21.  
  22. #bit flanco=0x81.6
  23. int16 an;
  24. int16 pausa;
  25. int1 control=0;
  26. #int_ext
  27. void int_ex(){
  28. control=1;
  29. flanco=!flanco;
  30. }
  31. void main (void)
  32. {
  33. float temp,medicion,res_1,res_2,serial;
  34. float n_sumar = 244;
  35. lcd_init();
  36. printf(lcd_putc,"\f");
  37. lcd_gotoxy(1,1); printf(LCD_PUTC, "  control ");
  38.    lcd_gotoxy(1,2); printf(LCD_PUTC, "   bombillo   ");
  39.  
  40.  
  41. setup_adc (adc_clock_internal);
  42. setup_adc_ports (all_analog);
  43. set_adc_channel (0);                // Elige canal a medir RA0
  44. delay_us (1);
  45. medicion=read_adc ();              // Hace conversión AD
  46. setup_adc (adc_off);                 // Apaga ADC
  47. temp=medicion*(0.4594);     // Pasa binario a °C
  48.  
  49. res_1=(30-temp);
  50. res_2=(12.75*res_1);
  51. serial=(255+res_2);
  52. trisb=0x01;
  53. portb=0x00;
  54. trisa=0x01;
  55. porta=0x00;
  56. trisd=0x00;
  57. portd=0x00;
  58.  
  59. setup_adc(ADC_clock_div_8);//trabaja con 4MHZ (fosc/8)
  60. setup_adc_ports(an0);
  61. enable_interrupts(int_ext);
  62. flanco=1;
  63. enable_interrupts(global);
  64. while(true){
  65. SET_ADC_CHANNEL(0);
  66.  
  67. if (control==1){
  68.    an=read_adc();
  69.    pausa=an*7;
  70.    delay_us(pausa+400);//desplaza el pulso
  71.    bit_set(portd,0);
  72.    delay_us(100);
  73.    bit_clear(portd,0);
  74.    control=0;
  75.  
  76.    
  77. }
  78.  printf(lcd_putc,"\f");
  79. lcd_gotoxy(1,1); printf(LCD_PUTC, "  lectura  ");
  80.    lcd_gotoxy(1,2);printf(lcd_putc,"Serial=%ld",an);
  81. }}
  82. }

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:UNIR DOS PROGRAMAS EN UNO
« Respuesta #6 en: 14 de Diciembre de 2016, 23:46:59 »
El LCD se ve parpadeante por que estas actualizando TODO el LCD cada unos milisegundos. Es muy dificil de ver porque el codigo no esta correctamente identado, pero es esta parte:

Código: C
  1. printf(lcd_putc,"\f");
  2. lcd_gotoxy(1,1); printf(LCD_PUTC, "  lectura  ");
  3.    lcd_gotoxy(1,2);printf(lcd_putc,"Serial=%ld",an);

Lo que podrias hacer es antes de entrar al while enviar esto:

Código: C
  1. printf(lcd_putc,"\f");
  2. lcd_gotoxy(1,1); printf(LCD_PUTC, "  lectura  ");
  3. lcd_gotoxy(1,2);printf(lcd_putc,"Serial=");

Luego si podes usar un lcd_gotoxy(8,2); y un printf de solo an y nada mas , es decir printf(lcd_putc,"%u",an) dentro del while.
Asi solo actualiza el numero, ahora verias el numero de forma parpadeante. Esto se solucionaria si solo lo actualizas en intervalos mas grandes.

¿Como podes hacer para actualizarlo en intervalos mas largos?
Sabes que tenes la entrada y estas viendo los flancos, los cuales son de 20ms, si quisiera que se actualize cada segundo, entonces pongo un contador y cada 50 entradas activo una variable de 1 bit, luego en el programa principal actualizo solo el numero y pongo esa variable a 0. Lo mismo que hiciste con "control" nomas que ahora solo se pone a 1 si es que entra 50 veces a la interrupcion. Y tenes solucionado el problema.

Desconectado p_starkon

  • PIC10
  • *
  • Mensajes: 7
Re:UNIR DOS PROGRAMAS EN UNO
« Respuesta #7 en: 15 de Diciembre de 2016, 21:45:06 »
gracias veere si me resulta te comento de los avances :-/