Programación con MikroC

y si pruebas precargando el registro del TMR0:

void interrupt(){
PORTB.B0 = !PORTB.B0;
INTCON.T0IF = 0; //flag de interrupcion del timer0 puesto en 0
TMR0=255; ' donde 255 es la precarga del timer con el valor que desees
return;
}
 
Última edición:
y antes de salir de la interrupcion no tenes que volver a habilitar las interrupciones globales ? yo uso el CCS las habilita automaticamente pero como te decia,, en assembler habia que habilitarlas por software antes de salir de la interrupcion
en MicroC desconozco si se habilitan automaticamente podrias averiguar eso a ver si te resulta
 
cada vez que se interrumpe lo que se tenga que interrumpir

antes de salir de la funcion hay que limpiar la bandera de dicha interrupcion , la global simepre estara habilitada simpre y cuando uno la deshabilite ;)

tambien lo de precargar nuevamente el timer es cierto puede estar antes o despues de la limpieza del flag de la interrupcion
 
Gracias a todos por los comentarios, logre solucionarlo mirando algunos ejemplos que incluye el IDE, resulta que no estaba funcionando debido a que el pin que estaba utilizando no lo configure como digital:

Código:
void interrupt(){
PORTB = !PORTB;
INTCON.T0IF = 0;               //flag de interrupcion del timer0 puesto en 0
return;
}

void main() {
OPTION_REG = 0b00000111;      //reloj interno (fosc/4);  prescalador al Timer0; prescalador en 256
  

ANSELH = 0;
  
TRISB = 0x00;                  //todos los pines del puerto B como salida
PORTB = 0;                     //todos los pines del puerto B en 0
INTCON = 0b10100000;           //habilito interrupcion del timer0

OSCCON.IRCF2= 1;               //configuracion del oscilador interno a 8Mhz
OSCCON.IRCF1= 1;               //
OSCCON.IRCF0= 1;               //
OSCCON.SCS = 1;                //fuente de clock interno
while(1)
{
}
}

Me faltaba " ANSELH = 0; ".
También me di cuenta que el debbuger no me refresca el registro TMR0 (desconozco si omití alguna configuración en particular). Para probarlo use Proteus, con lo cual también me di cuenta que la configuración de clock de 8Mhz que le había indicado cuando cree el proyecto la omitió, lo tuve que configurar con el registro OSCCON (sino usaba los 4Mhz que vendria configurado por default).
La verdad que no tengo idea de como afecta ANSEL al funcionamiento de este problema.
 
Última edición:
Hola, les les envio codigo para micros de 8 bit para pasar un numero binario de 32 bit a BCD, el resultado son 10 digitos, el codigo original esta escrito en C mikroelectronica para un micro ATMEGA16, el codigo puede ser usado en un PIC o cualquier otro micro, el metodo de conversion es el de desplazar bit comparar si el numero es mayor de 5 y sumar tres.
Estoy por armar un sintonizador digital en donde el valor de frecuencia es un numero muy grande de manejar.


Código:
unsigned char numero_bcd[10]={0,0,0,0,0,0,0,0,0,0};

void binbcd_8(unsigned char valor)
{
 //   el valor de entrada es un unsigned char
 //   el valor de salida BCD queda almacenado en numero_bcd
 //   numero_bcd[2] = centenas - numero_bcd[1] = decenas -  numero_bcd[0] = unidades
 //   conversion de 0xFF  871 ciclos de maquina, 0x00 842 ciclos de maquina
 //
 
 
             int i;
             
             for(i=0;i<=2;i++)              // limpio los valores de salida
                    numero_bcd[i]=0;

             for(i=1;i<=8;i++)
             {

                if(numero_bcd[1]>4)
                         numero_bcd[1]= numero_bcd[1]+3;
                numero_bcd[2]=numero_bcd[2]<<1;           //digito 2
                if((numero_bcd[1]|0b11110111)==0xFF)
                         numero_bcd[2]=numero_bcd[2]|0b00000001;
                else
                         numero_bcd[2]=numero_bcd[2]&0b11111110;
                numero_bcd[2]=numero_bcd[2]&0x0F;



                if(numero_bcd[0]>4)
                         numero_bcd[0]= numero_bcd[0]+3;
                numero_bcd[1]=numero_bcd[1]<<1;           //digito 1
                if((numero_bcd[0]|0b11110111)==0xFF)
                         numero_bcd[1]=numero_bcd[1]|0b00000001;
                else
                         numero_bcd[1]=numero_bcd[1]&0b11111110;
                numero_bcd[1]=numero_bcd[1]&0x0F;


                if(numero_bcd[2]>4)
                         numero_bcd[2]= numero_bcd[2]+3;
                numero_bcd[0]=numero_bcd[0]<<1;           //digito 0
                // ver abajo
                if((valor|0x7F)==0xFF)     //ver cantidad de bytes de la variable valor
                         numero_bcd[0]=numero_bcd[0]|0b00000001;
                else
                         numero_bcd[0]=numero_bcd[0]&0b11111110;
                numero_bcd[0]=numero_bcd[0]&0x0F;




                valor=valor<<1;

             }
}

void binbcd_32(unsigned long int valor)
{
 //   el valor de entrada es un unsigned long int
 //   el valor de salida BCD queda almacenado en numero_bcd
 //   numero_bcd[9] = MSB  numero_bcd[0] = LSB
 //   conversion de 0xFFFFFFFF   10174 ciclos de maquina, 0x00000000 9658 ciclos de maquina
 //   [https://www.forosdeelectronica.com/]


             int i;
             for(i=0;i<=9;i++)         // limpio los valores de salida
                    numero_bcd[i]=0;

             for(i=1;i<=32;i++)
             {
                //digito 9
                if(numero_bcd[8]>4)
                         numero_bcd[8]= numero_bcd[8]+3;
                numero_bcd[9]=numero_bcd[9]<<1;
                if((numero_bcd[8]|0b11110111)==0xFF)
                         numero_bcd[9]=numero_bcd[9]|0b00000001;
                else
                         numero_bcd[9]=numero_bcd[9]&0b11111110;
                numero_bcd[9]=numero_bcd[9]&0x0F;

                //digito 8
                if(numero_bcd[7]>4)
                         numero_bcd[7]= numero_bcd[7]+3;
                numero_bcd[8]=numero_bcd[8]<<1;
                if((numero_bcd[7]|0b11110111)==0xFF)
                         numero_bcd[8]=numero_bcd[8]|0b00000001;
                else
                         numero_bcd[8]=numero_bcd[8]&0b11111110;
                numero_bcd[8]=numero_bcd[8]&0x0F;

                //digito 7
                if(numero_bcd[6]>4)
                         numero_bcd[6]= numero_bcd[6]+3;
                numero_bcd[7]=numero_bcd[7]<<1;
                if((numero_bcd[6]|0b11110111)==0xFF)
                         numero_bcd[7]=numero_bcd[7]|0b00000001;
                else
                         numero_bcd[7]=numero_bcd[7]&0b11111110;
                numero_bcd[7]=numero_bcd[7]&0x0F;

                //digito 6
                if(numero_bcd[5]>4)
                         numero_bcd[5]= numero_bcd[5]+3;
                numero_bcd[6]=numero_bcd[6]<<1;
                if((numero_bcd[5]|0b11110111)==0xFF)
                         numero_bcd[6]=numero_bcd[6]|0b00000001;
                else
                         numero_bcd[6]=numero_bcd[6]&0b11111110;
                numero_bcd[6]=numero_bcd[6]&0x0F;

                //digito 5
                if(numero_bcd[4]>4)
                         numero_bcd[4]= numero_bcd[4]+3;
                numero_bcd[5]=numero_bcd[5]<<1;
                if((numero_bcd[4]|0b11110111)==0xFF)
                         numero_bcd[5]=numero_bcd[5]|0b00000001;
                else
                         numero_bcd[5]=numero_bcd[5]&0b11111110;
                numero_bcd[5]=numero_bcd[5]&0x0F;

                //digito 4
                if(numero_bcd[3]>4)
                         numero_bcd[3]= numero_bcd[3]+3;
                numero_bcd[4]=numero_bcd[4]<<1;
                if((numero_bcd[3]|0b11110111)==0xFF)
                         numero_bcd[4]=numero_bcd[4]|0b00000001;
                else
                         numero_bcd[4]=numero_bcd[4]&0b11111110;
                numero_bcd[4]=numero_bcd[4]&0x0F;

                //digito 3
                if(numero_bcd[2]>4)
                         numero_bcd[2]= numero_bcd[2]+3;
                numero_bcd[3]=numero_bcd[3]<<1;
                if((numero_bcd[2]|0b11110111)==0xFF)
                         numero_bcd[3]=numero_bcd[3]|0b00000001;
                else
                         numero_bcd[3]=numero_bcd[3]&0b11111110;
                numero_bcd[3]=numero_bcd[3]&0x0F;

                //digito 2
                if(numero_bcd[1]>4)
                         numero_bcd[1]= numero_bcd[1]+3;
                numero_bcd[2]=numero_bcd[2]<<1;
                if((numero_bcd[1]|0b11110111)==0xFF)
                         numero_bcd[2]=numero_bcd[2]|0b00000001;
                else
                         numero_bcd[2]=numero_bcd[2]&0b11111110;
                numero_bcd[2]=numero_bcd[2]&0x0F;

                //digito 1
                if(numero_bcd[0]>4)
                         numero_bcd[0]= numero_bcd[0]+3;
                numero_bcd[1]=numero_bcd[1]<<1;
                if((numero_bcd[0]|0b11110111)==0xFF)
                         numero_bcd[1]=numero_bcd[1]|0b00000001;
                else
                         numero_bcd[1]=numero_bcd[1]&0b11111110;
                numero_bcd[1]=numero_bcd[1]&0x0F;

                //digito 0
                if(numero_bcd[9]>4)
                         numero_bcd[9]= numero_bcd[9]+3;
                numero_bcd[0]=numero_bcd[0]<<1;
                // ver abajo
                if((valor|0x7FFFFFFF)==0xFFFFFFFF)     //ver cantidad de bytes de la variable valor
                         numero_bcd[0]=numero_bcd[0]|0b00000001;
                else
                         numero_bcd[0]=numero_bcd[0]&0b11111110;
                numero_bcd[0]=numero_bcd[0]&0x0F;


                valor=valor<<1;

             }
}



