簡體   English   中英

PIC16F887 接收到錯誤的 UART 數據

[英]PIC16F887 receiving wrong UART Data

我正在用 C (XC8) 制作一個清潔機器人,但我在使用 UART 時遇到了一些問題。 讓我解釋:

該項目在 PIC16F887 和 HC06 之間進行了 UART 通信。 之前,該項目有一個 PIC16F1455,效果很好。 但我需要更多並改變了微觀。 使用基於 Android 的應用程序(我從不更改並且我知道它工作正常)我通過藍牙向 HC06 發送一個字符。 通過UART,HC06將char發送到pic,我根據數據更改了一個名為“Pressed”的變量。

所以......我配置了一切,改變了新圖片的寄存器,放了一個 LED 來知道我是否在每次接收中斷時收到一些東西(我這樣做)但變量永遠不會改變(我想我正在接收垃圾數據),我正在使用一個簡單的“數據 == 數據”函數來更改變量。 我的猜測:問題是波特率。 HC06 需要 9600,不知何故我的不一樣。

波特率需要 pic 頻率和一些寄存器更改,對嗎?

我需要找出為什么我的波特率不是 9600,你能幫我嗎?

這是我的一些代碼,從配置位開始。 我將使用內部振盪器和 8MHz:

 PIC16F887 Configuration Bit Settings

// CONFIG1
#pragma config FOSC = INTRC_NOCLKOUT // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF      // RE3/MCLR pin function select bit (RE3/MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF      // Brown Out Reset Selection bits (BOR disabled)
#pragma config IESO = OFF       // Internal External Switchover bit (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)
#pragma config LVP = OFF         // Low Voltage Programming Enable bit

// CONFIG2
#pragma config BOR4V = BOR21V   // Brown-out Reset Selection bit (Brown-out Reset set to 2.1V)
#pragma config WRT = OFF        // Flash Program Memory Self Write Enable bits (Write protection off)

主函數就到這里了。

void main(void){

    GeneralConfig(); //Configuración general.
    BrushStart = 1; //Activamos el cepillo.
    TRISBbits.TRISB0 = 0; //TEST LED
    RB0 = 0; //TEST LED

    while(1){

        //THIS IS ANOTHER TEST
        if(Pressed==1){RB0 = 1;}
        else if(Pressed==2){RB0 = 0;}

    } //Bucle infinito.

    return;
}

這里重要的是:當 Pressed 為 1 時,LED 亮起,為 0 時熄滅。 現在,我要根據數據表將 OSCCON 更改為 8MHz 內部振盪器。

//Oscilador
OSCCON = 0b01110101; //Internal 8MHz

現在,按照我的頻率,我正在配置 USART:

void USARTConfig(void){ //USART Configuration

    //BAUDRATE (9600) = Fosc/(64*(SPBRG+1))

    BAUDCTL = 0b00000000;
    BRGH = 0;
    SPBRG = 12; 
    TXSTA = 0b10100110;
    RCSTA = 0b10010110; 

}

這應該給我 9600 波特率。 數據表的12.3節甚至還有一個表格(表12-5):with 8MHz, BRGH=0, BRG16=0, SPBRG=12 --> BAUD=9600。

以防萬一,這是我的接收代碼:

int USARTRead(char *Rxdata){

    int j=0;

    while(PIR1bits.RCIF){

            if(RCSTAbits.OERR == 1) //Overrun error           
               {RCSTAbits.CREN = 0; //Clear overrun error (disable receiver)                              
                RCSTAbits.CREN = 1;} //Enable receiver       
            if(RCSTAbits.FERR == 1) //Framing error bit
               {RCSTAbits.SPEN = 0; //Serial Port Disable
                RCSTAbits.SPEN = 1;}

            Rxdata[j]=RCREG; 
            j++;

        }

    return j;

}

這是我對接收到的數據所做的:

void ReceiveControl(char *Rxdata){

    if(DataCompare(Rxdata, "M",1)){
        ManualMode = 1;
        //BrushStart = 0;
        //Stop();
    }
    else if(DataCompare(Rxdata, "A",1)){       
        ManualMode = 0;
    }

    else if(DataCompare(Rxdata, "U",1)){Pressed = 1;} //Forward
    else if(DataCompare(Rxdata, "D",1)){Pressed = 2;} //Backward
    else if(DataCompare(Rxdata, "L",1)){Pressed = 3;} //Left
    else if(DataCompare(Rxdata, "R",1)){Pressed = 4;} //Right
    else if(DataCompare(Rxdata, "S",1)){Pressed = 0;} //Stop
    else if(DataCompare(Rxdata, "B",1)){BrushStart = 1;} //Brush Start
    else if(DataCompare(Rxdata, "X",1)){BrushStart = 0;} //Brush Stop


}

最后,我如何比較收到的數據:

int DataCompare(unsigned char Buffer[], unsigned char Data[], unsigned int length){

    int i = 0;

    while(i<length){
        if(Buffer[i] == Data[i]){

            i++;
            if(i==length){

                return 1;
            }   
        }
        if(Buffer[i] != Data[i]){

            i=length;
            return 0;
        }           
    }
}

這在我上一個使用 PIC16F1455 的項目中完全發揮作用,並且它們起作用了。 我只更改寄存器,因為這是另一張圖片。 他們不工作。 我錯過了什么嗎?

我可能是錯的,但我認為您在設置 BRGH 時犯了一個錯誤。

根據 數據表,我有:

EUSART 設置

因此,如果您設置BRGH = 0但隨后執行TXSTA = 0b10100110您將 BRGH(位 2)重寫為 1,這意味着您需要除以 16 來計算波特率。

如果您將 12 加載到 SPBRG( n中的n ),您可能會以 38.4k 而不是 9.6kbaud 運行。

在調試 UARTS 時,我發現手邊有一個示波器來查看信號是絕對必要的。

你的問題的第一句話為你贏得了一票。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM