PIC16F887 接收到错误的 UART 数据
PIC16F887 receiving wrong UART Data
我正在用 C (XC8) 制作一个清洁机器人,我在使用 UART 时遇到了一些问题。让我解释一下:
该项目在 PIC16F887 和 HC06 之间进行了 UART 通信。之前,该项目有一个 PIC16F1455 并且运行良好。但我需要更多并改变了微观。
使用基于 Android 的应用程序(我从不更改,我知道它工作正常)我通过蓝牙向 HC06 发送一个字符。 HC06通过UART把char发给pic,我根据数据改了个叫Pressed的变量。
所以...我配置了所有内容,更改了新图片的寄存器,放置了一个 LED 以了解我是否在每次接收中断时收到了一些东西(我这样做了)但是变量永远不会改变(我想我正在接收垃圾数据),我正在使用一个简单的“Data == Data”函数来更改变量。我的猜测:问题是波特率。 HC06需要9600,我的不一样
波特率需要图片频率和一些寄存器更改,对吗?
我需要找出为什么我的波特率不是 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 时,LED 熄灭。现在,我要根据数据表为 8MHz 内部振荡器更改 OSCCON。
//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 节中甚至有一个 table (Table 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 有误。
根据 datasheets 我有:
因此,如果您设置 BRGH = 0
但随后执行 TXSTA = 0b10100110
,您会将 BRGH(位 2)重写为 1,这意味着您需要除以 16 来计算波特率。
如果您将 12 加载到 SPBRG(等式中的 n
),您可能 运行 在 38.4k 而不是 9.6kbaud。
调试 UART 时,我发现绝对有必要在手边放一个示波器来查看信号。
您问题的第一句话为您赢得了赞成票。
我正在用 C (XC8) 制作一个清洁机器人,我在使用 UART 时遇到了一些问题。让我解释一下:
该项目在 PIC16F887 和 HC06 之间进行了 UART 通信。之前,该项目有一个 PIC16F1455 并且运行良好。但我需要更多并改变了微观。 使用基于 Android 的应用程序(我从不更改,我知道它工作正常)我通过蓝牙向 HC06 发送一个字符。 HC06通过UART把char发给pic,我根据数据改了个叫Pressed的变量。
所以...我配置了所有内容,更改了新图片的寄存器,放置了一个 LED 以了解我是否在每次接收中断时收到了一些东西(我这样做了)但是变量永远不会改变(我想我正在接收垃圾数据),我正在使用一个简单的“Data == Data”函数来更改变量。我的猜测:问题是波特率。 HC06需要9600,我的不一样
波特率需要图片频率和一些寄存器更改,对吗?
我需要找出为什么我的波特率不是 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 时,LED 熄灭。现在,我要根据数据表为 8MHz 内部振荡器更改 OSCCON。
//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 节中甚至有一个 table (Table 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 有误。
根据 datasheets 我有:
因此,如果您设置 BRGH = 0
但随后执行 TXSTA = 0b10100110
,您会将 BRGH(位 2)重写为 1,这意味着您需要除以 16 来计算波特率。
如果您将 12 加载到 SPBRG(等式中的 n
),您可能 运行 在 38.4k 而不是 9.6kbaud。
调试 UART 时,我发现绝对有必要在手边放一个示波器来查看信号。
您问题的第一句话为您赢得了赞成票。