Autor Tema: interrupciones de C a C18 - me exan una manito?  (Leído 1943 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Roddrickk

  • PIC10
  • *
  • Mensajes: 6
interrupciones de C a C18 - me exan una manito?
« en: 04 de Mayo de 2011, 15:04:36 »
Hola, toy aprendiendo C18 y quiero pasar este codigo  C a C18, he leído y leído pero no soy hábil con las interrupciones, que tipo de interrupciones son las que debo poner??, todo lo demas lo entiendo y esta listo. Falta hacer correctamente las interrupciones.

Código: [Seleccionar]
char *text = "ER-4 Remote"; // Define message
unsigned char ir_cmd=0; // Keep Command button from ER-4 Remote
//------------------ Interrupt service routine INT -----------------//

void interrupt() {
unsigned char i; // Keep counter
if(INTCON.INTF) // Check interrupt flag RB0 (Falling edge)
{
Delay_us(416); // Delay 1/2 of 1 bit timing
                       // (baudrate 1200 bps)
for(i=0;i<8;i++) // Loop 8 times for keep data from ER-4
{
Delay_us(833); // Delay of 1 bit timing
                       // (baudrate 1200 bps)

ir_cmd = ir_cmd>>1; // Shitt bit 1 time
if((PORTB & 0x01)==1) // Get logic @ RB0 = '1'?
ir_cmd = ir_cmd | 0x80; // Inset bit data is '1'
}
Delay_us(833); // Delay of 1 bit timing
                       // (baudrate 1200 bps)
INTCON.INTF =0; // Clear interrupt flag
}
}

//------------------ Function for get character from Remote ---------//

unsigned char get_remote()
{
unsigned char _key=ir_cmd; // Get character to buffer
ir_cmd=0; // Clear old data
return(_key); // Return character from Remote
}

//------------------ Main Program ----------------------------------//

void main()
{
unsigned char key; // Save Remote Key Press
ANSELH.F4=0; // RB0 ==> Digital IO
OPTION_REG.INTEDG = 0; // INT falling edge
INTCON.INTE =1; // Enable INT/PB0
INTCON.GIE =1; // Enable Global interrupt
Lcd_Init(&PORTD); // Initialize LCD connected to PORTD
Lcd_Cmd(Lcd_CLEAR); // Clear display
Lcd_Cmd(Lcd_CURSOR_OFF); // Turn cursor off
Lcd_Out(1, 1, text); // Print text to LCD,2nd row,1st column
Sound_Init(&PORTC,0);

while(1) // Infinite loop
{
key = get_remote(); // Get Remote
if(key=='a' || key=='A') // Button A press?
{
Lcd_Out(2, 1, "Button A Press "); // Display message Button A press
Sound_Play(100,500);
}
else if(key=='b' || key=='B') // Button B press?
{
Lcd_Out(2, 1, "Button B Press "); // Display message Button B press
Sound_Play(110,500);
}
else if(key=='c' || key=='C') // Button C press?
{
Lcd_Out(2, 1, "Button C Press "); // Display message Button C press
Sound_Play(120,500);
}
else if(key=='d' || key=='D') // Button D press?
{
Lcd_Out(2, 1, "Button D Press "); // Display message Button D press
Sound_Play(130,500);
} } }

lo que hace es capturar una señal de un control remoto. El receptor es un ZX-IRM de 38khz. El codigo funciona en C.

saludos.-

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: interrupciones de C a C18 - me exan una manito?
« Respuesta #1 en: 04 de Mayo de 2011, 15:13:14 »
Debes implementar interrupción externa por pin RB0 de flanco descendente. Como implementarlo en C18, utiliza el buscador  ;-)


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado Roddrickk

  • PIC10
  • *
  • Mensajes: 6
Re: interrupciones de C a C18 - me exan una manito?
« Respuesta #2 en: 13 de Mayo de 2011, 13:34:51 »
Bueno, buscando y leyendo en el foro llegué a este código. Funciona la recepción, lo malo que me llegan puros símbolos raros y a veces me muestra el botón correcto, he intentado averiguar el porque?, al parecer tienen que ver los delays, pero no logro tenerlo muy claro, a ver si pueden despejarme mis dudas, saludos.-

Código: [Seleccionar]
#include <p18f452.h>
#include <timers.h>
#include <delays.h>
#include "LCD16x1.h"
#include <stdlib.h> //Libreria para conversiones.
#include <portb.h>

#pragma config OSC = HS   
#pragma config WDT = OFF
#pragma config LVP = OFF 
#pragma config DEBUG = ON



// Comandos para el LCD

void DelayFor18TCY(void){
Delay10TCYx(2);
}

void DelayPORXLCD(void){
Delay1KTCYx(15);
}

void DelayXLCD(void){
Delay1KTCYx(2);
}
// Envia comando al LCD
void comandXLCD(unsigned char a){
BusyXLCD();
WriteCmdXLCD(a);
}

// Ubica cursor en (x = Posicion en linea, y = nº de linea)
void gotoxyXLCD(unsigned char x, unsigned char y){
unsigned char direccion;
if(y != 1)
direccion = 0x40;
else
direccion=0;
direccion += x-1;
comandXLCD(0x80 | direccion);
}

//Termino comandos LCD
unsigned char ir_cmd=0; // Keep Command button from ER-4 Remote
volatile char bandera=0;
 
void int_extISR(void);
 
// Creamos una nueva seccion de codigo a partir de la direccion 0x08.-
#pragma code Interrupcion = 0X0008
void VectorInterrupcion(void){
  _asm goto int_extISR _endasm
}
#pragma code // Cerramos seccion.

// Rutina de Interrupcion.-
#pragma interrupt int_extISR
void int_extISR(void){
  if(INTCONbits.INT0IF==1){

    bandera=1;       // Indicamos que se ha producido la interrupción.-
    INTCONbits.INT0IF=0;  // Borramos bandera.-
  }
}

//------------------ Function for get character from Remote ---------//
unsigned char get_remote(void)
{
unsigned char _key=ir_cmd; // Get character to buffer
ir_cmd=0; // Clear old data
return(_key); // Return character from Remote
}
//TERMINO get remote

void main(void)
{
char String[4];
unsigned char i; // Keep counter
unsigned char key; // Save Remote Key Press

//Main para LCD
OpenXLCD(FOUR_BIT & LINES_5X7); // Iniciamos LCD.-
comandXLCD(0x00); // Encendemos LCD.-
Delay10KTCYx(100);


    ADCON1=0x7f;
//puerto a entradas
TRISB=0xf7; //solo RC7 salida
LATBbits.LATB3=1; //RC7 puesto a uno
OpenRB0INT(PORTB_CHANGE_INT_ON & FALLING_EDGE_INT & PORTB_PULLUPS_OFF);
//INTCON = 0X90;//configuramos la interrupcion externa del RB0
//INTCON2 = 0X40;//configuramos el flanco de subida para la interrupcion
RCONbits.IPEN=0;  // Deshabilitamos Prioridades
//INTCONbits.INT0IE=1; //Habilitamos Interrupción Externa 0
INTCONbits.GIE=1;    //

//Cierre Main LCD

while(1)
   {
if(bandera==1){
//Delay_us(416);  // Delay 1/2 of 1 bit timing
Delay10TCYx(208); // (baudrate 1200 bps)

for(i=0;i<8;i++) // Loop 8 times for keep data from ER-4
{
//Delay_us(833); // Delay of 1 bit timing
Delay10TCYx(416);
Delay1TCY();
Delay1TCY();
Delay1TCY();
Delay1TCY();
Delay1TCY();


// (baudrate 1200 bps)
ir_cmd = ir_cmd>>1; // Shitt bit 1 time
if((PORTB & 0x01)==1) // Get logic @ RB0 = '1'?
ir_cmd = ir_cmd | 0x80; // Inset bit data is '1'
}
//Delay_us(833);  // Delay of 1 bit timing
Delay10TCYx(416); // (baudrate 1200 bps)
Delay1TCY( );
Delay1TCY( );
Delay1TCY( );
Delay1TCY( );

}

key = get_remote(); // Get Remote
if(key=='a' || key=='A') // Button A press?
{
gotoxyXLCD(1,1);
putrsXLCD("boton A");
Delay1KTCYx(100); //Retardo mientras escribe
gotoxyXLCD(1,1);
}
else if(key=='b' || key=='B') // Button B presionado?
{
gotoxyXLCD(1,1);
putrsXLCD("boton B");
Delay1KTCYx(100); //Retardo mientras escribe
gotoxyXLCD(1,1);
}
else if(key=='c' || key=='C') // Button C presionado?
{
gotoxyXLCD(1,1);
putrsXLCD("boton C");
Delay1KTCYx(100); //Retardo mientras escribe
gotoxyXLCD(1,1);

}
else if(key=='d' || key=='D') // Button D presionado?
{
gotoxyXLCD(1,1);
putrsXLCD("boton D"); //
Delay1KTCYx(100); //Retardo mientras escribe
gotoxyXLCD(1,1);

}
}
}


