Curso de programación en C para microcontroladores PIC

lo brackets los uso solamente cuando es mas de una instruccion
para for o while, igual los puede poner no hace diferencia.
Dime si entendi bien, Tu quieres que la interrupcion este
habilitada solo cuando PIN_B2 = 0, que supongo es un push button.
la interrupcion entra solo cuando el PIN_B0 va de 0 a 1, que es otro push button.
y un LED parpadea controlado por el PIN_B7
el board tu lo hiciste?
:)


en pin_b2 tiene conectado un interruptor normal y el pin_b0 es en verdad un sensor con salida de frecuencia mas adelante voy agregarle cosas a la rutina para que me guarde la cuenta de los pulsos en una variable, del resto todo esta bien como lo entendiste. no lo he probado en board solo en ISIS mañana voy a montarlo ya hice el programa completo lo unico malo es que se me vuela un pulso que no se de donde sale.
cuando lo monte te digo a ver si pasa lo mismo fisicamente
 
Por favor ayudenme con este codigo

Código:
#include <pic.h>
#include "delay.c"
#include "delay.h"

const unsigned char display[]={0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6f};

void main (void)
{
	unsigned char i;

	for(i=0;i<=9;i++)
	{
		
		mostrar(i);
		retardos(1000);
	
	}
}

void mostrar(unsigned char i)
{
	PortB=display[i];
}

void retardos(unsigned char time)
{
	unsigned char k;
	
	do{
		k++;
		DelayMs(250);
		DelayMs(250);
		DelayMs(250);
		DelayMs(250);
	}while(k < time);
}

Cuando lo compilo en MPLAB con Hitech C Compiller me sale error:

Código:
Executing: "C:\HT-PIC\bin\picc.exe" -C -E"Display_Directo.cce" "Display_Directo.c" -O"Display_Directo.obj" -Zg9 -O -ASMLIST -Q -MPLAB -16F877A
Halting build on first failure as requested.
BUILD FAILED: Fri Mar 04 17:42:30 2011
 
Hola, no entiendo como configuarar el oscilador interno en ccs se hace con #byte osccon=0x8F o con setup_oscillator(OSC_32MHZ); o #OCS 20 MHz, ¿Cual de estas es la correcta?, espero que me puedan ayudar.
 
#fuses INTRC,NOWDT,NOCPD,PROTECT,NOMCLR,NOPUT

este ejemplo sirve para 12f629 y 16f628.

INTRC, define oscilador interno
XT, cristal externo
Usa el tutorial del CCS para mas informacion
:apreton:
 
buena soy alumno del 5 semestre de electronica de la unefa venezuela creo q tener la solucion a tu problema en vez de colocarle if utiliza lo siguiente


while(input(pin_a0)){
contador++;

}
utiliza el while, este while indica que mientras tengas una entrada por el pin_a0 ba a pasar la condicion que coloques de hay hacia abajo, yo hice uno que contara hasta 9 y volviera a empezar de 0 a medida q fuera pulsando.

te comento que tambien tiene q ver el tipo de display que uses si es anodo comun es decir positivo comun como es en mi caso tienes que entonces negar esa entrada ya que la configuracion de ese display es 1 para obtener el numero que deseas debes apagar los bits que no deseas usar... para negar dicha entrada solo se agrega un sigo de exclamacion

while(!input(pin_a0)){
contador++;

}

este signo solo dice que mientras que no haiga una entrada por ese pin_a0 sucedera la condicion que coloques dentro de las llaves

cualquier duda pues abisarme y te envio el programa y el proteus ya listo para que verifiques y te oritentes espero te sirva de algo
 
Hola estoy tratando de saber como utilizar las interrupciones externas y lo flancos pero cuando compilo dise que las #INT_EXT1 E #INT_EXT2 son invalidas las disrectivas anexo mi codigo para que me puedan ayudar.

PHP:
#include <16F648A.H>      //Libreria del PIC Implementado.
#fuses HS, NOWDT, NOLVP, PUT, MCLR   //Osclador Externo, Deshabilita el Doggy.
#use delay( clock = 20M )   //Frecuencia de Reloj.
#byte port_B = 0x06      //Direccion del Puerto B.
#bit CERO = 0x06.4        //Variable en RB4.
#bit UNO = 0x06.5        //Variable en RB5.
#bit DOS = 0x06.6        //Variable en RB6.

//RB7   RB6   RB5   RB4   RB3   RB2   RB1   RB0

#INT_EXT               //Interrupcion Externa0.
void isr( void )
   {
      CERO = 1;//output_high( PIN_B4 );      //RB4 en Alto.
      delay_ms( 500 );            //Espera 500mseg.
      CERO = 0;//ouput_low( PIN_B4 );        //RB4 en Bajo.
   }
   
#INT_EXT1
void isr1( void )
   {
      UNO = 1;//output_high( PIN_B5 );      //RB5 en Alto.
      delay_ms( 500 );            //Espera 500mseg.
      UNO = 0;//ouput_low( PIN_B5 );        //RB5 en Bajo.
   }
   
#INT_EXT2
void isr2( void )
   {
      DOS = 1;//output_high( PIN_B6 );      //RB6 en Alto.
      delay_ms( 500 );            //Espera 500mseg.
      DOS = 0;//ouput_low( PIN_B6 );        //RB6 en Bajo.
   }
   
void main( void )
   {
      set_tris_B( 0x00 );   //Puerto B como Salida.
      port_B = 0x00;      //Inicializa el Puerto B.
      
      ext_int_edge( 0, L_TO_H );   //Interrupcion 0 por Flanco de Subida.
      ext_int_edge( 1, L_TO_H );   //Interrupcion 1 por Flanco de Subida.
      ext_int_edge( 2, L_TO_H );   //Interrupcion 2 por Flanco de Subida.
      
      enable_interrupts( INT_EXT );   //Habilita la Interrupcion Externa0.
      enable_interrupts( INT_EXT1 );   //Habilita la Interrupcion Externa1.
      enable_interrupts( INT_EXT2 );   //Habilita la Interrupcion Externa2.
      enable_interrupts( GLOBAL );   //Habilita la Interrupcion Global.
      
      while( 1 )
         {
         }
   }
 
Última edición por un moderador:
Hola presento una inquietud ya que este tuturia es para programar microcontroladores en C
Sucede que en mi universida nos enseñan C con el programa Codeblocks (que aparte es gratuito) que aqui ni lo mencionan, me serviria para programar un microcontrolador ese programa? Que referencias tienen de ese programa? Es como para saber donde estoy parado
 
Hola presento una inquietud ya que este tuturia es para programar microcontroladores en C
Sucede que en mi universida nos enseñan C con el programa Codeblocks (que aparte es gratuito) que aqui ni lo mencionan, me serviria para programar un microcontrolador ese programa? Que referencias tienen de ese programa? Es como para saber donde estoy parado

hola como estas mira el c con el cual se programa en codeblocks o en devc es exactamente el mismo. cambian algunas cosas como algunas rutinas que se le agregan para manejar puertos interrupciones etc pero si sabes codeblocks ccs no va a ser ningún problema es mas a continuación te voy a pasar un pdf muy bueno cuando lo leas veras que es lo mismo que ya sabes
 

Adjuntos

  • Microcontroladores y lenguaje C.pdf
    1.8 MB · Visitas: 567
Hola presento una inquietud ya que este tuturia es para programar microcontroladores en C
Sucede que en mi universida nos enseñan C con el programa Codeblocks (que aparte es gratuito) que aqui ni lo mencionan, me serviria para programar un microcontrolador ese programa? Que referencias tienen de ese programa? Es como para saber donde estoy parado

Hi Javier,

La mayoria de los microcontroladores actuales acepta lenguaje ANSI C,
esto facilita la migracion de las aplicaciones de un microcontrolador a otro.
Pero depende del micro que quieras utilizar y de tu aplicacion.

:)
 
Estaran de acuerdo conmigo, que es el mejor foro sobre temas de electrónica y micros
Creo que a todos quienes estamos aqui inscritos, nos sirve siempre que que lo necesitamos.
Un saludo a los moderadores:aplauso: ya a todos los miembros del mismo..:apreton:
 
Hola a todos,

Me ha surgido una duda en cuanto al lenguaje C. Pongo mi duda aquí porquéno sé dónde ponerla. Es la siguiente:

- Tengo entendido que utilizar variables globales puede dar problemas, por qué?

Saludos!
 
no es que den problemas es que hay que saberlas utilizar, mas bien tener mucho cuidado de cuando vas a hacer los cambios. voy a buscar un fragmento del Deitel donde habla de esto y te lo coloco
 
No genera problemas... simplemente hay que saberlas usar....

Recuerda que un PIC no es un procesador grande y tiene los recursos muy limitados, las variables globales nunca pierden su valor ya que deben ser accesibles desde cualquier parte del programa, esto obliga al compilador a reservar una localidad de memoria (y hasta 4 si la declaras flotante) por cada variable global que uses, asi que la memoria se agotaria pronto

En cambio si las declaras locales, la variable se destruye al salir de la subrutina, por lo tanto el compilador puede reusar la RAM y meter mas variables en una sola localidad....
 
ola como estan veo que les gusta programar en C y quisiera su opinion yo estoy realiando una tesis profesional y tengo algunos ejemplos sobre C y quisiera q alguine mas me diera su opinion de que tan buenos son los adjunto todos los codigos y simulaciones para el circuito armado espero sus comentarios y ademas en youtube pueden buscar videos de multiyack y ai estan ya fisicamente dejen comentarios para mejorarlos gracias mas adelante espero poder subir el manual de CCS que estoy armando coomo parte de lo mismo

Gracias, ahora me voy a poner a estudiar la programación en C.

Pregunta:

¿El lenguaje C es indistinto al compilador usado? Me pregunto si un código hecho en C puede ser compilado en C18 y en CCS sin problemas, o cada uno tiene sus cosas diferentes.

Gracias por la atención.
 
hola saludos alguien me puede ayudar con un programa de interrupcion externa en el pic 18f4550 el programa lo quisiera en CSS Compiler.???
quiero hacer un contador del 0 al 99. quiero que se active un numero ala ves por cada interrupcion.(si le doy un pulso a la interrupcion, que se active un "1" en un display, si doy otro pulso, que se active el siguiente numero "2" y asi susesivamente hasta al 99)

si pudieras aportarme algun ejemplo por lo menos del 1 al cinco...graxiaz
 
int8 contador=0; // variable global

#int_EXT
void EXT_isr(void)
{
contador ++
lcd_init();
lcd_putc('\f');
printf(lcd_putc,"Contador = %u",contador);
}


void main()
{

enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
ext_int_edge(L_TO_H);

while(){
if(contador >= 100){contador = 0;}

}

}

en resumen es algo asi. aunque faltan cosas.
de todos modos te recomiendo un manual que coloque aqui es el comentario 104 leelo con calma.
 
os dejo uno de una termocupla para controlar un horno
controlhorno.png


Código:
/*********************************************************************
**Control analógico de  un horno  de reflujo para soldadura SMD y   **
**BGA, este código está  implementado  para el componente MAX6675 y   **
**un microcontrolador PIC16F876A, utilizando el protocolo SPI por   **
**hardware + la entrada analógica digital del micro, donde conectamos**
**un potenciómetro con el cuál regularemos el ancho de pulso de     **
**una señal en PWM                                                  **
**El autor y propietario del código Thulsa_Doom autoriza su libre   **
**distribución, copia y modificación del mismo siempre y cuando se  **
**mencione al autor                                                      **
**********************************************************************
-------------------------------PATILLAJE-------------------------------------
--PIN-2;A0 = Entrada analógica donde conectamos el potenciómetro           --
--PIN-6;A4 = Donde conectamos el pulsador por medio de resistencias Pull-UP--
--PIN-7;A5 = Señal CS o bit-select hacia el MAX6675 PIN-6                  --
--PIN-13;C2 = Salida de la señal PWM                                       --
--PIN-14;C3 = Salida de reloj para el MAX6675 PIN-5                        --
--PIN-15:C4 = Entrada de dato de temperatura que proviene PIN-7 MAX6675    --
-----------------------------------------------------------------------------
*/