void main()
{

    while(1)
    {
        binbcd_8(0x00);
        binbcd_8(0xFF);
        dec2bcd16(65535);         //solo en Mikroelectronica
        binbcd_32(0x00000000);
        binbcd_32(0xFFFFFFFF);

    }

}

Espero les sirva
 
Binario a BCD 32 bit

El código puede ser adaptado a cualquier micro, puede ser reducido utilizando un for con 32 pasadas, esto reducimos el tamaño del código pero los ciclos de máquina quedan muy similares, sirve para poder representar lo frecuencia de un frecuencimetro en cualquier display hasta los 4ghz con todos sus digitos
 
Hola.

Basándome en tu idea, lo he simplificado un poco. He quitado algunas líneas que sobraban y he reducido las operaciones por medio de bucles for() anidados.

PHP:
/*
    Conversión de binario a dígitos decimales.
    Joaquín Ferrero, octubre 2015.

    Constantes:
        N : tamaño del array para almacenar los dígitos

    Variables:
        digitos : array donde se almacenan los dígitos
    
    Compilación en Linux: gcc -o bin2dec bin2dec.c
*/

#include <stdio.h>
#include <math.h>
#include <stdint.h>

#define N 10					// N=3 para 8 bit. N=10 para 32 bit.

uint8_t digitos[N];				// reserva de espacio


void pinta_dec(uint8_t precision) {
    int8_t i;
    uint8_t ceros = 1;				// indicador de ceros a la izquierda

    for (i = precision-1; i >= 0; i--) {

        if (!ceros || digitos[i] || i == 0) {	// dígito normal
            ceros = 0;				// ya no hay ceros a la izquierda
            printf("%c", digitos[i] + '0');
        }
        else					// pintar un cero a la izquierda
            printf(" ");			// poner "0" en caso de quererlos
    }
}

void byte2dec(uint8_t valor) {
    uint8_t i, j;

    for (i = 0; i < N; i++)			// limpio los valores de salida
        digitos[i] = 0;

    for (i = 1; i <= 8; i++) {

        for (j = N-1; j > 0; j--) {

            digitos[j] <<= 1;

            // si el dígito anterior es >= 5, se producirá una coversión a 10 o más cuando
            // se multiplique aquel dígito por 2 (en la siguiente vuelta), por lo que necesitamos
            // influir en el dígito actual (hay una decena más)
            if (digitos[j-1] >  4) {		// 5->8, 6->9, 7->10, 8->11, 9->12
                digitos[j-1] += 3;

                if (digitos[j-1] &  0x08)	// ¿ dígito >= 8 ?
                    digitos[j]   |= 0x01;	// siguiente dígito ++
            }
            
            digitos[j] &= 0x0F;
        }

        digitos[0] <<= 1;

        if (valor & 0x80)			// ver siguiente bit superior de valor
            digitos[0] |= 0x01;

        digitos[0] &= 0x0F;

        //pinta(valor, 4);

        valor <<= 1;
    }
}

void long2dec(uint32_t valor) {
    uint8_t i, j;

    for (i = 0; i < N; i++)			// limpio los valores de salida
        digitos[i] = 0;

    for (i = 1; i <= 32; i++) {

        for (j = N-1; j > 0; j--) {

            digitos[j] <<= 1;

            if (digitos[j-1] >  4) {		// 5->8, 6->9, 7->10, 8->11, 9->12
                digitos[j-1] += 3;

                if (digitos[j-1] &  0x08)	// ¿ dígito >= 8 ?
                    digitos[j]   |= 0x01;	// siguiente dígito ++
            }
            
            digitos[j] &= 0x0F;
        }

        digitos[0] <<= 1;

        if (valor & 0x80000000)			// ver siguiente bit superior de valor
            digitos[0] |= 0x01;

        digitos[0] &= 0x0F;

//        pinta_dec(10); printf("\t%lx\n", (long int)valor);

        valor <<= 1;
    }
}

void main(void) {
    uint8_t test[] = { 0, 0xFF, 100, 112, 75, 66 };
    uint8_t n_test = 6;
    uint8_t i;
    uint32_t tlargo;

    for (i = 0; i < n_test; i++) {
        byte2dec(test[i]);
        pinta_dec(3);
        printf("\t%d\n", test[i]);
    }
  
    tlargo = (unsigned long int)pow(2,32) - 1;
    long2dec(tlargo);
    pinta_dec(10);
    printf("\t%ld\n", (unsigned long)tlargo);

    tlargo = 1.235778E8;
    long2dec(tlargo);
    pinta_dec(10);
    printf("\t%ld\n", (unsigned long)tlargo);

}
La salida es:
Código:
  0	0
255	255
100	100
112	112
 75	75
 66	66
4294967295	4294967295
 123577800	123577800

Las versiones de 8 y 32 bits son prácticamente la misma. Solo cambian el número de vueltas del bucle for() interno (tantas como bits) y la máscara que usamos para conocer el estado del bit de más peso del valor a convertir. Nada más.
 
Hola.

Soy nuevo en Programación de PIC y quisiera saber si alguien sabe qué tengo mal, porque el programa me dice que está todo excelente.
Estoy usando en el programa (mikroC Pro For PIC)

PHP:
#define LED_1 PORTA.RA0
#define LED_3 PORTA.RA1



void main(){

 TRISA = 0;
 PORTA = 0;

 LED_1 = 0;
 delay_ms(2000);

 LED_1 = 1;
 delay_ms(5000);

 LED_1 = 0;
 
 LED_3 = 1;
 delay_ms(5000);

 LED_3 = 0;
 delay_ms(10000);

 LED_3 = 1;

 }


void main_2() {


 CMCON = 0X07;       // DESACTIVA SEÑAL ANALOGICA

 TRISA = 1;          // ENTRADA
 TRISB = 0;          // SALIDA

while(1){
 if(ENTRADA == 1){
 delay_ms(20);

  SALIDA = 1;
  delay_ms(30000);

  
 }
 else{
 SALIDA = 0;
 }
 }
}

Bueno, en la primer menú enciende el LED a los 2 segundos, luego sigue encendido 5 segundos y luego se apaga.
Me funciona perfectamente en la simulación sólo el puerto A.

Pero no me funciona la botonera del puerto B que tengo mal, que no funciona el puerto A con el B, hay que sincronizarlo.
 

Adjuntos

  • Foto.jpg
    Foto.jpg
    106.4 KB · Visitas: 9
La configuración donde defines el puerto B como salidas, está en la subrutina "void main_2()"
El compilador conoce como inicio del programa a "void main()" pero no, un void main_2

Por lo tanto, las instrucciones que están dentro de void main_2() nunca se ejecutarán.
Aparte, por estar void main_2 debajo del void main(), debe ser declarado en la cabecera o incluir esa rutina arriba del void main().
De otra manera, cuando llames a esa rutina, el compilador dará un error por no estar declarada.
 
pues si esta mal...

lo que veo es que la variable entrada y salida no esta relacionada con ningun puerto, y el puerto B esta como salida...

y yo no pondria eso de main y main_2
 
