【小技巧】Microchip 把 MPLAB X IDE工程编码改成 UTF-8

对的,你现在遇到的是编码不一致 典型场景:

VS Code → UTF-8;

MPLAB X 工程 → 默认 ISO-8859-1,所以中文全乱了。

分两步搞定:


一、把 MPLAB X 工程编码改成 UTF-8

MPLAB X 是支持 UTF-8 的,只是默认不是。官方说明:项目创建时会选一个编码,之后可以在 Project Properties → General 里修改 。(Microchip Support)

在 MPLAB X v6.25 里这样操作:

  1. Projects 窗口 中,右键你的工程(比如 exer1.X

  2. Properties...(工程属性)

  3. 在左边树里选:Conf: [default] → General

  4. 右侧最下面有一项:Encoding

    • 默认一般是 ISO 8859-1
    • 下拉选项改为 UTF-8
  5. OK 保存

  6. 把已经打开的 .c/.h 文件关掉重开一次,看中文是否恢复正常

这个设置是整个工程的默认编码 ,之后 MPLAB X 读/写源码都会按 UTF-8 处理。(Microchip Docs)


二、确认源码文件本身真的是 UTF-8

如果你在 VS Code 里保存就是 UTF-8,一般没问题;

可以在 VS Code 状态栏右下角看:

  • 显示 UTF-8 → OK
  • 如果是 GBK / GB2312 / ANSI → 需要先转换;

转换方法(在 VS Code 中):

  1. 打开该 .c/.h 文件
  2. 右下角点编码(比如 GBK
  3. "另存为编码 / Save with Encoding..."
  4. UTF-8
  5. 保存

然后回到 MPLAB X(工程编码已设置为 UTF-8),再打开这个文件,中文就不会乱了。


小结

  • 必须两边统一:

    • VS Code 保存:UTF-8
    • MPLAB X 工程 Encoding:UTF-8
  • 只改一边不行:

    • 工程还是 ISO-8859-1 → UTF-8 文件照样被当成 Latin-1 来解 → 中文乱码(典型"莫名乱码/mojibake"现象)。

c 复制代码
/*
 * ============================================================================
 * DSPIC33CK32MC105 Curiosity Nano OOB Demo 主控程序
 * ----------------------------------------------------------------------------
 * - 负责配置 MCU 的时钟、复位、调试与安全相关配置位
 * - 初始化 UART1 以便通过 Curiosity Nano 板载调试器的 USB-CDC 输出日志
 * - 通过 RB2 读取板载按钮状态,驱动 RC8 LED 并输出提示字符串
 * ============================================================================
 */

// DSPIC33CK32MC105 配置位设置
// 以下 pragma config 基于 Curiosity Nano OOB Demo 推荐设置

// FSEC
#pragma config BWRP = OFF               // Boot 区段写保护位(Boot 区段允许写入)
#pragma config BSS = DISABLED           // Boot 区段代码保护级别位(无保护(除非设置了 BWRP))
#pragma config BSEN = OFF               // Boot 区段控制位(没有 Boot 区段)
#pragma config GWRP = OFF               // 通用区段写保护位(通用区段允许写入)
#pragma config GSS = DISABLED           // 通用区段代码保护级别位(无保护(除非设置了 GWRP))
#pragma config CWRP = OFF               // 配置区段写保护位(配置区段允许写入)
#pragma config CSS = DISABLED           // 配置区段代码保护级别位(无保护(除非设置了 CWRP))
#pragma config AIVTDIS = OFF            // 备用中断向量表禁用位(禁用备用中断向量表)

// FBSLIM - 设置 Boot 区段 Flash 地址上限
#pragma config BSLIM = 0x1FFF           // Boot 区段 Flash 页地址上限位(输入十六进制值)

// FOSCSEL - 决定 MCU 上电后的初始振荡源
#pragma config FNOSC = FRCDIVN          // 振荡源选择(内部高速 RC(FRC)振荡器,带分频器)
#pragma config IESO = ON                // 双速振荡器启动使能位(先用 FRC 启动,再切换到用户选择振荡源)

// FOSC
#pragma config POSCMD = NONE            // 主振荡器模式选择位(主振荡器禁用)
#pragma config OSCIOFNC = OFF           // OSC2 引脚功能位(OSC2 为时钟输出)
#pragma config FCKSM = CSDCMD           // 时钟切换模式位(时钟切换和故障安全时钟监控均禁用)
#pragma config PLLKEN = ON              // PLL 锁定使能(如锁定丢失,则禁用 PLL 时钟输出)
#pragma config XTCFG = G3               // 晶体配置(24-32 MHz 晶体)
#pragma config XTBST = ENABLE           // 晶体启动增强(增强启动,kick-start)

// FWDT
#pragma config RWDTPS = PS2147483648    // 运行模式看门狗定时器预分频选择(1:2147483648)
#pragma config RCLKSEL = LPRC           // 看门狗定时器时钟选择(始终使用低功耗 RC 时钟)
#pragma config WINDIS = ON              // 看门狗定时器窗口使能(非窗口模式)
#pragma config WDTWIN = WIN25           // 看门狗定时器窗口选择(窗口为 WDT 周期的 25%)
#pragma config SWDTPS = PS2147483648    // 睡眠模式看门狗定时器预分频选择(1:2147483648)
#pragma config FWDTEN = ON              // 看门狗定时器使能位(硬件使能 WDT)

// FPOR
#pragma config BISTDIS = DISABLED       // 内存 BIST 功能禁用(复位时 mBIST 功能禁用)

// FICD
#pragma config ICS = PGD1               // 在电路调试通道选择位(在 PGC1 和 PGD1 通道通讯)
#pragma config JTAGEN = OFF             // JTAG 使能位(禁用 JTAG)

// FDMTIVTL
#pragma config DMTIVTL = 0xFFFF         // Dead Man 计时器低字节区间(输入十六进制值)

// FDMTIVTH
#pragma config DMTIVTH = 0xFFFF         // Dead Man 计时器高字节区间(输入十六进制值)

// FDMTCNTL
#pragma config DMTCNTL = 0xFFFF         // 32 位 DMT 指令计数超时值低 16 位(输入 0-0xFFFF 十六进制值)

// FDMTCNTH
#pragma config DMTCNTH = 0xFFFF         // 32 位 DMT 指令计数超时值高 16 位(输入 0-0xFFFF 十六进制值)

// FDMT
#pragma config DMTDIS = OFF             // Dead Man 计时器禁用位(禁用 Dead Man 计时器,可软件使能)

// FDEVOPT
#pragma config ALTI2C1 = OFF            // I2C1 备用引脚位(I2C1 映射到 SDA1/SCL1 引脚)
#pragma config SMB3EN = SMBUS3          // SMBus 使能(采用 SMBus 3.0 输入电平标准)
#pragma config SPI2PIN = PPS            // SPI2 引脚选择(SPI2 使用 PPS 可重映射引脚)

// FALTREG
#pragma config CTXT1 = OFF              // 分配给备用工作寄存器 1 的中断优先级(未分配)
#pragma config CTXT2 = OFF              // 分配给备用工作寄存器 2 的中断优先级(未分配)
#pragma config CTXT3 = OFF              // 分配给备用工作寄存器 3 的中断优先级(未分配)
#pragma config CTXT4 = OFF              // 分配给备用工作寄存器 4 的中断优先级(未分配)

// #pragma config 语句应放在项目文件包含之前。
// 使用项目枚举代替 #define 来表示 ON 和 OFF。

#include <xc.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#define FCY 1000000UL
#include <libpic30.h>

/*
 * 功能: 初始化 UART1,用于板载调试器虚拟串口输出提示信息
 * 步骤:
 *   1. 清零 UART1 模块寄存器,从已知状态开始
 *   2. 以 Fosc=200 MHz 计算波特率,配置为 9600 bps
 *   3. 启用 TX/RX、输出使能以及 UART 模块
 *   4. 通过 PPS 将 UART1 TX/RX 映射到板载调试器连接的 RD10/RD11 (RP58/RP59)
 */

void UartInit(void)
{
    U1MODE = 0;
    U1MODEH = 0;    
    U1STA = 0;
    U1STAH = 0;
    U1BRG = 25;  // 9600 baud @ Fcy ~4 MHz (BRGH=0)

    U1STAHbits.URXISEL = 6;
    U1MODEHbits.BCLKSEL = 0;
    U1MODEbits.UTXEN = 1;
    U1MODEbits.URXEN = 1;
    U1MODEbits.UARTEN = 1;
    
    //DEBUGGER USB RX/TX TEST - FOR OOB DEMO EFFORT
    RPOR13bits.RP58R = 1;
    RPINR18bits.U1RXR = 59;
}

/*
 * 功能: 通过轮询方式发送单个字节
 * - 等待发送移位寄存器空,再写入发送寄存器
 */
void UartSendByte(char data)
{
    while (U1STAbits.TRMT == 0)
    {
    } // wait for room in TX buffer

    U1TXREG = data;
} 

/*
 * 功能: 发送以 '\0' 结尾的字符串
 * - 遍历字符数组并逐字节发送
 */
void UartSendString(char *pData)
{
    unsigned int x = 0;

    while(pData[x] != 0)
    {
        UartSendByte(pData[x]);
        x = x + 1;
    }
}


int main(void)
{
    /*
     * data2: 设备刚上电且按钮未按下时,周期性提示用户按下按钮
     * data : 检测到按钮按下后,提示 LED 将执行闪烁
     * data1: 按钮释放后提示用户再次按下
     */
    char data2[] = "DSPIC33CK32MC105 Curiosity Nano Demo. Please press on-board button to initiate demo.\n\r";
    char data[] = "\n Button pressed! Enjoy the blink. \n\r";
    char data1[] = "\n Button not pressed... please press to observe blink. \n\r";

    /*
     * I/O 配置:
     * - RB2: 板载按钮输入,使用内部上拉保证未按下时保持高电平
     * - RC8: 板载 LED 输出,由 MCU 控制亮灭
     */
    _ANSELB2 = 0; //make RB2 a digital input
    _CNPUB2 = 1; //turn on internal pull up for RB2 
    _TRISB2 = 1; //RB2 an input 
    _TRISC8 = 0; // make trisc8 an output

    // 初始化 UART 日志接口
    UartInit();

    /*
     * 上电欢迎阶段:
     * - 持续检测按钮是否被按下
     * - 若未按下,每秒向主机发送提示并点亮 LED
     * - 一旦按钮被按下,跳出循环进入主逻辑
     */
    while(PORTBbits.RB2 != 0)
    {
        UartSendString(data2);
        __delay_ms(1000);
        _LATC8 = 1;
    }

    /*
     * 主循环:
     * - 实现按钮→LED 的简单人机交互
     * - 按钮按下: 熄灭 LED,打印 "pressed" 信息
     * - 按钮松开: 点亮 LED,打印 "not pressed" 信息
     * - 每个状态保持 1 秒,以便观察
     */
    while(1)
    {
        if(PORTBbits.RB2 == 0)
        {
            LATCbits.LATC8 = 1;
            UartSendString(data);
            __delay_ms(1000);
        }
        else
        {
            LATCbits.LATC8 = 0;
            UartSendString(data1);
            __delay_ms(1000);
        }
    }
} 
    
    
    
相关推荐
im_AMBER4 小时前
Leetcode 59 二分搜索
数据结构·笔记·学习·算法·leetcode
天殇凉5 小时前
AC自动机学习笔记
java·笔记·学习
AA陈超5 小时前
从0开始学习 **Lyra Starter Game** 项目
c++·笔记·学习·游戏·ue5·lyra
2301_800256118 小时前
第七章 空间存储与索引 知识点梳理3(空间填充曲线)
数据库·笔记·sql·postgresql
凉凉的知识库9 小时前
书海拾遗:《枪炮、病菌与钢铁》
笔记·电子书
im_AMBER9 小时前
算法笔记 16 二分搜索算法
c++·笔记·学习·算法
摇滚侠9 小时前
2025最新 SpringCloud 教程,Nacos-总结,笔记19
java·笔记·spring cloud
在逃热干面9 小时前
(笔记)获取终端输出保存到文件
java·笔记·spring
leoufung9 小时前
逆波兰表达式 LeetCode 题解及相关思路笔记
linux·笔记·leetcode