2017-09-04 43 views
6

8ビットPIC用のファームウェアの作成に慣れています。 RXコマンドを受け取るLEDモジュールにPIC16F1829を使用しています。私は、RXピンで一定の値が受信されたときにLEDを点灯させるような基本設定をしようとしていますが、それを得ることさえできません。PIC16F1829 UART RX割り込みがMPLABXとXC8コンパイラを使用していません

割り込み経由でUARTを動作させたいのですが、メインループでポーリングを行うことさえできません。私の割り込みベクトルは以下のコードでコメントアウトされています。

RXピン:RC5

TXピン:オンとオフのLEDを切り替えるRB7

ピン:RA5

ピンRA5は、オンとオフのLEDを切り替えるには正常に動作します。 TXピンは動作していますが、RCIFが機能していないのと同様に、TXIF割り込みも機能していないかどうか確認していません。

私はRCIFとPIR1bits.RCIFを読んでみました。どちらもコンパイルされています。どちらもうまくいきませんでした。私は2つの異なるLEDモジュール上の2つの異なるPICでこれを試しました。それらはオンになりますが、RXピンを読み取ってもどちらでも動作しませんでした。

変数RXINは最初は3と定義されています。したがって、メインループ内のRXIN_ループによって、ライトが起動時に3回点滅するため、メインループに入ることがわかります。しかし、RCIF割り込みがRXピンでの受信時に発火していないことが分かります。

オシロスコープで、同じボーを使用してRXとTXピンの信号が一致していることを確認しましたので、ボーレートが正しく設定されていると思います(300ボー、8N1)。 5V信号。これまでRCIFをポーリングしたり、割り込みサービスルーティングを使用したりしていませんでした。私が見ていないコードで誰かが問題を見ることができれば、あなたの助けに感謝します。

マイコード:

#include <stdio.h> 
#include <stdlib.h> 
#include <xc.h> 

// This is for 300 baud rate 
#define _BAUD_PRESCALER_LOW_ 0x2A 
#define _BAUD_PRESCALER_HIGH_ 0x68 
#define _XTAL_FREQ 32000000 

#pragma config FOSC = INTOSC // Oscillator Selection->INTOSC oscillator: I/O function on CLKIN pin 
#pragma config WDTE = OFF // Watchdog Timer Enable->WDT enabled 
#pragma config PWRTE = OFF // Power-up Timer Enable->PWRT disabled 
#pragma config MCLRE = OFF // MCLR Pin Function Select->MCLR/VPP pin function is digital input 
#pragma config CP = OFF // Flash Program Memory Code Protection->Program memory code protection is disabled 
#pragma config CPD = OFF // Data Memory Code Protection->Data memory code protection is disabled 
#pragma config BOREN = ON // Brown-out Reset Enable->Brown-out Reset enabled 
#pragma config CLKOUTEN = OFF // Clock Out Enable->CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin 
#pragma config IESO = OFF // Internal/External Switchover->Internal/External Switchover mode is disabled 
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable->Fail-Safe Clock Monitor is disabled 

// CONFIG2 
#pragma config WRT = OFF // Flash Memory Self-Write Protection->Write protection off 
#pragma config PLLEN = ON // PLL Enable->4x PLL enabled 
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable->Stack Overflow or Underflow will cause a Reset 
#pragma config BORV = LO // Brown-out Reset Voltage Selection->Brown-out Reset Voltage (Vbor), low trip point selected. 
#pragma config LVP = OFF 

int flagRXFramingError = 0; 
int flagRXOverrunError = 0; 
volatile unsigned char RXIN = 3; 

unsigned char UARTRead(){ 
    return RCREG; 
} 

void writeRXIN(unsigned char a){ 
    RXIN = a; 
} 

void TX(unsigned char a){ 
    while(!TXIF){} 
    TXREG = a; 
} 

