简体   繁体   English

PIC16F887 接收到错误的 UART 数据

[英]PIC16F887 receiving wrong UART Data

I'm making a cleaning robot in C (XC8) and I've got some problems with UART.我正在用 C (XC8) 制作一个清洁机器人,但我在使用 UART 时遇到了一些问题。 Let me explain:让我解释:

The project got an UART communication between a PIC16F887 and a HC06.该项目在 PIC16F887 和 HC06 之间进行了 UART 通信。 Before, the project has a PIC16F1455 and worked great.之前,该项目有一个 PIC16F1455,效果很好。 But I needed more and changed the micro.但我需要更多并改变了微观。 With an App based on Android (wich I never change and I know it works fine) I send a char via Bluetooth to the HC06.使用基于 Android 的应用程序(我从不更改并且我知道它工作正常)我通过蓝牙向 HC06 发送一个字符。 Through UART, the HC06 send the char to the pic, and I change a variable named "Pressed" according to the data.通过UART,HC06将char发送到pic,我根据数据更改了一个名为“Pressed”的变量。

So... I configured everything, changed the registers for the new pic, put a LED to know if I'm receiving something in every receive interruption (wich I do) but the variable never change (I guess I'm receiving trash data), and I'm using a simple "Data == Data" function to change the variable.所以......我配置了一切,改变了新图片的寄存器,放了一个 LED 来知道我是否在每次接收中断时收到一些东西(我这样做)但变量永远不会改变(我想我正在接收垃圾数据),我正在使用一个简单的“数据 == 数据”函数来更改变量。 My guess: the problem is the BAUD RATE.我的猜测:问题是波特率。 HC06 needs 9600, and somehow mine is different. HC06 需要 9600,不知何故我的不一样。

BAUD RATE needs the pic frequency and some register changes, right?波特率需要 pic 频率和一些寄存器更改,对吗?

I need to find why my BAUD RATE isn't 9600, can you help me?我需要找出为什么我的波特率不是 9600,你能帮我吗?

Here go some of my code, starting with the configuration bits.这是我的一些代码,从配置位开始。 I'm going to use an internall oscillator and 8MHz:我将使用内部振荡器和 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)

Here goes the main function.主函数就到这里了。

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;
}

The important here is: when Pressed is 1, the LED turns on and when it is 0 it turns off.这里重要的是:当 Pressed 为 1 时,LED 亮起,为 0 时熄灭。 Now, I'm gonna change OSCCON, according to the datasheet, for 8MHz internal oscillator.现在,我要根据数据表将 OSCCON 更改为 8MHz 内部振荡器。

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

Now, with my frequency, I'm configuring the USART:现在,按照我的频率,我正在配置 USART:

void USARTConfig(void){ //USART Configuration

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

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

}

This should give me 9600 BAUD RATE.这应该给我 9600 波特率。 There is even a table (Table 12-5) in section 12.3 of the datasheet: with 8MHz, BRGH=0, BRG16=0, SPBRG=12 --> BAUD=9600.数据表的12.3节甚至还有一个表格(表12-5):with 8MHz, BRGH=0, BRG16=0, SPBRG=12 --> BAUD=9600。

Just in case, here is my reception code:以防万一,这是我的接收代码:

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;

}

Here is what I do with the received data:这是我对接收到的数据所做的:

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


}

And last, how I compare the data received:最后,我如何比较收到的数据:

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;
        }           
    }
}

This exact functions where in my last project with the PIC16F1455, and they worked.这在我上一个使用 PIC16F1455 的项目中完全发挥作用,并且它们起作用了。 I only changes registers because this is another pic.我只更改寄存器,因为这是另一张图片。 And they don't work.他们不工作。 Am I missing something?我错过了什么吗?

I might be wrong but I think you made a mistake setting BRGH.我可能是错的,但我认为您在设置 BRGH 时犯了一个错误。

According to the datasheets I have:根据 数据表,我有:

EUSART 设置

So if you set BRGH = 0 but then do TXSTA = 0b10100110 you are rewriting BRGH (bit 2) to 1, meaning you need to divide by 16 to calculate the baudrate.因此,如果您设置BRGH = 0但随后执行TXSTA = 0b10100110您将 BRGH(位 2)重写为 1,这意味着您需要除以 16 来计算波特率。

If you load 12 onto SPBRG ( n in the equation) you are probably running at 38.4k instead of 9.6kbaud.如果您将 12 加载到 SPBRG( n中的n ),您可能会以 38.4k 而不是 9.6kbaud 运行。

When debugging UARTS I find absolutely necessary to have a scope close at hand to look at the signals.在调试 UARTS 时,我发现手边有一个示波器来查看信号是绝对必要的。

The first sentence of your question won you an upvote.你的问题的第一句话为你赢得了一票。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM