问题描述
我试图与 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。