Hola buenos días, alguien sabe porque me marca error en los pines de entrada del puerto B :confused:
Código:
TRISB=0b11110000; //  los 4 bits de menor peso como salida, y los 4 bits de mayor 
PORTB=0b00000000; //Los bits de salida asumen un 0 lógico.
//Este ejemplo usa un pulsador y un par de LEDs para ver el comportamiento del programa. Observe y analice el programa a continuación:
void main ( void ){
unsigned int CONTADOR=0;
TRISB = 0b11110000; // Configura los cuatro bits de menor peso como salida, y
//los cuatro bits de mayor peso como entrada.
PORTB=0b00000000; //Los bits de salida asumen un 0 lógico.
while( 1 ) //Bucle infinito
{
if( PORTB.F7==0 ) //Evalúa si bit RB7 es 0
{
if( PORTB.F0==1 ) //Evalúa el valor del bit RB0 y conmuta su valor.
PORTB.F0=0;
else
PORTB.F0=1;
while( PORTB.F7==0 ); //Espera a que el RB7 cambie a 1.
}
CONTADOR++; //Incrementa el valor del CONTADOR.
//La siguiente condición if cambia automáticamente el estádo del bit RB1
if( CONTADOR&0x0100 ) //Evalúa si el bit 8 del CONTADOR es 1
PORTB.F1=1;
else
PORTB.F1=0;
}
}
 
Debe ser porque las primeras dos instrucciones están fuera del main.
Ya dentro del main las estás volviendo a escribir.
Elimina o comenta las dos primeras y con las que ya están dentro no te debe dar error.
 
Debe ser porque las primeras dos instrucciones están fuera del main.
Ya dentro del main las estás volviendo a escribir.
Elimina o comenta las dos primeras y con las que ya están dentro no te debe dar error.

Gracias por la respuesta D@rkbytes.
Tengo una duda respecto al if y else , como haria para nombrar 2 pines de diferentes puertos


Código:
#define  puerto portb //define a todo el puerto B, puerto
#define CS1 PORTB.F0 // define una constante un puento del pin
const int retraso=1000;// define como una constante tipo entera al tiempo
void main(){
TRISb=0b00000000; //configurado como salida
portb=0b00000000; //mando todo a cero

TRISc=0b00000000; //configurado como salida
portc=0b00000000; //mando todo a cero


TRISd=0b00011111;// mando todo a cero    ]
PORTd=0b00000000;
while(1){
if( PORTd.F0==1 ) //Evalúa el valor del bit Rd0 y conmuta su valor.

PORTc.F6=0;
PORTc.F7=0;
else
PORTc.F6=1;
PORTc.F7=1;
}
}
 
Última edición:
No entendí muy bien tu pregunta en cuanto al if y else, con dar nombre a un pin de un puerto.
¿Será algo así?
PHP:
#define pulsador PORTB.F0       // Nombre para el bit 0 del puerto B
#define led      PORTD.F2       // Nombre para el bit 2 del puerto D

void main (void)
{
    TRISD = 0b11111011;  // RD2 como salida.
    OPTION_REG.F7 = 0;   // Activar resistencias pull-up del puerto B
    led = 0;             // led en 0 al iniciar (RD2)

    while(1)
    {
        if(!pulsador)    // Si "pulsador" está en 0...
            led = 1;     // Encender el LED
        else             // Caso contrario...
            led = 0;     // Apagar el LED
    }
}
 
Hola a todos. Estoy tratando de hacer un sensor de temperatura con el PIC16F887, mostrarlo en una pantalla LCD y enviarlo al celular con un módulo Bluetooth.
Hasta esa parte creo que está bien el código, porque lo compilo y no me marca errores, pero al agregarle una interrupción por RB0, me marca este error y no sé cómo solucionarlo

not enough ram for call stack mikroc

También me abre una pestaña que dice __Lib Delays.c

Espero que alguien me pueda ayudar. Se los agradecería!

Código:
/*Sensor de temperatura LCD*/
//Conexiones del modulo LCD
sbit LCD_RS at RD4_bit;
sbit LCD_EN at RD5_bit;
sbit LCD_D4 at RD0_bit;
sbit LCD_D5 at RD1_bit;
sbit LCD_D6 at RD2_bit;
sbit LCD_D7 at RD3_bit;
sbit LCD_RS_Direction at TRISD4_bit;
sbit LCD_EN_Direction at TRISD5_bit;
sbit LCD_D4_Direction at TRISD0_bit;
sbit LCD_D5_Direction at TRISD1_bit;
sbit LCD_D6_Direction at TRISD2_bit;
sbit LCD_D7_Direction at TRISD3_bit;
//Final de las conexiones del modulo LCD

unsigned int Radc = 0;      // Variable que almacena lo obtenido en el ADC
unsigned int vtemp = 0;             // Voltaje temporal tipo entero
char *tempC = "000.0";              // Apuntador, Voltaje final
float Tem = 0;              // Valor real del ADC
char Text[15], texto[4];              // Almacena el Tem pero tipo Texto para el LCD
char txt1[] = "Temperatura:";      // Texto mostrado en el LCD
char txt2[] = "Temperatura Min";   // Texto mostrado en el LCD
char txt3[] = "Temperatura Max";   // Texto mostrado en el LCD
char minimo=0, maximo=0,contador;

void LM35(){
  if(vtemp < 10000){
   tempC[0] = ' ';
   tempC[1] = (vtemp/1000)%10 + 48;
   tempC[2] = (vtemp/100)%10 + 48;
   tempC[4] = (vtemp/10)%10 + 48;
   Lcd_Out(2,1,tempC);
   UART1_Write_Text(tempC);
   UART1_Write(0x0D);              // ASCII - Retorno de Carro
   UART1_Write(0x0A);              // ASCII - Avance de Linea
   Delay_ms(20);
 } else{
    tempC[0] = (vtemp/10000)%10 + 48;
    tempC[1] = (vtemp/1000)%10 + 48;
    tempC[2] = (vtemp/100)%10 + 48;
    tempC[4] = (vtemp/10)%10 + 48;
    Lcd_Out(2,1,tempC);
    UART1_Write_Text(tempC);
    UART1_Write(0x0D);              // ASCII - Retorno de Carro
    UART1_Write(0x0A);              // ASCII - Nueva Linea
    Delay_ms(20);
 }
}

void main(){
 INTCON = 0X90;            //Habilito interrupcciones y RBO(int)
 INTEDG_bit=0;             //INT por flanco descendente.
 ANSEL  = 0x01;            // Configure AN0 pin as analog
 ANSELH = 0x00;            // Configure other AN pins as digital I/O
 TRISA = 0x0D;              // AN0, AN2, AN3 como entradas
 ADCON1.F4 = 1;             // VREF+ 1 = externo 0 = VDD
 ADCON1.F5 = 1;            // VREF- 1 = externo 0 = VSS
 C1ON_bit = 0;             // Deshabilitar comparadores
 C2ON_bit = 0;

 ADC_Init();               // Inicializa el Modulo ADC
 UART1_Init(9600);           // Iniciar comunicacion Serial
 Delay_us(100);            // Retardo para estabilizar el ADC

 Lcd_Init();               // Inicializa el LCD
 Lcd_Cmd(_LCD_CLEAR);      // Comando para limpiar el LCD
 Lcd_Cmd(_LCD_CURSOR_OFF); // Comando para quitar el cursor
 Lcd_Out(1,1, txt1);       // Mandamos nuestro mensaje al LCD
 Lcd_Chr(2,6,223);         // Display symbol "°" (grado)
 Lcd_Chr(2,7,'C');        // Display "C" for Celsius
 Delay_ms(100);

 while(1){
  Radc = ADC_Get_Sample(0);     // Obtenemos lectura del AN0
  Delay_ms(600);                // Este retardo ayuda a de manera burda a
                                //estabilizar el LCD de las actualizaciones de
                                //la lectura del ADC.
  Tem = (float)(Radc * 0.195);  // Obtenemos el valor Real de la Conversion A/D
                                // (ADCread * 0.00488)/0.01)= Vreal
                                // Resumimos que 0.00488 / 0.01 = 0.488
  vtemp = (tem*100);
  //Se convierte el número entero a una cadena de caracteres.
  FloatToStr(Tem, Text);
  LM35();
  Delay_ms(400);           //Retardo de 50m segundos.
  }
 }
 
 void interrupt()
{Delay_ms(20);
 if(INTCON.B0==1){
 Lcd_Cmd(_LCD_CLEAR);    // Comando para limpiar el LCD
 Lcd_Out(1,1,txt2);      // mandamos nuestro msg al LCD
 if(PORTB.B1==1) minimo++;
 if(PORTB.B2==1) maximo++;
 ByteToStr(minimo,texto);
 Lcd_Out(2,1,texto);      // mandamos nuestro msg al LCD
 INTF_bit=0;
}
}
 
Última edición:
Prueba usando una bandera dentro del servicio de interrupción, y no escribas en la pantalla estando dentro.
Esa bandera la debes usar como comprobación para cuando se requiera escribir datos en la pantalla, pero realiza ese proceso dentro del bucle principal.
 
Prueba usando una bandera dentro del servicio de interrupción, y no escribas en la pantalla estando dentro.
Esa bandera la debes usar como comprobación para cuando se requiera escribir datos en la pantalla, pero realiza ese proceso dentro del bucle principal.

que tal ya solucione eso gracias, en vez de utilizar interrupciones para los pulsadores mejor utilice un teclado matricial, pero ahora me surgió otro problema y es que no me acepta algunas condiciones if que son estas.

Código:
if(tempC<minimo)PORTE=0X01;
if(tempC>maximo)PORTE=0X02:

según yo estoy bien, lo que quiero hacer es que mediante las temperaturas mínima y máxima que yo ingrese con el teclado, se mantenga en ese rango..... abajo les dejo mi código completo y con la simulación si alguien quiere checarlo y ayudarme a solucionarlo
 

Adjuntos

  • lm35.rar
    30.5 KB · Visitas: 10
Última edición:
Esas instrucciones no están en el programa que adjuntas.
Se encuentran las siguientes, pero no existe error de compilación.
PHP:
if(temperatura<=40&&temperatura>=35){
PORTb=0b11000000;// Dos motores trabajando
}

else{
PORTb=0b11000000;// Motor trabajando
  }
En las instrucciones que existe error, es en: CMCON y CVRCON.
Eso es porque el PIC16F887 no tiene esos registros.
En cambio tiene: CM1CON0, CM2CON0, CM2CON1 y VRCON
Como no estás usando los comparadores, esos registros no tiene caso configurarlos.
Su estado por defecto en el POR (Power On Reset) es inactivo.

Tampoco se muestra nada en la pantalla, porque existe una configuración errónea en cuanto a software y hardware.

Tal vez subiste el programa equivocado. :rolleyes:
 
Cierto subí otro código que no era :LOL: jejej, El codigo es este.

Código:
/*Sensor de temperatura LCD*/
//Conexiones del modulo LCD
sbit LCD_RS at RD4_bit;
sbit LCD_EN at RD5_bit;
sbit LCD_D4 at RD0_bit;
sbit LCD_D5 at RD1_bit;
sbit LCD_D6 at RD2_bit;
sbit LCD_D7 at RD3_bit;
sbit LCD_RS_Direction at TRISD4_bit;
sbit LCD_EN_Direction at TRISD5_bit;
sbit LCD_D4_Direction at TRISD0_bit;
sbit LCD_D5_Direction at TRISD1_bit;
sbit LCD_D6_Direction at TRISD2_bit;
sbit LCD_D7_Direction at TRISD3_bit;
//Final de las conexiones del modulo LCD
void teclado(void);
void lcdmostrar(void);
unsigned umil, centenas, decenas, numero;
int minimo, maximo;
unsigned int vtemp = 0;               // Voltaje temporal tipo entero
unsigned int Radc = 0;      // Variable que almacena lo obtenido en el ADC
char Text[15], texto[4];              // Almacena el Tem pero tipo Texto para el LCD
char txt1[] = "Temperatura:";         // Texto mostrado en el LCD
char txt2[] = "Temperatura Min";      // Texto mostrado en el LCD
char txt3[] = "Temperatura Max";      // Texto mostrado en el LCD
char *tempC = "000.0";                // Apuntador, Voltaje final
float Tem = 0;              // Valor real del ADC
char kp, contador=0;
char keypadPort at PORTB;

