Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

11/09/2015 #1


Cómo usar un puerto entrada analógica y entrada digital en CCS (lenguaje C)
Estoy usando el PIC16F873A
Quiero usar el puerto A como entrada analógica y digital a la misma vez, debido a que quiero leer el voltaje proveniente de un LM35 (pin RA0) y dos entradas donde se leerán los pulsadores RA4 y RA5.
Por favor si me pueden ayudar en la programación

Código:
//termostato 
#include <16F873A.h>
#device adc=10
#FUSES NOWDT                    
#FUSES HS                       
#FUSES NOPUT                    
#FUSES NOPROTECT                
#FUSES NODEBUG                 
#FUSES NOBROWNOUT              
#FUSES NOLVP                   
#FUSES NOCPD                    
#use delay(clock=20000000)
#define time 200
#define use_portb_lcd true    
#include <lcd.c>    

#BYTE TRISA = 0x85 
#BYTE PORTA = 0x05
#BYTE PC=0x07

unsigned int16 adc;
float tamb;
int w=0;
int i=0;
int tdes[41]=
               {0,1,2,3,4,5,6,7,8,9,10,11,12,
                13,14,15,16,17,18,19,20,21,
                22,23,24,25,26,27,28,29,30,
                31,32,33,34,35,36,37,38,39,40};

int tb[41]=
               {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
                0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
                0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
                0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
                0x28};

void main(){

bit_set (TRISA , 4);          // A4 como entrada digital, para el pulsador
bit_set (TRISA , 5);          // A5 como entrada digital, para el pulsador
set_tris_c(0b00000000);    
pc=0b00000000;             
   
setup_adc_ports(AN0);         //A0 como entrada analogica, para lm35     
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
delay_us(20);

lcd_init();         
lcd_putc("\\f");     
lcd_gotoxy(1,1);               
printf(lcd_putc,"   Bienvenido");  
delay_ms(500);

while (true)
{

adc=read_adc();                
delay_ms(1);                    
tamb=adc*(0.48875);

lcd_putc(\'\\f\');
lcd_gotoxy(1,1);             
printf(lcd_putc,"Temp-des:%d C",tdes[w]);  
lcd_gotoxy(1,2);
printf(lcd_putc,"Temp-amb:%f C",tamb);
output_c(tb[i]);
delay_ms(10);

 if(input(pin_a4)==1){
delay_ms(time);
w++;
i++;
 if((w>41)&&(i>0x29))
 {
 w=0;
 i=0;
 }

lcd_putc(\'\\f\');
lcd_gotoxy(1,1);            
printf(lcd_putc,"Temp-des:%u C",tdes[w]);  
lcd_gotoxy(1,2);
printf(lcd_putc,"Temp-amb:%f C",tamb);
output_c(tb[i]);
delay_ms(100);

}
 if (input(pin_a5)==1){
delay_ms(time);
w--;
i--;
 if((w==255)&&(i==255))
{
 w=41;
 i=0x29;
}
lcd_putc(\'\\f\');
lcd_gotoxy(1,1);            
printf(lcd_putc,"Temp-des:%u C",tdes[w]); 
lcd_gotoxy(1,2);
printf(lcd_putc,"Temp-amb:%f C",tamb);
output_c(tb[i]);
delay_ms(100);
}
}
} ...
12/09/2015 #2


Parece que esta bien, ¿que es lo que te falla?

El código es que no corre en mi compilador.
12/09/2015 #3


dogflu66 dijo: Ver Mensaje
Parece que esta bien, ¿que es lo que te falla?

El código es que no corre en mi compilador.
Estimado, lo que sucede es que cuando monto el circuito en la protoboard, la entrada analogica no me funciona (no me muestra la temperatura en el LCD).
12/09/2015 #4
Moderador

Avatar de Ratmayor

Intenta declarando la función set_adc_channel() dentro del bucle...

Código PHP:
#include <16F84A.h> 
#device adc=8 
 
#FUSES NOWDT                    
#FUSES HS                       
#FUSES NOPUT                    
#FUSES NOPROTECT                
#FUSES NODEBUG                 
#FUSES NOBROWNOUT              
#FUSES NOLVP                   
#FUSES NOCPD
 
#use delay(clock=4000000) 
 
#include <LCD420.C> 
 
float sensortemper;
 
void main(){ 
   
setup_adc_ports(ALL_ANALOG); 
   
setup_adc(adc_clock_internal); 
 
   
lcd_init(); 
   for(;;){ 
     
set_adc_channel(0); 
         
delay_ms(10); 
         
sensor read_adc(); 
         
temper = (1.97 sensor);
     
lcd_gotoxy(1,1); 
     
printf(lcd_putc "    %.1f%CC      ",temper,0xDF); 

12/09/2015 #5


Este código a mi me funciona perfecto:

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

//#use standard_io (a) //Por defecto
//#use standard_io (b) //Por defecto
//#use standard_io (c) //Por defecto
//#use fast_io (a)
//#use fast_io (b)
//#use fast_io (c)

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

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

void main()
{
   //Configuración general Pic EBasic
   setup_adc_ports(NO_ANALOGS); //Puerto como I/O
   setup_adc(ADC_OFF); //Módulo ADC a Off
   setup_ccp1(CCP_OFF); //Módulo CCP a Off
   set_tris_a(0b11111111); 
   set_tris_b(0b11011110);
   set_tris_c(0b11111111);

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

   //setup_adc_ports(NO_ANALOGS); //Puerto como I/O
   lcd_init();
   _lcdclear();
   
   //setup_adc_ports(ALL_ANALOG);     //AN4 como entrada analogica, para lm35
   setup_adc(ADC_CLOCK_INTERNAL);
   set_adc_channel(4);
   delay_us(20); 

 while(TRUE){
   Int16 _adc;
   //setup_adc_ports(ALL_ANALOG); //Puerto como Analogico
   _adc = read_adc();
   //setup_adc_ports(NO_ANALOGS); //Puerto como I/O
   _lcdline1home();
   printf(lcd_putc, "ADC:%Lu   ", _adc);
   //lcd_putc("hello");
   printf("ADC:%Lu", _adc);
   putc(cr);
   putc(lf);
   
   if (bit_test(portb, 2) == 0) Bit_clear(PORTB, 0);
   Bit_set(PORTB, 5);
   delay_ms(100);
   if (bit_test(portb, 2) == 0) Bit_set(PORTB, 0);
   Bit_clear(PORTB, 5);
   Delay_ms(100);
 }
}
El display está en el puerto A también, por lo que este trabaja como analógico e I/O.
13/09/2015 #6
Moderador

Avatar de Ratmayor

Seguro que funciona? Veo que en tu código los puertos analógicos están deshabilitados...
14/09/2015 #7


//#use standard_io (a) //Por defecto
//#use standard_io (b) //Por defecto
//#use standard_io (c) //Por defecto

Cuando no se indica nada el ccs incorpora la #use standard_io (letra del port), esto implica que se le deja al compilador la misión de configurar los pin como analógicos o I/O que son utilizados en sus funciones.
Entonces, llamamos una sola vez a "setup_adc_ports(NO_ANALOGS); //Puerto como I/O", esto indica que se elije por defecto los "NO_ANALOGS", por lo tanto al llamar a una función del sistema el compilador almacena "NO_ANALOGS" y luego reconfigura los pin que utiliza la función según la necesidad de esta, posteriormente al terminar la función vuelve a configurar los puertos por defecto "NO_ANALOGS", sin embargo, si la ultima llamada que hicimos fue "ALL_ANALOG", esta quedará por defecto y el programa no funcionará ya que este cambio automático no se aplica al manejo directo de puertos, al parecer solo se aplica a las funciones.

---------- Actualizado después de 9 minutos ----------

Yo solo uso la #use fast_io y no tengo un circuito donde pueda probar exactamente tu configuración.
La "#use fast_io" obliga al programador a definir en todo momento como trabajan los puertos, el compilador por su cuenta no cambia la configuración de los pin. Puedes probar a incorporarla en tu código, lo mismo te soluciona el problema, pero ten en cuenta que prevalece la ultima configuración de puertos que hagas. Así que la ultima configuración tiene que ser la que tu deseas. Seguramente con esta ultima opción el uso de NO_ANALOGS o ALL_ANALOG, puede generar problemas dependiendo de donde los coloques o todo lo contrario.

Nota: el programa funciona perfectamente en hardware.
14/09/2015 #8
Moderador

Avatar de Ratmayor

Lo digo es por el "//" al comienzo de la línea, al colocar eso, la línea de código se convierte en comentario y pierde efecto...
14/09/2015 #9


Esto es lo que predomina, lo demás han sido pruebas para ver lo que pasa.

Código PHP:
void main()
{
   
//Configuración general Pic EBasic
   
setup_adc_ports(NO_ANALOGS); //Puerto como I/O

------------------------------------------------------------------------

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

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

#BYTE PORTA = 0x05
#BYTE PORTB = 0x06
#BYTE PORTC = 0x07
#BYTE TRISA = 0x85 
#BYTE TRISB = 0x86 //Corregido: antes decía TRISC.
#BYTE TRISC = 0x87

void main()
{
   
//Configuración general Pic EBasic
   
setup_adc_ports(NO_ANALOGS); //Puerto como I/O
   
setup_adc(ADC_OFF); //Módulo ADC a Off
   
setup_ccp1(CCP_OFF); //Módulo CCP a Off
   
set_tris_a(0b11111111); 
   
set_tris_b(0b11011110);
   
set_tris_c(0b11111111);

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

   
lcd_init();
   
_lcdclear();
   
   
setup_adc(ADC_CLOCK_INTERNAL);
   
set_adc_channel(4);
   
delay_us(20); 

 while(
TRUE){
   
Int16 _adc;
   
_adc read_adc();
   
_lcdline1home();
   
printf(lcd_putc"ADC:%Lu   "_adc);
   
//lcd_putc("hello");
   
printf("ADC:%Lu"_adc);
   
putc(cr);
   
putc(lf);
   
   if (
bit_test(portb2) == 0Bit_clear(PORTB0);
   
Bit_set(PORTB5);
   
delay_ms(100);
   if (
bit_test(portb2) == 0Bit_set(PORTB0);
   
Bit_clear(PORTB5);
   
Delay_ms(100);
 }

14/09/2015 #10
Moderador

Avatar de Ratmayor

Pero mientras sigas diciendo:

Código PHP:
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF); 
El puerto analógico no se va activar, no se, digo yo...
14/09/2015 #11


Lo he vuelto a probar en mi hardware porque no había definido el "TRISB", y sigue funcionado correctamente.

Código:
#BYTE TRISC = 0x86 (mal) ----> #BYTE TRISB= 0x86 (Ok)
---------- Actualizado después de 28 minutos ----------

Este que parece más lógico también me funciona, hace lo mismo que el anterior.

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

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

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

void main()
{
   
//Configuración general Pic EBasic
   
setup_adc_ports(NO_ANALOGS); //Puerto como I/O
   
setup_adc(ADC_OFF); //Módulo ADC a Off
   
setup_ccp1(CCP_OFF); //Módulo CCP a Off
   
set_tris_a(0b11111111); 
   
set_tris_b(0b11011110);
   
set_tris_c(0b11111111);

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

   
setup_adc_ports(NO_ANALOGS); //Puerto como I/O
   
lcd_init(); //Líneas de datos LCD a 4Bit (PORTA).
   
_lcdclear();
   
   
setup_adc_ports(ALL_ANALOG);   //AN4 como entrada analogica, para lm35
   
setup_adc(ADC_CLOCK_INTERNAL);
   
set_adc_channel(4);
   
delay_us(20); 

 while(
TRUE){
   
Int16 _adc;
   
setup_adc_ports(ALL_ANALOG); //Puerto como analogico
   
_adc read_adc();
   
setup_adc_ports(NO_ANALOGS); //Puerto como I/O, a partir de aquí solo digital.
   
_lcdline1home();
   
printf(lcd_putc"ADC:%Lu   "_adc);
   
//lcd_putc("hello");
   
printf("ADC:%Lu"_adc);
   
putc(cr);
   
putc(lf);
   
   if (
bit_test(portb2) == 0Bit_clear(PORTB0);
   
Bit_set(PORTB5);
   
delay_ms(100);
   if (
bit_test(portb2) == 0Bit_set(PORTB0);
   
Bit_clear(PORTB5);
   
Delay_ms(100);
 }

14/09/2015 #12


Muchas gracias por su ayuda estimados, saludos cordiales.
Respuesta
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.