Desconectado DaYeS

  • PIC16
  • ***
  • Mensajes: 119
Re: interrupciones de C a C18 - me exan una manito?
« Respuesta #3 en: 13 de Mayo de 2011, 15:08:54 »
Que tal Roddrickk, bueno, lo primero que tendríamos que mirar es el micro que vas a utilizar, ya que hay bastante diferencia de uno a otro.

La diferencia de C a C18 no es ninguna, lo único es que sea apto o no para programar micros de la familia 18f o no.

Por lo que veo en el último código lo que quieres es ver los datos que te llegan de un receptor infrarojos de 38 kHz. Cogiendo el Datasheet del ZR-IRM cuando detecta infrarojos en 38 kHz, la línea de data (pin 1) saca un nivel bajo, y cuando no lo recibe un nivel alto.

Citar
Funciona la recepción, lo malo que me llegan puros símbolos raros y a veces me muestra el botón correcto, he intentado averiguar el porque?, al parecer tienen que ver los delays, pero no logro tenerlo muy claro, a ver si pueden despejarme mis dudas, saludos.-

La verdad es que tampoco voy a analizar el código muy bien, porque soy partidario que empieces escribiendolo de nuevo, así se evitan errores y una mejor comprensión del programa.
Pero, por lo que veo del sensor, soló es capaz de decir si algo esta emitiendo en 38 kHz o no, por lo que no hay ningún tipo de transmisión de datos, por lo soló sería posible ver esto, o haciendo un comparaciones por tiempo, mirar si es pulsado varias veces...etc.

Lo que quiero decir es que la interrupción adecuada sería la que dice Suki, la de RB0 (o RB4-7), el flanco da lo mismo, y la idea que te decia era que el emisor, para diferenciar entre 2 o 3 botones, es que uno mande un pulso, otro de los botones mande 2 pulsos en X tiempo y el 3º que mande 3 pulsos en el mismo tiempo (x).

Por lo tanto el programa temdría un tiempo en la recepción, que analiza en X tiempo, cuantos pulsos a recibido, y que pasado ese tiempo x la variable vuelva a 0. Pero personalmente pienso que si lo que quieres es transmitir datos, o hacer un mando a distancia o algo así este sensor no es el adecuado. :?

El programa sería más o menos: activamos interrupciones (mirar datasheet del pic) supongo que INT0IE (RB0), GIE (General). Dentro de la interrupcion bajar la bandera del rb0 (INT0IF) y sumar 1 a la variable, en main un bucle de 300 ms (deberás meter dalays ya que es mucho tiempo) y despues de este bucle comparar la variable a ver a cuanto esta para determinar lo pulsado.


Salu2 y espero haber ayudado.
Si buscas resultados distintos, no hagas siempre lo mismo. Albert Einstein.