2017-01-16 21 views
2

:간단한 인터럽트 프로그램 트랩/CPU를 정지 (USART/PIC18F/마이크로 칩/XC8) 나는 다음과 같은 사용하고

  • PIC18F4550을
  • xc8 컴파일러,
  • MPLAB X IDE에서의 v3.20,
  • 송신기 및 수신기 모듈 (중단없이 작동하는 주 프로그램으로 테스트 됨).
  • 의 LED (1 = 점등)
  • 버튼 //이 점에서 문제가되지 않는다
RB0, RB1 및 RB2 (0 = 버튼을 누름)에 접속 RD0, RD1 및 RD2에 연결된

분명히이 코드의 모든 것이 잘 작동하지만 인터럽트가 있습니다. "void interrupt SerialComm(void)"
(나는 인터럽트없이 프로그램을 만들었습니다.)

메인이로드되지 않습니다. "PORTD = 0x0F",
(주 프로그램의 3 행)을 입력했습니다.

그래서 led가 켜지면 적어도 주 프로그램의 세 번째 줄이 작동 함을 의미합니다.
(적어도 그 라인까지,하지만 led는하지 않았다.)

내가 이것을 놓친 레지스터를 먼저 비활성화해야합니까?
또한 대부분의 자습서에 따라 내가 놓친 뭔가있을 수 있습니까?, #pragma와 함께 많은 프로그램을 보았지만 XC8 컴파일러를 사용할 때 필요한지 확실하지 않습니다.

/* 
* File: transmit.c 
* Author: steve 
* 
* Created on September 25, 2016, 12:36 AM 
*/ 
#define _XTAL_FREQ 48000000 

#include <xc.h> 
#include <pic18f4550.h> 
void DelayMs(int x); 
char ButtonsChecker(); 
char ButtonsCheckValue = 0; //returned value 
char data_received = 0; 


void main(void) { 
    TRISB = 0x0F; 
    TRISD = 0b00000000; 

    TRISCbits.TRISC2 = 0; //TXD Power 
    TRISCbits.TRISC6 = 0; //RC6 
    TRISCbits.TRISC7 = 1; //RC7 
    PORTCbits.RC2 = 1; 

    RCSTA = 0x90; 
    TXSTA = 0x20; 
    SPBRG = 77; 

    RCREG = 0; 
    RCIF = 0; 


    PORTDbits.RD0 = 1; 
    PORTDbits.RD1 = 1; 
    PORTDbits.RD2 = 1; 

    RCIE = 1; 
    TXIE = 0; 

    PEIE = 1; 
    GIE = 1; 

    while (1) { 

     while (ButtonsChecker()) { 

      TXREG = ButtonsChecker(); 
     } 


     //while (!TRMT); // waiting for a whole data frame to be ready for a transmission 
     //TXREG = PORTB; 

     //while (!RCIF); // waiting for a whole data frame to be received 
     //PORTD = RCREG; 

    } 
} 

void DelayMs(int x) { 
    while (x > 0) { 
     __delay_ms(1); 
     x--; 
    } 
} 

char ButtonsChecker() { 
    if (PORTBbits.RB0 == 0) { 
     ButtonsCheckValue = 1; 
    } else if (PORTBbits.RB1 == 0) { 
     ButtonsCheckValue = 2; 
    } else if (PORTBbits.RB2 == 0) { 
     ButtonsCheckValue = 4; 
    }//else if (PORTBbits.RB3 == 0) { 
     // ButtonsCheckValue = 8;} 
    else ButtonsCheckValue = 0; 

    return (ButtonsCheckValue); 
} 


void interrupt ReceiveData() { 
    if (RCIF == 1) { 
     RCIF = 0; 
     ~PORTDbits.RD1; 
    } 
} 
+0

인터럽트 벡터 테이블에 인터럽트를 등록 했습니까? – Lundin

+0

처음에는 PORTD = 0x0F를 수행하지만 갑자기 나중에 PORTD = 0x01로 덮어 씁니다. PORTD.0 (lsb 비트)에 연결된 것은 무엇입니까? 핀에서 전압을 찾았는지 확인하십시오 (아마 그렇게 할 것이므로 메인이 while()으로 들어갑니다). – linuxfan

+0

@linuxfan 실제로 비트 0 = 1 인 경우 LED가 3 개 연결되고 LED가 켜지면 bit1과 bit 2가 같아 지므로 0x0F 3 개가 모두 켜지지만 주 프로그램이 완전히 시작되면 0x0F는 while 루프에서 0x01에 의해 정말 빨리 overwrited되므로 RD0에있는 LED가 켜지고 나머지는 꺼지기 때문에 아무 것도 켜지지 않으므로 내가 만든 인터럽트 함수라고 가정합니다. // 뭔가 내가 생각하기에 내가 만든 인터럽트 함수에 CPU를 걸러 내고 있다고 생각하지만 무엇을 모르겠다. –

답변

0

모든 것이 O.K로 보입니다. TX 및 RC 인터럽트를 활성화하지 않았다는 점만 다릅니다. 그래서 USART 개시에 추가 : 시작 부분의 끝에서

PIE1bits.RCIE = 1; 
PIE1bits.TXIE = 1; 

도 추가

INTCONbits.GIE = 1; 

는 ... 글로벌 인터럽트를 활성화합니다.

+0

omg 고마워, 내가 그 사실을 잊어 버렸다고 나는 믿을 수 없다. 나는 꽤 오래 전에 만든 오래된 템플릿을 재사용했다. 실제로 나의 이전 버전은 TXIE 비트가 인터럽트 수신 부분을 테스트하기 위해 비활성화 된 상태 였지만, 다시 tommorow를 시도해 보겠습니다. –

+0

"RCIE"비트가 활성화되었지만 작동하지 않는 것을 본 적이있는 이전 버전의 코드를 실제로 업데이트했습니다. –

+0

Amm? 'RCREG' 레지스터는 읽기 전용이어야합니다. 그래서 왜 쓸까요? 그리고'RCIE'는 약간의 변수이므로 그렇게 설정할 수 있습니까? –