Código para controlar PIC por comunicación RS232 y LCD

#1
Buenas tardes, estoy trabajando en un proyecto para la clase, gracias a los cursos y comentarios que he leído en esta página he aprendido lo básico para programar en C, esta vez les pido el favor de decirme como puedo continuar el programa que a continuación anexo ya que no sé como escribir en el programa lo relacionado con los switches, si me pueden ayudar por favor diciéndome los errores les agradecería mucho ya que deseo aprender mucho de programación.

Muchas gracias y disculpen la molestia.

Código:
#include <16f887.h>
#include <lcd.c>
#fuses INTRC_IO,nowdt,nomclr  
#use delay(clock = 4MHZ) 
#use rs232(baud=9600,bits=8,,xmit=PIN_C6,RCV=PIN_C7)
#byte portb =0x06 
#byte trisb = 0b11000000


char tecla;

void main(){
lcdinit();

while(true) {
lcdgotoxy(6,1);
lcd_putc("PRACTICA #2");
lcdgotoxy(5,2);
lcd_putc("MICROCONTROLADOR")};

printf ("INSTITUTO TECNOLOGICO METROPOLITANO, 
PULSE LAS SIGUIENTES TECLAS:
TECLA <1> PARA ACTIVAR LED 1 
TECLA <2> PARA ACTIVAR LED 2
TECLA <3> PARA ACTIVAR LED 3
TECLA <4> PARA ACTIVAR LED 4 
TECLA <0> PARA DESACTIVAR LOS LEDS
TECLA <5> ESTADO DEL PULSADOR 1
TECLA <6> ESTADO DEL PULSADOR 2\r\n");

tecla=getc();

if(tecla=='1'){
printf("LED 1 ENCENDIDO \r\n");
bit_set(portb,3);
lcdgotoxy(6,1);
lcd_putc("LED 1 ENCENDIDO")
}

if(tecla=='2'){
printf("LED 2 ENCENDIDO \r\n");
bit_set(portb,2);
lcdgotoxy(6,1);
lcd_putc("LED 2 ENCENDIDO")
}

if(tecla=='3'){
printf("LED 3 ENCENDIDO \r\n");
bit_set(portb,1);
lcdgotoxy(6,1);
lcd_putc("LED 3 ENCENDIDO")
}

if(tecla=='4'){
printf("LED 4 ENCENDIDO \r\n");
bit_set(portb,0);
lcdgotoxy(6,1);
lcd_putc("LED 4 ENCENDIDO")
}

if(tecla=='0'){
printf("DESACTIVAR LEDS");
portb=0b00000000;
lcdgotoxy(6,1);
lcd_putc("DESACTIVAR LEDS")
}
}
}
 

Adjuntos

Última edición por un moderador:
#2
Te ha faltado muy poco para terminarlo.
No tengo el microcontrolador que usas pero será casi igual, este código esta probado.
Tendrás que cambiar algunas cosas porque el hardware en el que lo he probado no es el mismo (Librería LCD y Led 1 y 2, tipo de oscilador, baudios)
También es posible que tengas que configurar el pin Rx del puerto serie en su correspondiente registro TRIS:

PHP:
//Placa entrenadora PicEBasic (PIC16F876)
//Test puerto RS232, LCD, I/O
#include <16F876.h>
#device adc=10
#use delay (clock = 20000000) //Reloj a 20Mhz
//#use delay(internal=4000000) //Pic 16F887
#FUSES HS         //Fast clock (Quitar para INTERNAL OSCILLATOR) 
#FUSES PUT        //Power-up Timer
#FUSES BROWNOUT   //Brown-out reset 
#FUSES NOWDT      //No, Watchdog Timer 
#FUSES NOCPD      //No, Data EEPROM Memory Code Protection
#FUSES NOPROTECT  //No, (CP) Flash Program Memory Code Protection
#FUSES NOLVP      //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

#include "Flex_Lcd.c"
#use rs232 (UART1, BAUD = 4800, PARITY=N, BITS=8, TIMEOUT=1)

#BYTE PORTA = 0x05
#BYTE PORTB = 0x06
#BYTE PORTC = 0x07
#BYTE TRISA = 0x85 
#BYTE TRISB = 0x86
#BYTE TRISC = 0x87

void main(){
   //Constantes (codigos de control ASCII del hyperterminal)
   Const int FF = 0x0c;  //FF, Avance de pagina
   Const int BELL = 0x07;  //BELL, Señal sonora
   Const int SP = 0x20; //SP, Espacio
   Const int BKSP = 0x08;  //BKSP, Retroceso
   Const int CR = 0x0d; //CR, retorno de carro
   Const int LF = 0x0a; //LF, Salto de linea
   Const int CTRLZ = 0x1a; //Ctrl-z
   Const int ESC = 0x1b;   //Escape

   Char tecla = 0xff; //Tecla de control

   Setup_adc_ports(NO_ANALOGS);
   TRISB = 0b11000000;
    TRISC = 0b10000001;
   lcd_init();

   lcd_gotoxy(1,1);
   lcd_putc("PRACTICA #2");
   lcd_gotoxy(1,2);
   lcd_putc("MICROCONTROLADOR");

   Putc(FF); //Pagina en blanco en consola serie
   printf("INSTITUTO TECNOLOGICO METROPOLITANO\r\n");
   printf("------------------------------------\r\n");
   Printf("PULSE LAS SIGUIENTES TECLAS:\r\n\r\n");
   Printf("TECLA <1> PARA ACTIVAR LED 1\r\n");
   Printf("TECLA <2> PARA ACTIVAR LED 2\r\n");
   Printf("TECLA <3> PARA ACTIVAR LED 3\r\n");
   Printf("TECLA <4> PARA ACTIVAR LED 4\r\n");
   Printf("TECLA <0> PARA DESACTIVAR LOS LEDS\r\n");
   Printf("TECLA <5> ESTADO DEL PULSADOR 1\r\n");
   Printf("TECLA <6> ESTADO DEL PULSADOR 2\r\n\r\n");

   while(true) {

      if (kbhit()) tecla=getc(); //Solo si hay datos en el buffer serie

      if(tecla=='1'){
         printf("LED 1 ENCENDIDO\r\n");
         bit_set(portb,5);//3);
         lcd_gotoxy(1,2);
         lcd_putc("LED 1 ENCENDIDO ");
         tecla = 0xff; //Reset a la última pulsación
      }

      if(tecla=='2'){
         printf("LED 2 ENCENDIDO\r\n");
         bit_set(portb,0);//2);
         lcd_gotoxy(1,2);
         lcd_putc("LED 2 ENCENDIDO ");
         tecla = 0xff;
      }

      if(tecla=='3'){
         printf("LED 3 ENCENDIDO\r\n");
         bit_set(portb,1);
         lcd_gotoxy(1,2);
         lcd_putc("LED 3 ENCENDIDO ");
         tecla = 0xff;
      }

      if(tecla=='4'){
         printf("LED 4 ENCENDIDO\r\n");
         bit_set(portb,0);
         lcd_gotoxy(1,2);
         lcd_putc("LED 4 ENCENDIDO ");
         tecla = 0xff;
      }
   
      if(tecla=='0'){
         printf("DESACTIVAR LEDS\r\n");
         portb=0b00000000;
         lcd_gotoxy(1,2);
         lcd_putc("DESACTIVAR LEDS ");
         tecla = 0xff;
      }   
    
      if(tecla=='5') {
         If(Bit_test(PORTB, 2) == 0) {
            printf("PULSADOR 1: ON\r\n");
            lcd_gotoxy(1,2);
            lcd_putc("PULSADOR 1: ON  ");
         }
         Else {
            printf("PULSADOR 1: OFF\r\n");
            lcd_gotoxy(1,2);
            lcd_putc("PULSADOR 1: OFF ");
         }
         tecla = 0xff;
      }       
      if(tecla=='6') {
         If(Bit_test(PORTc, 0) == 0) {
            printf("PULSADOR 2: ON\r\n");
            lcd_gotoxy(1,2);
            lcd_putc("PULSADOR 2: ON  ");
         }
         Else {
            printf("PULSADOR 2: OFF\r\n");
            lcd_gotoxy(1,2);
            lcd_putc("PULSADOR 2: OFF ");
         }
         tecla = 0xff;
      }          
   }
}
 
Última edición por un moderador:
#3
Hola, amigo. Muchísimas gracias, que detalle haberme ayudado.
Te pregunto; ¿En el código que voy a escribir, es necesario escribir esto que le escribiste al tuyo, o sin eso funciona?

Código:
//Constantes (codigos de control ASCII del hyperterminal)
Const int FF = 0x0c; //FF, Avance de pagina
Const int BELL = 0x07; //BELL, Señal sonora
Const int SP = 0x20; //SP, Espacio
Const int BKSP = 0x08; //BKSP, Retroceso
Const int CR = 0x0d; //CR, retorno de carro
Const int LF = 0x0a; //LF, Salto de linea
Const int CTRLZ = 0x1a; //Ctrl-z
Const int ESC = 0x1b; //Escape
Gracias.
 
