Electoday 2025

ไมโครคอนโทรลเลอร์ => Microchip PIC => Topic started by: pantthakarn on January 02, 2015, 07:17:45 AM

Title: รบกวนถามเกี่ยวกับ การเขียน PIC 16F887 ควบคุมด้วย Remote IR
Post by: pantthakarn on January 02, 2015, 07:17:45 AM
ขอออกตัวก่อนนะครับผม มือใหม่นะครับ แต่พอเขียนโปรแกรม พื้นฐานได้บ้าง ผมอยากทราบว่าหากผมจะเขียนรับค่าจะ Remote IR
http://www.spelecshop.com/1402480/525633/infrared-remote-Kit.html
ตัวตาม Link ด้านบน ผมต้องเขียน อย่างไร และรับค่าอย่างไร มีพี่ๆพอแนะนำได้บ้างไหมครับเคยเห็นโค๊ดของที่เค้าเขียนไว้แต่ไม่เข้าใจเลยอยากจะรบกวนแนะนำให้หน่อยจะได้ไหมครับ
Title: Re: รบกวนถามเกี่ยวกับ การเขียน PIC 16F887 ควบคุมด้วย Remote IR
Post by: JENG on January 02, 2015, 12:16:53 PM
ใช้ input capture




//--------------------------------------------------
// Program  :IR Receiver (SIRC Protocol)
// Author   :Somlak Mangnimit
// Date     :21/03/2012
// Device   :PIC16F676 @int clock 4Mhz
//--------------------------------------------------
#include    <htc.h>


#define     _XTAL_FREQ 4000000


#include    "clcd.c"




__CONFIG(FOSC_HS&LVP_OFF&WDTE_OFF);


#define     LED1            PORTCbits.RC0
#define     LED2            PORTCbits.RC1
#define     LED3            PORTCbits.RC2
#define     LED4            PORTCbits.RC3
#define     LED5            PORTCbits.RC4
#define     LED6            PORTCbits.RC5
#define     LED7            PORTAbits.RA4
#define     LED8            PORTAbits.RA5


volatile unsigned char
Current_state,Counter,Got_data,bit_count,Command_code,
Device_code,WaitRelease
;


volatile unsigned int
input_data
;


enum{
Idle,Start_bit,Capture_bit
};


//------------------------------------------------
// Interrupt Service
//------------------------------------------------
void interrupt service(void){
//-------------------------
// External interrupt RB0
//-------------------------
    if(INTF){
        switch (Current_state){
            case Idle:
                INTEDG = 1;                     //interrupt on rising edge.
                Counter = 0;
                Current_state = Start_bit;
            break;
            //-------------------------
            // found the rising edge,
            // check lenght for 2.4ms
            //-------------------------
            case Start_bit:
                if(Counter == 4){               //correct signal, move on to next state
                    Counter = 0;
                    bit_count = 0;
                    input_data = 0;
                    Current_state = Capture_bit;
                }


                else {
                    INTEDG = 0;             //interrupt on falling edge.
                    Current_state = Idle;       //fault signal, reset to Idle
                }
            break;
            //-------------------------
            // check plus length
            // for 0 or 1
            //-------------------------
            case Capture_bit:
                if(Counter == 2){
                    input_data >>= 1;           // add 0 to received data
                    bit_count++;
                } 
                else{
                    if(Counter == 3){
                        input_data >>= 1;
                        input_data |= 0x8000;   //add 1 to received data
                        bit_count++;
                    }
                    //-------------------------
                    // error occurs,
                    // reset to Idle state
                    //-------------------------
                    else{
                        INTEDG = 0;             //interrupt on falling edge.
                        Current_state = Idle;
                    }
                }
                //-------------------------
                //compleat 12 bit
                //-------------------------
                if(bit_count >= 12){
                    Got_data = 1;
                    input_data >>= 4;
                    INTEDG = 0;                 //interrupt on falling edge.
                    Current_state = Idle;
                }
                Counter = 0;
            break;


            default:
                INTEDG = 0;                     //interrupt on falling edge.
                Current_state = Idle;
        }
        INTF = 0;                               //clear interrupt flag.
    }


    if(T0IF){
        TMR0 = 110;     //600us@4mhz
        T0IF = 0;       //Clear flag
        Counter++;


        if(Counter>5){
            INTEDG = 0;                     //interrupt on falling edge.
            Current_state = Idle;
        }


        if(Counter>40){
            LED8 = 0;
        }


        if(Counter>50){
            WaitRelease = 0;
        }
    }
}


