# Programación con MikroC



## Aleix

Hola, 
hace poco he empezado a programar con MikroC y la verdad es que va muy bien pero ahora que he epezado hacer un proyecto algo mas grande quiero ordenar en partes haciendo un archivo .c y otro .h para cada TAD del proyecto. Mi problema viene cuando quiero llamar a una funcion en el main que esta en otro archivo. No me dice que no existe o no esta definida y he mirado que los #includes estubieran bien. Luego me di cuenta que tienes que indicarle donde buscar los includes y también lo he hecho pero las de un .h si me las reconoce y las de otros no. que puede ser? 

Muchas gracias
Espero su respuesta.
Atentamente Aleix.


----------



## cooperharris

hola , que bien !m, iterezante, tengo el mikroc, pero aun no me  he puesto a  programarlo, tendras algunos documentos de  interes para compartir?


----------



## antoniotenorio

hola amigo aleix, cuando yo quiero utilizar una libreria la coloco en la misma carperta donde esta mi .c siempre lo vi utilizar asi, y me parece que asi es mejor asi me llevo la carperta completa cuando me voya otra pc, si en otro programa quiero utilizar las mismas herramientas pues vuelvo a copiar los .h que utilizaba 

Para cooperharris aqui un ejemplito con teclado, LCD...  simulados en Proteus


----------



## lula

Hola , que pena realmente no se nada de Mikro C, y lo que pasa es que soy muy nuevo en el manejo de este, y tengo una preguntica lo que pasa es que es que estoy intentando manejar la interrupciones y no me funcionas hice un ejemplito sencillo y no funciona y tambien lo probe con un ejemplo del soporte de Mikro C y tampoco funciona la interrupcion ni siquiera el timer  correo y si no se desborda pues no hay interrupcion, espero que alguin me pueda ayudar muchas gracias


----------



## transistor007

hola que tal!

alguien ha usado el reloj de tiempo real ds1302 con mikro c? este reloj es por i2c! saludos


----------



## leonardo925

hola soy nuevo en el foro, les escribo para solisitar su ayuda  con respecto a un proyecto el cual trata de un llava electronica de 4 digitos, con un teclado de 4x4 y cuatro display 7 segmentos, el programa tiene que ser en c, yo tengo el miKro c y el pic 16f877, les agradeceria su ayuda


----------



## iDan

OK amigo!! estaria encantado de que trabajaramos juntos ya sea resolviendo dudas del otro y compartiendo información que el otro desconoce!! bueno si quieres te puedo pasar mi msn o tambien si quieres resolvemos las dudas por el foro... como tu quieras!! 

Saludos!!


----------



## iDan

Hola a todos... bueno al ver este tema yo me he ofrecido en ayudar en lo que fuera posible y ps como yo programo en MikroC ya e puesto algunos ejemplos dentro de este foro en otros temas... aqui las direcciones:

https://www.forosdeelectronica.com/f24/agregarle-medidor-voltaje-26780/

https://www.forosdeelectronica.com/f24/sonido-buzzer-usando-pic-lenguaje-c-26854/


espero que les sirva a muchos para poder entender mejor la programacion en MikroC y ps si quieren alguna ayuda o algun otro ejemplo no duden en postear su pregunta o duda y yo con mucho gusto tratare de ayudar en lo que me sea posible

Saludos


----------



## musicogui

Aqui hay un pequeño tutorial en Español sobre MikroC
http://musicogui.microdesing.net/in...t&view=category&layout=blog&id=915&Itemid=121


----------



## rafaelnotty

hola todos.... tengo un gran inconveniente con mikrobasic igual con mikrocpro es que no puedo llamar funciones como las de la lcd o keypad dentro de las interupciones... q hago??? alguna declaracion global o alguna libreria... como sera?


----------



## bastidasro

Hola que tal soy nuevo en mikroc, estoy utilizando el conversor ad y muestro los datos en un lcd, pero pro ejemplo quiero mostrar el valor de la conversion y solo me salen enteros, no me salen valores como 1.23 u otro valor con decimales, no se que comando utilizar


----------



## bampi13

Hola soy estudienate de electronica , mi proyecto final es sensar una habitacion de un hotel tengo que utilizar el pica6f877a , pero no ce nada de el en cuanto a programacion con C , si podria ayudarme se los agradeceria .debo utilizar (Mikro C) 

o si pudieran darme algunos ejemplos con codigo basicos


----------



## iDan

Hola a todos


Perdon si no pude responder rapido en este tiempo, espero poder ayudarles en algo:

rafaelnotty: llamas a las funciones de la LCD dentro de la interrupcion (directamente) o la llamas desde otro subprograma??


bastidasro: al querer mostrar el voltaje que estas sensando en la pata analogica de tu PIC me imagino que la guardas en una variable y la muestras directamente en la LCD pero el detalle que tiene es que el compilador aproxima la cifra (por ejemplo si tienes ese 1.23 que dices solo te pondra un 1 en la LCD); para mostrar el valor junto con sus decimales tienes que separar las decenas de las unidades Y unidades de los decimales, para eso tienes que realizar una serie de operaciones para extraer el valor deseado y mostrarlo en un lugar de la LCD (por ejemplo despues de haber hecho la separacion que menciono anteriormente "unidades" y "decimales" tendrias que poner los datos como *Lcd_Out(1,1,unidad); Lcd_Out(1,2,'.'); Lcd_Out(1,3,decima);*) si quieres puedes ver un pequeño ejemplo que puse en el foro de un voltimetro de 0 a 9 que tambien muestra decimales, alli podras ver las operaciones que se necesitan para realizar la separacion de los valores: 
https://www.forosdeelectronica.com/f24/voltimetro-0-9-simple-pic12f683-28129/
si tienes alguna duda me avisas y yo con mucho gusto te ayudare en lo que pueda.

bampi13: que tipo de proyecto o que debe realizar exactamente?? puedes poner tus dudas aqui y si quieres puedo ayudarte en lo que pueda, solo necesito saber que tanto o por lo menos que conoces en lenguaje c y el compilador MikroC.


Saludos y perdon por el retraso


----------



## bastidasro

Gracia amigo, disculpa que te moleste otra vez, tienes ejemplos de comunicacion ethernet. Sabes si los datos que envio en ethernet se transmiten de acuerdo a la variable en la que son almacenados, por ejemplo si son char, float o int, se transmiten de la misma manera o existe algun tipo de conversion en latransmision en cuanto al tipo de variables. Y por ultimo en otros lenguajes he utilizado la funcion gosub que genera un salto y regresa a la siguiente linea, me parece que en mikroc es void, pero noe stoy muy seguro


----------



## iDan

Hola bastidasro



Lo siento!! por el momento no tengo un ejemplo de Ethernet... pero en la ayuda que trae MikroC ("Help" en la barra o presiona F11) si te mentes a las librerias veras la libreria de Ethernet con su sintaxis y un ejemplo... tratare de encontrate un ejemplo.


Saludos


----------



## bampi13

Alguien podria instruirme sobre Mikroc , en codigo y demas porque estoy perdido .
Necesito aprender sobr el ADC Del pic16f877a como programarlo con este lenguaje si alguno se ofrece , se lo agradeceria mucho.


----------



## Gabry17

Necesito crear un programa que mida la frecuencia (frecuencimetro) utilizando el lenguaje MicroC y usando un PIC16F84 o un 16F87. Alguien puede ayudarme??


----------



## FRYCK

Hola  *Gabry17* para  eso  lo que  puedes  hacer  es utilizar interrupciones  con  el  puerto rb0  o utilizar  el tmr0 con reloj externo y un timerx  para que demore cierto tienpo digamos 1 seg, a lo que suceda la interrupción del timerx  lees el valor del timer0  o el contador que se incremente con rb0 y  con eso sabes cuantos siclos contó  en ese tiempo.
saludos


----------



## bampi13

Wenas a todos.
Este programa esta hecho en Mikroc pro for pic.El motivo de esto es para ver si me podrian ayudar con este programa , el problema que me presenta es que no realiza la funcion que deberia realizar abase de el ADC del PIC16f877A que esta justo debajo del while(1) todo lo que compete al ADC
, pero todo lo demas si lo hace osea (apartir de donde dice if(PORTB.F6==1)) luego de ahy todo lo realiza bien 



		Código:
	

int cnt,x,v,b;
void main()
{
ADCON1=0x8D;
TRISA=15;
CMCON=0;
INTCON=0;  // apagar las interrupciones
TRISB.F2=0;
TRISB.F3=0;
TRISB.F4=0;
TRISB.F5=0;
TRISB.F6=1;
TRISB.F7=1;
PORTB=0;
while(1)
{
v=ADC_Read(0);
b=ADC_Read(1);
if(v>b)
{
PORTB.F0=1;
PORTB.F1=0;
PORTB.F2=0;
}
else if(b>v)
{
PORTB.F0=0;
PORTB.F1=1;
PORTB.F2=0;
}
else if(b==v)
{
PORTB.F0=0;
PORTB.F1=0;
PORTB.F2=1;
}
if(PORTB.F6==1) //RB6 Usuario
{
PORTB.F5=0;
PORTB.F4=0;
PORTB.F3=1;
cnt++;
Delay_ms(1000);
}
else
{
PORTB.F5=1;
PORTB.F4=0;
PORTB.F3=0;
cnt=0;
}
while(cnt>10){
if(PORTB.F6==0 && PORTB.F7==0)
{
PORTB.F3=0;
PORTB.F4=1;
delay_ms(500);
PORTB.F4=0;
delay_ms(500);
}
else
{
PORTB.F4==0;
PORTB.F5==1;
}
if(PORTB.F6==0 && PORTB.F7==1)
{
x=1;
PORTB.F4=1;
delay_ms(1000);
}
if(PORTB.F7==0 && x==1)
{
PORTB.F4=0;
PORTB.F5=1;
cnt=0;
x=0;
}
}
}
}


aca os dejo circuito de proteus por si desena simularlo y conprobar por si encuantran algun  otro problema por favor haganmelo saber necesito terminarlo


----------



## Gabry17

FRYCK dijo:


> Hola  *Gabry17* para  eso  lo que  puedes  hacer  es utilizar interrupciones  con  el  puerto rb0  o utilizar  el tmr0 con reloj externo y un timerx  para que demore cierto tienpo digamos 1 seg, a lo que suceda la interrupción del timerx  lees el valor del timer0  o el contador que se incremente con rb0 y  con eso sabes cuantos siclos contó  en ese tiempo.
> saludos


Gracias FRYCK!! probare tu consejo y te avisare que tal me resulta ok? 
gracias de nuevo


----------



## FRYCK

hola bampi13  en este ya esta corregido el error creo que era de configuración del adc 
saludos


		PHP:
	

unsigned int temp_res_1,temp_res_2;

void main() {
ADCON1 =192;
ADCON0 =128;
TRISA  =0xff;
TRISB  = 0;                 // PORTB is output
TRISC  = 0x00;              // Pins RC7, RC6 are outputs
PORTB=0;
PORTC=0;

do {
    temp_res_1 = ADC_Read(0);   // Get 10-bit results of AD conversion
    temp_res_2 = ADC_Read(1);   // Get 10-bit results of AD conversion
    

    if(temp_res_1>temp_res_2){
      PORTB.F0=1;
      PORTB.F1=0;
      PORTB.F2=0;
    }
    if(temp_res_1<temp_res_2){
      PORTB.F0=0;
      PORTB.F1=1;
      PORTB.F2=0;
     }
else if(temp_res_1==temp_res_2){
        PORTB.F0=0;
        PORTB.F1=0;
        PORTB.F2=1;
        }
  } while(1);
}


----------



## bampi13

Modifique algo mas y ya me esta funcionanado ademas de que le agregue algunas cosas ,pero cuando lo programe el pic con es eprog , no funciona bn , pero en  proteus si funciona bien , ahora lo unico que me falta es enviar esos datos de la temperatura via serial y noce como ahcerlo. aver si me echarian una manito con eso.



		PHP:
	

int cnt,x,habitacion,ambiente,db;
void usuario()
{
if(PORTB.F6==1) //RB6 Usuario
{
PORTB.F5=0;
PORTB.F4=0;
PORTB.F3=1;
cnt++;
Delay_ms(1000);
}
else
{
PORTB.F5=1;
PORTB.F4=0;
PORTB.F3=0;
cnt=0;
}
while(cnt>10){
if(PORTB.F6==0 && PORTB.F7==0)
{
PORTB.F3=0;
PORTB.F4=1;
delay_ms(500);
PORTB.F4=0;
delay_ms(500);
}
else
{
PORTB.F4==0;
PORTB.F5==1;
}
if(PORTB.F6==0 && PORTB.F7==1)
{
x=1;
PORTB.F4=1;
delay_ms(1000);
}
if(PORTB.F7==0 && x==1)
{
PORTB.F4=0;
PORTB.F5=1;
cnt=0;
x=0;
}
}
}


ESTA PARTE ES LA QUE DESEO ENVIAR SERIALMENTE OSEA LOS CAMBIOSQUE PASEN POR EJEMPLO EN EL PRIMER IF QUE SI LA TEMPERATURA ESTA ENTRE 32 GRADOS Y 44 HAGA ESO , TENGO QUE ENVIAR ESO A LA PC Y CON VISUAL BASIC SABERLO PARA MOSTRARLO. EL PUNTO ES QUE NO CE COMO UTILISAR EL TX Y EL RX DE EL PIC 16F877A.



		PHP:
	

void main()
{
ADCON1=0x8D;   //codigo para 4 entradas analogas
TRISA=15;     //usar 4 entradas
CMCON=0;     //activar analogas""
INTCON=0;  // apagar las interrupciones
TRISB=0b11000000;
PORTB=0;
while(1)
{
habitacion=ADC_Read(0);
ambiente=ADC_Read(1);
usuario();
if((habitacion>604 && habitacion<856)&& ambiente<habitacion)
{

while (db!=10)
{
usuario();
PORTB.F0=1;
PORTB.F1=0;
db++;
delay_ms(1000);
}
if(!(habitacion>438 && habitacion<456))
{
while(!(habitacion>438 && habitacion<456)){
usuario();
PORTB.F0=0;
PORTB.F1=1;
PORTB.F2=0;
habitacion=ADC_Read(0);
}
}
else {
usuario();
PORTB.F0=0;
PORTB.F1=0;
}
}
else{
usuario();
PORTB.F0=0;
PORTB.F1=0;
}

if(habitacion>856 && ambiente<habitacion)
{
while (!(habitacion>604 && habitacion<622)){
usuario();
PORTB.F0=0;
PORTB.F1=1;
habitacion=ADC_Read(0);
}
}
if((habitacion>604 && habitacion<622) && habitacion==ambiente)
{
usuario();
PORTB.F0=0;
PORTB.F1=0;
}
}
}


----------



## cristiancrm

Hola, amigos;

Estoy tratando de configurar el ENC28J60 en un PIC18F452 bajo MikroC. Funciona todo perfecto, el único problema es que el PIC se reinicia solito cuando llega a la rutina de adquisición de datos. Probé con un PIC16F877A y no se reinicia, pero cuando lo cambio al 18F452, si. A continuación les dejo el código simple que utilicé:




		Código:
	

// Definición de pines para la conexión del LCD
sbit LCD_RS at RD0_bit;
sbit LCD_EN at RD1_bit;
sbit LCD_D7 at RD7_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D4 at RD4_bit;

// Dirección de pines
sbit LCD_RS_Direction at TRISD0_bit;
sbit LCD_EN_Direction at TRISD1_bit;
sbit LCD_D7_Direction at TRISD7_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D4_Direction at TRISD4_bit;

//Tipo de Duplex Ethernet
#define Spi_Ethernet_HALFDUPLEX     0x00  // half duplex
#define Spi_Ethernet_FULLDUPLEX     0x01  // full duplex

// Definición de pines del ENC28J60
sfr sbit SPI_Ethernet_Rst at RC0_bit;
sfr sbit SPI_Ethernet_CS  at RC1_bit;
sfr sbit SPI_Ethernet_Rst_Direction at TRISC0_bit;
sfr sbit SPI_Ethernet_CS_Direction  at TRISC1_bit;
// end ethernet NIC definitions

// Variables de configuración de la red
unsigned char ethMac[6] = {0x00, 0x14, 0xA5, 0x76, 0x19, 0x3b};       // my MAC address
unsigned char ethIp[4]  = {10, 0, 0, 3};                       // my IP address
unsigned char ethMask[4] = {255, 255, 255, 0};                        // Mask
unsigned char ethGw[4] = {10, 0, 0, 1};                          // Gateway
unsigned char ethDns[4] = {10, 0, 0, 1};                         // DNS
unsigned char getRequest[15];                                         // HTTP request buffer
unsigned char dyna[30];                                               // buffer for dynamic response
unsigned long httpCounter = 0;                                        // counter of HTTP requests

int i = 0;

//Procesa peticiones TCP
unsigned int SPI_Ethernet_UserTCP(unsigned char *remoteHost, unsigned int remotePort, unsigned int localPort, unsigned int reqLength,char *canClose);
//Procesa peticiones UPD
unsigned int SPI_Ethernet_UserUDP(unsigned char *remoteHost, unsigned int remotePort, unsigned int destPort, unsigned int reqLength);

//Procesa peticiones TCP
unsigned int SPI_Ethernet_UserTCP(unsigned char *remoteHost, unsigned int remotePort, unsigned int localPort, unsigned int reqLength,char *canClose){
      return 0;
}

//Procesa peticiones UDP (ARP+ICMP)
unsigned int SPI_Ethernet_UserUDP(unsigned char *remoteHost, unsigned int remotePort, unsigned int destPort, unsigned int reqLength){
      return 0;
}


void main() {

     ADCON0 |= 0x0F;                 // turn off ADC convertors

     PORTA = 0;
     TRISA = 0xff;          // set PORTA as input for ADC

     TRISD = 0;                          //PORTD como salida
     PORTD = 0;


       /*
     * initialize ethernet board
     * start ENC28J60 with :
     * reset bit on RC0
     * CS bit on RC1
     * my MAC & IP address
     * full duplex
     */


     //Esto es simplemente para probar que el PIC está OK.
    for(i=0;i<=2;i++){
         PORTD.F2 = 1;
         Delay_ms(500);
         PORTD.F2 = 0;
         Delay_ms(500);
    }
    Spi1_Init();
    SPI_Ethernet_Init(ethMac, ethIp, Spi_Ethernet_FULLDUPLEX) ;
    SPI_Ethernet_confNetwork(ethMask, ethIp, ethDns);
    while(1){
         SPI_Ethernet_doPacket();   // Procesa los paquetes entrantes
    }

}


A alguien le pasó lo mismo? Verifiqué las tensiones para ver si se disparaba el Brown-out, pero está todo en condiciones; y como les dije, pasa solo con el PIC18F452. 
Agradeceré cualquier ayuda.

Saludos


----------



## iDan

Hola cristiancrm mira sinceramente no encuentro otra explicacion a tu problema mas que ver si la pata MCLR esta a positivo... pero si encuentro algo mas te aviso...


Hola tigre9226 dime piensas hacer algo asi como una caja fuerte de 4 digitos con un keypad?? dime que es lo que quieres exactamente y que llevas hecho...


Saludos...


----------



## bubu23

Hola a ver si alguien me puede ayudar estoy usando el mikroc y tengo que guardar datos que me entrega el sensor de temperatura ds18b20 en la eeprom 24lc256, pero tengo un problema no logro visualizar los datos en la memoria, tengo entendido que tengo que separar los datos del sensor, porque son 2 bits y la memoria es 1 bits, alguien sabe como puedo  hacer eso?.
De antemano Gracias!


----------



## iDan

Hola bubu23

Mira la verdad ignoro del tema pero puedes ver esta pagina http://davidkilly.blogspot.com/ en la cual puedas encontrar algo util...


Saludos


----------



## bubu23

hola yo nuevamente aún no encuentro la soucion a mi problema,necesito guardar las medidas de temperaturas o las variaciones de temperatura que presenta el ds18b20 ojalá en una memoria eeprom externa como la 24lc256,pero no sé como hacerlo,esto es lo unico que me está atrasando con mi proyecto de título..estoy trabajando con mikroc y proteus para simular,por favor alguien que utilice el mikroc que me ayude.
De antemano gracias!


----------



## ByAxel

bubu23 dijo:


> hola yo nuevamente aún no encuentro la soucion a mi problema,necesito guardar las medidas de temperaturas o las variaciones de temperatura que presenta el ds18b20 ojalá en una memoria eeprom externa como la 24lc256,pero no sé como hacerlo,esto es lo unico que me está atrasando con mi proyecto de título..estoy trabajando con mikroc y proteus para simular,por favor alguien que utilice el mikroc que me ayude.
> De antemano gracias!


Cual es tu problema en concreto? el código?, El mikroC tiene librerías para manejar dispositivos con bus "OneWire" e "I2C" para el sensor y la memoria respectivamente.


----------



## bubu23

Hola,gracias por responder,si la verdad es que he probado varios codigos y no me funcionan,utilizo i2c.
Lo otro es que como guardo la variable del sensor en la eeprom o sea como hago para que me lea los datos del sensor,eso no sé.
gracias


Mi principal problema es adquirir datos del sensor y guardarlos.


----------



## ByAxel

El MikroC tiene hasta un ejemplo de la "OneWire Library" con el mismo sensor incluido un circuito de prueba, has visto eso?...
De otro modo, creo que ya lo tendrías que implementar manualmente. En el foro hay ejemplos usando el mismo sensor.

saludos.


----------



## bubu23

Sí, si vi el ejemplo,pero eso es solo para obtener la temperatura del lugar que quieras tomarla,yo eso ya lo tengo todo listo yo puedo ver la temperatura de los dormitorios,living etc,lo que necesito es guardar esos datos,por ejemplo en un block de notas que salga algo asi:
25ºC
26ºC
25ºC
27ºC
..........etc..con el fin de hacer graficos y comparar los cambios de temperaturas que hay.


----------



## ByAxel

Block de notas?, bueno es decir, lo que buscas es guardar por ejemplo 25 (se sobreentiende que son grados) en la memoria EEPROM externa?. Si es así, creo que te conviene guardarlos tal y como se obtienen del sensor, guardando en la memoria 2 bytes (creo 10bits de resolución) por cada valor obtenido.

En el programa, antes de guardar en la memoria se tendría que verificar que la nueva temperatura sea distinta a una anterior para evitar que se llene la memoria demasiado rápido. 

Con block de notas entiendo que eso lo vas a mandar a una PC, en ese caso el PIC esperaría a que la memoria se llene con datos válidos para luego enviarlos a la PC pero está vez convertidos a un valor legible de temperatura (25°C, 26°C, etc)...


----------



## bubu23

siiii eso es llo que necesito!!!, pero aun no sé como hacerlo ..gracias!!


----------



## ByAxel

Una forma fácil de enviar datos del PIC a la PC es por medio del puerto serie, sobre eso hay bastante en el foro. Para tratar esos datos en la PC necesitaras un programa de PC, intenta con esto Manual Puerto serie RS232 controlado por Visual C# o este Como usar puerto Serie en VBA (Excel).

Cuando practiques la recepción de los datos usa el hyperterminal ¿Cómo configurar la hyperterminal para comunicación serial?.
Con lo del sensor, guarda en la memoria el dato válido (de 2 en 2 ya que cada lectura ocupa 2bytes) y cuando esta se llene la envías a la PC pero convertido en temperatura.

saludos.


----------



## Josempb9

Hola a todos ,
soy nuevo en el tema de ADC, y pues estoy tratando de utilizar un sensor de proximidad en un proyecto de la escuela.

Estuve viendo el codigo que corrigieron para darme una idea de como funcionaba el ADC, pero la verdad no comprendo los valores de ADCON1 y ADCON0.

/*
ADCON1=192; //<- valores
ADCON0=128; //<- valores
*/

No se si me pudieran explicar por que pusieron esos valores, para darme una idea del funcionamiento de ADCON1 y ADCON0.

Gracias a todos XD.


----------



## ByAxel

Josempb9 dijo:


> Estuve viendo el codigo que corrigieron para darme una idea de como funcionaba el ADC, pero la verdad no comprendo los valores de ADCON1 y ADCON0.
> 
> /*
> ADCON1=192; //<- valores
> ADCON0=128; //<- valores
> */
> 
> No se si me pudieran explicar por que pusieron esos valores, para darme una idea del funcionamiento de ADCON1 y ADCON0.


Siempre trabaja con la hoja de datos del dispositivo.
Por ejemplo para el PIC16F877A:
- En el registro ADCON1 se configura los pines que van a ser entradas análogas, la justificación del resultado y la velocidad de conversión.
- En el registro ADCON0 se configura la velocidad de conversión, el canal o pin del cual se a a obtener el valor a convertir, se obtiene o establece el estado del módulo y el encendido/apagado del módulo.

Entonces:
ADCON1=192; //<- En binario es 0b11000000 y viendo el registro en el datasheet se establece:
- La justificación del resultado es a la derecha.
- La velocidad de conversión es de (Fosc/4, Fosc/16, Fosc/64 o Interno RC).
- Todos los pines son entradas análogas.

ADCON0=128; //<- En binario es 0b10000000.
- Se complementa la velocidad establecida en ADCON1, entonces la velocidad escogida es Fosc/64.
- Se leerá el canal cero (0).
- Con la conversión detenida.
- Y el módulo apagado.


----------



## Josempb9

Muchas gracias ByAxel, la verdad me sirvio mucho lo que me acabas de decir. Estuve checando la datasheet y ya todo tiene sentido XD WOOOTT!!!.

De nuevo muchisimas gracias , y pues espero que todos esten bien .


----------



## omi281193

disculpen hay alguien que me podria ayudar es que quisiera saber como puedo programar en basic estuve ocupando el microcode pero no se si es solo la version que tengo pero solo me deja compilar 31 lineas la verdad quisiera saber si alguien me puede pasar una version que pueda compilar programas mas grandes o si me recomiendan algun otro programa
de antemano gracias


----------



## ByAxel

omi281193 dijo:


> disculpen hay alguien que me podria ayudar es que quisiera saber como puedo programar en basic estuve ocupando el microcode pero no se si es solo la version que tengo pero solo me deja compilar 31 lineas la verdad quisiera saber si alguien me puede pasar una version que pueda compilar programas mas grandes o si me recomiendan algun otro programa
> de antemano gracias



Bienvenido.
Revisa: Curso programacion de pic en bsic pro... los programas usados son el compilador PicBasicPro 2.6 y el IDE de MicrocodeStudio 4... ambos se complementan.