Última edición por un moderador:
#4
otra cosa

puedes usar la funcion switch para evitar usar tantos if
ahorita no se nota pero cuando haces muchas comparaciones a altas velocidades el if empieza a fallar

ejemplo con if:

tecla=getc();

if(tecla=='a')
{}

if(tecla=='b')
{}

if(tecla=='c')
{}

if(tecla=='d')
{}


ahora el mismo ejemplo con switch


tecla=getc();

switch(tecla)
{

case a:
break;

case b:
break;

case c:
break;

case d:
break;

}

en pocas palabras el switch es mas rapido en ejecucion y aparte reduce la posibilidad de tener un bug cuando el codigo se hace mas grande
 
#6
Eso son los códigos de control del hyperterminal, solo utilizo el primero, que es poner la pagina en blanco antes de enviar el menú, queda mucho mejor.

Const int FF = 0x0c; //FF, Avance de pagina
 
#9
Parece que tienes algo raro en este IF:

if (kbhit()) tecla=getc(); //Solo si hay datos en el buffer serie

kbhit() es una función que devuelve 1 si algún dato llego al puerto serie, se usa para leer datos solo si los hay, si esta función no te funciona en tu compilador pon la línea como la tenias antes:

tecla=getc();

Y si quieres emularla nada más fácil; añade esto al código en la declaración de registros:
#BYTE PIR1 = 0x0C
#BIT KBHIT = PIR1.5 //PIR1.RCIF

Después de esto ya tienes el flag de comprobación de recepción de datos operativo, este flag lo controla directamente el micro, así que no hay que hacer nada más, solo comprobarlo con la siguiente línea.

If (KBHIT) tecla = getc();

Nota: El flag RCIF se utiliza para comprobar si entraron datos al buffer serie, si el buffer serie no tiene datos... ¿para qué leerlo?... en este programa puede que no tenga mucha importancia porque el micro apenas tiene que hacer nada, pero cuando un código se complica cualquier tiempo de ahorro es bienvenido.
 
Última edición:
#10
Buenas noches amigos, que pena molestarlos, estoy tratando de compilar el programa pero me sale este error que será? Gracias!!
Salvo que no este en lo cierto yo no veo ningun errror en la imagen que muestras, lo que si hay es un Warning, de ser un Warning eso no es problematico, ojo mejor no tenerlos.

Tienes una prueba sencilla compila cualquier codigo y dentro del while pon (1), veras que te sale un Warning pero si pones (true) que es lo mismo, ya no te sale.
 
#11
Muchas gracias amigos por tanta ayuda, la verdad he aprendido mucho mas por aqui que en la U jajjajaj.

Miren como me quedó el montaje del circuito, esta noche programo el PIC y les cuento como me va. Gracias a todos!
 

Adjuntos

#12
Tienes que colocar un condensador de 100nF lo más cerca posible a los pin de alimentación de cada integrado, y no está de más colocar al lcd otros dos, uno de 100nF y otro de 4.7uF lo más cerca de sus pin de alimentación.
Y aunque la fuente sea muy buena, es recomendable colocar a la entrada del regulador uno de 10nF y otro de 10uF y a su salida de 100nF y otro de 4.7uF.

Esto es fundamental, no comprendo como no te lo han dicho.
 
Última edición:
#13
Que bien, súper importante ese dato. Si vió, como les digo, aprendo más con ustedes que en clase. :(

Buenas noches compañeros, ya programé el PIC y nos leds no encienden, el texto se ve perfecto en la hiperterminal y en el LCD.
¿Qué sucederá con los leds?

Este es el programa:
PHP:
#include <16f887.h>
#fuses INTRC_IO,nowdt,nomclr  
#use delay(clock = 4MHZ) 
#use RS232(baud=9600,bits=8,xmit=PIN_C6,RCV=PIN_C7)
#byte portb =0x06 
#byte trisb = 0b11000000
#include <lcd.c>


void main(){
Const int FF = 0x0c;  //FF, Avance de pagina
Char tecla = 0xff; //Tecla de control
lcd_init();

lcd_gotoxy(1,1);
lcd_putc("PRACTICA #2");
lcd_gotoxy(1,2);
lcd_putc("MICROCONTROLADOR");

Putc(FF); //Pagina en blanco en consola serie
printf("INSTITUTO TECNOLOGICO METROPOLITANO, ITM\r\n");
printf("INGENIERIA BIOMEDICA\r\n");
printf("YEISSON VASQUEZ\r\n");
printf("GISELA VITOLA\r\n");
Printf("PULSE LAS SIGUIENTES TECLAS:\r\n\r\n");
Printf("TECLA <1> PARA ACTIVAR LED 1\r\n");
Printf("TECLA <2> PARA ACTIVAR LED 2\r\n");
Printf("TECLA <3> PARA ACTIVAR LED 3\r\n");
Printf("TECLA <4> PARA ACTIVAR LED 4\r\n");
Printf("TECLA <0> PARA DESACTIVAR LOS LEDS\r\n");
Printf("TECLA <5> ESTADO DEL PULSADOR 1\r\n");
Printf("TECLA <6> ESTADO DEL PULSADOR 2\r\n\r\n");

while(true) {

tecla=getc();


if(tecla=='1'){
printf("LED 1 ENCENDIDO\r\n");
bit_set(portb,3);
lcd_gotoxy(1,2);
lcd_putc("LED 1 ENCENDIDO");
tecla = 0xff; //Reset a la última pulsación
}

if(tecla=='2'){
printf("LED 2 ENCENDIDO\r\n");
bit_set(portb,2);
lcd_gotoxy(1,2);
lcd_putc("LED 2 ENCENDIDO ");
tecla = 0xff;
}

if(tecla=='3'){
printf("LED 3 ENCENDIDO\r\n");
bit_set(portb,1);
lcd_gotoxy(1,2);
lcd_putc("LED 3 ENCENDIDO ");
tecla = 0xff;
}

if(tecla=='4'){
printf("LED 4 ENCENDIDO\r\n");
bit_set(portb,0);
lcd_gotoxy(1,2);
lcd_putc("LED 4 ENCENDIDO ");
tecla = 0xff;
}

if(tecla=='0'){
printf("DESACTIVAR LEDS\r\n");
portb=0b00000000;
lcd_gotoxy(1,2);
lcd_putc("DESACTIVAR LEDS ");
tecla = 0xff;
} 

if(tecla=='5') {
If(Bit_test(PORTB, 6) == 1) {
printf("PULSADOR 1: ON\r\n");
lcd_gotoxy(1,2);
lcd_putc("PULSADOR 1: ON ");
}
Else {
printf("PULSADOR 1: OFF\r\n");
lcd_gotoxy(1,2);
lcd_putc("PULSADOR 1: OFF ");
}
tecla = 0xff;
} 
if(tecla=='6') {
If(Bit_test(PORTB, 7) == 1) {
printf("PULSADOR 2: ON\r\n");
lcd_gotoxy(1,2);
lcd_putc("PULSADOR 2: ON ");
}
Else {
printf("PULSADOR 2: OFF\r\n");
lcd_gotoxy(1,2);
lcd_putc("PULSADOR 2: OFF ");
}
tecla = 0xff;
} 
}
 
}
---------- Actualizado después de 1 hora ----------

Amigos, muchas gracias por todo. Aprendí muchísimo por aquí, volveré.
Los felicito porque saben mucho de programación, ya me funcionó perfecto el circuito.
Para que los leds me encendieran, le escribí esta instrucción: output_high(pin_b1); y funcionaron perfecto.

De verdad que súper agradecido!!
 
Última edición por un moderador:
#14
Debes poner bien la dirección del puerto B.

Yo diría que probaras con usar:
output_high(pin_b1); Para prender un bit en el puerto B.

Y para apagar:
output_low(pin_b1); Para apagar el bit.
 
Última edición por un moderador:
#15
Tienes mal la dirección del registro TRISB del puerto B, cámbiala, porque aunque funcione esta mal y afea el código.

#byte portb =0x06
#byte trisb = 0x086 //0b11000000
 
#16
Perfecto dogflu66 muchas gracias, ya mismo le hago la corrección. Gracias por todo

Debes poner bien la dirección del puerto B.

Yo diría que probaras con usar:
output_high(pin_b1); Para prender un bit en el puerto B.

Y para apagar:
output_low(pin_b1); Para apagar el bit.
Súper bien TRILO-BYTE con ese comando me funciona perfecto! Gracias!
 
#17
si estabien que uses la directiva propia del CCS

eso lo puedes checar en el index del CCS ahi viene mucha ayuda de pardte del compilador

y tambien esta mal

pues te haces dependiente del CCS y al migrar a otro compilador te generara dudas pero si se trata de hacer algunos proyectos pequeños esta bien que lo uses
 
#19
¿5 de 5 o 5 de 10?

una vez hise un compilador grafico y pude leer el ADC a nivel byte de un freescale KWISTICK por que el code warrior 10.5 estaba limitado con la licencia.

y me reprobaron por ayudar a un compañero con un proyecto aveces la vida es injusta pero bueno
 
Arriba