miércoles, 8 de junio de 2011

Programacion de microcontrolador PIC 16F877A en lenguaje C

Aqui dejo mis codigos para programar PICs, empezando con un programa bastante sencillo, y complicandose todo esto comentado, explicado.
Todo esto en el compilador PICCompiler, si no lo tienes descargalo e instalalo.
la instalacion es recontra simple, instala todo los instaladores si, next, next y listo ni necesita crakear. Puedes utilizar el Proteus para simular los programas.




Antes que se pierda en mi biblioteca universitaria lo dejo para el provecho de todos los interesados.

/**************PROGRAMA 1, DE ESTA ENTREGA***************************
//Modelo Básico funcion correr Led//****************///-__-
#include <16f877a.h>
#fuses NOPROTECT,NOWDT,HS,NOLVP //codigo para quemado
#use delay(clock=10000000) //de acuerdo al crystal
#define tiempo 100   //Defino mi variable tiempo=100
//declaracion de puertos y bits -hacerlo siempre-
#byte PORTA=0x05
#Byte TRISA=0x85
#byte PORTB=0X06
#Byte TRISB=0x86
#byte PORTD=0X08
#Byte TRISD=0x88
#bit Entrada=PORTB.0
//inicializacion de variables
void MCU_Init(){
PORTD=0x00;    //para asegurarnos q D, estará en 0 al inicio
TRISD=0x00;   //PORTD salida
PORTB=0x00;   //para asegurarnos q D, estará en 0 al inicio
TRISB=0xFF;   //PORTB entrada
}
//Tarea que va ha realizar mi programa
void Task_Led_Run(){  //creamos una funcio para correr leds
   int8 i;
if(Entrada){
   PORTD=0x01;
   delay_ms(tiempo);
      for (i=1;i<=7;++i){
      PORTD=PORTD*2;
      delay_ms(tiempo);
      }    
}
else{   PORTD=128;
      delay_ms(tiempo);
      for (i=1;i<=7;++i){
      PORTD=PORTD/2;
      delay_ms(tiempo);
      }
      }
}
//Programa proncipal
void main()
{
MCU_Init();  //inicializamos
while(1)
{
Task_Led_Run(); //llamamos a la funcion
}
}


/**************PROGRAMA 2, DE ESTA ENTREGA***************************
//Modelo para trabajar con Interrupciones//*********************///-_-
#include <16f877a.h>
#fuses NOPROTECT,NOWDT,HS,NOLVP //Para quemado
#use delay(clock=10000000)
#define Tiempo 100
//declaracion de puertos y bits -hacerlo siempre-
#byte PORTA=0x05
#Byte TRISA=0x85
#byte PORTB=0X06
#Byte TRISB=0x86
#byte PORTD=0x08
#Byte TRISD=0x88
#byte INTCON=0x0B
#bit Entrada=PORTB.1
#bit RB7=PORTB.7
//Interrupciones RB0 RB WDT
#INT_EXT
void irb0_handler() {
//cuando se da la iterrupcion, guardamos lo de D, atendemos
//la interrupcion, y luego devolvemos a D los valores iniciales
   int8 Temporal;
   Temporal=PORTD;
   PORTD=0xFF;
   delay_ms(2*Tiempo);
   PORTD=Temporal;
   }
#INT_RB
void irb47_handler() {
   int8 Temporal;
   //Temporal=PORTB;
   if(RB7==1){
   Temporal=PORTD;
   PORTD=0x0F;
   delay_ms(1000);
   PORTD=Temporal;
   }
}

/**************PROGRAMA 3, DE ESTA ENTREGA***************************
//Modelo para trabajar con entradas Analógicas//////**/-*-//////////
#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#device adc=8
#use delay(clock=10000000)
//#use rs232(baud=19200,xmit=PIN_C6, rcv=PIN_C7)
#include "lcdJuan.c"
#define Tiempo 100
// Declaración de puertos y bits:
#byte PORTA=0x05
#byte TRISA=0x85
#byte PORTB=0x06
#byte TRISB=0x86
#byte PORTC=0x07
#byte TRISC=0x87
#byte PORTD=0x08
#byte TRISD=0x88
#byte INTCON=0x8B
#bit Entrada = PORTB.1
#bit Conf_Entrada = TRISB.1
#bit Flanco_externa = 0x81.6
#bit RB7 = PORTB.7
unsigned long  AD_read=0;
void AD_Init(){
   TRISA=0x0F;
   setup_adc(ADC_CLOCK_DIV_32);
   setup_adc_ports(AN0);
}
void Port_Init(){
   PORTD=0x00;
   TRISD=0x00;
   PORTC=0x00;
   TRISC=0x00;
   PORTB=0x00;
   TRISB=0x00;
   Conf_Entrada=0;
}
void MCU_Init(){
   Port_Init();
   lcd_init();
   AD_Init();
 }
void Task_AD_Run(){
   float k;
   AD_read=read_adc();
   PORTB=AD_read;
   k=AD_read*5.0/255;
   //lcd_gotoxy(1,2);
   printf(lcd_putc,"\fValor: %lu   ",AD_read);
   //printf("\r\n: %lu   ",AD_read);
   printf(LCD_PUTC, "\nAN4=%01.2fv",k);
   //delay_ms(10);
}

void presentacion(){
   printf(lcd_putc,"   CONVERSION\n");
   printf(lcd_putc,"       AD");
   //printf("Vamos a ver este dato por el puerto serie"); //para verlo por el serial
   delay_ms(1000);
   printf(LCD_PUTC, "\f");  
}
void main(void){
   MCU_Init();
   presentacion();
   while (TRUE){
      Task_AD_Run();
   }
}

/**************PROGRAMA 4, DE ESTA ENTREGA***************************
//Modelo como trabajar con el serial*****/*_*////////////
#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#device adc=8
#use delay(clock=20000000)
#use rs232(baud=19200,xmit=PIN_C6, rcv=PIN_C7)
#include "lcd.c"
#define Tiempo 100
// Declaración de puertos y bits:
#byte PORTA=0x05
#byte TRISA=0x85
#byte PORTB=0x06
#byte TRISB=0x86
#byte PORTC=0x07
#byte TRISC=0x87
#byte PORTD=0x08
#byte TRISD=0x88
#byte INTCON=0x8B
#bit Entrada = PORTB.1
#bit Conf_Entrada = TRISB.1
#bit Flanco_externa = 0x81.6
#bit RB7 = PORTB.7
unsigned long  AD_read=0;
void AD_Init(){
   TRISA=0x0F;
   setup_adc(ADC_CLOCK_DIV_32);
   setup_adc_ports(AN0);
}
void Port_Init(){
   PORTD=0x00;
   TRISD=0x00;
   PORTC=0x00;
   TRISC=0x00;
   PORTB=0x00;
   TRISB=0x00;
   Conf_Entrada=0;
}
void MCU_Init(){
   Port_Init();
   lcd_init();
   AD_Init();
 }
void Task_AD_Run(){
   AD_read=read_adc();
   PORTB=AD_read;
   lcd_gotoxy(1,2);
   printf(lcd_putc,"Valor: %lu   ",AD_read);
   printf("\r\n: %lu   ",AD_read);
   delay_ms(10);
}

void presentacion(){
   printf(lcd_putc,"   CONVERSION\n");
   printf(lcd_putc,"       AD");
   printf("Vamos a ver este dato por el puerto serie"); //para verlo por el serial
   delay_ms(1000);
}
void main(void){
   MCU_Init();
   presentacion();
   while (TRUE){
      Task_AD_Run();
   }
}


/**************PROGRAMA 5, DE ESTA ENTREGA**********ESTA CHEVRE**************
//Modelo Serial-Analogico, etc...no olvidar incluir el archivo lcd
#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#device adc=8            //cantidad de bits utilizados para la division, debe ser 8 o 10 bits
#use delay(clock=10000000)
#use rs232(baud=19200,xmit=PIN_C6, rcv=PIN_C7)
#include "lcd.c"
#define Tiempo 100
//************************Declaración de puertos y bits:************************
#byte PORTA=0x05
#byte TRISA=0x85
#byte PORTB=0x06
#byte TRISB=0x86
#byte PORTC=0x07
#byte TRISC=0x87
#byte PORTD=0x08
#bit RPEIE=0x0B.6
#byte TRISD=0x88
#byte ADECON0=0x1F
#byte ADECON1=0x9F
#byte INTCON=0x8B
#bit Entrada = PORTB.1
#bit Conf_Entrada = TRISB.1
#bit Flanco_externa=0x181.6
//#bit Flanco_externa = 0x81.6
#bit RB7 = PORTB.7
int i=0;
int j=0;
int n=0;
unsigned long  AD_read=0;   //lectura de AD definirlo de este tipo si se quiere q sea para leer dato
//********************************DECLARACION DE LAS FUNCIONES*********************
void presentacion();
void Port_Init();
void AD_Init();
void MCU_Init();
void Task_AD_Run1();
void Task_AD_Run2();
void Task_AD_Run1a();
void Task_AD_Run2a();
void Task_Seria_opc();

//******************************************************************************\\
//******************************************************************************\\
//************************************PROGRAMA PRINCIPAL************************\\
void main(void){
   MCU_Init();
   presentacion(); delay_ms(1000);
   while (1){
   if(i==0&&j==1){
      Task_AD_Run1();}
   if(i==1&&j==1) {Task_AD_Run2();}
   }
}
//******************************************************************************\\
//******************************************************************************\\
//******************************************************************************\\

//*******************************DESARROLLO DE FUNCIONES***************************
void presentacion(){
   printf(lcd_putc,"   CONVERSION\n");
   printf(lcd_putc,"       AD");
   printf("Camarena Quinto Juan Elmer"); //para verlo por el serial
   //delay_ms(1000);
   printf("\f");
}
void Port_Init(){
   PORTD=0x00;
   TRISD=0x00;
   PORTC=0x00;
   TRISC=0x80;
   PORTB=0x00;
   TRISB=0xff;
   Conf_Entrada=0;
}
void AD_Init(){
   TRISA=0xFF;
   //ADECON0=0x20;  // el canal es AN4 -CHANEL 4-
   //ADECON0=0x00;  // el canal es AN4 -CHANEL 0-
   //ADECON0=0x08;  // el canal es AN1 -CHANEL 1-
   //ADECON0=0x2D;  // el canal es AN5 -CHANEL 5-   //*** No olvidar ADON=1 ***/
                   // 0x28+1:habilitar AD + 100:GO/DONE en progreso, pero funca si=0 osea *0x28*
   ADECON0=0xA5;      //divison DIV_32(1000x0) + ADECON0=0x2D canal 5
   //ADECON1=0x02;      //todas las entradas ANALOGICAS excepto AN5 AN6 AN7
   ADECON1=0x00;      //todas las entradas ANALOGICAS
   //setup_adc(ADC_CLOCK_DIV_32);   //la div_32 combierte l + rapido posible
   //****setup_adc_ports(ALL_ANALOG);         //habilitamos todos los canales
   //****set_adc_channel(5);                  //elegimos CANAL 5
   //ADECON0=0x08;                 
}
void MCU_Init(){
   Port_Init();
   lcd_init();
   AD_Init();
   //INTCON=0x90;  //habilitamos las interrupciones
   enable_interrupts(GLOBAL);
   //enable_interrupts(INT_EXT);
   enable_interrupts(INT_RDA);
   RPEIE=1;
   Flanco_externa=0;
 }
