微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

波特率为 115200 时的 UART 错误,带有 ESP32 的 PIC

如何解决波特率为 115200 时的 UART 错误,带有 ESP32 的 PIC

我试图与 PIC 16F887 和 ESP32 模块通信,我试图发送一些数字只是为了测试 UART 通信,但是,读取 ESP32 接收(我在 arduino 监视器串行读取)它给了我不正确的值,例如,我在图片上发送 1,ESP32 收到 6,发送 8,发送 3,然后接收 14。我不知道这个错误代码是否与 de SPBRGH 寄存器有关,但我需要帮助。

这是我在 C 处的 PIC 代码


#define _XTAL_FREQ 8000000

#include <xc.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "mpu6050.h"
#include "I2C.h"
#include "USART.h"



//Definimos variables
char Ax,Ay,Az;
uint8_t contador;
uint8_t valorRX;


// BEGIN CONfig
#pragma config FOSC = INTRC_NOCLKOUT  // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON // brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O,HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
//END CONfig




//Prototipos de funciones
void setup(void);
void __interrupt() isr(void);



//Configuramos interrupciones
//Interrupciones

void __interrupt() isr(void) {
    if (PIR1bits.RCIF == 1) {
        valorRX = UART_get_char(); //Aqui recibimos el dato de la recepcion
        PIR1bits.RCIF = 0;
        //   PORTD = valorRX;
    }
}

void main() {
    setup();
    mpu6050_init();
    UART_config();
    while (1) {
        UART_send_char(0);
        UART_send_char(1);
        UART_send_char(2);
        UART_send_char(3);
        UART_send_char(4);
        UART_send_char(5);
        UART_send_char(6);
        UART_send_char(7);
        UART_send_char(8);
        UART_send_char(9);

void setup(void) {
    ANSEL = 0;
    ANSELH = 0;
    TRISA = 0;
    TRISA = 0;
    PORTA = 0;
    TRISB = 0;
    PORTB = 0;
    TRISC = 0;
    PORTC = 0;
    TRISD = 0;
    PORTD = 0;
    TRISE = 0;
    PORTE = 0;
    contador = 0;
    I2C_Master_Init(100000);
    INTCONbits.GIE = 1; //Habilitamos las interrupciones
    INTCONbits.PEIE = 1; //Habilitamos las interrupciones perifericas
    PIR1bits.RCIF = 0; //Apagamos la bandera del RX
}

我的 UART 库是:

#include "USART.h"

void UART_config() {


    //Para la TRANSMISION
    TXSTAbits.TXEN = 1; //Habilitamos la transmision - La bandera TXIF se pone 1 auto.
    TXSTAbits.SYNC = 0; //Configura EUSART para operacion asincrona
    RCSTAbits.SPEN = 1; //Habilita el EUSART Y PONE TX/CK I/O pin como salida
    TRISCbits.TRISC6 = 0; //Lo ponemos como salida para asegurar
    TXSTAbits.TX9 = 0; // No usaremos los 9 bits solo 8

    //Para la RECEPCION

    RCSTAbits.CREN = 1; // Habilitamos la recepcion
    PIE1bits.RCIE=1; //Se habilita la interrupcion de la recepcion
    RCSTAbits.RX9 = 0; // No usaremos los 9 bits,solo 8
    TRISCbits.TRISC7 = 1; //Lo ponemos como enTrada para asegurar

    //BAUD RATE
    SPBRG = ((_XTAL_FREQ/(8*Baud_rate))-1)/2;
    TXSTAbits.BRGH = 1;


}

void UART_send_char(char bt) {
    while (!TXIF); // ESPERAMOS HASTA QUE ESTE LIBRE LA BANDERA
    TXREG = bt; //YA QUE ESTA LIBRE CARGAMOS EL DATO
}

void UART_send_string(char* st_pt) {
    while (*st_pt) //SI HAY ALGUN CHAR
        UART_send_char(*st_pt++); //Lo procesamos como un dato
}

char UART_get_char() {
    if (RCSTAbits.OERR==1) //Vemos si hay error
    {
        RCSTAbits.CREN = 0; //Si lo hay reseteamos la recepcion
        RCSTAbits.CREN = 1; 
    }

    while (!PIR1bits.RCIF); // esperamos hasta que la bandera este libre
    return RCREG; //amos el dato de retorno


}

如果有人能帮助我,我将不胜感激。

解决方法

您的波特率公式错误。

//BAUD RATE
SPBRG = ((_XTAL_FREQ/(8*Baud_rate))-1)/2;
TXSTAbits.BRGH = 1;

从数据表第 160 页表 12-3:

// Assuming: 
#define BAUD_RATE 115200ul

TXSTAbits.BRGH = 1;
SPBRG = ((XTAL_FREQ / BAUD_RATE) / 64) - 1;

然而,这并不能确保完美的 115200 波特率。实际波特率将是,使用示例 12-1 中的公式:

unsigned long actual_baud_rate = XTAL_FREQ / (64 * (SPBRG + 1));

long delta  = actual_baud_rate - BAUD_RATE;
float error = (float)delta / (float)BAUD_RATE;

如果此误差超过 +-4%,则无法以该速度进行串行通信,您需要选择另一个主振荡器,请参阅数据表的表 12-5。或者,您可以尝试找到匹配的非标准波特率来与 Arduino 通信。在这种情况下,您还需要调整 Arduino 端口速度,类似的限制也适用于 Arduino。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。