<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/scripts/pretty-feed-v3.xsl" type="text/xsl"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:h="http://www.w3.org/TR/html4/"><channel><title>建设中… What410802 Site</title><description>建设中…… What410802的网站</description><link>https://guileless-beijinho-42fd22.netlify.app</link><item><title>MusicGen｜数字设计与计算机原理专题实验　实验报告</title><link>https://guileless-beijinho-42fd22.netlify.app/blog/musicgen-readme</link><guid isPermaLink="true">https://guileless-beijinho-42fd22.netlify.app/blog/musicgen-readme</guid><description>数字设计与计算机原理专题实验｜PWM波应用：音乐播放器　实验报告</description><pubDate>Tue, 16 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import { Image } from &apos;astro:assets&apos;;&lt;/p&gt;
&lt;h1&gt;数字设计与计算机原理专题实验｜音乐播放器&lt;/h1&gt;
&lt;h2&gt;Design&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;对于音符长度固定（无法细分）、BPM固定的问题，设计了存储元信息的ROM，并更新了歌曲信息ROM的存储格式。具体来说，music_list_rom存储的是歌曲在music_rom中的开始、结束、BPM信息3个字段，music_rom存储的是音符序列的长度、八度、音名3个字段。&lt;/li&gt;
&lt;li&gt;对于有连续相同音的曲子，播放起来这些相同音连在一起。改进方法是设计一个时限，对每个音符前（或后），在这个时限内表现为静音。但只使用固定比例（如1/16）会出现对全音符和二分音符间隔过长的问题；只使用固定时长又会导致短音符效果不佳甚至被完全跳过的问题。于是将两者结合，取两种计算方式的较小值作为断开间隔，达到了较好的效果。（这一改进是在上一改进基础上进行的，即单独存储音符时值，不再通过多个音符叠加来表示更长的音。）&lt;/li&gt;
&lt;li&gt;增加了使用数码管显示当前歌曲以及音符序号的功能，便于查看和调试。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;实现步骤&lt;/h2&gt;
&lt;p&gt;对于音符播放部分，首先实现基本的定长音符序列播放功能。通过维护当前时间、当前音符开始/上一音符结束时间戳以及指向ROM当前行号的变量来实现，其中当前时间初始化为0，每时钟周期加1。每次判断当前时间是否超过了当前音符开始时间加上音符时长，若是则将行数切换到下一行。如果行数超出了给定范围，则复位到起始位置。行数变量控制ROM读取，读取出的按二进制分位包括所在八度（0-8，4位）以及音名（A-G和休止，包含对应升调，4位）；将音名用case查表，得到基本周期，由于相邻八度对应音为倍频关系，故将最低八度内对应音的周期位右移即可得到当前音的周期；将计算得到的周期送入PWM波发生模块驱动无源蜂鸣器，即实现功能。&lt;/p&gt;
&lt;p&gt;然后实现变长音符序列播放功能。在上述ROM中再加入表示时值的若干列，在读取时对应载入并替换原固定时长即可，另外由于希望拍频BPM可调，故仅加载相对时长（x分音符）。考虑到一般少有32分音符以下的，故采用8位定点数来表示，小数点位于首位之后。例如&lt;code&gt;10000000&lt;/code&gt;表示全音符，&lt;code&gt;00110000&lt;/code&gt;表示附点四分音符。读出后，根据预设BPM值按比例换算为相对时钟周期的绝对时长即可。&lt;/p&gt;
&lt;p&gt;最后实现了多曲切换、循环、预设BPM功能。上面功能仅限一首歌曲，要加入多首歌曲，需再引入一个索引ROM来存储每首歌曲在主ROM中的元信息，具体包括第$i$首歌在主ROM中的开始、结束地址，以及歌曲元信息（本项目中仅包括BPM）。这样需再引入索引中的行号变量。在主循环中，当检测到输入歌曲编号变化时，切换索引ROM行号；据行号读出元信息后，加载对应歌曲边界变量及BPM，之后复位主ROM行号到当前歌曲起始即可。&lt;/p&gt;
&lt;p&gt;除上述歌曲播放之外，还有快进/快退、暂停/恢复、数码管显示等。快进快退采用主ROM行号加减预设值的方式，若超边界则循环。暂停使用停止时间戳更新并停止PWM驱动无源蜂鸣器的方式。数码管显示采用一个将二进制整数转为字符数组然后对应载入数码管的方式，详见代码。&lt;/p&gt;
&lt;h3&gt;遇到的问题及解决&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;在换算音符相对时长到基于时钟周期的绝对时长时，涉及乘法运算。查找资料得知乘法在某些型号中可能占用多个时钟周期，导致可能出现音符的时长晚于频率得出。但实际上，音符的时长远大于2个时钟周期，因此将上一音符播放周期切换为当前音符时，即使切换频率先于切换时长，也不会引起人耳可闻的异常。&lt;/li&gt;
&lt;li&gt;歌曲间切换部分出现了和上面这个问题类似的问题，但现象表现出来了。在主ROM最后一首歌的最后一个音符播放结束后的一两个时钟周期内，本该切换到该首歌的首个音符，但由于主ROM未使用部分都被设为0，而在最开始的版本中，判断当前时间是否超出当前音符使用的是&lt;code&gt;==&lt;/code&gt;，此时将导致永远无法切换。更改为&lt;code&gt;&gt;=&lt;/code&gt;后解决问题。&lt;/li&gt;
&lt;li&gt;实验过程中，发现按键以及拨码开关的高/低与输出0/1的关系较为混乱。实际上，实验用到的按键按下输出0，弹起输出1；拨码开关低位输出0，高位为1。代码中&lt;code&gt;music_gen&lt;/code&gt;主模块的&lt;code&gt;reset_n&lt;/code&gt;变量对应拨码开关低位为暂停，高位为播放；&lt;code&gt;list_index&lt;/code&gt;变量对应拨码开关高位将索引ROM二进制对应位置为1；&lt;code&gt;back15s&lt;/code&gt;, &lt;code&gt;forw15s&lt;/code&gt;对应按键按下为快退/快进，高位为正常。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Results&lt;/h2&gt;
&lt;h3&gt;Simulation&lt;/h3&gt;
&lt;p&gt;import 仿真结果 from &apos;README_assets/Screenshot 2026-06-17 152331.png&apos;;&lt;/p&gt;
&lt;h3&gt;Pictures &amp;#x26; Videos&lt;/h3&gt;
&lt;p&gt;import 概览 from &quot;README_assets/IMG_20260617_161702.jpg&quot;;
import 初始化 from &quot;README_assets/IMG_20260617_155315.jpg&quot;;
import { ImageGroup, } from &apos;@/components/advanced&apos;;&lt;/p&gt;
&lt;p&gt;import 天空之城 from &quot;README_assets/VID_20260617_160111.mp4&quot;;
import 为世界之光 from &quot;README_assets/VID_20260617_160303.mp4&quot;;
import 梦中的婚礼_ from &quot;README_assets/VID_20260617_160740.mp4&quot;;
import 钢铁洪流进行曲 from &quot;README_assets/VID_20260617_161402.mp4&quot;;
import 千本桜 from &quot;README_assets/VID_20260617_162104.mp4&quot;;&lt;/p&gt;
&lt;p&gt;import 天空之城_Compatible from &quot;README_assets/Compatibility.d/VID_20260617_160111.mp4&quot;;
import 为世界之光_Compatible from &quot;README_assets/Compatibility.d/VID_20260617_160303.mp4&quot;;
import 梦中的婚礼__Compatible from &quot;README_assets/Compatibility.d/VID_20260617_160740.mp4&quot;;&lt;/p&gt;
&lt;h2&gt;Future Improvements&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;现在是全部分开相邻音符，可以改进为在in.txt中引入记号（例如，在需要和后一个音符分割的音符后加上斜杠/），使得能够控制在哪些音符间断开。&lt;/li&gt;
&lt;li&gt;数码管两部分都有前缀0，可以改为不显示。&lt;/li&gt;
&lt;li&gt;娱乐向：多个板子同时演奏来构造单无源蜂鸣器无法完成的复音效果。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Problems &amp;#x26; Debugging&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;.coe文件不支持行末分号注释，AI提供的关于.coe文件格式的介绍有误。&lt;/li&gt;
&lt;li&gt;用于ROM等IP核初始化的.coe文件在更新后，需要打开IP核、进行一些改动并重新保存，以使IP核真正更新。&lt;/li&gt;
&lt;li&gt;各&lt;code&gt;reg&lt;/code&gt;类型的变量需要初始化；无需依赖reset信号，可以使用等号初始化。&lt;/li&gt;
&lt;li&gt;对于music_rom中最后一首歌（所有在end位置上是一个0长度音符的歌），它在循环播放时，首个音符在第2次及以后播放时会被吞掉。这可能是由于在。改进方法：在music_rom后加入一个有长度的休止符作为缓冲。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;{/* Easy debugging:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;快进/快退可能超出当前歌曲区间乃至向下溢出，故需判断进退后的结果；&lt;/li&gt;
&lt;li&gt;Post-Synthesis/Implementation Simulation 非常慢（我的电脑上~10us/s，跑1s需要1天）&lt;/li&gt;
&lt;li&gt;歌曲通常含有大量音符，故手动编写.coe文件已经十分复杂且易出错。我选择使用Python代码，将事先转写好的乐谱信息转换为.coe文本，再写入Vivado中。 */}&lt;/li&gt;
&lt;/ul&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>RaspCar｜数字设计与计算机原理专题实验　实验报告</title><link>https://guileless-beijinho-42fd22.netlify.app/blog/rasp-car-readme</link><guid isPermaLink="true">https://guileless-beijinho-42fd22.netlify.app/blog/rasp-car-readme</guid><description>数字设计与计算机原理专题实验｜基于树莓派的嵌入式系统综合项目　实验报告</description><pubDate>Tue, 16 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import { Image } from &apos;astro:assets&apos;;&lt;/p&gt;
&lt;p&gt;{/* &lt;/p&gt;
&lt;h1&gt;数字设计与计算机原理专题实验｜基于树莓派的嵌入式系统综合项目　实验报告&lt;/h1&gt;
&lt;h2&gt;项目名称&lt;/h2&gt;
&lt;h2&gt;设计功能描述&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;自动大灯：通过光敏传感器获取环境亮度信息，当环境亮度低于某一范围后，点亮LED灯珠；&lt;/li&gt;
&lt;li&gt;自动雨刷：通过雨滴传感器获取是否有雨水，当雨滴传感器面板有水时，在LCD面板上显示“Raining”字样；&lt;/li&gt;
&lt;li&gt;障碍物报警：通过超声波传感器获取物体距离信息，通过蜂鸣器报警，并且根据距离不同报警声音间隔不同；&lt;/li&gt;
&lt;li&gt;行驶里程计量：通过旋转编码器传感器获取转动角度，在LCD面板上实时显示转动情况以及总里程数；&lt;/li&gt;
&lt;li&gt;姿态感知：通过陀螺仪加速度传感器获取x、y、z三个轴向的加速度数据或者姿态角度数据，在晃动或侧翻时利用发光二极管报警；&lt;/li&gt;
&lt;li&gt;按键控制：通过旋转编码器自带按钮实现两种LCD屏显（环境传感器数据和里程计）之间的切换；&lt;/li&gt;
&lt;li&gt;车载遥控音乐播放器：通过遥控器按键控制无源蜂鸣器进行音乐播放、暂停与切换。在播放时自动暂停有源蜂鸣器的距离报警以避免噪音；停止后恢复。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;实现步骤&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;硬件规划：概览需要完成的功能；进行管脚分配（如图1所示）。&lt;/li&gt;
&lt;li&gt;软件准备：远程桌面。&lt;/li&gt;
&lt;li&gt;程序编写及调试：各硬件驱动包含及初始化；中断处理；主循环（传感器数据更新；简单输出外设更新；复杂外设检测是否到达更新间隔并适时更新）。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;import _pinplan from &apos;assets/接口规划.jpg&apos;;&lt;/p&gt;
&lt;h2&gt;每个功能的实现方法与结果&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;自动大灯（光敏传感器+AD-&gt;3色LED）：通过光敏传感器获取环境亮度（越大越暗），控制LED亮度正相关于环境暗度。由于蓝色看起来更显眼，故适当调低蓝分量占比。&lt;/li&gt;
&lt;li&gt;自动雨刷（雨滴传感器+AD-&gt;LCD）：当雨滴传感器数值低于设定值时，在LCD面板上显示“Raining”；否则显示“No rain”。&lt;/li&gt;
&lt;li&gt;障碍物报警（超声测距-&gt;有源蜂鸣器/LCD）：通过超声波传感器获取物体距离信息（float类型），据此设置蜂鸣器变化周期；蜂鸣器端则借助定时器，在半周期后切换状态。注意低电平触发，以及后期的与音乐播放避让。&lt;/li&gt;
&lt;li&gt;行驶里程计量：通过旋转编码器计数正、反转，判断正反转通过记录上一统计周期结束时的总里程并与当前周期末相比较来完成。旋转编码器原理是在每2个相邻机械位置之间，有2组交错的触点对，当转子转过一个周期（从一个机械位置转到相邻的一个）时，触点对A和触点对B导通状况依次经历了00-01-11-10-00状态。因此，设置中断为两个信号的上升、下降沿（一周期共4次触发）并与上次触发时的状况对比即可完成记录。&lt;/li&gt;
&lt;li&gt;姿态感知（陀螺仪-&gt;红绿双色LED）：通过陀螺仪加速度传感器获取z轴向的加速度数据。若小于设定值，则判断为侧翻，点亮红灯；若大于等于此值但小于更大的一个给定值，则点亮黄灯（红绿按比例混合）；否则亮绿灯。&lt;/li&gt;
&lt;li&gt;按键控制：检测按钮是否按下，实现两种LCD屏显（环境传感器数据和里程计）之间的切换；&lt;/li&gt;
&lt;li&gt;车载遥控音乐播放器：通过遥控器按键控制无源蜂鸣器进行音乐播放、暂停与切换。在播放时自动暂停有源蜂鸣器的距离报警以避免噪音；停止后恢复。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;实现本任务需要用到的软硬件功能模块；各模块端口配置参数&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;模数转换模块：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;#define	PCF 	        120
...
pcf8591Setup(PCF, 0x48);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;硬件按照指导教材连线即可，无冲突。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;光敏传感器（模拟）：&lt;code&gt;SIG&lt;/code&gt;连至PCF8591的&lt;code&gt;AIN0&lt;/code&gt;。使用时读取&lt;code&gt;analogRead(PCF)&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;雨滴传感器（模拟）：&lt;code&gt;DO&lt;/code&gt;连至&lt;code&gt;G12&lt;/code&gt;（这个在本实验中用处不大），&lt;code&gt;AO&lt;/code&gt;连至&lt;code&gt;AIN1&lt;/code&gt;。使用时读取&lt;code&gt;analogRead(PCF+1)&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;陀螺仪：硬件按照教材连线。使用时按照教材例程的方式对$z$轴信号量进行经验性的放缩。代码中使用&lt;code&gt;get_acclZ()&lt;/code&gt;读取即可。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;旋转编码器：&lt;code&gt;CLK&lt;/code&gt;-&lt;code&gt;G20 (pin-28)&lt;/code&gt;, &lt;code&gt;DT&lt;/code&gt;-&lt;code&gt;G19 (pin-24)&lt;/code&gt;, &lt;code&gt;SW&lt;/code&gt;-&lt;code&gt;G18 (pin-1)&lt;/code&gt;。初始化使用教材例程。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;超声波测距模块：&lt;code&gt;Trig&lt;/code&gt;-&lt;code&gt;G13&lt;/code&gt;, &lt;code&gt;Echo&lt;/code&gt;-&lt;code&gt;G16&lt;/code&gt;。软件上按照教材例程进行初始化，使用&lt;code&gt;float disMeasure()&lt;/code&gt;函数获取当前距离。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;红外接收模块：&lt;code&gt;DO&lt;/code&gt;-&lt;code&gt;G23&lt;/code&gt;。需要根据指导教材包含&lt;code&gt;lirc/lirc_client.h&lt;/code&gt;等头文件，并在树莓派系统配置中根据教材内容反注释一个设置项并重启。可使用irw命令来测试是否能够正常接收到红外信号。在读取接收到的信号时，需要轮询poll提供的队列，若不为空则说明已有信号到来，根据映射正确处理即可。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;红绿双色LED：&lt;code&gt;R&lt;/code&gt;-&lt;code&gt;G6&lt;/code&gt;, &lt;code&gt;G&lt;/code&gt;-&lt;code&gt;G5&lt;/code&gt;。软件上使用&lt;code&gt;softPwm.h&lt;/code&gt;及教材提供的封装来配置各色占空比来调光。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;3色LED：&lt;code&gt;B&lt;/code&gt;-&lt;code&gt;G21&lt;/code&gt;, &lt;code&gt;G&lt;/code&gt;-&lt;code&gt;G22&lt;/code&gt;, &lt;code&gt;R&lt;/code&gt;-&lt;code&gt;G26&lt;/code&gt;。同上。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LCD：引脚根据教材配置。软件上，使用教材提供的例程来驱动，但需注意不能完全撤掉delay，否则可能导致时序错误。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;有源蜂鸣器：&lt;code&gt;I/O&lt;/code&gt;-&lt;code&gt;G24 (pin=5)&lt;/code&gt;。使用&lt;code&gt;digitalWrite&lt;/code&gt;来控制高低电平即可。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;无源蜂鸣器：&lt;code&gt;I/O&lt;/code&gt;-&lt;code&gt;G27 (pin=2)&lt;/code&gt;。软件上使用&lt;code&gt;softTone.h&lt;/code&gt;头文件来直接输出指定频率的音频（&lt;code&gt;softToneCreate&lt;/code&gt;, &lt;code&gt;softToneWrite&lt;/code&gt;, &lt;code&gt;softToneStop&lt;/code&gt;）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;程序流程图；实现具体功能的关键程序代码（核心语句有注释）&lt;/h2&gt;
&lt;p&gt;import RaspCar_Diagram_Main from &quot;assets/RaspCar_Diagram_Main.svg&quot;;
import RaspCar_Diagram_Subplots from &quot;assets/RaspCar_Diagram_Subplots.svg&quot;;&lt;/p&gt;
&lt;p&gt;以下为关键代码片段，包括实验系统的&lt;strong&gt;数据采集&lt;/strong&gt;（超声波、光敏、雨滴、加速度计）、&lt;strong&gt;实时控制&lt;/strong&gt;（蜂鸣器报警、LED 颜色/亮度）、&lt;strong&gt;人机交互&lt;/strong&gt;（LCD 显示、编码器、红外遥控）等核心功能。&lt;/p&gt;
&lt;h3&gt;1. 超声波测距与有源蜂鸣器动态报警&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;// 根据当前距离（cm）计算蜂鸣器的报警半周期（ms）
// 距离越近，半周期越短 → 蜂鸣器声音越急促
uint get_beep_T_ms(float distance_cm) {
    static const float min_dis = 10;      // 最小报警距离 10cm
    if (distance_cm &amp;#x3C; min_dis) distance_cm = min_dis;
    return 100 + (distance_cm - min_dis) * 2; // 半周期从 100ms 到 2100ms
}

// 蜂鸣器定时器回调函数：交替开/关蜂鸣器，实现间歇报警
void beep_alarm_handle(void) {
    if (!beep_ctrl.timer.expired) return;
    beep_ctrl.timer.expired = 0;

    uint half_cycle = get_beep_T_ms(beep_ctrl.current_distance) / 2;
    if (beep_ctrl.beep_phase == 0) {      // 响阶段
        digitalWrite(BuzPin, ABUZZER_HIGH);
        beep_ctrl.beep_phase = 1;
    } else {                              // 不响阶段
        digitalWrite(BuzPin, ABUZZER_LOW);
        beep_ctrl.beep_phase = 0;
    }
    timer_start_ms(&amp;#x26;beep_ctrl.timer, half_cycle); // 重新启动下一阶段
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 主循环中的传感器数据读取与报警触发&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;while (main_running) {
    // 读取光敏电阻（暗度）和雨滴传感器（干度）
    DDark = analogRead(PCF);       // 通道0：光强（值越小越暗）
    DDry  = analogRead(PCF + 1);   // 通道1：湿度（&amp;#x3C;180 表示有雨）

    // 每 300ms 更新一次超声波距离
    if (millis() - last_distance_update_ms &gt;= 300) {
        dis = disMeasure();                 // 获取距离（cm）
        beep_ctrl.current_distance = dis;   // 更新报警控制器的当前距离
        last_distance_update_ms = millis();
    }

    // 根据 MPU6050 的 Z 轴加速度值改变 LED2 颜色（倾斜报警）
    accl_z = get_acclZ();
    if (accl_z &amp;#x3C; 0.5) {
        led2ColorSet(100, 0);      // 偏红
    } else if (accl_z &amp;#x3C; 0.8) {
        led2ColorSet(75, 100);     // 橙黄
    } else {
        led2ColorSet(0, 100);      // 偏绿
    }

    // 根据光敏电阻值控制 LED3 亮度（模拟自动夜灯）
    white_lum = DDark * DDark / 128;        // 非线性映射，暗环境亮度高
    led3ColorSet(white_lum, white_lum, white_lum * 2 / 3);

    // 若无源蜂鸣器未播放音乐，则启动有源蜂鸣器距离报警
    if (!song_player.is_playing || music_paused) {
        beep_alarm_handle();                // 动态调整报警节奏
    }

    delay(50);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. LCD 显示模式切换（通过旋转编码器按钮）&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;// 在 LCD 定时器回调函数中处理编码器按钮事件
void handle_lcd_update(...) {
    // 检测编码器按钮是否被按下（消抖 250ms）
    if (encoder_state.button_pressed) {
        if (millis() - *last_mode_change &gt; 250) {
            *display_mode = !(*display_mode);   // 在 0（传感器模式）和 1（编码器模式）间切换
            *last_mode_change = millis();
        }
        encoder_clear_button();
    }

    LCD_clear();
    if (*display_mode == 0) {
        // 模式0：显示暗度、雨滴状态和超声波距离
        sprintf(for_LCD[0], &quot;Dark=%3d %s&quot;, *DDark, *DDry &amp;#x3C; 180 ? &quot;Raining&quot; : &quot;No rain&quot;);
        sprintf(for_LCD[1], &quot;Dis=%7.2fcm&quot;, *dis);
    } else {
        // 模式1：显示旋转编码器累计值和瞬时速度
        long delta = encoder_state.count - prev_encoder_state.count;
        sprintf(for_LCD[0], &quot;Total=%+08ld&quot;, encoder_state.count);
        sprintf(for_LCD[1], &quot;Dir:%s v=%8.3f&quot;,
            delta == 0 ? &quot;P&quot; : (delta &amp;#x3C; 0 ? &quot;-&quot; : &quot;+&quot;),
            delta * 1e3f / (millis() - prev_encoder_state.timestamp));
    }
    LCD_write(0, 0, for_LCD[0]);
    LCD_write(0, 1, for_LCD[1]);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4. 红外遥控控制无源蜂鸣器播放音乐（切换歌曲、暂停/继续）&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;// 红外按键处理函数
void handle_ir_command(int key) {
    // 数字键 1~9 对应歌曲库中的前9首歌曲
    if (key &gt;= 13 &amp;#x26;&amp;#x26; key &amp;#x3C;= 21) {
        int idx = key - 13;               // 按键13对应数字1，映射到歌曲索引0
        if (idx &amp;#x3C; song_count) {
            current_song = song_library[idx];
            music_paused = 0;
            song_player_play(&amp;#x26;song_player, current_song); // 播放新歌曲
        }
    }
    // 播放/暂停键（红外码为 KEY_PLAYPAUSE）
    else if (key == IR_KEY_PLAYPAUSE) {
        if (song_player.is_playing &amp;#x26;&amp;#x26; !music_paused) {
            song_player_pause(&amp;#x26;song_player);
            music_paused = 1;
        } else if (music_paused) {
            song_player_resume(&amp;#x26;song_player);
            music_paused = 0;
        } else {
            // 完全停止 → 从头播放当前歌曲
            song_player_play(&amp;#x26;song_player, current_song);
        }
    }

    // 音乐播放时关闭距离报警，否则启动报警
    if (song_player.is_playing &amp;#x26;&amp;#x26; !music_paused) {
        beep_alarm_stop();
    } else {
        beep_alarm_start();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;实验过程中遇到什么疑难问题？是怎么解决的？&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;有源蜂鸣器低电平触发，需要为其更换为反转后的 &lt;code&gt;HIGH&lt;/code&gt;、&lt;code&gt;LOW&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;实验中需要有多个传感器接入AD模块，但器材只有1个AD模块。查阅指导书后，得知可以将多个模拟元件接入同一AD模块，软件上用PCD+n的地址即可。&lt;/li&gt;
&lt;li&gt;超声波测距有时会使程序卡死，经排查，可能是超声波测距模块的接线接触不良导致驱动出现状态异常，重新用牢固的杜邦线连接后解决了问题。&lt;/li&gt;
&lt;li&gt;LCD显示屏有时会出现花屏的现象，可能是和上一个问题类似的问题导致驱动状态异常，更换杜邦线及避免移动LCD屏解决了问题。&lt;/li&gt;
&lt;li&gt;在有定时器的程序中，按下Ctrl-C后程序可能不能停止，解决方法是加入一个表示程序是否正在运行的变量，在按下Ctrl-C后设置为0，主循环中及定时器中检测这一变量，若变为0则停止并正常退出。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;最终成果&lt;/h2&gt;
&lt;p&gt;import Raining from &quot;assets/Raining.jpg&quot;;
import Dark from &quot;assets/Dark.jpg&quot;;
import Green from &quot;assets/Green.jpg&quot;;
import Yellow from &quot;assets/Yellow.jpg&quot;;
import Red from &quot;assets/Red.jpg&quot;;
import Summary from &quot;assets/Summary.jpg&quot;;
import Final from &quot;assets/Final.mp4&quot;;&lt;/p&gt;
&lt;h2&gt;Extra: 待改进方向&lt;/h2&gt;
&lt;p&gt;import 菜汪 from &quot;assets/317.gif&quot;;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;有源蜂鸣器切换频率不稳，推测有可能是LCD屏更新导致阻滞。改进方向可能包括减少LCD屏单次更新时间，以及在主循环中降低更新LCD的软件优先级。&lt;/li&gt;
&lt;li&gt;歌曲数量较少，可以将music_gen项目的歌曲迁移到这里。 &lt;a href=&quot;%E8%A1%A8%E6%83%85%E6%9D%A5%E8%87%AA%5Bkoishijs/QFace%5D(https://github.com/koishijs/QFace)%E3%80%82%E6%89%80%E6%9C%89%E8%A1%A8%E6%83%85%E8%B5%84%E6%BA%90%E5%9D%87%E6%9D%A5%E8%87%AA%E8%85%BE%E8%AE%AF%E5%AE%98%E6%96%B9%EF%BC%8C%E7%89%88%E6%9D%83%E5%BD%92%E8%85%BE%E8%AE%AF%E5%85%AC%E5%8F%B8%E6%89%80%E6%9C%89%E3%80%82%E4%BB%85%E4%BE%9B%E5%AD%A6%E4%B9%A0%E4%BA%A4%E6%B5%81%E4%BD%BF%E7%94%A8%E3%80%82&quot;&gt;^1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;旋转编码器仍存在较小（约1/160）概率会丢失一次的计数。基本确定是软件原因，但可能较难修正。&lt;/li&gt;
&lt;li&gt;可以将项目整体重构为基于poll与轮询的，这样可以进一步减小丢失信号的可能，但较难改进LCD屏更新拖延时间的问题（可能能通过拆解为小操作来解决？）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;{/*  */}&lt;/p&gt;
&lt;p&gt;{/*  */}&lt;/p&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>Axi Theme 基础使用与配置</title><link>https://guileless-beijinho-42fd22.netlify.app/blog/axi-theme-basics</link><guid isPermaLink="true">https://guileless-beijinho-42fd22.netlify.app/blog/axi-theme-basics</guid><description>从本地启动到站点配置：了解内容结构、配置入口与常见改动点。</description><pubDate>Sun, 11 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. 前置条件&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Node.js 18+（建议 20+）&lt;/li&gt;
&lt;li&gt;包管理器：&lt;code&gt;pnpm&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;pnpm install
pnpm dev
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;2. 目录结构（最常用）&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;src/site.config.ts&lt;/code&gt;：主题配置入口（站点信息、导航、集成配置等）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;src/content/blogs/&amp;#x3C;slug&gt;/index.mdx&lt;/code&gt;：中文文章&lt;/li&gt;
&lt;li&gt;&lt;code&gt;src/content/blogs/&amp;#x3C;slug&gt;/index-en.mdx&lt;/code&gt;：英文文章（可选，没有则英文列表会回退到中文）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;public/&lt;/code&gt;：静态资源（&lt;code&gt;/images/*&lt;/code&gt;、&lt;code&gt;/avatar/*&lt;/code&gt; 等）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;3. 配置站点信息（&lt;code&gt;src/site.config.ts&lt;/code&gt;）&lt;/h2&gt;
&lt;p&gt;常改字段：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;theme.title&lt;/code&gt; / &lt;code&gt;theme.description&lt;/code&gt;：站点标题/描述&lt;/li&gt;
&lt;li&gt;&lt;code&gt;theme.personal.domains.main&lt;/code&gt;：主域名（用于生成绝对链接、RSS 等）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;theme.header.menu&lt;/code&gt;：导航菜单&lt;/li&gt;
&lt;li&gt;&lt;code&gt;integ.pagefind&lt;/code&gt;：站内搜索（Pagefind）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;integ.waline&lt;/code&gt;：评论系统（见 Waline 文档）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;4. 写一篇文章（中英双语）&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;新建文件夹：&lt;code&gt;src/content/blogs/my-first-post/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;写中文：&lt;code&gt;src/content/blogs/my-first-post/index.mdx&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;写英文：&lt;code&gt;src/content/blogs/my-first-post/index-en.mdx&lt;/code&gt;（可选）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;最小 Frontmatter（两种语言都要有）：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-md&quot;&gt;---
title: My Title
publishDate: 2026-01-11
description: Short summary.
tags: [&apos;docs&apos;]
---
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;5. 构建与产物&lt;/h2&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;pnpm build
pnpm preview
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;构建产物默认在 &lt;code&gt;dist/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;astro.config.mjs&lt;/code&gt; 会根据 &lt;code&gt;DEPLOYMENT_PLATFORM&lt;/code&gt; 选择适配器与输出模式（详见部署文档）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;6. 部署推荐（GitHub + Vercel）&lt;/h2&gt;
&lt;p&gt;建议使用 GitHub 托管代码 + Vercel 自动部署（PR 预览、回滚、CDN、HTTPS 都更省心）。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;部署思路与注意事项：&lt;a href=&quot;https://axi404.top/blog/website-vercel&quot;&gt;Website on Vercel&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>GitHub + Vercel 部署（推荐）</title><link>https://guileless-beijinho-42fd22.netlify.app/blog/deploy-vercel</link><guid isPermaLink="true">https://guileless-beijinho-42fd22.netlify.app/blog/deploy-vercel</guid><description>使用 GitHub 管理代码，并用 Vercel 自动构建与部署（含环境变量与常见坑）。</description><pubDate>Sun, 11 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. 为什么推荐 GitHub + Vercel&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;PR 预览：每个分支/PR 都能拿到可访问的预览链接&lt;/li&gt;
&lt;li&gt;自动构建：push 即部署&lt;/li&gt;
&lt;li&gt;HTTPS / CDN：默认就有&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;详细流程与说明：&lt;a href=&quot;https://axi404.top/blog/website-vercel&quot;&gt;Website on Vercel&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;2. 部署前检查&lt;/h2&gt;
&lt;p&gt;本地先跑通：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;pnpm install
pnpm build
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配置域名（建议至少填主域名）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;src/site.config.ts&lt;/code&gt; → &lt;code&gt;theme.personal.domains.main&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;3. Vercel 部署要点&lt;/h2&gt;
&lt;p&gt;主题会读取 &lt;code&gt;DEPLOYMENT_PLATFORM&lt;/code&gt; 来选择适配器与输出：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;vercel&lt;/code&gt;（默认）：Vercel adapter，输出通常为 &lt;code&gt;server&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;github&lt;/code&gt;：用于 GitHub Pages，输出为 &lt;code&gt;static&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cloudflare&lt;/code&gt;：用于 Cloudflare Pages，输出为 &lt;code&gt;static&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在 Vercel 项目里设置环境变量：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;DEPLOYMENT_PLATFORM=vercel
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;构建命令建议使用：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;pnpm build
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输出目录（Output Directory）保持默认即可（Astro 会由适配器处理）。&lt;/p&gt;
&lt;h2&gt;4. 静态站点（可选）&lt;/h2&gt;
&lt;p&gt;如果你希望生成纯静态站点（例如 GitHub Pages），使用：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;DEPLOYMENT_PLATFORM=github
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;并确保你的部署平台支持静态产物 &lt;code&gt;dist/&lt;/code&gt;。&lt;/p&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>Friend Circle（朋友圈）：接入与配置</title><link>https://guileless-beijinho-42fd22.netlify.app/blog/friend-circle</link><guid isPermaLink="true">https://guileless-beijinho-42fd22.netlify.app/blog/friend-circle</guid><description>使用 Friend-Circle-Lite 生成数据源，并在 Links 页面展示朋友圈动态。</description><pubDate>Sun, 11 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. Friend Circle 是什么&lt;/h2&gt;
&lt;p&gt;“朋友圈”页面会展示友链站点的最新文章聚合，适合在 Links 页让访问者快速看到朋友们的新内容。&lt;/p&gt;
&lt;p&gt;本主题的 Links 页集成入口在：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;src/pages/links/index.astro&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;2. 先准备数据源（Friend-Circle-Lite）&lt;/h2&gt;
&lt;p&gt;本主题使用 Friend-Circle-Lite 的接口数据（&lt;code&gt;all.json&lt;/code&gt; 等）。搭建与使用方式建议参考：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.liushen.fun/posts/4dc716ec/&quot;&gt;Friend Circle 参考文档&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你需要得到一个可访问的域名，例如：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;fc.example.com
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;并确保以下地址可访问：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;https://fc.example.com/all.json
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;3. 在主题中启用&lt;/h2&gt;
&lt;p&gt;编辑 &lt;code&gt;src/site.config.ts&lt;/code&gt;，设置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;theme.personal.domains.friendCircle = &apos;fc.example.com&apos;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;配置完成后，&lt;code&gt;/links&lt;/code&gt; 页面会自动显示 “Small Circle / 朋友圈” 区块。&lt;/p&gt;
&lt;h2&gt;4. 友链 RSS 建议&lt;/h2&gt;
&lt;p&gt;如果某个站点在友链里但朋友圈里没有内容，通常是该站点未提供 RSS 或 RSS 不可访问。建议为友链站点补全 RSS。&lt;/p&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>MDX 组件使用：User &amp; Advanced</title><link>https://guileless-beijinho-42fd22.netlify.app/blog/mdx-components</link><guid isPermaLink="true">https://guileless-beijinho-42fd22.netlify.app/blog/mdx-components</guid><description>文章内组件（Aside/Tabs 等）与高级组件（LinkPreview/GithubCard 等）的使用方式。</description><pubDate>Sun, 11 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import { Aside, Tabs, TabItem, Spoiler } from &apos;@/components/user&apos;
import { GithubCard, LinkPreview, QRCode, ImageGroup, WebVideo } from &apos;@/components/advanced&apos;&lt;/p&gt;
&lt;h2&gt;1. 必须使用 MDX&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;.md&lt;/code&gt; 文章无法 &lt;code&gt;import&lt;/code&gt; 组件；请使用 &lt;code&gt;.mdx&lt;/code&gt;（如 &lt;code&gt;src/content/blogs/&amp;#x3C;slug&gt;/index.mdx&lt;/code&gt;）。&lt;/p&gt;
&lt;h2&gt;2. User 组件示例&lt;/h2&gt;
&lt;h2&gt;3. Advanced 组件示例&lt;/h2&gt;
&lt;h3&gt;GitHub 卡片&lt;/h3&gt;
&lt;h3&gt;链接预览&lt;/h3&gt;
&lt;h3&gt;二维码&lt;/h3&gt;
&lt;h3&gt;图片组（等高拼图）&lt;/h3&gt;
&lt;p&gt;&amp;#x3C;ImageGroup
images={[
{ src: &apos;https://picr2.axi404.top/1767811093734_image.webp&apos;, alt: &apos;Image A&apos;, aspectRatio: 16 / 9 },
{ src: &apos;https://picr2.axi404.top/1767811093734_image.webp&apos;, alt: &apos;Image B&apos;, aspectRatio: 1 },
]}
/&gt;&lt;/p&gt;
&lt;h3&gt;内嵌视频&lt;/h3&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>Waline 评论系统：部署与接入</title><link>https://guileless-beijinho-42fd22.netlify.app/blog/waline</link><guid isPermaLink="true">https://guileless-beijinho-42fd22.netlify.app/blog/waline</guid><description>部署 Waline 服务端，并在 Axi Theme 中启用评论与访问量统计。</description><pubDate>Sun, 11 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. 部署 Waline 服务端&lt;/h2&gt;
&lt;p&gt;请参考这篇完整教程（包含服务端部署与配置项说明）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://axi404.top/blog/waline-install&quot;&gt;Waline Comments: Deploy &amp;#x26; Integrate&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;部署完成后你会得到一个服务端地址，例如：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;https://waline.example.com/
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;2. 在主题中启用 Waline&lt;/h2&gt;
&lt;p&gt;编辑 &lt;code&gt;src/site.config.ts&lt;/code&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;integ.waline.enable&lt;/code&gt;: 设为 &lt;code&gt;true&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;integ.waline.server&lt;/code&gt;: 填你的 Waline Server URL&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;示例：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;waline: {
  enable: true,
  server: &apos;https://waline.example.com/&apos;,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;3. 常见说明&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;评论区组件：&lt;code&gt;src/components/advanced/Comment.astro&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;页面访问量/评论数：部分页面会加载 Waline 的 &lt;code&gt;pageview&lt;/code&gt; 统计（见 &lt;code&gt;src/pages/*&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;单篇文章是否显示评论：由文章 Frontmatter 的 &lt;code&gt;comment&lt;/code&gt; 控制（默认 &lt;code&gt;true&lt;/code&gt;）&lt;/li&gt;
&lt;/ul&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>写作指南：Markdown / MDX</title><link>https://guileless-beijinho-42fd22.netlify.app/blog/writing-markdown-mdx</link><guid isPermaLink="true">https://guileless-beijinho-42fd22.netlify.app/blog/writing-markdown-mdx</guid><description>主题内支持的 Markdown 扩展、数学公式、代码高亮与一些写作约定。</description><pubDate>Sun, 11 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. Markdown 支持范围&lt;/h2&gt;
&lt;p&gt;主题默认启用了常用扩展：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GFM：表格、删除线、任务列表等&lt;/li&gt;
&lt;li&gt;数学公式：KaTeX（&lt;code&gt;$...$&lt;/code&gt; / &lt;code&gt;$$...$$&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;代码高亮：Shiki（支持标题、差异标注等）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;2. 数学公式（KaTeX）&lt;/h2&gt;
&lt;p&gt;行内：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-md&quot;&gt;欧拉公式：$e^{i\\pi}+1=0$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;块级：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-md&quot;&gt;$$
\\int_0^1 x^2 dx = \\frac{1}{3}
$$
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;3. 代码块增强（差异/高亮）&lt;/h2&gt;
&lt;p&gt;你可以在代码中使用注释标记来展示变更（示例来自主题的高亮 transformer）：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;const a = 1 // [!code --]
const a = 2 // [!code ++]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;也可以做行高亮：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;const token = &apos;secret&apos; // [!code highlight]
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;4. 什么时候用 MDX&lt;/h2&gt;
&lt;p&gt;当你需要在文章里使用组件（例如 &lt;code&gt;Aside&lt;/code&gt;、&lt;code&gt;Tabs&lt;/code&gt;、&lt;code&gt;GithubCard&lt;/code&gt; 等）时，请使用 &lt;code&gt;.mdx&lt;/code&gt;，并在文件顶部 &lt;code&gt;import&lt;/code&gt; 组件。&lt;/p&gt;
&lt;p&gt;组件用法示例文档：见 “MDX 组件使用”。&lt;/p&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item></channel></rss>