void Task_AD_Run1(){
   float k;
  ADECON0=0x85;
  ADECON1=0x00;
   AD_read=read_adc(adc_start_and_read);
   //PORTB=AD_read;
   k=AD_read*5.0/255;
   //lcd_gotoxy(1,2);
   //printf(lcd_putc,"\fValor: %lu   ",AD_read);
   printf(LCD_PUTC, "\fEntrada:0");
   printf(LCD_PUTC, "\nAN0=%01.2fv",k); 
   delay_ms(20);
}
void Task_AD_Run1a(){
   unsigned long q=0;
   float p;
  ADECON0=0xA5;
  ADECON1=0x00;
   q=read_adc();     //lectura del canal elegido, en este caso el CHANNEL 0
   printf(lcd_putc,"AN1= %lu   ",q);
   ////////////////////////
}

void Task_AD_Run2a(){
   unsigned long q=0;
   float p;
  ADECON0=0xAD;
  ADECON1=0x00;
   q=read_adc();     //lectura del canal elegido, en este caso el CHANNEL 0
   printf(lcd_putc,"AN1= %lu   ",q);
   ////////////////////////
}
void Task_AD_Run2(){
   float p;
  ADECON0=0x8D;
  ADECON1=0x00;
   AD_read=read_adc(adc_start_and_read);
   //PORTB=AD_read;
   p=AD_read*5.0/255;
   //lcd_gotoxy(1,2);
   //printf(lcd_putc,"\fValor: %lu   ",AD_read);
   printf(LCD_PUTC, "\fEntrada:1");
   printf(LCD_PUTC, "\nAN1=%01.2fv",p); 
   delay_ms(20);
}


//void Task_Serial0();
//void Task_Serial1();

//***************************DESARROLLO DE LAS INTERRUPCIONES***********************
#INT_RDA
void rda_handler(void){
//char comando;
//char comando2;
//comando=getc();
//printf("A= %c",comando);
Task_Seria_opc();
}
void Task_Seria_opc(){
char comando;
comando=getc();
if(comando=='0'&&j==1)
{printf("\f"); i=0;printf("A= %c",comando);}
if(comando=='1'&&j==1)
{printf("\f"); i=1;printf("A= %c",comando);}
if(comando=='s')
{printf(" x       v "); j=1; printf("siga %c",comando);}
if(comando=='d')
{printf("\f"); j=0; printf("Detengase %c",comando);}
//if(comando=='A')
//{void Task_AD_Run1(); delay_ms(2000); printf("se llego-0"); i=1;}
}



Bueno, tengo más cada vez mas complicados pero esto es todo por ahora.
En cuanto al quemado (PIC 16F877A), mi modulo es el del Pickit de Microchip.
Similar al que muestro:

Todo esto en mi entrenador, luego coloco el circuito losta para hacer la placa (del entrenador), espero les sirva cualquier cosa comenten y lo pongo.

3 comentarios:

  1. hola amigo oye como puedo hacer un programa en el que le pueda cargar un programa de corrimiento de leds y y otro de adentro hacia afuera y cargarlos en el pic como uno solo y a traves de un push botón poder cambiar a uno u otro de los dos. espero y e puedas ayudar gracias

    ResponderEliminar
  2. Juan, un gusto saludarte, me encuentro realizando un proyecto con motor PAP y el pic 16f877a (simular un ascensor), tendras algun programa guia que me puedas recomendar.

    ResponderEliminar
  3. Best Casino Slots Real Money - Mapyro
    Find the best casino 충청북도 출장안마 slots free play 안성 출장마사지 anywhere in 삼척 출장안마 New Jersey. 강릉 출장마사지 It offers a 100% bonus match 의정부 출장샵 up to $2000 and 1st Deposit Bonus.

    ResponderEliminar