为什么我的 PIC MCU 在串行端口上发送垃圾而不是正确的字?
why is my PIC MCU sending garbage instead of correct words on the serial port?
我已经编写了一个简单的代码来使用 PIC18F26K22 MCU 将一些字符串发送到 pc。
这段代码适用于其他一些 MCU,但在这个 MCU 上我得到连续的 0xFF 输出!。
如果我写 TXREG2='k' 它确实有效!但是为了发送一个字符串,程序似乎卡在了 pc_write 函数上,因为 RA0 引脚没有打开和关闭并且 pc 接收到连续的 0xFF 并且永不结束!
我做错了什么?!
提前致谢。
这是代码(20 Mhz 频率之前在项目属性中定义)
#pragma config FOSC = HSHP // Oscillator Selection bits (HS oscillator (high power > 16 MHz))
#pragma config PLLCFG = OFF // 4X PLL Enable (Oscillator used directly)
#pragma config PRICLKEN = ON // Primary clock enable bit (Primary clock enabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover
mode disabled)
// CONFIG2L
#pragma config PWRTEN = OFF // Power-up Timer Enable bit (Power up timer disabled)
#pragma config BOREN = SBORDIS // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
#pragma config BORV = 190 // Brown Out Reset Voltage bits (VBOR set to 1.90 V nominal)
// CONFIG2H
#pragma config WDTEN = OFF // Watchdog Timer Enable bits (Watch dog timer is always disabled. SWDTEN has no effect.)
#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)
// CONFIG3H
#pragma config CCP2MX = PORTC1 // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = OFF // PORTB A/D Enable bit (PORTB<5:0> pins are configured as digital I/O on Reset)
#pragma config CCP3MX = PORTB5 // P3A/CCP3 Mux bit (P3A/CCP3 input/output is multiplexed with RB5)
#pragma config HFOFST = ON // HFINTOSC Fast Start-up (HFINTOSC output and ready status are not delayed by the oscillator stable status)
#pragma config T3CMX = PORTC0 // Timer3 Clock input mux bit (T3CKI is on RC0)
#pragma config P2BMX = PORTB5 // ECCP2 B output mux bit (P2B is on RB5)
#pragma config MCLRE = EXTMCLR // MCLR Pin Enable bit (MCLR pin enabled, RE3 input pin disabled)
// CONFIG4L
#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = ON // Single-Supply ICSP Enable bit (Single-Supply ICSP enabled if MCLRE is also 1)
#pragma config XINST = ON // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode enabled)
// CONFIG5L
#pragma config CP0 = OFF // Code Protection Block 0 (Block 0 (000800-003FFFh) not code-protected)
#pragma config CP1 = OFF // Code Protection Block 1 (Block 1 (004000-007FFFh) not code-protected)
#pragma config CP2 = OFF // Code Protection Block 2 (Block 2 (008000-00BFFFh) not code-protected)
#pragma config CP3 = OFF // Code Protection Block 3 (Block 3 (00C000-00FFFFh) not code-protected)
// CONFIG5H
#pragma config CPB = OFF // Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)
#pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM not code-protected)
// CONFIG6L
#pragma config WRT0 = OFF // Write Protection Block 0 (Block 0 (000800-003FFFh) not write-protected)
#pragma config WRT1 = OFF // Write Protection Block 1 (Block 1 (004000-007FFFh) not write-protected)
#pragma config WRT2 = OFF // Write Protection Block 2 (Block 2 (008000-00BFFFh) not write-protected)
#pragma config WRT3 = OFF // Write Protection Block 3 (Block 3 (00C000-00FFFFh) not write-protected)
// CONFIG6H
#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot Block (000000-0007FFh) not write-protected)
#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected)
// CONFIG7L
#pragma config EBTR0 = OFF // Table Read Protection Block 0 (Block 0 (000800-003FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF // Table Read Protection Block 1 (Block 1 (004000-007FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF // Table Read Protection Block 2 (Block 2 (008000-00BFFFh) not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF // Table Read Protection Block 3 (Block 3 (00C000-00FFFFh) not protected from table reads executed in other blocks)
// CONFIG7H
#pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot Block (000000-0007FFh) not protected from table reads executed in other blocks)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void delay(int x){
int b=0;
for(b=0; b<x;b++){
__delay_ms(1);
}
}
void pc_write(const char *data)
{
while(*data){
while (TXSTA2bits.TRMT==0);
TXREG2=(*data++);
}
}
int main() {
ANSELA=0;
ANSELB=0;
ANSELC=0;
TRISC=0b11000000;
TRISB=0b11000000;
TRISA=0X0;
LATA=0;
LATB=0;
LATC=0;
TXSTA1bits.TXEN=1;
TXSTA1bits.SYNC=0;
RCSTA1bits.SPEN=1;
TXSTA2bits.TXEN=1;
TXSTA2bits.SYNC=0;
RCSTA2bits.SPEN=1;
RCSTA1bits.CREN=1;
RCSTA2bits.CREN=1;
TXSTA2bits.BRGH=1; //
BAUDCON2bits.BRG16=0; // 8 bit baud active
SPBRG2=129;
while (1){
LATAbits.LA0=1;
delay(500);
pc_write("Test") ;
LATAbits.LA0=0;
delay(500);
}
}
@Hesi 我在 MPLABX 模拟器中试过你的代码。我的IDE版本是5.50,XC8版本是2.32。但它没有为以下配置编译您的原始代码:
#pragma config XINST = ON
出现此错误:
/opt/microchip/mplabx/v5.50/packs/Microchip/PIC18F-K_DFP/1.4.87/xc8/pic/include/proc/pic18f26k22.h:16684:: error: (1504) the PIC18 extended instruction set was enabled but is not supported by this compiler
然后我将config pragma行修改为XINST = OFF
并成功编译。它确实输出 UART window 中的字符。然而,在真实的物理世界中,有许多因素可能会影响 MCU 的行为。我认为您使用某种 RS232 电缆和电平转换器将您的电路连接到您的 PC。如果是这样,请确保您的中间设备连接正确并且没有问题。您还可以采取其他几个步骤来调试电路:
- 您可以使用示波器调试 MCU 的 TX 线
- 如果不可能,您可以使用另一个 MCU 通过直接首尾相连来测试您的 MCU。您可以编写一个测试程序来读取 UART 输入并将其显示在字符 LCD 上。
顺便问一下,这与您在 MCU 中使用的代码相同吗?在我工作的一个项目中,我有效地使用了 18F46K22 及其 USART2 外设来毫无问题地发送字节序列。如果有帮助,这就是我在 16 MHz 下启动它的方式:
// BRG16 = 1, BRGH = 1
// disable interrupts before changing states
PIE3bits.RC2IE = 0;
PIE3bits.TX2IE = 0;
// ABDOVF no_overflow; CKTXP async_noninverted_sync_fallingedge; BRG16 16bit_generator; WUE disabled; ABDEN disabled; DTRXP not_inverted;
BAUDCON2 = 0x08;
// SPEN enabled; RX9 8-bit; CREN enabled; ADDEN disabled; SREN disabled;
RCSTA2 = 0x90;
// TX9 8-bit; TX9D 0; SENDB sync_break_complete; TXEN enabled; SYNC asynchronous; BRGH hi_speed; CSRC slave_mode;
TXSTA2 = 0x24;
// 9Fh @9600 bps ve @16 MHz
SPBRG2 = 0x9F;
// 1h @9600 bps ve @16 MHz
SPBRGH2 = 0x01;
// enable receive interrupt
PIE3bits.RC2IE = 1;
我已经编写了一个简单的代码来使用 PIC18F26K22 MCU 将一些字符串发送到 pc。 这段代码适用于其他一些 MCU,但在这个 MCU 上我得到连续的 0xFF 输出!。
如果我写 TXREG2='k' 它确实有效!但是为了发送一个字符串,程序似乎卡在了 pc_write 函数上,因为 RA0 引脚没有打开和关闭并且 pc 接收到连续的 0xFF 并且永不结束!
我做错了什么?!
提前致谢。
这是代码(20 Mhz 频率之前在项目属性中定义)
#pragma config FOSC = HSHP // Oscillator Selection bits (HS oscillator (high power > 16 MHz))
#pragma config PLLCFG = OFF // 4X PLL Enable (Oscillator used directly)
#pragma config PRICLKEN = ON // Primary clock enable bit (Primary clock enabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover
mode disabled)
// CONFIG2L
#pragma config PWRTEN = OFF // Power-up Timer Enable bit (Power up timer disabled)
#pragma config BOREN = SBORDIS // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
#pragma config BORV = 190 // Brown Out Reset Voltage bits (VBOR set to 1.90 V nominal)
// CONFIG2H
#pragma config WDTEN = OFF // Watchdog Timer Enable bits (Watch dog timer is always disabled. SWDTEN has no effect.)
#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)
// CONFIG3H
#pragma config CCP2MX = PORTC1 // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = OFF // PORTB A/D Enable bit (PORTB<5:0> pins are configured as digital I/O on Reset)
#pragma config CCP3MX = PORTB5 // P3A/CCP3 Mux bit (P3A/CCP3 input/output is multiplexed with RB5)
#pragma config HFOFST = ON // HFINTOSC Fast Start-up (HFINTOSC output and ready status are not delayed by the oscillator stable status)
#pragma config T3CMX = PORTC0 // Timer3 Clock input mux bit (T3CKI is on RC0)
#pragma config P2BMX = PORTB5 // ECCP2 B output mux bit (P2B is on RB5)
#pragma config MCLRE = EXTMCLR // MCLR Pin Enable bit (MCLR pin enabled, RE3 input pin disabled)
// CONFIG4L
#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = ON // Single-Supply ICSP Enable bit (Single-Supply ICSP enabled if MCLRE is also 1)
#pragma config XINST = ON // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode enabled)
// CONFIG5L
#pragma config CP0 = OFF // Code Protection Block 0 (Block 0 (000800-003FFFh) not code-protected)
#pragma config CP1 = OFF // Code Protection Block 1 (Block 1 (004000-007FFFh) not code-protected)
#pragma config CP2 = OFF // Code Protection Block 2 (Block 2 (008000-00BFFFh) not code-protected)
#pragma config CP3 = OFF // Code Protection Block 3 (Block 3 (00C000-00FFFFh) not code-protected)
// CONFIG5H
#pragma config CPB = OFF // Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)
#pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM not code-protected)
// CONFIG6L
#pragma config WRT0 = OFF // Write Protection Block 0 (Block 0 (000800-003FFFh) not write-protected)
#pragma config WRT1 = OFF // Write Protection Block 1 (Block 1 (004000-007FFFh) not write-protected)
#pragma config WRT2 = OFF // Write Protection Block 2 (Block 2 (008000-00BFFFh) not write-protected)
#pragma config WRT3 = OFF // Write Protection Block 3 (Block 3 (00C000-00FFFFh) not write-protected)
// CONFIG6H
#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot Block (000000-0007FFh) not write-protected)
#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected)
// CONFIG7L
#pragma config EBTR0 = OFF // Table Read Protection Block 0 (Block 0 (000800-003FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF // Table Read Protection Block 1 (Block 1 (004000-007FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF // Table Read Protection Block 2 (Block 2 (008000-00BFFFh) not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF // Table Read Protection Block 3 (Block 3 (00C000-00FFFFh) not protected from table reads executed in other blocks)
// CONFIG7H
#pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot Block (000000-0007FFh) not protected from table reads executed in other blocks)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void delay(int x){
int b=0;
for(b=0; b<x;b++){
__delay_ms(1);
}
}
void pc_write(const char *data)
{
while(*data){
while (TXSTA2bits.TRMT==0);
TXREG2=(*data++);
}
}
int main() {
ANSELA=0;
ANSELB=0;
ANSELC=0;
TRISC=0b11000000;
TRISB=0b11000000;
TRISA=0X0;
LATA=0;
LATB=0;
LATC=0;
TXSTA1bits.TXEN=1;
TXSTA1bits.SYNC=0;
RCSTA1bits.SPEN=1;
TXSTA2bits.TXEN=1;
TXSTA2bits.SYNC=0;
RCSTA2bits.SPEN=1;
RCSTA1bits.CREN=1;
RCSTA2bits.CREN=1;
TXSTA2bits.BRGH=1; //
BAUDCON2bits.BRG16=0; // 8 bit baud active
SPBRG2=129;
while (1){
LATAbits.LA0=1;
delay(500);
pc_write("Test") ;
LATAbits.LA0=0;
delay(500);
}
}
@Hesi 我在 MPLABX 模拟器中试过你的代码。我的IDE版本是5.50,XC8版本是2.32。但它没有为以下配置编译您的原始代码:
#pragma config XINST = ON
出现此错误:
/opt/microchip/mplabx/v5.50/packs/Microchip/PIC18F-K_DFP/1.4.87/xc8/pic/include/proc/pic18f26k22.h:16684:: error: (1504) the PIC18 extended instruction set was enabled but is not supported by this compiler
然后我将config pragma行修改为XINST = OFF
并成功编译。它确实输出 UART window 中的字符。然而,在真实的物理世界中,有许多因素可能会影响 MCU 的行为。我认为您使用某种 RS232 电缆和电平转换器将您的电路连接到您的 PC。如果是这样,请确保您的中间设备连接正确并且没有问题。您还可以采取其他几个步骤来调试电路:
- 您可以使用示波器调试 MCU 的 TX 线
- 如果不可能,您可以使用另一个 MCU 通过直接首尾相连来测试您的 MCU。您可以编写一个测试程序来读取 UART 输入并将其显示在字符 LCD 上。
顺便问一下,这与您在 MCU 中使用的代码相同吗?在我工作的一个项目中,我有效地使用了 18F46K22 及其 USART2 外设来毫无问题地发送字节序列。如果有帮助,这就是我在 16 MHz 下启动它的方式:
// BRG16 = 1, BRGH = 1
// disable interrupts before changing states
PIE3bits.RC2IE = 0;
PIE3bits.TX2IE = 0;
// ABDOVF no_overflow; CKTXP async_noninverted_sync_fallingedge; BRG16 16bit_generator; WUE disabled; ABDEN disabled; DTRXP not_inverted;
BAUDCON2 = 0x08;
// SPEN enabled; RX9 8-bit; CREN enabled; ADDEN disabled; SREN disabled;
RCSTA2 = 0x90;
// TX9 8-bit; TX9D 0; SENDB sync_break_complete; TXEN enabled; SYNC asynchronous; BRGH hi_speed; CSRC slave_mode;
TXSTA2 = 0x24;
// 9Fh @9600 bps ve @16 MHz
SPBRG2 = 0x9F;
// 1h @9600 bps ve @16 MHz
SPBRGH2 = 0x01;
// enable receive interrupt
PIE3bits.RC2IE = 1;