Otros (ni mejor ni peor)...
- Proton IDE Basic > http://www.protonbasic.co.uk/
- MiKroBasic > http://www.mikroe.com/eng/products/view/9/mikrobasic-pro-for-pic/
- PicSimulatorIDE > http://www.oshonsoft.com/pic.html

Las "Reglas del foro" impiden poner links con crack y esas cosas...

saludos.


----------



## bubu23

Muchas gracias ByAxel es justo lo que me falta hacer,pero mi problema es el siguiente que yo utilizo la libreria on-wire y la lectura del sensor se guarda en distintas variables las que finalmente visualizo por la pantalla lcd,entonces como estoy utilizando la memoria i2c 24lc256 realizo el programa así:

  I2C1_Init(100000);      // initialize I2C communication
  I2C1_Start();           // issue I2C start signal
  I2C1_Wr(0xA0);          // send byte via I2C  (device address + W)
  I2C1_Wr(0x00);             // send byte (address of EEPROM location)
  i2c1_wr(0x00);
  i2c1_wr(temp); //esta variable hace que se visualize la temperatura en el lcd,pero en la eeprom no veo la temperatura correcta veo otra.
  I2C1_Stop();            // issue I2C stop signal
  Delay_100ms();

  I2C1_Start();           // issue I2C start signal
  I2C1_Wr(0xA0);          // send byte via I2C  (device address + W)
  I2C1_Wr(0x00);             // send byte (data address)
  I2C1_Repeated_Start();  // issue I2C signal repeated start
  I2C1_Wr(0xA1);          // send byte (device address + R)
  PORTA = I2C1_Rd(0u);    // Read the data (NO acknowledge), en este puerto ta conectado el ds18b20
  I2C1_Stop();            // issue I2C stop signal

yo creo que no estoy guardando lo que se debe guardar y no sé como hacerlo.
Por favor si alguien mas me puede ayudar se lo agradeceré inmensamente.


----------



## ByAxel

Ando un poco ocupado...
Lo estás simulando o no? si lo simulas en proteus usa el archivo *.cof más la simulación paso a paso (step) de ese modo se abre una ventana donde aparece el programa y puedes poner punto de ruptura (BreakPoints) para detener el programa y que lo analices con calma que es lo que hace.
Otra con el datasheet de ambos componentes revisa que la secuencia de escritura/lectura la realices bien, así mismo como el código de acceso. 
Otra es que lo que leas lo envíes por el puerto serie, así visualizas el dato, de la misma forma, lo que escribes en la EEPROM, lo vuelves a leer y lo envías por el puerto serie a la PC o en caso de simulación, al "Virtual Terminal".
saludos.


----------



## sdel

Hola, estoy usando el mikroc y quiero hacer in generador de señales, especialmente de onda senoidal, el problema es que cuando declaro un vector de 90 enteros no me compila, me dice ¡memoria insuficiente!  cuanto ocupa un entero en mikroc?
la otra forma que intente es hacer yo mismo la funcion seno, pero el codigo se jace muy largo y tambien me da memoria insufuciente? estoy usando el 16f877. 
sera que tengo que registrarme y pagar la version completa? 

pd:
lei por ahi que necesitaban algo de una cerradura. yo tengo un proyecto terminado de una cerradura electronica en mikroc, usando un display lcd y un teclado de 4x4, tengo el archivo de proteus, si quieren se los subo.

saludos


----------



## Pedro34

hola a todos soy nuevo en este foro 
Yo tube problemas con el I2C por hardware del pic 18f4550 y al final lo hice funcionar con el I2C por software que tambie lleba el Mikroc

Feliz Navidad y Prospero Año Nuevo


----------



## sdel

Pedro34 dijo:


> hola a todos soy nuevo en este foro
> Yo tube problemas con el I2C por hardware del pic 18f4550 y al final lo hice funcionar con el I2C por software que tambie lleba el Mikroc
> 
> Feliz Navidad y Prospero Año Nuevo



hola y no probaste en assembler dentro del mikroc?


----------



## asdlocal

Y necesito unos programas para entender mejor, ahora estoy utilizando los pic, y por lo que veo no se define en ningun lado o almenos eso entendi, bien por eso  necesito unos programas hechos con el mikro, o si no almenos unos ejemplos con LCD y manejo del ADC 


Por favor.... lo necesito

Se los agradezco de antemano.......


----------



## mikromax

Estimados:

Estoy usando un 16F877a con proteus.
Tengo conectado una referencia al RA3, un generador de senial al RA0.
Luego mediante leds verifico que la conversion sea correcta, pero al enviar los datos solo puedo visualizar 255 cuando la conversion es maxima(todos leds encendidos) y 248 con 0V (todos leds apagados)

adjunto codigo.



void envio ();
void recibo ();

unsigned int peso1,peso2,set,temp_p1, temp_p2;

void main()


{
  ADCON1 = 0x81;  // Configure analog inputs and Vref en la entrada RA3
  TRISA  = 0xFF;  // PORTA is input
  TRISD  = 0;     // PORTD is output
  TRISB  = 0x3F;  // Pins RB7, RB6 are outputs


  // Initialize USART module (8 bit, 2400 baud rate, no parity bit..)
  Usart_Init(4800);

  do {
    peso2 = Adc_Read(0);
    delay_ms(10); // Get results of AD conversion
    PORTD = peso2;       // 8 bits menos significativos se mueven al puerto PORTD
    PORTB = peso2 >> 2;  // Send 2 most significant bits to RB7, RB6
    envio();

  } while(1);
}

void envio ()

{
    Usart_Write(peso2);
    delay_ms(500);
    }


----------



## sanfor45

Buenas , yo estoy empezando con el ENC28j60 apenas y mi duda es. si yo configuro el controlador por medio de la comunicacion spi. 
Es decir programa mi pic y mi pic se encarga de configurar el conmtrolador.
necesito un progrmador especial par el controlador?

Buenas , yo estoy empezando con el ENC28j60 apenas y mi duda es. si yo configuro el controlador por medio de la comunicacion spi. 
Es decir programa mi pic y mi pic se encarga de configurar el conmtrolador.
necesito un progrmador especial par el controlador?


----------



## mendek

que tal foro, alguien sabra de algun tutorial con ejemplos un tanto basicos para empezar a familiarisarse con este programa? baje un tutorial en .pdf pero la verdad es q no trae ejemplos. desde ya muchas gracias


----------



## ByAxel

mendek dijo:


> que tal foro, alguien sabra de algun tutorial con ejemplos un tanto basicos para empezar a familiarisarse con este programa? baje un tutorial en .pdf pero la verdad es q no trae ejemplos. desde ya muchas gracias


Hola.
En la carpeta de instalacion (Mikroelektronika) ya sea en (Archivos de programa o en Mis documentos) encuentras varios ejemplos usando sus módulos internos y demàs... el resto sigue siendo lenguaje C.

Saludos


----------



## BeToR

Alguien que me pueda orientar a como enviar un numero entero mayor de 255 por USART de MikroC, estoy haciendo una trasmision PIC a PIC con un 16f877a y un 18f4620. Lo que busco es enviar un numero de 16bits por Tx y que lo reciba en Rx, se que hay forma de enviarlo en dos Bytes de 8bits y unirlos despues en el pic receptor para formar nuevamente el numero de 16bits.

Alguien lo ha realizado en MikroC, o sabe las bases para conseguir los dos grupos de 8 bits? Gracias


----------



## FRYCK

hola BeToR  puedes probar lo siguiente:



		Código:
	

unsigned int variable;
unsigned char var2[2];

   variable=0x3535;
   var2[0]=(unsigned char)(variable&0xff);
   var2[1]=(unsigned char)((variable>>8)&0xff);


saludos


----------



## Norberto

Consulta MIKROC

como defino una etiqueta a algo desconozco como se llama, que represente un numero
ejemplo  tengo muchos delay_us(476); y quiero que una palabra equivalga al numero 476 , 
este mismo lo pongo en el encabezado del pprog y cambio todos los delay desde alli.
No quiero que sea una variable.


----------



## tannke

#define tiempo 476

saludos


----------



## Norberto

buenisimo tannke, #define tiempo 476 sin ;


----------



## samlov

como utilizo la OPTION_REG para el pic16f887, ya que tengo que hacer un contador de 8bits, es decir de 0 a 255, este pic lo estoy programando en mikroc y lo que quiero saber es como 
configurar la option_reg para que haga el conteo y asi visualizarlo en la lcd...


----------



## tannke

El OPTION REGISTER no hace conteos, este sirve para activar/desactivar los pullups y para configurar algunos parametros del TIMER0 (este si hace conteos).

En el datasheet tienes toda la información de como configurarlo segun lo que necesites (el timer0), ya que este puede funcionar de distintas formas.

Un saludo


----------



## hmhumsa

Disculpen amigos ciber pero no puedo hacer correr el programa en miKroC talves por alguna configuracion una ayuda lo hise tal como lo mencionan con nuevo proyecto pero no compila. gracias