void LM35(){
  if(vtemp < 10000){
   tempC[0] = ' ';
   tempC[1] = (vtemp/1000)%10 + 48;
   tempC[2] = (vtemp/100)%10 + 48;
   tempC[4] = (vtemp/10)%10 + 48;
   Lcd_Out(2,1,tempC);
   UART1_Write_Text(tempC);
   UART1_Write(0x0D);              // ASCII - Retorno de Carro
   UART1_Write(0x0A);              // ASCII - Avance de Linea
   Delay_ms(20);
 } else{
    tempC[0] = (vtemp/10000)%10 + 48;
    tempC[1] = (vtemp/1000)%10 + 48;
    tempC[2] = (vtemp/100)%10 + 48;
    tempC[4] = (vtemp/10)%10 + 48;
    Lcd_Out(2,1,tempC);
    UART1_Write_Text(tempC);
    UART1_Write(0x0D);              // ASCII - Retorno de Carro
    UART1_Write(0x0A);              // ASCII - Nueva Linea
    Delay_ms(20);
 }
}

    void main(){
ANSEL  = 0x01;            // Configure AN0 pin as analog
ANSELH = 0x00;            // Configure other AN pins as digital I/O
TRISA = 0x0D;             // AN0, AN2, AN3 como entradas
TRISE = 0X00;
ADCON1.F4 = 1;            // VREF+ 1 = externo 0 = VDD
ADCON1.F5 = 1;            // VREF- 1 = externo 0 = VSS
C1ON_bit = 0;             // Deshabilitar comparadores
C2ON_bit = 0;
Keypad_Init(); //Inicializa el teclado. 
Lcd_Init(); //Inicializa el LCD. 
Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_CURSOR_OFF); //Apaga el cursor.
Lcd_Out(1,1, txt2);       // Mandamos "Temperatura min"
lcdmostrar(void);
Lcd_Cmd(_LCD_SECOND_ROW);
teclado(void);
minimo = numero;
numero=0;

Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1, txt3);       // Mandamos "Temperatura max"
lcdmostrar(void);         // Mandamos "°" y "C"
Lcd_Cmd(_LCD_SECOND_ROW);
teclado(void);
minimo = numero;
numero=0;

Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1, txt1);     //Mandamos "Temperatura"
lcdmostrar(void);

ADC_Init();               // Inicializa el Modulo ADC
 UART1_Init(9600);           // Iniciar comunicacion Serial
 Delay_us(100);            // Retardo para estabilizar el ADC

 while(1){
  Radc = ADC_Get_Sample(0);     // Obtenemos lectura del AN0
  Delay_ms(600);                // Este retardo ayuda a de manera burda a
                                //estabilizar el LCD de las actualizaciones de
                                //la lectura del ADC.
  Tem = (float)(Radc * 0.195);  // Obtenemos el valor Real de la Conversion A/D
                                // (ADCread * 0.00488)/0.01)= Vreal
                                // Resumimos que 0.00488 / 0.01 = 0.488
  vtemp = (tem*100);
  //Se convierte el número entero a una cadena de caracteres.
  FloatToStr(Tem, Text);
  LM35();
  if(tempC<minimo)PORTE=0X01;
  if(tempC>maximo)PORTE=0X02:
  Delay_ms(400);           //Retardo de 50m segundos.
  }
}

void teclado(void){
while(1){kp=0;
do //Espera por una tecla.
kp=Keypad_Key_Click(); //Lee el número de la tecla y lo guarda en kp.
while (!kp);
switch  (kp){
case 1:  kp = 49; break; //49 es el código ASCII del número 1.
case 2:  kp = 50; break; //50 es el código ASCII del número 2.
case 3:  kp = 51; break; //51 es el código ASCII del número 3.
case 4:  kp = 65; break; // A
case 5:  kp = 52; break; // 4
case 6:  kp = 53; break; // 5
case 7:  kp = 54; break; // 6
case 8:  kp = 66; break; // B
case 9:  kp = 55; break; // 7
case 10: kp = 56; break; // 8
case 11: kp = 57; break; // 9
case 12: kp = 67; break; // C
case 13: kp = 42; break; // *
case 14: kp = 48; break; // 0
case 15: kp = 35; break; // #
case 16: kp = 68; break; // D
}
Lcd_Chr_CP(kp); //Presenta el carácter en el LCD.

if (kp==35||kp==68){
Lcd_Cmd(_LCD_CLEAR); //Borra el display.
Delay_ms(100); //Espera 100ms.
break;
}
else{
contador++;
switch (contador){
case 1:;
       umil=kp;
       umil<<=12; //umil=0buuuu 0000 0000 0000
       break;
case 2:;
       centenas=kp;
       centenas<<=8; //centenas=0b0000 cccc 0000 0000
       break;
case 3:;
       decenas=kp;
       decenas<<=4; //decenas=0b0000 0000 dddd 0000
       break;
case 4:contador=0; //Si se han efectuado 4 pulsaciones.
       umil|=centenas; //Recupera las centenas.
       umil|=decenas; //Recupera las decenas.
       umil|=kp; //Recupera las unidades.
       numero=Bcd2Dec16(umil); //Obtiene el equivalente decimal del número umil=0xucdu.
}
}
}
}
void lcdmostrar(void){
Lcd_Chr(2,6,223);         // Display symbol "°" (grado)
Lcd_Chr(2,7,'C');          // Display "C" for Celsius
}
 
Atrás
Arriba