//--------------------------------------------------
// Initial start up
//--------------------------------------------------
void Start_up(void){
PORTA = 0x00;
PORTC = 0x00;


//ANSEL = 0x00;               //All digital I/O
//CMCON = 0x05;               //Turn off comparator
ADCON0 = 0x00;


TRISA = 0x00;
TRISC = 0x00;


TRISBbits.TRISB0 = 1;       //IR input
TRISAbits.TRISA3 = 1;       //Sw input


//-----
INTEDG = 0;                 //Falling edge


//-----
T0IE = 1;
INTE = 1;                   //External interrupt
PEIE = 1;                   //Peripheral interrupt
GIE = 1;                    //Global interrupt


}


//--------------------------------------------------
// Main program
//--------------------------------------------------
void main(void){
Start_up();
lcd_init();
lcd_gotoxy(0, 0);
lcd_print_string("HELLO");
__delay_ms(500);


    while(1){
        if(Got_data){
            Command_code = input_data & 0x7F;
            Device_code = input_data >> 7;
            Got_data = 0;
            if(Device_code == 1 && !WaitRelease){
            WaitRelease = 1;
                switch (Command_code){
                    case 0: LED1 = ~LED1; LED8 = 1;break;
                    case 1: LED2 = ~LED2; LED8 = 1;break;
                    case 2: LED3 = ~LED3; LED8 = 1;break;
                    case 3: LED4 = ~LED4; LED8 = 1;break;
                    case 4: LED5 = ~LED5; LED8 = 1;break;
                    case 5: LED6 = ~LED6; LED8 = 1;break;
                    //case 6: LED7 = ~LED7; LED8 = 1;break;
                    //case 7: LED8 = ~LED8; break;
                }
            }
        }
    }
}
Title: Re: รบกวนถามเกี่ยวกับ การเขียน PIC 16F887 ควบคุมด้วย Remote IR
Post by: pantthakarn on January 03, 2015, 03:37:19 AM
ขอบคุณครับที่มาตอบให้เดี่ยวยังไงผมขอลองก่อนแต่เท่าที่ดูผมไม่เข้าใจหลายๆส่วนเลยละครับ มือใหม่จิงๆ
Title: Re: รบกวนถามเกี่ยวกับ การเขียน PIC 16F887 ควบคุมด้วย Remote IR
Post by: JENG on January 03, 2015, 04:58:04 PM
อย่าเพิ่งไปมองที่ code ให้ทำความเข้าใจกับ capture module ของ pic16f887 ก่อน
หลักการก็แค่ดักจับสัญญาณขอบขาขึ้นและลงแล้วเอาคาบเวลามาคำนวณ
Title: Re: รบกวนถามเกี่ยวกับ การเขียน PIC 16F887 ควบคุมด้วย Remote IR
Post by: Chairat on January 03, 2015, 09:28:57 PM
Quote from: JENG on January 03, 2015, 04:58:04 PM
อย่าเพิ่งไปมองที่ code ให้ทำความเข้าใจกับ capture module ของ pic16f887 ก่อน
หลักการก็แค่ดักจับสัญญาณขอบขาขึ้นและลงแล้วเอาคาบเวลามาคำนวณ

สวัสดีครับพี่ JENG จะทำ Software Capture ยังไงดีครับเคยปรึกษาพี่ไปในกระทู้อื่น  นะตอนนี้ก็ยังทำไม่ได้ครับ  555
Title: Re: รบกวนถามเกี่ยวกับ การเขียน PIC 16F887 ควบคุมด้วย Remote IR
Post by: JENG on January 06, 2015, 09:39:35 AM
Quote from: Chairat on January 03, 2015, 09:28:57 PM
สวัสดีครับพี่ JENG จะทำ Software Capture ยังไงดีครับเคยปรึกษาพี่ไปในกระทู้อื่น  นะตอนนี้ก็ยังทำไม่ได้ครับ  555

ถ้าของ pic เหมือนจะมีขา interrupt ที่กำหนดขอบสัญญาณ trigger ได้นะ เอามาปรับใช้ร่วมกับ timer ได้เหมือนกัน