Saludos amigos


----------



## tannke

Poca información, con lo que nos das es difícil saber. Pon el error que te da al compilar, la línea, el código e incluso una imagen de la pantalla de configuración.

Un saludo.


----------



## yeysonp

buenas tengo una duda soy nuevo programando y por ejemplo si tomo el pic 16f84a y programo que el puerto a y el b sean salidas verdad y en e A coloco unos led que enciendan y apagen funcionan bien tal cual yo quiero pero al colocar  que ocurra lo mismo por el puerto B no ocurre osea que los dos puertos funcionen al mismo tiempo lo mas que he logrado es que por el puerto a se ejecute el encendido y apagado de los led infinitamente y por el B solo enciende y apaga una vez y ya pero no puedo lograr que se repitan infinitamente en los 2 puertos al mismo tiempo 

int x;
void main(void)
{
INTCOn=0;
TRISB=0;
PORTB=0;
trisa=0;
porta=1;
delay_ms(10);
porta=0;
delay_ms(10);

while(1)
{

for(x=0;x<8;x++)
{
delay_ms(500);
PORTB=1<<x;
}
}
}

ven si le coloco un bucle al puerto a no funciona el B que estoy haciendo mal??????


----------



## tannke

El único fallo que veo es que creo ahun no comprendes muy bién como va esto. En un microcontrolador las instrucciones se ejecutan una a una, solo una y una detrás de otra. Si tu pones un bucle infinito "while(1)" en la zona donde tratas el puerto "A" nunca llegarás a ejecutar las del bucle "B".
Soy un poco malo explicando, para que lo veas te recomiendo hagas una depuración de tu programa paso a paso poniendo el bucle en A y sin el (como lo tienes ahora) y ahí verás perfectamente lo que te intento decir.

Un saludo


----------



## carferper

como te explicaron antes, debes poner tu codigo dentro de un mismo lazo, algo asi:



		Código:
	

void main() {
     int i;
     TRISA = 0;
     TRISB = 0;
     PORTA = 0;
     PORTB = 0;

     while(1){
        PORTA = ~PORTA;
        for (i = 0; i <= 7; i++){
            PORTB = 1<<i;
            Delay_ms(200);
        }
     }
}


----------



## Norberto

Tengo un problema con Mikroc, cada vez que escribo una letra o modifico algo de mi codigo, se apaga la imagen del monitor de la pc y luego vuelve a encender, es muy molesto, es como si se estuviera por ejecutar algo en DOS, es un problema en la maquina del laburo, en otros lados no lo hace, probe de desactivar antivirus  y otros soft pero sigue haciendo lo mismo, no se si le paso a alguien mas y lo pudieron solucionar


----------



## raulavila1995

Buenas Noches, Les agradecería si me pudieran echar una mano en esto, Yo trabajo en       MiKroC pro.
Estoy tratando de realizar una comunicación serial entre dos pic.
Tengo entendido q*ue* cuando se escribe por ejemplo esto:

UART1_Write_Text("Dato");
  UART1_Write(10);
  UART1_Write(13);

Convierte el pic la palabra "dato" en una serie de ceros y unos que transmite a través de la linea tx los datos para ser recibidos por otro pic. 

El problema es q*ue* necesito convertir esos ceros y unos de nuevo a la palabra  "dato"  para poder transmitirla a un LCD y no se como hacer eso.
Mi programa es este:


		Código:
	

char dato ;
sbit LCD_RS at Rb0_bit;
sbit LCD_EN at Rb3_bit;
sbit LCD_D7 at Rb7_bit;
sbit LCD_D6 at Rb6_bit;
sbit LCD_D5 at Rb5_bit;
sbit LCD_D4 at Rb4_bit;

sbit LCD_RS_Direction at TRISb0_bit;
sbit LCD_EN_Direction at TRISb3_bit;
sbit LCD_D7_Direction at TRISb7_bit;
sbit LCD_D6_Direction at TRISb6_bit;
sbit LCD_D5_Direction at TRISb5_bit;
sbit LCD_D4_Direction at TRISb4_bit;