// Declaraciones de Post-Procesado
      #include <16f876a.h>
      #device adc=10
           
      #FUSES xt,nowdt,noprotect
      #USE delay(clock=4000000)

      #define use_portb_lcd TRUE
      #include <LCD.C>
     
      #use standard_io (A)
      #use standard_io (B)
      #use standard_io (C)
      #use SPI(MASTER,FORCE_HW,MODE=0,BITS=16)
     
     

//****************************Definición de pines**********************************
      #define CS PIN_A5
     
//******************************Variables Globales***********************************

long ad,buffer;                 //Variable que proviene del modulo analógico/digital
                                 //con el dato del potenciómetro y lo cargamos la función PWM
int msec=0,sec=0,min=0;
int swicht;
float temperatura=0;






//***************************Interrupciones de los timers**************************

#int_TIMER1
     
   void imprimir_cronometro(){
     set_timer1(55661);
     
       if(swicht==1){   //Si la variable swicht es igual a 1, se ejecuta el cronómetro
         if(msec++>99){       //incrementa el valor de msec y si es mayor a 99
              msec=0;               //pone msec a 0.
          if(sec++>58){       //incrementa el valor de sec y si es mayor de 59
                sec=0;             //ponesec a 0.
           if(min++>60){
                 min=0;
           }
         }
         }
       }
    else{      //Si la variable siwcht no es igual a 1 se pone a 0 mse, sec, min
    msec=0;
    sec=0;
    min=0;
    }
   }

   
//****************************Inicialización**************************************

void inicializar(){           //Ejecutamos una rutina de inicialización para que
                             //los valores se estabilizan antes de mostrarlo en pantalla
  printf(lcd_putc,"\fInicializando\n   Sistema");
  delay_ms(500);
  }

//******************************Subprogramas************************************



     
void leer_termocupula(){
        int16 temp;
        int cadena1,cadena2;  //declaramos las variables donde se guardaran el dato que viene del max6675
                                         //el dato viene en dos paquetes separados de 8 bits, por eso se guardan en dos cadenas                         
        delay_ms(200);
        output_low(CS);               //Se activa la señal de bit_select(CS) a 0 para que el max se active
        cadena1 = spi_read(0);  //Lee el primer byte que viene del max6675
        cadena2 = spi_read(0);  //Lee el segundo byte, con eso ya tenemos los 16bits de la lectura del max7765
        output_high(CS);              //Se pone a 1 la señal de bit_select(CS) para que el max tome otra lectura
       
                 
     //  buffer = ((cadena1 * 256) + cadena2);  //Se unen las dos cadenas de 1 byte que viene del max6675 y se
                                                         //guardan en una variable int16 llamada buffer de 16 bits
           buffer = cadena2; // Cargo Byte LB
*((char *)&buffer+1)=cadena1; // Cargo Byte HB.  y los uno los dos en una palabra de 16 bits que se llama buffer         

                      temp = (buffer & 0b0111111111111000)>>3;    //Seleccionamos los bits que nos interesan haciéndole lo que se llama
                                                           //Una máscara, se le hace un AND al dato con un número en binario, los unos significan los bits que queremos utilizar y los 0 los que desechamos
                                                           //Luego le hacemos un >>3 que significa que rodamos los 1 a la derecha 3 posiciones para eliminar los 0 del final                                                         
          temperatura = (temp * 0.25);  //12 bits en decimal equivalen a 4095, para que de los 1023,75 ºC se tiene que multiplicar por 0.25 que es la resolución de cada bit del MAX6675
         
         
         
}         
 
void modulo_AD(){         //Rutina del módulo analógico digital
          ad = 0;                     //Inicializamos la variable del dato del potenciómetro y la limpiamos para una nueva lectura
       
          delay_us(30);                  //Retraso necesario para la medida
          ad = read_adc();               //Captura del valor transformado a digital que entra por AN0 que viene del valor del potenciómetro
         
}

  float modulacion(float pwm){    //Rutina para la modulación de un pulso
 
    pwm=0;                 //inicializamos la variable
   
    if(swicht==1){
    setup_timer_2(T2_DIV_BY_16,255,1);  //configuración del timer_2 para la señal PWM
    setup_ccp1(CCP_PWM);               //Activamos el CCP ósea PWM por hardware
   
    set_pwm1_duty(ad);               //función donde cambiaremos el ancho del pulso, se cambiará en función del valor de ad que luego se pasa a dato
    pwm=(ad/10.23);                 //al dividir el entero por esto, hacemos que en pantalla aparezca 100.0 cuando la PWM  esté a tope
   }                               
   
    else{                              //Si swicht no es igual a 1
    setup_timer_2(T2_DISABLED,255,1);  //Desactivamos el timer2
    setup_ccp1(CCP_OFF);               //Apagamos el módulo ccp1
  }
    return pwm;
}
       
   
    void pulsador (void){   //Rutina para transformar un pulsador en un pulsador con enclavamiento
    int limite=2;

    if(input(PIN_A4)==0){     //Si la entrada A4 está a 0
    swicht++;                 //Se incrementa la variable swicht
    delay_ms(20);           //Un retraso para evitar rebotes del pulsador
    }
    if(swicht > (limite-1)){   //Si la variable swicht es mayor que límite -1
    swicht = 0;                // se pone la variable swicht a 0
    }
   }
 
   
//******************************Función Principal*********************************
   
main(){
                   
          float pwm,pwm1;            //Variables locales para la señal pwm
         
         
          lcd_init();
          inicializar();  //Llamamos a la función inicializar y ejecutamos el código de la función
                 
      port_b_pullups(TRUE); //Seleccionamos la resistencias de pull-ups internas para el puerto B
     
      setup_spi(SPI_MASTER | SPI_L_TO_H); //   Configuramos el SPI por hardware del micro, sin esto no rula   
                         
     setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);  //Configuración del timer1 para el cronómetro
     set_timer1(55661);  //Carga del buffer del timer1 para que el salto sea a 1 ms
   
     setup_adc_ports(AN0);          //Seleccionamos que pin estará tomando las muestras
     setup_adc(ADC_CLOCK_INTERNAL); //Configuración del módulo A/D por hardware
     set_adc_channel(0);            //Canal del micro o pin de entrada en el micro para la conversión A/D
     
     enable_interrupts(INT_TIMER1); //Activamos las interrupciones del timer1
     enable_interrupts(global);   //Activamos las interrupciones globales
           
     do{
         
           leer_termocupula();   //Llamamos al la rutina para leer la temperatura
           pulsador();    //Llamamos a la función pulsador
           
           termocupula_error = (buffer & 0b0000000000000100)>>2; //Seleccionamos el bit D2, nos indica si el termopar está
                                                                         //conectado o no                                                                     
          if(bit_test(buffer,2)){ // Si el bit D2 es igual a 1, se ejecutan las sentencias siguientes             
              lcd_putc('\f');  //Limpiamos la pantalla LCD
              lcd_gotoxy(5,1); //Posición del LCD para imprimir el siguiente comando
              printf(lcd_putc,"Termopar"); //Se muestra en pantalla que el termopar está desconectado
              lcd_gotoxy(3,2);
              printf(lcd_putc,"Desconectado"); //Se muestra en pantalla, en la posición 3,2
               
                setup_timer_2(T2_DISABLED,255,1);  //Desactivamos el timer2
                setup_ccp1(CCP_OFF);               //Apagamos el módulo ccp1
                 }
                else{                 // si no está pulsado - modulamos la señal PWM, medimos le resistencia del potenciómetro y medimos temperatura
                   pwm1 = modulacion(pwm);     //Llamamos a la rutina de PWM y guardamos el dato en pwm1
                   modulo_AD();                //Llamamos a la rutina de modulación A/D para capturar el valor del potenciómetro
                   lcd_putc('\f');             //Limpiamos la pantalla LCD para una nueva escritura
                   lcd_gotoxy(1,1);                           
                    printf(lcd_putc,"Temp=%f C",temperatura); //mostramos en pantalla la temperatura en la posición 1,1
               
                    if(swicht==1){                          //Si el pulsador está activado
                       
                       lcd_gotoxy(1,2);                      //Designamos la posición en el display     
                       printf(lcd_putc,"%02u:%02u",min,sec);//y mostramos el tiempo
                       lcd_gotoxy(6,2);                      //Designamos la posición del valor PWM
                       printf(lcd_putc,"  PWM=%3.1f",pwm1);//mostramos en pantalla el valor de la señal PWM
                       }
                       else{                           //Si NO
                         lcd_gotoxy(1,2);             //designamos la posición en pantalla
                         printf(lcd_putc,"TimeStop");     //mostramos stop, y paramos el tempo
                         lcd_gotoxy(9,2);
                         printf(lcd_putc," PwmStop");      //así como paramos la PWM
                         }
            }             
       }
      while(TRUE);
}
 