int main(int argc, char** argv) { 

    // SCS FOSC; SPLLEN disabled; IRCF 8MHz_HF; 
    OSCCON = 0xF0; 
    // TUN 0; 
    OSCTUNE = 0x00; 
    // Set the secondary oscillator 
    // Wait for PLL to stabilize 
    while(PLLR == 0) 
    { 
    } 

    // WDTPS 1:65536; SWDTEN OFF; 
    WDTCON = 0x16; 
    __delay_ms(5); 

    GIE = 1; // Global interrupts enabled 
    __delay_ms(5); 
    PEIE = 1; // Active peripheral interrupts enabled 
    __delay_ms(5); 
    RCIE = 1; // Enable USART Receive interrupt 
    __delay_ms(5); 
    TXIE = 1; // Enable USART Transmitter interrupt 
    __delay_ms(5); 
    ADIE = 1; // Enable ADC interrupts 
    __delay_ms(5); 
    RXDTSEL = 0; // RX is on RC5 pin 
    __delay_ms(5); 
    TXCKSEL = 0; // TX is on RB7 pin 
    __delay_ms(5); 

    TRISC5 = 1; // RX pin set as input 
    __delay_ms(5); 

    SPEN = 1; // Serial Port Enabled 
    __delay_ms(5); 
    SYNC = 0; // Asynchronous mode 
    __delay_ms(5); 
    RX9 = 0; // 8 bit reception 
    __delay_ms(5); 
    TX9 = 0; // 8-bit transmission 
    __delay_ms(5); 
    CREN = 1; // Receiver enabled 
    __delay_ms(5); 
    TXEN = 1; // Transmitter enabled 
    __delay_ms(5); 
    BRG16 = 1; // 16-bit baud generation 
    __delay_ms(5); 
    BRGH = 1; // High baud rate enabled 
    __delay_ms(5); 
    ABDEN = 0; // Auto baud detect disabled 
    __delay_ms(5); 

    // Baud prescaler n = [Fosc/(D*BR)] - 1 

    SPBRGH = _BAUD_PRESCALER_HIGH_; 
    __delay_ms(5); 
    SPBRGL = _BAUD_PRESCALER_LOW_; 
    __delay_ms(5); 

    TRISC6 = 0; // IadjPWM pin configured as output 
    __delay_ms(5); 
    ANSC6 = 0; // IadjPWM pin not analog input 
    __delay_ms(5); 
    TRISA5 = 0; // DimPWM pin configured as output 
    __delay_ms(5); 

    LATC6 = 1; // Max current for now until PWM written 
    __delay_ms(5); 

    while(1){ 

    // Inline assembly code to clear watchdog timer 
    //asm("CLRWDT"); 

    /*if(RXIN == 5){ 
     RA5 = 1; 
    } 
    else{ 
     RA5 = 0; 
    }*/ 

     if(PIR1bits.RCIF){ 
      writeRXIN(UARTRead()); 
      //RA5 = 0; 
      TX(RXIN); 
     } // end if RCIF 

     while(RXIN > 0){ 
      RA5 = 1; 
      __delay_ms(100); 
      RA5 = 0; 
      __delay_ms(100); 
      RXIN--; 
     } 

    } 
    // infinite loop 
    // never leave this loop 

    RA5 = 1; 
    return (EXIT_SUCCESS); 
} // end main 

/*void interrupt ISR(void){ 
    if(RCIF){// if USART Receive interrupt flag 
     RA5 = 1; 

     if(FERR){ 
      flagRXFramingError = 1; 
      SPEN = 0; 
      SPEN = 1; 

     } 
     if(OERR){ 
      flagRXOverrunError = 1; 
      CREN = 0; 
      CREN = 1; 
     } 

     while(RCIF){ // RCIF high as long as there is data in FIFO register. Read RCREG to clear RCIF flag 
      writeRXIN(UARTRead()); 
     } 

     RA5 = 0; 
    } 

    if (TXIF){// if USART Transmit interrupt 
     TXIF = 0; // Clear interrupt flag 
    } 
} // end ISRs*/ 
+1

レジスタへの書き込みの間の5msの遅延はナンセンスです。 5ミリ秒は厄介なPICでも永遠です。これらはオンチップのメモリマップドレジスタです。遅延はまったく必要ありません。 (いくつかの特殊なケースでは、ポートI/Oのデータ方向を設定してから数クロックサイクル待つ必要があるかもしれませんが、それはそれです。)5msの遅延をすべて取り除くことから始めます。 – Lundin

+1

(将来の参照のための補足として、この質問はうまく話題になりますが、https://electronics.stackexchange.com/で特定のハードウェア周辺機器に関する質問がある場合は、 )特定のPIC上のUART。そのサイトとマイクロコントローラのファームウェアの質問に潜んでいるPICの専門家の多くは、そこに完全にトピックです。) – Lundin

+0

しかし、私はこれをupvoteに強制されています、私はボーレートが正しく設定されていると思います(300ボー、8N1)。また、オシロスコープのRXピンが強くクリーンな5V信号を受信して​​いることを確認しました。ハードウェアが動作していることをまったく示唆していない埋め込み質問が多すぎるので、ソフトウェアのQ&Aサイトでは投票がすぐに終了/削除/削除されなければならない;( –

答えて

0

は、私は正確に問題を解決したが、私は私が作った大きな変化と新しいコードを共有することになりますかわからないですPROBLEM

を解決しました。

  1. 私はTXIEを有効にしました。 TXIFはほぼ常に高いので、連続割り込みを 発生します。 TX割り込みを有効にする理由が表示されません、 良いかもしれませんが。 TXIFが でゼロにならないようにTXを待ちたい場合は送信し、そうでない場合はなぜフラグを使用するのですか?

  2. 私は間違った順序で割り込みを有効にしました。私は 周辺機器を有効にしてから、それぞれの割り込みが の場合はPEIE、最後にGIEが必要です。

  3. 割り込みでFERRとOERRを処理していませんでしたが、 割り込みが発生している可能性があります。

また、元のコードにRXDTSELが正しく設定されていませんでした。ここに新しいコードがあります。今のところ、RX信号をエコーし​​て、送信された回数だけLEDを点滅させます。

#include <stdio.h> 
#include <stdlib.h> 
#include <xc.h> 

// This is for 300 baud rate 
#define _BAUD_PRESCALER_LOW_ 0x2A 
#define _BAUD_PRESCALER_HIGH_ 0x68 
#define _XTAL_FREQ 32000000 
#define _PIN_DIMPWMPIN_ RA5 

#pragma config FOSC = INTOSC // Oscillator Selection->INTOSC oscillator: I/O function on CLKIN pin 
#pragma config WDTE = OFF // Watchdog Timer Enable->WDT enabled 
#pragma config PWRTE = OFF // Power-up Timer Enable->PWRT disabled 
#pragma config MCLRE = OFF // MCLR Pin Function Select->MCLR/VPP pin function is digital input 
#pragma config CP = OFF // Flash Program Memory Code Protection->Program memory code protection is disabled 
#pragma config CPD = OFF // Data Memory Code Protection->Data memory code protection is disabled 
#pragma config BOREN = ON // Brown-out Reset Enable->Brown-out Reset enabled 
#pragma config CLKOUTEN = OFF // Clock Out Enable->CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin 
#pragma config IESO = OFF // Internal/External Switchover->Internal/External Switchover mode is disabled 
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable->Fail-Safe Clock Monitor is disabled 

// CONFIG2 
#pragma config WRT = OFF // Flash Memory Self-Write Protection->Write protection off 
#pragma config PLLEN = ON // PLL Enable->4x PLL enabled 
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable->Stack Overflow or Underflow will cause a Reset 
#pragma config BORV = LO // Brown-out Reset Voltage Selection->Brown-out Reset Voltage (Vbor), low trip point selected. 
#pragma config LVP = OFF 

int flagRXFramingError = 0; 
int flagRXOverrunError = 0; 
volatile unsigned char RXIN = 3; 

unsigned char RX(){ 
    return RCREG; 
} 

void writeRXIN(volatile unsigned char a){ 
    RXIN = a; 
} 

void TX(unsigned char a){ 
    while(!PIR1bits.TXIF); // TXIF is usually 1, only 0 when busy transmitting 
    TXREG = a; 
} 

int main(int argc, char** argv) { 

    // SCS FOSC; SPLLEN disabled; IRCF 8MHz_HF; 
    OSCCON = 0xF0; 
    // TUN 0; 
    OSCTUNE = 0x00; 
    // Set the secondary oscillator 
    // Wait for PLL to stabilize 
    while(OSCSTATbits.PLLR == 0){} 

    ADCON0bits.ADON = 0; 
    ANSELA = 0x00; 
    ANSELB = 0x00; 
    ANSELC = 0x00; 
    PIE1bits.ADIE = 0; // Disable ADC interrupts 

    TRISCbits.TRISC5 = 1; // RX pin set to input 
    TRISCbits.TRISC6 = 0; // IadjPWM pin configured as output 
    TRISAbits.TRISA5 = 0; // DimPWM pin configured as output 

    LATCbits.LATC6 = 1; // Max current for now until PWM written 

    //UART Init 
    BAUDCONbits.BRG16 = 1; // 16-bit baud generation 
    TXSTAbits.BRGH = 1; // High baud rate enabled 
    BAUDCONbits.ABDEN = 0; // Auto baud detect disabled 

    // Baud prescaler n = [Fosc/(D*BR)] - 1 
    SPBRGH = _BAUD_PRESCALER_HIGH_; 
    __delay_ms(1); 
    SPBRGL = _BAUD_PRESCALER_LOW_; 
    __delay_ms(1); 

    APFCON0bits.RXDTSEL = 1; // RX is on RC5 pin 
    APFCON0bits.TXCKSEL = 0; // TX is on RB7 pin 
    TXSTAbits.SYNC = 0; // Asynchronous mode 
    RCSTAbits.SPEN = 1; // Serial Port Enabled 
    RCSTAbits.RX9 = 0; // 8 bit reception 
    TXSTAbits.TX9 = 0; // 8-bit transmission 

    RCSTAbits.CREN = 1; // Receiver enabled 
    TXSTAbits.TXEN = 1; // Transmitter enabled 

    PIE1bits.TXIE = 0; // Enable USART Transmitter interrupt 
    PIE1bits.RCIE = 1; // Enable USART Receive interrupt 
    while(PIR1bits.RCIF){ 
     writeRXIN(RX()); 
    } 

    INTCONbits.PEIE = 1; // Enable peripheral interrupts 
    INTCONbits.GIE = 1; // Enable global interrupts 

    while(1){ 
     while(RXIN > 0){ 
      TX(RXIN); 
      _PIN_DIMPWMPIN_ = 1; 
      __delay_ms(100); 
      _PIN_DIMPWMPIN_ = 0; 
      __delay_ms(100); 
      RXIN--; 
     } 

    } 
    // infinite loop 
    // never leave this loop 
    return (EXIT_SUCCESS); 
} // end main 

void interrupt ISR(void){ 

    if(PIE1bits.RCIE && PIR1bits.RCIF){ // handle RX pin interrupts 
     while(PIR1bits.RCIF){ 
      writeRXIN(RX()); 
     } 
     if(RCSTAbits.FERR){ 
      flagRXFramingError = 1; 
      SPEN = 0; 
      SPEN = 1; 

     } 
     if(RCSTAbits.OERR){ 
      flagRXOverrunError = 1; 
      CREN = 0; 
      CREN = 1; 
     } 
    } // end RX pin interrupt handlers 

} // end ISRs*/ 
+0

私はあなたが今周辺機器の保留中のエラーをクリアしていると思います。 –

0

いくつかのマイクロコントローラは、何らかのエラーがあった場合、バイトの受信を停止します。これらのエラーをクリアしてください。通常は、いくつかのUART制御レジスタのビットをクリアすることによって行われます。

関連する問題