void main() {
Delay_ms(100);
cmcon = 7 ;
trisa = 0 ;
Lcd_Init();
Lcd_Cmd(_LCD_CLEAR);
  Lcd_Cmd(_LCD_CURSOR_OFF);
  UART1_Init(2404);
  Delay_ms(100);


while (1) {
if(UART1_Data_Ready()== 1) {
      dato = UART1_Read();
      Lcd_out_cp(dato);
      Lcd_Cmd(_LCD_CLEAR);
      dato = 0 ;
      delay_ms (1000) ;
      }
}


De antemano gracias.


----------



## oscarlis

estoy haciendo un código en mikroC para enviar datos por usb pero me sale un error en esta linea de codigo 

//Función de rutina USB
//dentro de las interrupciones.
void HID_Inte( void )
{
asm CALL _Hid_InterruptProc    //esta parte sale marcada de rojo
asm nop
}

y en el error me sale

undeclarer identifier '_Hid_interruptProc' in expresion

y no doy con el problema


----------



## jjv

gente a*quí *les dejo un tutorial acerca de como crear un nuevo proyecto en mikroc espero q*ue* les sea útil saludos


----------



## Fogonazo

oscarlis dijo:


> estoy haciendo un código en mikroC para enviar datos por usb pero me sale un error en esta linea de codigo
> 
> //Función de rutina USB
> //dentro de las interrupciones.
> void HID_Inte( void )
> {
> asm CALL _Hid_InterruptProc    //esta parte sale marcada de rojo
> asm nop
> }
> 
> y en el error me sale
> 
> undeclarer identifier '_Hid_interruptProc' in expresion
> 
> y no doy con el problema



Se esta haciendo una llamada a un procedimiento *NO* declarado *(_Hid_InterruptProc)*



jjv dijo:


> gemte aki les dejo un tutorial acerca de como crear un nuevo projecto en mikroc espero q les sea util saludos



Gracias por el aporte


----------



## picnoob

Buenas, estoy trabajando con mikroc 2012, estoy imprimiendo una cadena pero me sobre escribe lo que esta a un lado y no se porq.



		Código:
	

int valor;
char prueba;
valor=EEPROM_Read(0x30);
IntToStr(valor,prueba);
Lcd_Out(2, 1, text1);
Lcd_Out(2, 4, prueba);//este da el problema, probe colocando un texto y aparece justo
//en la cuarta linea del LCD tambien probe char prueba[5], *prueba[5] pero imprimen
//caracteres raros








Como vez alli el primer cuadro es colocando un texto directo.

El segundo qda alejado mas si suma(operacion que realizo) que es lo importante pero sobreescribe max o lo que esta a la derecha.

El tercer cuadro es colocandolo prueba[5] o *prueba [5], este me muestra caracteres raros ademas del simbolo de grados que parece que lo copiara de la linea de arriba.


Y en el segundo cuadro para poder que se vean los numeros tuve que eliminar la impresion del max ya que lo tapaba.


----------



## tannke

Muy buenas, esta librería tenía sus cositas, yo las dejé de usar por el tema este, si usas un int te reserva 7 espacios que va rellenado por la derecha menos el ultimo que lo pone como 0x00 que intdica que es un string, en el caso de usar un byte o char te reserva 4, pero ya no te sirve con valores mayores a 255

Puedes provar con la conversión byte si tus valores no superan este:


		Código:
	

char valor;
char prueba[4];
valor=EEPROM_Read(0x30);
ByteToStr(valor, prueba);
Lcd_Out(2, 1, text1);
Lcd_Out(2, 4, prueba);


Si este no te sirve (pinsa que el 4º digito es nulo y borrará lo que tengas) solo te quedan 2 alternativas, usar estas librerias y luego tratar la matriz (creando una nueva mas corta y solo poniento los bytes que necesites) o crearte tu propia librería.

esto es lo que hay.

Ah y recuerda (no se si lo puse en este hilo y no se si en nuevas versiones de mikroc ya está arreglado que me parece que no), cuando usas la librería Lcd_Out(x,x,x); el texto que pones consume memoria ram, y si vas a crear un menú con mucho texto constante (tipo: "Menu:", "Configuración", .....) la ram te va a volar y tenemos poca. Pues tienes que usar esto:


		Código:
	

void Lcd_Out2(char fila, char col, const char *dat)
{
     while(*dat)
     {
         Lcd_Chr(fila,col++, *dat++);
     }
}

Con esto usas la rom en lugar de la ram.Lo pones ahi arriba en tu codigo y se usa de la misma manera:
Lcd_Out2(2, 1, "Hola mundo");
Pero solo para texto constante, no variables.

Un saludo


----------



## picnoob

tannke dijo:


> Muy buenas, esta librería tenía sus cositas, yo las dejé de usar por el tema este, si usas un int te reserva 7 espacios que va rellenado por la derecha menos el ultimo que lo pone como 0x00 que intdica que es un string, en el caso de usar un byte o char te reserva 4, pero ya no te sirve con valores mayores a 255
> 
> Puedes provar con la conversión byte si tus valores no superan este:
> 
> 
> Código:
> 
> 
> char valor;
> char prueba[4];
> valor=EEPROM_Read(0x30);
> ByteToStr(valor, prueba);
> Lcd_Out(2, 1, text1);
> Lcd_Out(2, 4, prueba);
> 
> 
> Si este no te sirve (pinsa que el 4º digito es nulo y borrará lo que tengas) solo te quedan 2 alternativas, usar estas librerias y luego tratar la matriz (creando una nueva mas corta y solo poniento los bytes que necesites) o crearte tu propia librería.
> 
> esto es lo que hay.
> 
> Ah y recuerda (no se si lo puse en este hilo y no se si en nuevas versiones de mikroc ya está arreglado que me parece que no), cuando usas la librería Lcd_Out(x,x,x); el texto que pones consume memoria ram, y si vas a crear un menú con mucho texto constante (tipo: "Menu:", "Configuración", .....) la ram te va a volar y tenemos poca. Pues tienes que usar esto:
> 
> 
> Código:
> 
> 
> void Lcd_Out2(char fila, char col, const char *dat)
> {
> while(*dat)
> {
> Lcd_Chr(fila,col++, *dat++);
> }
> }
> 
> Con esto usas la rom en lugar de la ram.Lo pones ahi arriba en tu codigo y se usa de la misma manera:
> Lcd_Out2(2, 1, "Hola mundo");
> Pero solo para texto constante, no variables.
> 
> Un saludo




Hice lo de ByteToStr y me salio asi


Lo que me parecio bien, el unico detallito que no entiendo es por que sale el simbolo de grados (°).

En cuanto a la memoria RAM no se si esto te diga algo, uso un 16f887

0 1141 Used RAM (bytes): 70 (20%)  Free RAM (bytes): 282 (80%) Used RAM (bytes): 70 (20%)  Free RAM (bytes): 282 (80%)


----------



## tannke

Buenas otra vez, con el simbolo de grados ni idea, no recuerdo que me pasara nunca, habría que ver el codigo entero y segun se vea hacer un debug para ver donde mete ese simbolo, lo malo de mikroc es que sus librerías son cerradas y no sabemos realmente como funcionan.
Sobre el tema de la RAM de momento tienes de sobra, pero puede llegar el caso que utilices mucho texto en el lcd y en ese caso sí te sería mas util la función.

Un saludo


----------



## gonza2-5

Hola, estoy programando en MikroC 4.6 y 5.4. Tengo un problema con el mismo. Cada vez que agrego la llave de cierre se agrega automáticamente las barras "//" para comentarios. ¿Hay alguna forma de quitarlos? Muchas gracias!


----------



## elmismo

Hola a todos.
Pregunta para quien me pueda ayudar. Cualquier código que intento montar (Bild) en MikroC, siempre me devuelve el Finished (with error) en la linea 0 error 102. Según tengo entendido no es problema del compilador ni el código tiene error alguno, es un problema del sistema pero llevo todo el dia recomponiendo el registro del sistema y demás cosas que se me han podido ocurrir y he consultado en la red pero nada. No sé por donde continuar. ¿Alguien me puede orientar como salir de ésta?.
Gracias de antemano.


----------



## viedmon

Buenos días.

No he logrado inicializar ninguno de los Timers, ¿será que requieren alguna instrucción en ASM? Les agradezco su respuesta


----------



## raulli

Hola desde hace tiempo busco un programa hecho en Mickro C pro for compiler, para un PIC16F628
para hacer un contador con punto decimal, para que en el LCD 2x16 aparesca los digitos 000.000

si alguin tiene algo les agradeceria su ayuda gracias. ...


----------



## ByAxel

El modo fácil es usando la función FloatToStr(), convierte valor numérico a cadena string... revisa la documentación del MikroC.


----------



## william21

Buenas noches, estoy trabajando con el compilador mikroC y estoy intentando programar el teclado matricial 4x4 con una lcd 128x64, en las librerias aparece pero con una lcd mas pequeña, pero con una lcd mas grande no veo como funciona ya que veo que no tiene los mismos comandos. 

Les agradeceria bastante, gracias ...


----------



## BrunoARG

Hola.
No programo en MikroC, pero te puedo asegurar que no todos los LCDs se controlan con la misma librería, ni con el mismo protocolo. Según imagino, es de 128x64 caracteres, pero no debe tener el mismo driver que los demás LCDs, o los más conocidos de 16x2.

Saludos.


----------



## TRILO-BYTE

debes leer la hoja de datos de esa LCD
y en base a sus comandos debes programarla no todo viene del cielo


----------



## Hypnos202

Hola a todos.
A ver si me pueden ayudar con este código en mikroc, apenas me estoy iniciando en lenguaje C, por lo tanto no consigo dar con la solución.

En si; lo que quiero hacer es mostrar por la LCD el Numero 11 en "Binario, Decimal, Hexadecimal y Punto Flotante"

N = 11
Binario = 1011
Decimal = 11
Hexadecimal = B
Punto Flotante = 11.00

Aquí esta el código a ver si me echan una mano:



		Código:
	

//Definición de pines del LCD
sbit LCD_RS at RB0_bit;
sbit LCD_EN at RB1_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;

//Definición de los TRIS del LCD
sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
// End de la Configuracion
// *************************************************

char Text1[] = "Bienvenido";
char Text2[] = "Bin";
char Text3[] = "Dec";
char Text4[] = "Hex";
char Text5[] = "Punt.F";

char Text6[16];
char Text7[16];
char Text8[16];
char Text9[16];

//Impresión de el Numero 11 en Binario, Decimal, Hexadecimal y Punto Flotante
unsigned int v1 = 1011;
unsigned int v2 = 11;
unsigned int v3, v4;
unsigned float v5 = 11.00;

void main()
{
//Inicio del LCD.
Lcd_Init();
//Borrado del cursor.
Lcd_Cmd(_LCD_CURSOR_OFF);
delay_ms(500);
Lcd_Cmd(_LCD_CLEAR);
//Impresión de Text1 durante 1 segundo.
Lcd_Out(1, 4, Text1);
delay_ms(1000);
Lcd_Cmd(_LCD_CLEAR);
// Impresión de Textos "Text2, Text3, Text4, Text5"
Lcd_Out(1,0, Text2);
Lcd_Out(1,9, Text3);
Lcd_Out(2,0, Text4);
Lcd_Out(2, 6, Text5);
// Conversión de decimal a Binario
IntToStr(v1, Text6);
Lcd_Out(1,4, Text6);
// Conversion de entero a cadena de caracteres para mostrar decimal = 11
IntToStr(v2, Text7);
Lcd_Out(1, 13, Text7);
// Conversión de decimal a hexadecimal
v3 = 11;
v4 = Dec2Bcd16(v3);
IntToStr(v4,Text8);
Lcd_Out(2,4, Text8);
// Conversion de Decimal a Punto Flotante
FloatToStr(v5, Text9);
Lcd_Out(2,10, Text9);
}


----------



## D@rkbytes

Hypnos202 dijo:


> Hola a todos.
> A ver si me pueden ayudar con este código en mikroc, apenas me estoy iniciando en lenguaje C, por lo tanto no consigo dar con la solución.
> 
> En si; lo que quiero hacer es mostrar por la LCD el Numero 11 en "Binario, Decimal, Hexadecimal y Punto Flotante"
> 
> N = 11
> Binario = 1011
> Decimal = 11
> Hexadecimal = B
> Punto Flotante = 11.00



Prueba con esta modificación del código al cual le agregué una rutina para convertir de decimal a binario (4 Bits)


		Código:
	

//Definición de pines del LCD
sbit LCD_RS at RB0_bit;
sbit LCD_EN at RB1_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;

//Definición de los TRIS del LCD
sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
// End de la Configuracion
// *************************************************

//Impresión de el Numero 11 en Binario, Decimal, Hexadecimal y Punto Flotante

void main()
{
char bin_buffer[5];
char Text1[3];
char Text2[5];
char Text3[9];

unsigned int i,valor;
unsigned int v1 = 11;
float v2 = 11.00;
//Inicio del LCD.
    Lcd_Init();
//Borrado del cursor.
    Lcd_Cmd(_LCD_CURSOR_OFF);
    Lcd_Cmd(_LCD_CLEAR);
//Impresión de Texto durante 1 segundo.
    Lcd_Out(1, 4, "Bienvenido");
    delay_ms(1000);
    Lcd_Cmd(_LCD_CLEAR);

// Conversión de Decimal a Binario (4 Bits)
   valor = v1;
   for (i = 0; i < 4; i++)
   {
   if (valor & 0x08)    // Se comprueba el MSB (Bit mas significante "Bit3")
      bin_buffer[i] = '1'; // Si este es uno, colocar un 1 en el buffer
   else
      bin_buffer[i] = '0'; // Si este es cero, colocar un 0 en el buffer
   valor <<= 1;         // Rotar los Bits a la izquierda 1 Bit
   }
   lcd_out(1,1,"Bin:");
   Lcd_Out(1,6, bin_buffer);
// Conversion de entero a cadena de caracteres para mostrar decimal = 11
   lcd_out(2,1,"Dec:");
   ByteToStr(v1, Text1);
   Lcd_Out(2,5, Text1);
   delay_ms(2000);
// Conversión de decimal a hexadecimal
   Lcd_Cmd(_LCD_CLEAR);
   lcd_out(1,1,"Hex:");
   IntToHex(v1,Text2);
   Lcd_Out(1,6, Text2);
// Conversion de Decimal a Punto Flotante
   lcd_out(2,1,"Flt:");
   FloatToStr(v2, Text3);
   Lcd_Out(2,6, Text3);
}

Suerte.


----------



## Mushito

¿como se configura los fuses para trabajar con el pic 18F2550 en HID?, tengo la version de mikroC 6.0.0
por favor posteen una imagen


----------



## D@rkbytes

Mushito dijo:


> ¿como se configura los fuses para trabajar con el pic 18F2550 en HID?, tengo la versión de mikroC 6.0.0
> por favor posteen una imagen


La configuración de fuses para trabajar con el módulo USB depende del cristal que quieras usar.
Ve la hoja de datos para que sepas los cristales que puedes usar para llevar el CPU a 48MHz.
Ahí también encontrarás la forma de hacerlo y conforme a eso configuras los fuses.


----------



## Mushito

Gracias por responder, uso cristales de 20MHz. Pero tal vez no fui muy claro en mi pregunta. Adjunto dos imajenes para que alguien me diga la diferencia en la configuracion.
Gracias.
La Primera imagen es del libro *
Diseño y simulación de sistemas microcontrolados en lenguaje C 
*



No se puede subri imagenes pero la pag 47 de ese libro es diferente a las opciones de "Edit Project" del MikroC pro for pic version 6.0.0


----------



## D@rkbytes

Mira la imagen adjunta para la configuración de fuses con cristal de 20MHz.

También adjunto un ejemplo (Blinking LED) a 1 segundo, para que no queden dudas.

Para adjuntar archivos e imágenes, mira por aquí: *¿Cómo subo imágenes y archivos?* 

Suerte.


----------



## washington14

*H*ola chicos*.* *E*stoy viendo el MikroC y es muy interesante IDE*,* tiene para distintas familias de microcontroladores.
*T*iene muy buenas librer*í*as*,* sin embargo me gustar*í*a saber si éstas librer*í*as se pueden modificar en c*ó*digo.
*L*as he buscado y no encontré por ninguna parte  las librer*í*as en los archivos del Mikroc.


----------



## D@rkbytes

Las librerías que usa mikroC están compiladas y por lo tanto no se pueden modificar.
Se encuentran en las carpetas "P16", "P16_Enh" y "P18" dentro de la carpeta "Uses" y tienen la extensión *.MCL


----------



## lordaenema

Amigos, disculpen que les hable del mikroBasic pero es con el que estoy trabajando y creo que la pregunta es válida para los dos compiladores.
Actualmente estoy trabajando con un keypad. Lo  que quiero saber, es cómo puedo hacer para poder manipular los valores que entran por el teclado.

Más o menos, esto es lo que llevo:


		Código:
	

if kp="*" then // este es el boton de enter
Lcd_Cmd(_LCD_CLEAR)
lcd_out(1,1,"simulando ro")
lcd_Cmd(_LCD_SECOND_ROW)
Lcd_chr(2,5,ro1)
goto generar
end if
Lcd_Chr_CP(kp) // aquí muestra los numeros que van entrando por el teclado
inc(curx)          // este contador es para el cursor 
if curX=1 then  // esto es lo que trato de hacer para salvar el valor, 
ro1= keypad_key_press()// introducido por el teclado y  poder 
end if                           // hacer algunas operaciones artimeticas para despues mostrarlas otra vez 
if curX=2 then               //por la lcd, mas o menos a una calculadora!
ro2=kp 
end if
if curX=3 then
lcd_cmd(_LCD_MOVE_CURSOR_RIGHT)
ro3=kp
end if
wend
generar:

El problema está en que con eso no puedo obtener el valor real que esta entrando y me sale cualquier disparate cuando trato de mostrar el valor.

Si me pudiesen ayudar, se los agradezco. Bless.


----------



## D@rkbytes

¿Con *Select Case*?

*Select Case* kp
*Case 1*
' Código o llamada a subrutina.
*Case 2*
' Código o llamada a subrutina.
*Case 3*
' Etcétera.
*End Select*

El valor que retorna *Keypad_Key_Click()* es del 1 al 16 para un teclado 4x4
También puedes cambiar los valores al ASCII o darles el tipo que quieras.


		Código:
	

Case 1
    kp = 49  ' 1
Case 2
    kp = 50  ' 2
Case 3
    kp = 51  ' 3
Case 4
    kp = 65  ' A
Case 5
    kp = 52  ' 4
Case 6
    kp = 53  ' 5
Case 7
    kp = 54  ' 6
Case 8
    kp = 66  ' B
Case 9
    kp = 55  ' 7
Case 10
    kp = 56  ' 8
Case 11
    kp = 57  ' 9
Case 12
    kp = 67  ' C
Case 13
    kp = 42  ' *
Case 14
    kp = 48  ' 0
Case 15
    kp = 35  ' #
Case 16
    kp = 68  ' D
End Select

Posteriormente y si lo requieres, puedes convertir el valor de kp con: *ByteToStr(Input, Output)* para mostrar en pantalla la tecla que se presionó.

PD: No utilizo mikroBasic.


----------



## ruben90

Estaba escribiendo un pequeño código en lenguaje C, y me surgió la duda de ¿Si es bueno utilizar las librerías del compilador en cuestión de tiempo? Yo utilizo mikroC y escribí estos dos códigos:

Código 1:


		Código:
	

unsigned int valor_adc;
void main () {
ANSEL = 0X01;
ANSELH = 0;
TRISA0_bit = 1;
PORTA = 0;
while(1) {
valor_adc = ADC_Read(0);
}
}

Código 2:


		Código:
	

unsigned int valor_adc;
void main () {
ANSEL = 0X01;
ANSELH = 0;
TRISA0_bit = 1;
ADCON0 = 0X80;
ADCON1 = 0X80;
PORTA = 0;
while(1) {
ADCON0.ADON = 1;
delay_us(20);
ADCON0.GO = 1;
while(ADCON0.GO == 1);
valor_adc = (ADRESH << 8) + ADRESL;
}
}


¿Cuál tarda menos en ejecutarse?
¿Cuál utiliza menos memoria al ejecutarse?


----------



## papirrin

> cual tarda menos en ejecutarse?



Yo he medido los tiempos haciendo ambos metodos y practicamente es lo mismo.


----------



## Daniel Meza

Puedes darte una idea importando a MPLAB el archivo .hex que te genera mikroC y ver en la opción "desensamblar". Allí verás cuál de las dos rutinas ocupa más espacio y tiempo de ejecución

Salu2


----------



## ruben90

muchas gracias, como escuche un rumorcillo de que utilizar librerias hace que el pic busque los registros y esto hace que tarde un poco más de lo usual, usare el MPLAB para sacarme de dudas


----------



## papirrin

Yo cambiaria la forma de verlo...

Digamos que el conversor tarda 10ms en hacer el calculo y el pic se lleva 20nS en las instrucciones con la libreria y 30nS con codigo el tiempo total no es muy diferente.


----------



## Daniel Meza

No como tal, el "riesgo" de usar librerías es que posiblemente dentro de esas librerías hay funciones que nunca se utilizan dentro del programa pero aún así se graban en el micro y esto ocupa memoria. Pero aclaro, esto depende del desarrollador de la librería; generalmente las librerías del mismo compilador están optimizadas para usar sólo lo que el programador escribe.


----------



## D@rkbytes

Daniel Meza dijo:


> No como tal, el "riesgo" de usar librerías es que posiblemente dentro de esas librerías hay funciones que nunca se utilizan dentro del programa pero aún así se graban en el micro y esto ocupa memoria. Pero aclaro, esto depende del desarrollador de la librería; generalmente las librerías del mismo compilador están optimizadas para usar sólo lo que el programador escribe.


Así es. Tanto las librerías como el programa principal, se pueden optimizar para que únicamente se compilen las funciones que se requiera usar.
Para eso se emplean las directivas  *#IFDEF* o *#IFNDEF*
Al establecer definiciones el compilador sólo compilará el código requerido y la parte *#ELSE* será parte del código pero no será compilada.


----------



## Miguel2015

Hola. Buenas tardes compañeros. Soy nuevo el foro y estoy estudiando programación de PICs.
Tengo un pequeño problema a la hora de interpretar la sintaxis de un código del libro que estoy estudiando.

Se las anexo.


		PHP:
	

PORTE&=(0<<RS|0<<RW|0<<E);

TRISE&=(0<<RS|0<<RW|0<<E);

DB=(1<<DB5)|(1<<DB4)|(1<<NL);

DB=(1<<DB3)|(1<<DSP)|(1<<CUR);
PORTE|=(1<<E);

PORTE&=~((1<<E));

Son algunas partes del código que no puedo comprender, se me dificulta por los operadores a nivel de bit de desplazamiento, no entiendo el por qué poner 0<<RS ¿El cero qué equivale?
El RS tiene un valor de 0.
¿Alguien me puede explicar con peras y manzanas para poder entender a este tipo de operadores nivel bit?

Gracias.


----------



## Miembro eliminado 356005

El código, corregido, es así:



		PHP:
	

PORTE &= (0 << RS  |  0 << RW  |  0 << E);

TRISE &= (0 << RS  |  0 << RW  |  0 << E);

DB = (1 << DB5) | (1 << DB4) | (1 << NL);

DB = (1 << DB3) | (1 << DSP) | (1 << CUR);

PORTE |=   (1 << E);

PORTE &= ~((1 << E));

El operador '<<' hace un desplazamiento del primer operando, tantos bits hacia la izquierda como lo indique el segundo operando.

Así, por ejemplo, '1 << E' quiere decir que desplazará el valor '1' tantos bits hacia la izquierda como el valor indicado por 'E'.

Si 'E' vale, digamos, 3, entonces el '1' (0b00000001) se desplaza hacia la izquierda tres posiciones, quedando en '8' (0b0001000).

Entonces, '0 << RS', siendo RS = 0; tenemos que '0' (0b00000000) debe desplazarse cero posiciones a la izquierda, así que... no lo desplaza, y el resultado es '0' (0b0000000).


----------



## IDMar

Hola a todos. Estoy queriendo simplemente generar una onda cuadrada de aproximadamente 2Khz y realmente no me está funcionando.
Estoy usando el micro "PIC16F887" (programándolo mediante MikroC)

Adjunto el código:


		Código:
	

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

void main() {

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
OPTION_REG = 0b00000111;      //reloj interno (fosc/4);  prescalador al Timer0; prescalador en 8
OSCCON.SCS = 1;                //fuente de clock interno
while(1)
{
}
}

Depurando, encuentro que el registro TMR0 queda eternamente en 0, por ende jamás llega a ejecutarse la interrupción.
¿Qué puede estar pasando?

Gracias.


----------



## ilcapo

hola IDMar ! no me acuerdo mucho de la programacion en ASM pero creo que te falta habilitar el bit GIE (interrupciones globales) proba con eso a ver si te funciona, saludos!


----------



## IDMar

Gracias por tu consejo ilcapo!! Justamente la habilitación esta hecha con el bit 7 del registro INTCON (INTCON = 0b10100000 y con el bit 5 habilito la interrupción del timer.


----------



## papirrin

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;
> }


----------



## ilcapo

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


----------



## TRILO-BYTE

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


----------



## IDMar

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.


----------



## Norberto

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


----------



## Norberto

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


----------



## Miembro eliminado 356005

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.


----------



## JUAMPYHDR

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.


----------



## D@rkbytes

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.


----------



## papirrin

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


----------



## JUAMPYHDR

Gracias solucionare mi error


----------



## danny90

Hola buenos días, alguien sabe porque me marca error en los pines de entrada del puerto B 


		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;
}
}


----------



## D@rkbytes

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.


----------



## danny90

D@rkbytes dijo:


> 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;
}
}


----------



## D@rkbytes

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
    }
}


----------



## dosekk

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;
}
}


----------



## D@rkbytes

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.


----------



## dosekk

D@rkbytes dijo:


> 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


----------



## D@rkbytes

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.


----------



## dosekk

Cierto subí otro código que no era  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
}


----------



## D@rkbytes

dosekk dijo:


> Cierto, subí otro código que no era  jejeje


La variable "tempC" la estás manejando como un arreglo, por eso el compilador no te permite hacer esa comparación.
Podrías trabajarlo cómo puntero, "if(*tempC<minimo)PORTE=0X01;" aunque de la forma en que vienes manejando los datos, no creo que funcione.
También puedes comparar un elemento, (El elemento que contenga la temperatura deseada) o varios elementos con un bucle for.

Por cierto, en ésta instrucción estás terminando con dos puntos:


		PHP:
	

    if(tempC>maximo)PORTE=0X02:


----------



## dosekk

ya hice que funcione jejeje gracias por todo, ahora viene una pregunta ¿Puedo conectar un modulo bluetooth y al mismo tiempo el max232 por los pines rx y tx del pic? lo que pasa es que tengo que mandar los datos de la temperatura a mi celular y a la pc..