Última edición por un moderador:
Hola
Estoy tratando de hacer un programa que me controle 5 leds con un pic12629 y con un push button cambien entre distintas secuencias cada que sea pulsado, el problema es que lo compilo y no me manda ningun error pero al probar en el protoboard no funciona, no hace nada, este es mi programita; ojala y alguien me pudiera decir en que estoy mal gracias


Código:
#include <luces 2.h>
#int_EXT

int boton=0;
void  EXT_isr(void) 
{
  If (!input (PIN_A3))          // Si la entrada es 0
      {  delay_ms(20);             // esperamos 20 ms
      If (!input (PIN_A3))       // comprobamos otra vez la entrada sea 0, por temas de rebote
         {  boton++;
            if(boton>3)
            {
            boton=0;
            }
         }
      }
  return;
}


void main()
{
   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);

   while(TRUE)
   {
    switch(boton)
    {
    case 0: sleep();
            break;
    case 1: int x;
            for(x=0;x<5;x++)
            {
            output_high(PIN_A0);
            output_high(PIN_A1);
            delay_ms(60);
            output_low(PIN_A0);
            output_low(PIN_A1);
            delay_ms(60);
            }
            delay_ms(50);
            output_high(PIN_A2);
            delay_ms(150);
            output_low(PIN_A2);
            int n;
            for(n=0;n<5;n++)
            {
            output_high(PIN_A4);
            output_high(PIN_A5);
            delay_ms(60);
            output_low(PIN_A4);
            output_low(PIN_A5);
            delay_ms(60);
            }
            delay_ms(50);
            output_high(PIN_A2);
            delay_ms(150);
            output_low(PIN_A2);
    case 2: int j;
            for(j=0;j<2;j++)
            {
            output_high(PIN_A0);
            output_high(PIN_A1);
            delay_ms(120);
            output_low(PIN_A0);
            output_low(PIN_A1);
            delay_ms(120);
            }
            delay_ms(50);
            output_high(PIN_A2);
            delay_ms(120);
            output_low(PIN_A2);
            delay_ms(50);
            output_high(PIN_A2);
            delay_ms(120);
            output_low(PIN_A2);
            int k;
            for(k=0;k<2;k++)
            {
            output_high(PIN_A4);
            output_high(PIN_A5);
            delay_ms(120);
            output_low(PIN_A4);
            output_low(PIN_A5);
            delay_ms(120);
            }
            delay_ms(50);
            output_high(PIN_A2);
            delay_ms(120);
            output_low(PIN_A2);
            delay_ms(50);
            output_high(PIN_A2);
            delay_ms(120);
            output_low(PIN_A2);        
    case 3: output_high(PIN_A0);
            output_high(PIN_A1);
            delay_ms(600);
            output_low(PIN_A0);
            output_low(PIN_A1);
            delay_ms(50);
            output_high(PIN_A2);
            delay_ms(120);
            output_low(PIN_A2);
            delay_ms(50);
            output_high(PIN_A2);
            delay_ms(120);
            output_low(PIN_A2);
            output_high(PIN_A4);
            output_high(PIN_A5);
            delay_ms(600);
            output_low(PIN_A4);
            output_low(PIN_A5);
            delay_ms(50);
            output_high(PIN_A2);
            delay_ms(100);
            output_low(PIN_A2);
            delay_ms(50);
            output_high(PIN_A2);
            delay_ms(100);
            output_low(PIN_A2);
            
    }
    
   }

}
 
Última edición por un moderador:
Atrás
Arriba