TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: japifer_22 en 17 de Septiembre de 2009, 22:47:27
-
hola tengo una duda con la entrada analoga N0 del pic 16f877a y ccs c. les comento:
estoy programando una interrupcion para una entrada analoga el cua es esta:
void Leer_ADC1(void){//interrupcion que avilita la entrada analoga N0
setup_port_A( ALL_ANALOG );
setup_adc( ADC_CLOCK_INTERNAL );
set_adc_channel( 0 );//numero del puerto analogo N0
V1 = read_adc();//guarda el dato optenido de la entrada analoga
delay_ms(20);
setup_adc (adc_off);
pero tengo una duda a la hora de llamar a esta interrupcion por que no se si ponerla en un do{}wile(TRUE); o For (;;) o si simplemente la dejo asi nomas osea sin poner las dos opciones anteriores
osea cual seria la mejor forma de visualisar el valor.
este:
void Leer_ADC1(void){//interrupcion que avilita la entrada analoga N0
setup_port_A( ALL_ANALOG );
setup_adc( ADC_CLOCK_INTERNAL );
set_adc_channel( 0 );//numero del puerto analogo N0
V1 = read_adc();//guarda el dato optenido de la entrada analoga
delay_ms(20);
setup_adc (adc_off);
void main()
{
lcd_init();
enable_interrupts(GLOBAL); //todas las interrupciones activadas
Leer_ADC1();
printf(lcd_putc,"Vol: %4.2f [V]",(float)V1*(5.0/1024.0)):
lcd_gotoxy(1,1);
}
o la otra forma con
void Leer_ADC1(void){//interrupcion que avilita la entrada analoga N0
setup_port_A( ALL_ANALOG );
setup_adc( ADC_CLOCK_INTERNAL );
set_adc_channel( 0 );//numero del puerto analogo N0
V1 = read_adc();//guarda el dato optenido de la entrada analoga
delay_ms(20);
setup_adc (adc_off);
void main()
{
lcd_init();
enable_interrupts(GLOBAL); //todas las interrupciones activadas
while (TRUE){
Leer_ADC1();
printf(lcd_putc,"Vol: %4.2f [V]",(float)V1*(5.0/1024.0)):
lcd_gotoxy(1,1);
}}
-
tal cual como lo tienes no es una interrupcion..para manejar la interrupcion para conversion AD seria asi:
#INT_AD
AD_ISR()
{
. aqui tu codigo
.
.
}
-
hola jhozate te coment oque no avia terminado de postiar y pase a apretar publicar por eso no alcansaste a ver todolo quepuse saludos...... pero la forma que lo tengo esta bien ??? osea por que e probado esto y me funciona
-
si te funciona esta bien :mrgreen: pero creo q hay leve confusion entre el manejo de funciones y el de la interrupcion, si vas a utilizar la interrupcion AD es como la estructura q te puse anteriormente, en ella lees el canal y fuera de ella publicas lo que quieres en el lcd, si utilizas funciones tal cual como lo tienes ahora no es necesario activar la interrupcion global.
Por otro lado se acostumbra a poner tu codigo en un ciclo infinito ya sea for(; ; ) o while (true)..pero me nace la duda de la primera forma como lo tienes solo funcionaria una sola vez? o asi tambien en ciclico.? pero creo q es mas viable la segunda forma q pusiste pero sin habilitar la interrupcion puesto q no la utilizas.
saludos
-
hola te comento que probe la primera fomra y tienes razon funciona solo la primera vez. por otra parte tu me dises que si pongo como tu dises no es nesesario poner un siclo infinito ??
lo otro como ago para generar 2 interrupciones una para N0 y otra para N1 osea me refiero a lo que pusiste como quedaria
#INT_AD
AD_ISR()
{
. aqui tu codigo
.
.
}
-
siempre es necesario que el programa principal se encuentre en un ciclo infinito, como ya comprobaste solo ejecutara una sola vez.
por ejemplo:
lcd_init()
FOR( ; ;)
{
Leer_ADC1(); //funcion de interrupcion
lcd_gotoxy(1,1);
printf(lcd_putc,"Vol: %4.2f [V]",(float)V1*(5.0/1024.0)):
}
-
como puedo entonses crear una interrupcion X como seria la forma de crear una por ejemplo que me sume dos numeros.
lo otro como ago para generar 2 interrupciones una para N0 y otra para N1 osea me refiero a lo que pusiste como quedaria
#INT_AD
AD_ISR()
{
. aqui tu codigo
.
.
}
-
la interrupcion es independiente del canal, en el programa principal puedes multiplexar el canal analogo y esperar a q ocurra la interrupcion, la interrupcion solo ocurrira cuando se ha completado la conversion AD. Supongo que tienes claro las fuentes de interrupcion en el PIC que son varias: finalizacion de conversion AD, interrupcion externa, desbordamiento del timer, USART(envio y recepcion de dato) cambio de nibble..entre otras mas...en condiciones normales el programa se encuentra en bucle infinito, cuando ocurre alguna de las interrupcion deja de hacer lo que estaba haciendo y se dirige a atender la interrupcion.
-
hola otra vez jhozate ya se como funciona una interrupcion pero se me presento una duda y es por que estoy tratando 2 entradas analogas y quiero que cada una de estas dos esten en una interrupcion distinta, y como tu dijiste para hacer una interrupcion para la entrada analoga hay que ponerle:
#INT_AD
AD_ISR(){
}
pero no se puede hacer 2 interrupciones distintas con en mismo nombre, claro esta que mi primera interrupcion se llama
#INT_AD
AD_ISR(){
}
pero la segunda ???
# quecosa iria aca para que se active la segunda interrupcion
-
Hola,
Por que te complicas la vida con interrupciones para los ADC.
Si tu codigo no es muy complejo puedes hacer la lectura de los puertos directamente desde el main de tu programa:
void main()
{
.....
while(TRUE)
{
set_adc_channel(0);
delay_us(20);
valor_1=read_adc();
set_adc_channe(1);
delay_us(20);
valor_2=read_adc();
....
}
}
En cada ciclo del ejecucion del while vas a leer las entradas analogicas, para agilizar tu codigo puedes hacer un if comparando el valor nuevo de la entrada analogica con su valor del ciclo anterior y si no ha cambiado, que no haga nada.
Espero que te haya ayudado.
Saludos