----------



## D@rkbytes

Podría ser, pero sería mejor que usaras otros pines y para alguno uses RS-232 por software.


----------



## dosekk

no tendrías un ejemplo en MikroC de como puedo configurar otros pines para que hagan la función de la comunicación serial???

Para que me de una idea mas o menos..


----------



## D@rkbytes

No uso ese compilador, pero posiblemente la instalación incluya algún ejemplo.


----------



## ruben90

El compilador tiene una librería llamada UART que permite asignar los pines TX y RX a cualquier pin del microcontrolador. Hay una pestaña en la parte izquierda del compilador llamada "Library Manager", busca la librería que te comento y clic sobre el signo (+). Te mostrara las funciones correspondiente a la librería, doble Clic sobre cualquiera y te mostrara una ventana de ayuda explicando cada función. Para futuras referencias descarga el manual de usuario del compilador, la versión en ingles, *es gratuita* y trae muchos ejemplos.


----------



## ericl

Una consulta estoy empezando a usar MicroC PRO for PIC y el tema es LCD cuando envio el dato tipo FLOAT valor = 0.125 .... en pantalla me imprime el valor de la imagen.
Lo que digo es que en otro compilador como PIC C eso no ocurria osea te da chance a modificar incluso la cantidad de datos despues del punto decimal y no se tenia que hacer conversion de dato como el FloatToStr(valor,x).... 
Ahora estoy usando este compilador porque lo necesito por temas de curso.

Ojo: No tomar en cuenta el dato ADC = 573, ya que la aplicacion era tomar datos analogicos y mostrarlo en una lcd pero tengo problemas con la conersion FloatToString.


----------



## D@rkbytes

ericl dijo:


> Una consulta. Estoy empezando a usar MikroC PRO for PIC y el tema es LCD cuando envío el dato tipo FLOAT valor = 0.125, en pantalla me imprime el valor de la imagen.


Otro de los problemas de mikroC.


ericl dijo:


> Lo que digo es que en otro compilador como PIC C, eso no ocurría.
> O sea, te da chance a modificar incluso la cantidad de datos después del punto decimal y no se tenía que hacer conversión de dato como el FloatToStr(valor,x)
> Ahora estoy usando este compilador porque lo necesito por temas de curso.


En mikroC se puede obtener la cantidad de dígitos después del punto, poniendo en 0 algún vector del arreglo que se usa como búfer.
Por ejemplo: buffer[4] = 0; y a continuación se pasa a la función de conversión.
Así se mostrarán dos dígitos después del punto.

Cuando termine el curso, cambia inmediatamente de compilador. 



ericl dijo:


> Ojo: No tomar en cuenta el dato ADC = 573, ya que la aplicación era tomar datos analógicos y mostrarlo en una lcd, pero tengo problemas con la conversión FloatToString.


Prueba de esta forma, evitando usar FloatToStr y mejor ir extrayendo las fracciones.


		PHP:
	

void main (void)
{
    unsigned int valor_adc;
    long voltaje;
    char fracc, *msj = " Voltios";

    lcd_init();
    lcd_cmd(_LCD_CURSOR_OFF);

    ANSEL = 0x01;            // Canal 0
    adc_init();

    while (1)
    {
        valor_adc = adc_read(0);
        voltaje = ((long) 5000 * valor_adc);
        voltaje /= 1024;
        fracc = voltaje / 1000;
        lcd_chr(1,1, fracc + 48);
        lcd_chr_cp('.');
        fracc = (voltaje / 100) % 10;
        lcd_chr_cp(fracc + 48);
        fracc = (voltaje / 10) % 10;
        lcd_chr_cp(fracc + 48);
        fracc = voltaje % 10;
        lcd_chr_cp(fracc + 48);
        LCD_Out(1, 6, msj);
        delay_ms(100);
    }
}


----------



## ericl

Gracias D@rkbytes el codigo es efectivo =)... Cuando termine el curso pasare a usar MPLAB en xc8, sera recomendable???


----------



## D@rkbytes

ericl dijo:


> Gracias, D@rkbytes. El código es efectivo. =)


Así es. De esa forma se tiene más control sobre los dígitos y se ahorra memoria.


ericl dijo:


> Cuando termine el curso pasaré a usar MPLAB en xc8.
> ¿Será recomendable?


Sí es recomendable, pero tendrás que aprenderte muy bien las hojas de datos de los microcontroladores.


----------

