Hola
He estado trabajando para el diseño de una interfaz para un equipo medico a traves de un PIC 16F877 y una LCD donde se selecciona la cantidad de concentracion deseada de medicamento y el PIC devuelve el dato de flujo de aire a fijar manualmente en el equipo.
La seleccion de la concentracion deseada se hace a traves de dos botones que tienen como funcion incrementar o decrementar una variable de uno en uno hasta el valor deseado.
El problema surge cuando se desea dejar pulsado un boton por 2 seg por ejemplo y entonces el valor de incremento o decremento sea de 10 en 10 y no de uno en uno como esta sucediendo y cuando este se deje de pulsar vuelva a su estado normal.
Los botones se estan atendiendo por interrupciones y cada vez que se pulsa uno se actualiza la informacion en la pantalla LCD.
He intentado hacer ciclos dentro de la interrupcion y el PICC me compila sin errores el programa pero a la hora de simularlo con el PROTEUS se pierden direcciones dentro del programa y por tanto no funciona. Tambien he probado verificando dentro de la interrupcion el estado del boton pero cuando veo el pantalla solo me sale el resultado final del incremento o decremento y no la subida o bajada paulatina que es lo deseado.
Aqui les dejo el codigo y garcias por la atencion.
He estado trabajando para el diseño de una interfaz para un equipo medico a traves de un PIC 16F877 y una LCD donde se selecciona la cantidad de concentracion deseada de medicamento y el PIC devuelve el dato de flujo de aire a fijar manualmente en el equipo.
La seleccion de la concentracion deseada se hace a traves de dos botones que tienen como funcion incrementar o decrementar una variable de uno en uno hasta el valor deseado.
El problema surge cuando se desea dejar pulsado un boton por 2 seg por ejemplo y entonces el valor de incremento o decremento sea de 10 en 10 y no de uno en uno como esta sucediendo y cuando este se deje de pulsar vuelva a su estado normal.
Los botones se estan atendiendo por interrupciones y cada vez que se pulsa uno se actualiza la informacion en la pantalla LCD.
He intentado hacer ciclos dentro de la interrupcion y el PICC me compila sin errores el programa pero a la hora de simularlo con el PROTEUS se pierden direcciones dentro del programa y por tanto no funciona. Tambien he probado verificando dentro de la interrupcion el estado del boton pero cuando veo el pantalla solo me sale el resultado final del incremento o decremento y no la subida o bajada paulatina que es lo deseado.
Aqui les dejo el codigo y garcias por la atencion.
Código:
#include <ozomed16f.h>
#include <STDLIB.h>
#define USE_2LINE_LCD TRUE
#define LCD_DATA0 PIN_D4
#define LCD_DATA1 PIN_D5
#define LCD_DATA2 PIN_D6
#define LCD_DATA3 PIN_D7
#define LCD_RS_PIN PIN_D1
#define LCD_RW_PIN PIN_D2
#define LCD_ENABLE_PIN PIN_D3
#include <my_lcd.c>
int opcion=0,bandera,cont=20,cont1_mem=100,cont1=9,des_lcd,valor=0,boton;
int16 dato=0,datoM=0,cu_mem=255,cu=72,T1=65285;
#bit op=bandera.0
#bit f=bandera.1
#bit g=bandera.2
#define size_opcion 4
#int_RB
void RB_isr()
{op=1;
switch (opcion) {
case 1:
if(!input(pin_B4))valor++;if(valor>100)valor=100;
if(!input(pin_B5))if(valor>0)valor--;
if(!input(pin_B7))opcion++;
if(opcion>size_opcion)opcion=0;
break;
case 2:
if(!input(pin_B7))opcion++;
if(opcion>size_opcion)opcion=0;
break;
case 3:
if(!input(pin_B7))opcion++;
if(!input(pin_B7)){enable_interrupts(INT_TIMER1);set_tris_c(0xF3);g=1;}
if(opcion==4)output_bit(pin_E0,0);
if(opcion>size_opcion)opcion=0;
break;
case 4:
if(!input(pin_B7))opcion++;
if(!input(pin_B7)){disable_interrupts(INT_TIMER1);set_tris_c(0xF7);g=0;}
if(opcion==5)output_bit(pin_E0,1);
if(opcion>size_opcion)opcion=0;
break;
default:
if(!input(pin_B6))opcion++;
if(opcion>size_opcion)opcion=0;
break;
}
clear_interrupt(INT_RB);
}
#int_TIMER1
void TIMER1_sr()
{
set_timer1(T1); //64555
cont--;
if(cont>cont1)set_tris_c(0xF7);else set_tris_c(0xF3);
if(!cont)cont=20;
clear_interrupt(INT_timer1);
}
#int_AD
void AD_isr()
{
if(datoM!=read_adc()){
if(opcion==0)op=1;
datoM=read_adc();}
clear_interrupt(INT_AD);
}
void main()
{
port_b_pullups(TRUE);
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_DIV_2);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
setup_timer_2(T2_DIV_BY_1,166,1);
setup_ccp1(CCP_PWM);
set_pwm1_duty(512);
set_tris_c(0xF7);
enable_interrupts(INT_RB);
disable_interrupts(INT_TIMER0);
disable_interrupts(INT_TIMER1);
disable_interrupts(INT_TIMER2);
enable_interrupts(INT_AD);
enable_interrupts(GLOBAL);
lcd_init();
delay_ms(500);
op=1;g=0;f=0;
cu=72; //C.U. = 50%
set_pwm2_duty(make8(cu,0));
printf(LCD_PUTC, "\f");
lcd_gotoxy(1,1);
printf(LCD_PUTC, " O");
delay_ms(100);
lcd_gotoxy(3,1);
printf(LCD_PUTC, "Z");
delay_ms(100);
lcd_gotoxy(4,1);
printf(LCD_PUTC, "O");
delay_ms(100);
lcd_gotoxy(5,1);
printf(LCD_PUTC, "M");
delay_ms(100);
lcd_gotoxy(6,1);
printf(LCD_PUTC, "E");
delay_ms(100);
lcd_gotoxy(7,1);
printf(LCD_PUTC, "D");
delay_ms(100);
lcd_gotoxy(8,1);
printf(LCD_PUTC, "PLUS \n\r");
delay_ms(800);
for (des_lcd = 12; des_lcd >= 1; --des_lcd)
{
lcd_gotoxy(des_lcd,2);
printf(LCD_PUTC, " Version 001.1 \n\r");
delay_ms(200);
}
while (true)
{
delay_ms(300);
while(true){
//read_adc(ADC_START_ONLY);
if(op){
switch (opcion) {
case 1:
printf(LCD_PUTC, "\f");
lcd_gotoxy(1,1);
printf(LCD_PUTC, " Concentracion \n\r");
lcd_gotoxy(1,2);
printf(LCD_PUTC, " mg/L: %u\n\r",valor);
op=0;
break;
case 2:
printf(LCD_PUTC, "\f");
lcd_gotoxy(1,1);
printf(LCD_PUTC, " Seleccione \n\r");
lcd_gotoxy(1,2);
printf(LCD_PUTC, " xxxx mL/min \n\r");
op=0;
break;
case 3:
printf(LCD_PUTC, "\f");
lcd_gotoxy(1,1);
printf(LCD_PUTC, " Presione OK \n\r");
lcd_gotoxy(1,2);
printf(LCD_PUTC, " para generar O3 \n\r");
op=0;
break;
case 4:
printf(LCD_PUTC, "\f");
lcd_gotoxy(1,1);
printf(LCD_PUTC, " Presione OK \n\r");
lcd_gotoxy(1,2);
printf(LCD_PUTC, " para detener O3 \n\r");
op=0;
break;
default:
printf(LCD_PUTC, "\f");
lcd_gotoxy(1,1);
printf(LCD_PUTC, " Pulse MENU para \n\r");
lcd_gotoxy(1,2);
printf(LCD_PUTC, " selec. Conc. O3 \n\r");
op=0;
break;
}
op=0;
}
}
}
}
Última edición por un moderador: