<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[会飞的猪的小屋]]></title><description><![CDATA[哈喽~欢迎光临]]></description><link>https://blog.flyyingpiggy2020.cn</link><image><url>https://blog.flyyingpiggy2020.cn/innei.svg</url><title>会飞的猪的小屋</title><link>https://blog.flyyingpiggy2020.cn</link></image><generator>Shiro (https://github.com/Innei/Shiro)</generator><lastBuildDate>Fri, 10 Apr 2026 13:46:21 GMT</lastBuildDate><atom:link href="https://blog.flyyingpiggy2020.cn/feed" rel="self" type="application/rss+xml"/><pubDate>Fri, 10 Apr 2026 13:46:21 GMT</pubDate><language><![CDATA[zh-CN]]></language><item><title><![CDATA[放弃输出详细的文档]]></title><description><![CDATA[<div><blockquote>该渲染由 Shiro API 生成，可能存在排版问题，最佳体验请前往：<a href="https://blog.flyyingpiggy2020.cn/notes/19">https://blog.flyyingpiggy2020.cn/notes/19</a></blockquote><div><p>好久没更新博客了，在安富莱论坛里写过一篇《相轨迹法判断步态的导读》。</p><p>最近还看了一篇霍尔前馈加观测器的论文，但是懒得整理成文字了。</p><p>之前想用费曼学习法来巩固知识，目前信号与系统和自控部分看了差不多了。但是没有写博客了。感觉详细的写特别累。我不应该把文字的受众假定为零基础的，应该假定为一个月前的自己。</p><p>不再打算输出完整的某个系列的课程了，如果有自己不懂的知识点，写小文章来分享吧。未来如果有大片的空白时间，或者复习的时候再对它们做汇总。</p></div><p style="text-align:right"><a href="https://blog.flyyingpiggy2020.cn/notes/19#comments">看完了？说点什么呢</a></p></div>]]></description><link>https://blog.flyyingpiggy2020.cn/notes/19</link><guid isPermaLink="true">https://blog.flyyingpiggy2020.cn/notes/19</guid><dc:creator><![CDATA[Lu Xianfan]]></dc:creator><pubDate>Fri, 10 Apr 2026 02:56:42 GMT</pubDate></item><item><title><![CDATA[AI重构代码失败]]></title><description><![CDATA[<div><blockquote>该渲染由 Shiro API 生成，可能存在排版问题，最佳体验请前往：<a href="https://blog.flyyingpiggy2020.cn/notes/18">https://blog.flyyingpiggy2020.cn/notes/18</a></blockquote><div><p>今天让AI帮我重构代码。</p><p>我已经实现了功能里，让它重构后，我直接运行功能没了..</p><p>然后我现在自己古法编程手敲</p></div><p style="text-align:right"><a href="https://blog.flyyingpiggy2020.cn/notes/18#comments">看完了？说点什么呢</a></p></div>]]></description><link>https://blog.flyyingpiggy2020.cn/notes/18</link><guid isPermaLink="true">https://blog.flyyingpiggy2020.cn/notes/18</guid><dc:creator><![CDATA[Lu Xianfan]]></dc:creator><pubDate>Thu, 02 Apr 2026 06:41:10 GMT</pubDate></item><item><title><![CDATA[更新博客后台，无刷电机有感]]></title><description><![CDATA[<div><blockquote>该渲染由 Shiro API 生成，可能存在排版问题，最佳体验请前往：<a href="https://blog.flyyingpiggy2020.cn/notes/17">https://blog.flyyingpiggy2020.cn/notes/17</a></blockquote><div><p>如题所示本人更新了一下后台，但是貌似默认所有文章都开启了AI总结的功能，哪怕我并没有设置API。</p><p>另外在AI的帮助下，感觉对电机控制慢慢有了一定的理解了。</p></div><p style="text-align:right"><a href="https://blog.flyyingpiggy2020.cn/notes/17#comments">看完了？说点什么呢</a></p></div>]]></description><link>https://blog.flyyingpiggy2020.cn/notes/17</link><guid isPermaLink="true">https://blog.flyyingpiggy2020.cn/notes/17</guid><dc:creator><![CDATA[Lu Xianfan]]></dc:creator><pubDate>Mon, 09 Mar 2026 06:57:07 GMT</pubDate></item><item><title><![CDATA[最近闲下来了]]></title><description><![CDATA[<div><blockquote>该渲染由 Shiro API 生成，可能存在排版问题，最佳体验请前往：<a href="https://blog.flyyingpiggy2020.cn/notes/16">https://blog.flyyingpiggy2020.cn/notes/16</a></blockquote><div><p>换了公司之后，目前在一家很小的小公司上班了</p><p>大概花了三个月(12月到2月) 把手头上的项目嵌入式软件部分写完了（项目排期是到9月份完毕）</p><p>除去留给生产的时间，领导预计是4月份完成嵌入式软件功能部分。（注：领导只想完成功能）</p><p>我这算是大大提前了。</p><p>目前卡在OTA、产测部分代码。</p><p>由于人员紧张，OTA部分需要APP组同事协助我。（APP开发一个安卓板，和我的MCU用USB连接）</p><p>但是有一个更加紧急的项目在4月1号开发布会，所以年后的到4月为止，我们公司所有资源都为它服务。</p><p>而我一个人无法完成OTA和产测联调，只能先写好我这部分的。</p><p>所以我现在有好几个月的空闲时间。（上班摸鱼ing）</p></div><p style="text-align:right"><a href="https://blog.flyyingpiggy2020.cn/notes/16#comments">看完了？说点什么呢</a></p></div>]]></description><link>https://blog.flyyingpiggy2020.cn/notes/16</link><guid isPermaLink="true">https://blog.flyyingpiggy2020.cn/notes/16</guid><dc:creator><![CDATA[Lu Xianfan]]></dc:creator><pubDate>Fri, 27 Feb 2026 01:56:27 GMT</pubDate></item><item><title><![CDATA[极点为什么可以判断稳定性]]></title><description><![CDATA[<div><blockquote>该渲染由 Shiro API 生成，可能存在排版问题，最佳体验请前往：<a href="https://blog.flyyingpiggy2020.cn/posts/basic/pole_logic_e_pt_stability">https://blog.flyyingpiggy2020.cn/posts/basic/pole_logic_e_pt_stability</a></blockquote><div><h4 id="">第一步：什么是极点？</h4><p>假设一个系统的传递函数是 $G(s) = \frac{1}{s - p}$。这里的 $p$ 就是<strong>极点</strong>（让分母为 0 的点）。</p><h4 id="">第二步：回到时间轴（拉普拉斯逆变换）</h4><p>我们在数学上知道， $\frac{1}{s - p}$ 在时间域上对应的函数是 $e^{pt}$。</p><ul><li>这个 $e^{pt}$ 描述了系统受到扰动后，自己“乱动”的规律（天然反应）。</li></ul><h4 id="p">第三步：看p的正负（复平面的左与右）</h4><p>极点 $p$ 通常是一个复数，可以写成 $p = \sigma + j\omega$（ $\sigma$ 是实部， $\omega$ 是虚部）。那么：
 $e^{pt} = e^{(\sigma + j\omega)t} = \mathbf{e^{\sigma t}} \cdot e^{j\omega t}$</p><ul><li><p><strong>如果极点在左半平面 ( $\sigma &lt; 0$)：</strong>
 $e^{\sigma t}$ 是一个<strong>指数衰减</strong>项（例如 $e^{-2t}$）。随着时间 $t$ 变大，这个值会趋于 <strong>0</strong>。</p><ul><li><strong>结论：</strong> 扰动消失了，系统回到了平衡点 —— <strong>稳定</strong>。</li></ul></li><li><p><strong>如果极点在右半平面 ( $\sigma &gt; 0$)：</strong>
 $e^{\sigma t}$ 是一个<strong>指数爆炸</strong>项（例如 $e^{2t}$）。随着时间 $t$ 变大，这个值会趋于 <strong>无穷大</strong>。</p><ul><li><strong>结论：</strong> 扰动被无限放大，系统炸了 —— <strong>不稳定</strong>。</li></ul></li><li><p><strong>虚部 $\omega$ 是干什么的？</strong>
 $e^{j\omega t}$ 代表<strong>振荡</strong>（波浪线）。所以如果极点有虚部，系统就会一边衰减一边摆动。</p></li></ul></div><p style="text-align:right"><a href="https://blog.flyyingpiggy2020.cn/posts/basic/pole_logic_e_pt_stability#comments">看完了？说点什么呢</a></p></div>]]></description><link>https://blog.flyyingpiggy2020.cn/posts/basic/pole_logic_e_pt_stability</link><guid isPermaLink="true">https://blog.flyyingpiggy2020.cn/posts/basic/pole_logic_e_pt_stability</guid><dc:creator><![CDATA[Lu Xianfan]]></dc:creator><pubDate>Sat, 07 Feb 2026 02:18:15 GMT</pubDate></item><item><title><![CDATA[CherryUSB协议栈]]></title><description><![CDATA[<div><blockquote>该渲染由 Shiro API 生成，可能存在排版问题，最佳体验请前往：<a href="https://blog.flyyingpiggy2020.cn/posts/protocol/CherryUSB">https://blog.flyyingpiggy2020.cn/posts/protocol/CherryUSB</a></blockquote><div><h1 id="cherryusb">CherryUSB协议栈学习使用</h1><p>基于<code>STM320B1</code>使用<code>CherryUSB</code>协议栈来做虚拟串口。这个协议栈是中国人自己写的一个USB协议栈，据说比STM32自带的好用。</p><p>之前作为螺丝钉，项目的芯片选型，技术选型一直不受我的控制。加入新公司之后，因为新公司人比较少，甚至没有产品经理，所以从硬件选型到技术选型都由我自己设计了。</p>
<p>于是我觉得项目中80%用旧技术，20%用新技术，也算是一种学习。如果实在搞不定，就在硬件上加一个<code>TLL to USB</code>的芯片。</p><h2 id="usb-ip">一、对于USB IP的理解</h2><p>这款USB协议栈是基于<code>USB</code>的<code>IP</code>核所设计的，可以从它的<code>port</code>文件夹内看到支持的IP类型。它的适配是比较全的，基本上市面上常有的芯片都有支持。</p><p>因为IP核设计是比较困难的，需要设计出符合规范的IP核需要一个庞大的IC团队，其中<code>Synopsys</code>的<code>dwc2</code>这款IP核是经过无数芯片验证的。</p><p>早年间<code>ST</code>也自己设计过自己的IP核<code>fsdev</code>(应用在<code>F1</code>,<code>F0</code>等一些低端的芯片上)，但是不支持<code>HOST</code>。</p><p>在高端芯片上，<code>ST</code>采取了支付授权费的方式，采用了<code>dwc2</code>的<code>IP</code>核。</p><p>我们国产的很多芯片例如<code>GD32</code>,<code>AT32</code>,<code>HC32</code>也是采用支付授权费的方式，使用dwc2这款IP核。</p>
<p><code>usb_dc_xxx.c</code> 是芯片所对应不同ip和的驱动，对不同的IP抽象出了统一的接口。</p><p>本次使用的单片机为<code>STM32G0</code>系列，可以通过阅读数据手册，对比寄存器来判断到底用的是哪个IP核。如果寄存器中有<code>USB_CNTR</code>，<code>USB_ISTR</code>，<code>USB_EPnR</code>字样，说明这个IP核是<code>ST</code>自研的<code>fsdev</code>。</p>
<p>根据上面的分析，将<code>port\fsdev</code>中的文件加入工程。其中<code>usb_glue_st</code>是针对<code>STM32CubeMX</code>生成的代码所设计的胶水层。</p><p>我的工程中没有用<code>CubeMX</code>生成代码，自然也没有里面使用到的<code>HAL</code>库的<code>API</code>接口。所以需要自己实现以下函数：</p><pre class="language-c lang-c"><code class="language-c lang-c">//初始化USB
void usb_dc_low_level_init(uint8_t busid)
{
}
//反初始化USB
void usb_dc_low_level_deinit(uint8_t busid)
{
}
</code></pre>
<p>并且在USB中断中调用</p><pre class="language-c lang-c"><code class="language-c lang-c">// 这里输入的参数（也就是busid）是usb接口的文件描述符。用于区分不同的USB
USBD_IRQHandler(0);
</code></pre>
<h2 id="usb">二、USB的类型</h2><p>USB控制器有三种类型：</p><p>从机是被控方，主机是控制方，OTG是既是从机也是主机的设备</p><p>在<code>core</code>目录下有着<code>usbd_core</code>、<code>usbh_core</code>和<code>usbotg_core</code>三个文件。</p><p>从名字就能看出来对应<code>device</code>，<code>host</code>和<code>otg</code>三种设备。</p><p>我这儿用到的从机，也就是<code>device</code>。</p><p>从机：例如单片机当U盘。</p><p>主机：例如读取U盘的单片机。</p><p>OTG：通过<code>ID</code>线切换角色，或者通过<code>type-c</code>的<code>cc</code>线协议切换。我没用过</p><h2 id="usbclass">三、USB的Class</h2><p>在USB出现前，每个硬件厂商都要为自己的设备写一个<code>Windows</code>驱动程序。用户买个鼠标还需要先从软盘装驱动，非常的痛苦。</p><p><code>USB Class</code>本质上是一套标准化的沟通协议。</p><p><code>USB</code>组织规定：所有的鼠标键盘都按<code>HID Class</code>说话。所有的U盘都按<code>MSC Class</code>说话。所有的摄像头都按 <code>UVC Class</code>说话。</p><p>这样的结果就是<code>windows</code>只需要内置几种通用的驱动，就能驱动世界上好几亿的设备。实现了免驱。</p><p>进阶：还有一种复合设备，例如4G模组，你插入后，它既是网卡又是串口还是U盘。这个就是定义了多个<code>interface</code>，每个<code>interface</code>声明不同的<code>Class</code>。</p>
<p>这样子相当于在<code>usbd_core</code>，用户应用层之间还有一个中间层。</p><p><code>CherryUSB</code>实现了许多常用的<code>Class</code>，本次使用的虚拟串口。将<code>class/usbd_cdc_acm.c</code>代码加入即可。</p>
<h2 id="">四、初始化的伪代码</h2><pre class="language-c lang-c"><code class="language-c lang-c">/*
 * Copyright (c) 2025 by Lu Xianfan.
 * @FilePath     : app_usb_cdc.c
 * @Author       : lxf
 * @Date         : 2025-01-20 10:00:00
 * @LastEditors  : lxf_zjnb@qq.com
 * @LastEditTime : 2026-01-21 16:00:00
 * @Brief        : USB CDC (虚拟串口) 应用层
 * @usage       :
 * @code
 *     app_usb_cdc_init();
 *     while (1) {
 *         app_usb_cdc_poll();
 *     }
 * @endcode
 */

/*---------- includes ----------*/
#include &quot;app_main.h&quot;
#include &quot;usbd_core.h&quot;
#include &quot;usbd_cdc.h&quot;
/*---------- macro ----------*/

/* USB配置描述符总长度 = 配置描述符(9) + CDC描述符(67) */
#define USB_CONFIG_SIZE (9 + CDC_ACM_DESCRIPTOR_LEN)

/* CDC最大包大小 (Full Speed) */
#define CDC_MAX_MPS     CONFIG_USB_CDC_MAX_MPS

/* CDC端点定义 */
#define CDC_IN_EP       0x81
#define CDC_OUT_EP      0x02
#define CDC_INT_EP      0x83

/*---------- type define ----------*/
/*---------- variable prototype ----------*/

/*---------- function prototype ----------*/
static const uint8_t *device_descriptor_callback(uint8_t speed);
static const uint8_t *config_descriptor_callback(uint8_t speed);
static const uint8_t *device_quality_descriptor_callback(uint8_t speed);
static const char *string_descriptor_callback(uint8_t speed, uint8_t index);
static void usbd_event_handler(uint8_t busid, uint8_t event);

/*---------- variable ----------*/

/* CDC端点结构体 */
static struct usbd_endpoint cdc_in_ep = {
    .ep_addr = CDC_IN_EP,
    .ep_cb    = NULL
};

static struct usbd_endpoint cdc_out_ep = {
    .ep_addr = CDC_OUT_EP,
    .ep_cb    = NULL
};

static struct usbd_endpoint cdc_int_ep = {
    .ep_addr = CDC_INT_EP,
    .ep_cb    = NULL
};

/* CDC接口 (需要2个接口：通信控制接口 + 数据接口) */
static struct usbd_interface intf0;
static struct usbd_interface intf1;

struct usb_descriptor cdc_descriptor = {
    .device_descriptor_callback = device_descriptor_callback,
    .config_descriptor_callback = config_descriptor_callback,
    .device_quality_descriptor_callback = device_quality_descriptor_callback,
    .string_descriptor_callback = string_descriptor_callback
};
/*---------- function ----------*/
/* USB 设备描述符 (18字节) */
static const uint8_t device_descriptor[] = {
    USB_DEVICE_DESCRIPTOR_INIT(
        USB_2_0,  /* bcdUSB: USB 2.0 */
        0xEF,     /* bDeviceClass: 0xEF (Miscellaneous) 用于复合设备或IAD */
        0x02,     /* bDeviceSubClass: 0x02 (Common) */
        0x01,     /* bDeviceProtocol: 0x01 (IAD) */
        USBD_VID, /* idVendor: VID */
        USBD_PID, /* idProduct: PID */
        0x0100,   /* bcdDevice: V1.00 */
        0x01      /* bNumConfigurations: 1个配置 */
        )
};

static const uint8_t config_descriptor[] = {
    USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
    CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02)
};

static const char *string_descriptors[] = {
    (const char[]){ 0x09, 0x04 }, /* Langid */
    USBD_MANUFACTURER_STRING,     /* Manufacturer */
    USBD_PRODUCT_STRING,          /* Product */
    USBD_SERIAL_STRING,           /* Serial Number */
};

static const uint8_t *device_descriptor_callback(uint8_t speed)
{
    return device_descriptor;
}

static const uint8_t *config_descriptor_callback(uint8_t speed)
{
    return config_descriptor;
}

static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
{
    return NULL;
}

static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
{
    if (index &gt; 3) {
        return NULL;
    }
    return string_descriptors[index];
}

static void usbd_event_handler(uint8_t busid, uint8_t event)
{
    switch (event) {
        case USBD_EVENT_RESET:
            break;
        case USBD_EVENT_CONNECTED:
            break;
        case USBD_EVENT_DISCONNECTED:
            break;
        case USBD_EVENT_RESUME:
            break;
        case USBD_EVENT_SUSPEND:
            break;
        case USBD_EVENT_CONFIGURED:
            // USB配置完成，可以开始传输数据
            // ep_tx_busy_flag = false;
            /* setup first out ep read transfer */
            // usbd_ep_start_read(busid, CDC_OUT_EP, read_buffer, 2048);
            break;
        case USBD_EVENT_SET_REMOTE_WAKEUP:
            break;
        case USBD_EVENT_CLR_REMOTE_WAKEUP:
            break;

        default:
            break;
    }
}

/**
 * @brief  USB CDC 初始化
 * @return 0=成功, &lt;0=失败
 */
int app_usb_cdc_init(void)
{
    /* 1. 注册描述符 */
    usbd_desc_register(0, &amp;cdc_descriptor);

    /* 2. 添加CDC接口 (2个接口：通信控制接口 + 数据接口) */
    usbd_add_interface(0, usbd_cdc_acm_init_intf(0, &amp;intf0));
    usbd_add_interface(0, usbd_cdc_acm_init_intf(0, &amp;intf1));

    /* 3. 添加端点 (OUT + IN + INT) */
    usbd_add_endpoint(0, &amp;cdc_out_ep);
    usbd_add_endpoint(0, &amp;cdc_in_ep);
    usbd_add_endpoint(0, &amp;cdc_int_ep);

    /* 4. 初始化USB设备栈 */
    usbd_initialize(0, USB_BASE, usbd_event_handler);

    return 0;
}
/*---------- end of file ----------*/

</code></pre>
<h2 id="">五、调试</h2><p>一直去发现进不了中断。</p><p>最后在群里询问<code>CherryUSB</code>的作者。群主说是不支持<code>G0</code>。</p><p>调试结束 OVER</p><p>最后使用了ST的官方库实现了<code>USB CDC</code>的功能，</p></div><p style="text-align:right"><a href="https://blog.flyyingpiggy2020.cn/posts/protocol/CherryUSB#comments">看完了？说点什么呢</a></p></div>]]></description><link>https://blog.flyyingpiggy2020.cn/posts/protocol/CherryUSB</link><guid isPermaLink="true">https://blog.flyyingpiggy2020.cn/posts/protocol/CherryUSB</guid><dc:creator><![CDATA[Lu Xianfan]]></dc:creator><pubDate>Mon, 02 Feb 2026 01:10:41 GMT</pubDate></item><item><title><![CDATA[前车之鉴，后车之师——关于IMA]]></title><description><![CDATA[<div><blockquote>该渲染由 Shiro API 生成，可能存在排版问题，最佳体验请前往：<a href="https://blog.flyyingpiggy2020.cn/notes/15">https://blog.flyyingpiggy2020.cn/notes/15</a></blockquote><div><p>腾讯推出IMA知识库。</p><p>沛公舞剑，意在项庄啊！</p><p>各行各业的人如果真的去使用这个知识库记录知识的话，能够提供高质量数据的话，未来这笔数据资产的价值就是无价的。</p><p>不过看看现在的Claude code，看看前端行业。</p><p>程序员开源的下场你们已经看到了，你们又该何去何从</p></div><p style="text-align:right"><a href="https://blog.flyyingpiggy2020.cn/notes/15#comments">看完了？说点什么呢</a></p></div>]]></description><link>https://blog.flyyingpiggy2020.cn/notes/15</link><guid isPermaLink="true">https://blog.flyyingpiggy2020.cn/notes/15</guid><dc:creator><![CDATA[Lu Xianfan]]></dc:creator><pubDate>Thu, 15 Jan 2026 00:57:59 GMT</pubDate></item><item><title><![CDATA[STM32G0B1调试记录]]></title><description><![CDATA[<div><blockquote>该渲染由 Shiro API 生成，可能存在排版问题，最佳体验请前往：<a href="https://blog.flyyingpiggy2020.cn/posts/other/stm32g0b1_debug_log">https://blog.flyyingpiggy2020.cn/posts/other/stm32g0b1_debug_log</a></blockquote><div><p>STM32G0B1系列的单片机，使用软件RS485通信。频繁进入<code>HAL_UART_ErrorCallback</code>。</p><p>因为在错误回调中做过清错误的处理，一直都功能正常，直到今天偶然间才发现这个问题。</p><p>错误寄存器显示ORE，NE，FE，PE错误，ORE为溢出错误，NE/FE为噪声错误/帧错误。</p><p>初步判定我的软件485收发切换不及时导致。</p>
<p>折腾了一天，测试结果现象如下：</p><p>1.发现问题之后，我怀疑我自己封装的驱动调用路径太长。所以用CubeMX新建了一个工程，新工程中没有复现该现象。我理解为现在STM32的HAL库中，提供的<code>HAL_UART_TxCpltCallback</code>就是说明TC中断触发，所以在里面切换为接收模式。在发送前切换为发送模式。</p><p>2.把CubeMX的收发方式移植到我的工程中，问题依旧。</p><p>3.注释掉其他代码，问题解决。</p><p>4.检查HAL库代码，感觉没什么问题。将工程的485改成硬件485问题解决。</p><p>5.使用-O0和-Ofast编译，进入错误中断的频率明显是-O0高很多。</p><p>现在疑惑：</p><p>我如下这样方式使用串口，加上自己的逻辑后，为什么会导致收发切换来不及？从而进入串口错误回调函数。</p><pre class="language-c lang-c"><code class="language-c lang-c">/**
 * @brief UART发送完成回调函数
 * @note  当一包数据发送完成时调用，用于RS485切换回接收模式
 */
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
    if (huart == &amp;huart1) {
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_RESET);
    } else if (huart == &amp;huart2) {
    } else if (huart == &amp;huart3) {
    }
}

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
    if (huart-&gt;Instance == USART1)
    {
        HAL_UARTEx_ReceiveToIdle_IT(&amp;huart1, rx_buffer1, RX_BUF_SIZE);
    }
}

int main(void)
{
  ...
  while (1)
  {
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET);
    uint8_t cmd = 0x02;
    HAL_UART_Transmit_IT(&amp;huart1, &amp;cmd, 1);
    HAL_Delay(10);
  }
}
</code></pre>
<p>虽然改成硬件485之后得以解决。但是还是没想通为啥。</p><hr/><p>2026年1月20日更新：</p><p>这个485口不复现这个情况了。但是发现上了24V供电后，另外一个传感器复现了。</p><p>目前板子用杜邦线连接的，怀疑是这个问题导致的。</p></div><p style="text-align:right"><a href="https://blog.flyyingpiggy2020.cn/posts/other/stm32g0b1_debug_log#comments">看完了？说点什么呢</a></p></div>]]></description><link>https://blog.flyyingpiggy2020.cn/posts/other/stm32g0b1_debug_log</link><guid isPermaLink="true">https://blog.flyyingpiggy2020.cn/posts/other/stm32g0b1_debug_log</guid><dc:creator><![CDATA[Lu Xianfan]]></dc:creator><pubDate>Wed, 14 Jan 2026 10:02:59 GMT</pubDate></item><item><title><![CDATA[记一次博客维修]]></title><description><![CDATA[<div><blockquote>该渲染由 Shiro API 生成，可能存在排版问题，最佳体验请前往：<a href="https://blog.flyyingpiggy2020.cn/posts/other/fixblog">https://blog.flyyingpiggy2020.cn/posts/other/fixblog</a></blockquote><div><p>博客：shiro</p><p>症状：前台访问502 Bad Gateway，后台可以正常登陆</p><p><a href="https://chat.deepseek.com/share/6p59zrneqgbe0gur0k">https://chat.deepseek.com/share/6p59zrneqgbe0gur0k</a></p><p><strong>1.提供给AI构建脚本</strong></p><pre class="language-yaml lang-yaml"><code class="language-yaml lang-yaml">name: Build and Deploy

on:
  push:
    branches:
      - main
  # schedule:
  #   - cron: &#x27;0 3 * * *&#x27;

  repository_dispatch:
    types: [trigger-workflow]

permissions: write-all
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

env:
  HASH_FILE: build_hash

jobs:
  prepare:
    name: Prepare
    runs-on: ubuntu-latest
    if: ${{ github.event.head_commit.message != &#x27;Update hash file&#x27; }}

    outputs:
      hash_content: ${{ steps.read_hash.outputs.hash_content }}

    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Read HASH_FILE content
        id: read_hash
        run: |
          content=$(cat ${{ env.HASH_FILE }}) || true
          echo &quot;hash_content=$content&quot; &gt;&gt; &quot;$GITHUB_OUTPUT&quot;
  check:
    name: Check Should Rebuild
    runs-on: ubuntu-latest
    needs: prepare
    outputs:
      canceled: ${{ steps.use_content.outputs.canceled }}

    steps:
      - uses: actions/checkout@v4
        with:
          repository: innei-dev/shiroi
          token: ${{ secrets.GH_PAT }} # `GH_PAT` is a secret that contains your PAT
          fetch-depth: 0
          lfs: true

      - name: Use content from prev job and compare
        id: use_content
        env:
          FILE_HASH: ${{ needs.prepare.outputs.hash_content }}
        run: |
          file_hash=$FILE_HASH
          current_hash=$(git rev-parse --short HEAD)
          echo &quot;File Hash: $file_hash&quot;
          echo &quot;Current Git Hash: $current_hash&quot;
          if [ &quot;$file_hash&quot; == &quot;$current_hash&quot; ]; then
            echo &quot;Hashes match. Stopping workflow.&quot;
            echo &quot;canceled=true&quot; &gt;&gt; $GITHUB_OUTPUT
          else
            echo &quot;Hashes do not match. Continuing workflow.&quot;
          fi
  build:
    name: Build artifact
    runs-on: ubuntu-latest
    needs: check
    if: ${{needs.check.outputs.canceled != &#x27;true&#x27;}}

    strategy:
      matrix:
        node-version: [lts/*]
    outputs:
      sha_short: ${{ steps.store.outputs.sha_short }}
      branch: ${{ steps.store.outputs.branch }}
    steps:
      - uses: actions/checkout@v4
        with:
          repository: innei-dev/shiroi
          token: ${{ secrets.GH_PAT }} # `GH_PAT` is a secret that contains your PAT
          fetch-depth: 0
          lfs: true

      - name: Checkout LFS objects
        run: git lfs checkout
      - uses: pnpm/action-setup@v2

      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: &#x27;pnpm&#x27;
      - uses: jongwooo/next-cache@v1
      - name: Install dependencies
        run: pnpm install
      - name: Build project
        run: |
          sh ./ci-release-build.sh
      # - uses: actions/upload-artifact@v4
      #   with:
      #     name: dist
      #     path: assets/release.zip
      #     retention-days: 7
      - name: Cache Build Artifacts
        id: cache-primes
        uses: actions/cache/save@v4
        with:
          path: assets
          key: ${{ github.run_number }}-release

      - name: Store artifact commit version
        shell: bash
        id: store
        run: |
          sha_short=$(git rev-parse --short HEAD)
          branch_name=$(git rev-parse --abbrev-ref HEAD)
          echo &quot;sha_short=$sha_short&quot; &gt;&gt; &quot;$GITHUB_OUTPUT&quot;
          echo &quot;branch=$branch_name&quot; &gt;&gt; &quot;$GITHUB_OUTPUT&quot;
  deploy:
    name: Deploy artifact
    runs-on: ubuntu-latest
    needs: build
    steps:
      # - name: Download artifact
      #   uses: actions/download-artifact@v4
      #   with:
      #     name: dist

      - name: Restore cached Build Artifacts
        id: cache-primes-restore
        uses: actions/cache/restore@v4
        with:
          path: |
            assets
          key: ${{ github.run_number }}-release
      - name: Move assets to root
        run: mv assets/release.zip release.zip

      - name: copy file via ssh password
        uses: appleboy/scp-action@v0.1.7
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USER }}
          password: ${{ secrets.PASSWORD }}
          key: ${{ secrets.KEY }}
          port: ${{ secrets.PORT }}
          source: &#x27;release.zip&#x27;
          target: &#x27;/tmp/shiro&#x27;

      - name: Exec deploy script with SSH
        uses: appleboy/ssh-action@master

        with:
          command_timeout: 5m
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USER }}
          password: ${{ secrets.PASSWORD }}
          key: ${{ secrets.KEY }}
          port: ${{ secrets.PORT }}
          script: |
            set -e
            source $HOME/.bashrc
            basedir=$HOME/shiro
            workdir=$basedir/${{ github.run_number }}
            mkdir -p $workdir
            mkdir -p $basedir/.cache
            mv /tmp/shiro/release.zip $workdir/release.zip
            rm -r /tmp/shiro
            cd $workdir
            unzip -qq -o $workdir/release.zip
            rm -rf $workdir/standalone/.env
            ln -s $HOME/shiro/.env $workdir/standalone/.env
            export NEXT_SHARP_PATH=$(npm root -g)/sharp
            # copy workdir ecosystem.config.js to basedir if not exists
            if [ ! -f $basedir/ecosystem.config.js ]; then
              cp $workdir/standalone/ecosystem.config.js $basedir/ecosystem.config.js
            fi
            # https://github.com/Unitech/pm2/issues/3054
            # symlink workdir node entry file to basedir
            ln -sf $workdir/standalone/server.js $basedir/server.js
            mkdir -p $workdir/standalone/.next
            rm -rf $workdir/standalone/.next/cache
            ln -sf $basedir/.cache $workdir/standalone/.next/cache
            cd $basedir
            pm2 reload ecosystem.config.js --update-env
            rm $workdir/release.zip
            pm2 save
            echo &quot;Deployed successfully&quot;
      - name: After deploy script
        run: |
          hash=${{ needs.build.outputs.sha_short }}
          # curl -X &quot;POST&quot; &quot;https://mx.innei.in/api/v2/fn/shiro/new-version-hook&quot; -H &#x27;Content-Type: application/json&#x27; -d &quot;{\&quot;hash\&quot;: \&quot;$hash\&quot;, \&quot;key\&quot;: \&quot;\&quot;}&quot;
          ${{ secrets.AFTER_DEPLOY_SCRIPT }}
  store:
    name: Store artifact commit version
    runs-on: ubuntu-latest
    needs: [deploy, build]
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal token
          fetch-depth: 0 # otherwise, you will failed to push refs to dest repo
      # Get the commit version from the build job
      - name: Use outputs from build
        env:
          SHA_SHORT: ${{ needs.build.outputs.sha_short }}
          BRANCH: ${{ needs.build.outputs.branch }}
        run: |
          echo &quot;SHA Short from build: $SHA_SHORT&quot;
          echo &quot;Branch from build: $BRANCH&quot;
      - name: Write hash to file
        env:
          SHA_SHORT: ${{ needs.build.outputs.sha_short }}

        run: echo $SHA_SHORT &gt; ${{ env.HASH_FILE }}
      - name: Commit files
        run: |
          git config --local user.email &quot;41898282+github-actions[bot]@users.noreply.github.com&quot;
          git config --local user.name &quot;github-actions[bot]&quot;
          git add ${{ env.HASH_FILE }}
          git commit -a -m &quot;Update hash file&quot;
      - name: Push changes
        uses: ad-m/github-push-action@master
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          branch: ${{ github.ref }}
Footer
© 2025 GitHub, Inc.
Footer navigation
Terms
Privacy
Security
Status
C
</code></pre>
<p>AI告诉我这个是是用一个叫<strong>pm2</strong>的管理工作做进程守护的。最后执行的是下面这一条命令</p><p><code>pm2 start ecosystem.config.js</code></p>
<p>我执行完毕之后，启动失败。AI让我执行<code>pm2 logs shiro --lines 50</code>查看日志。</p><p>分析日志后，发现是2323端口号冲突</p><p>利用<code>sudo lsof -i :2323</code>查看对应端口进程，发现是docker-pr</p>
<p>我再查看了docker容器里对应进程运行的是什么？</p><p><code>docker ps --format &quot;table {{.ID}}\t{{.Names}}\t{{.Ports}}&quot; | grep 2323</code></p><p>发现居然也是一个shiro</p>
<p>可能是我之前布置的开源的用的容器，所以导致了这个现象。</p><p>关闭了之后，在运行pm2就好了。</p>
<p><strong>websocket为什么不连接</strong></p><p>配置时地址填错了。</p></div><p style="text-align:right"><a href="https://blog.flyyingpiggy2020.cn/posts/other/fixblog#comments">看完了？说点什么呢</a></p></div>]]></description><link>https://blog.flyyingpiggy2020.cn/posts/other/fixblog</link><guid isPermaLink="true">https://blog.flyyingpiggy2020.cn/posts/other/fixblog</guid><dc:creator><![CDATA[Lu Xianfan]]></dc:creator><pubDate>Thu, 01 Jan 2026 13:27:38 GMT</pubDate></item><item><title><![CDATA[[信号与系统] 第三章 傅里叶级数的前世今生]]></title><description><![CDATA[<div><blockquote>该渲染由 Shiro API 生成，可能存在排版问题，最佳体验请前往：<a href="https://blog.flyyingpiggy2020.cn/posts/basic/fourier_transform">https://blog.flyyingpiggy2020.cn/posts/basic/fourier_transform</a></blockquote><div><h1 id="">傅里叶级数的前世今生</h1><p>傅里叶变换应用在我们生活中的方方面面，它本身值的用“传奇”两个字来评价。</p><p>相信学习通信和自动化的朋友们，都能够领会到这个变换的强大之处。</p><p>它提供了一个全新的视角去理解这个世界——从“时域”到“频域”。</p>
<p>不过在最开始的时候，约瑟夫傅里叶创造它并不是为了纯数学的优雅，而是为了解决一个非常实际的热传导问题——<strong>如何精确地描述热量在物体（比如一块金属）中随时间扩散和分布的规律？</strong></p>
<p>现在让我们把视角转到十九世纪，来回顾一下“傅里叶级数”的前世今生。（当然从级数到变换中间还有很长的路要走，这里从级数开始讲起）</p><h2 id="1">1.热传导问题的核心是解一个偏微分方程</h2><p>我们以一根细杆的一维热传导为例来介绍。设 $u(x,t)$ 表示在位置 $x$ 处、时间 $t$ 的温度，那么当时人们已经能够总结出基本的热传导方程如下所示：</p>
<p>$\frac{\partial u}{\partial t} = k \frac{\partial^2 u}{\partial x^2}$，</p><p>$u(x,0)=f(x)$，</p><p>求 $u(x,t)$</p>
<p>其中</p><p>$\frac{\partial u}{\partial t}$是温度对时间的一阶偏导数</p><p>$\frac{\partial^2 u}{\partial x^2}$是温度对空间的二阶偏导数</p><p>$k$是一个常数，代表热扩散率</p><p>已知<strong>初始时刻</strong>$t=0$的温度分布$u(x,0)=f(x)$，求任意$t$时间的任意$x$的温度$u(x,t)$：</p>
<p>这个热传导方程的难点就是不限制$f(x)$，对于给定一个任意的$f(x)$，都要求出$u(x,t)$。</p><p>像这样的偏导数求解，在傅里叶那个年代人类还从来没有遇到过，不知道怎么求解。</p><p>而傅里叶创造出傅里叶级数，就是为解这样的方程创造的一个工具。</p><blockquote>
<h3 id="">基础补充:什么是偏导数：</h3><p>考虑到有些朋友已经忘记偏导数是什么了。这里补充说明一下。如果对偏导数很熟悉的朋友可以跳过。</p><h4 id="-">单变量场景-导数</h4><p>首先我默认各位朋友知道什么是“导数”。导数就是瞬时变化率。以一辆汽车为例，假设任意 $t$ 时间的速度是$v(t)$，那么它的导数就是$v&#x27;(t)$速度的瞬时变化率，物理意义上就是加速度。</p><h4 id="-">多变量场景-偏导数</h4><p>如果速度和多个变量相关呢？</p><p>例如火箭发射中燃料不停的消耗，整个系统的质量$m$在不断的减少。在这个系统中，速度$v(m, t)$就和时间 $t$ ，质量 $m$ 两个参数相关了。</p><p><strong>偏导数</strong>是多元函数对<strong>其中一个自变量</strong>的导数，而将其他自变量视为<strong>常数</strong>。</p><p>上述这个例子中就有两个偏导数：</p><p>$\frac{\partial v}{\partial t}$ 这表示：<strong>固定质量不变</strong>时，速度随时间的变化率（纯粹由于加速度引起的变化）</p><p>$\frac{\partial v}{\partial m}$这表示：<strong>固定时间不变</strong>时，速度随质量的变化率（质量减少对速度的影响）</p></blockquote>
<h2 id="2">2.如何解这个偏微分方程</h2><h3 id="21-">2.1 当时人们对这个方程的认知</h3><p>当时的人们对于</p><p>$$\begin{cases}</p><pre class=""><code class="">\frac{\partial u}{\partial t}=k\frac{\partial ^2u}{\partial x^2}\
u(x,0)=u(x)\</code></pre><p>\end{cases}$$</p><p>这个问题，十九世纪的人们已经有以下几点认知：</p><ol start="1"><li><strong>如果 $u(x)= B$ ，那么 $u(x,t)= B$</strong></li><li><strong>如果 $u(x)= Bcos(\omega x)$ ，那么 $u(x,t)=Bcos(\omega x)e^{-K {\omega}^2 t}$</strong></li><li><strong>如果 $u(x)= Csin(\omega x)$ ，那么 $u(x,t)=Csin(\omega x)e^{-K{\omega}^2 t}$</strong></li></ol><p>这三个公式是当时的人们试凑出来的，我们把结论代回方程，也可以证明这三个式子成立</p><h4 id="">公式一验证</h4><p>$u(x,t)= B$</p><p><strong>求对t的一阶导数 </strong>$\frac{\partial u}{\partial t}$：因为B是一个常数，不随时间$t$变化，所以最后的结果为0</p><p><strong>求对x的二阶导数</strong>$\frac{\partial ^2u}{\partial x^2}$，因为B也不随空间$x$变化，所以左后结果为0。</p><p><strong>可以得到 $\frac{\partial u}{\partial t}=k\frac{\partial ^2u}{\partial x^2}$成立。</strong></p>
<p><strong>令</strong>$t=0$，求 $u(x,t)=B$： $u(x,0)=B=u(x)$</p><p><strong>可以得到 $u(x,0)=u(x)$成立。</strong></p><h4 id="">公式二验证</h4><p>$u(x,t)=Bcos(\omega x)e^{-K{\omega}^2 t}$</p><p><strong>求对t的一阶导数 $\frac{\partial u}{\partial t}$</strong>： $\frac{\partial u}{\partial t}= Bcos(\omega x)e^{-K{\omega}^2 t}(-K\omega^2)$</p><p><strong>求对x的二阶导数$\frac{\partial ^2u}{\partial x^2}$，方法为先求一阶导 $\frac{\partial u}{\partial x}$，再对 $\frac{\partial u}{\partial x}$求一次导得到二阶导 $\frac{\partial ^2u}{\partial x^2}$： </strong></p><blockquote><p>这里需要用复合函数求导的法则，因为是对x求导，所以 $e^{-k{\omega}^2 t}$看做是一个常数。</p><p>链式求导法则：1.先识别最外层函数，求导。2.再乘以内层函数的导数。3.如果嵌套，继续向内</p></blockquote>
<p>$\frac{\partial u}{\partial x}=-Bsin(\omega x)e^{-k{\omega}^2 t}\omega$</p><p><strong>再对 $x$做一阶导可得二阶导</strong> ：</p><p>$\frac{\partial ^2u}{\partial x^2}=-Bcos(\omega x)e^{-K{\omega}^2 t}\omega ^2$</p><p><strong>可以得到 $\frac{\partial u}{\partial t}=k\frac{\partial ^2u}{\partial x^2}$成立。</strong></p>
<p> $u(x,t)=Bcos(\omega x)e^{-K{\omega}^2 t}$把初始条件$t=0代入$。</p><p>$u(x,0)=Bcos(\omega x) e^{-Kx{\omega}^2 *0}=Bcos(\omega t)e^0=Bcos(\omega t)$</p><p><strong>所以 $u(x,0)=u(x)$成立。</strong></p><h4 id="">公式三验证</h4><p>$u(x,t)=Csin(\omega x)e^{-K{\omega}^2 t}$</p><p><strong>求对t的一阶导数 $\frac{\partial u}{\partial t}$</strong>： $\frac{\partial u}{\partial t}= Ccos(\omega x)e^{-K{\omega}^2 t}(-K\omega^2)$</p><p><strong>求对x的二阶导数 $\frac{\partial ^2u}{\partial x^2}$，方法为先求一阶导 $\frac{\partial u}{\partial x}$，再对 $\frac{\partial u}{\partial x}$求一次导得到二阶导 $\frac{\partial ^2u}{\partial x^2}$：</strong></p><p>$\frac{\partial u}{\partial x}=Ccos(\omega x)e^{-K{\omega}^2 t}\omega$</p><p><strong>再对$x$做一阶导可得二阶导</strong> ：</p><p>$\frac{\partial u}{\partial x}=-Csin(\omega x)e^{-K{\omega}^2 t}\omega^2$</p><p><strong>可以得到 $\frac{\partial u}{\partial t}=k\frac{\partial ^2u}{\partial x^2}$成立。</strong></p>
<p>同样再把初始条件$t=0代入$。</p><p>$u(x,0)=Csin(\omega x)$</p><p><strong>所以 $u(x,0)=u(x)$成立。</strong></p>
<h2 id="3-">3 傅里叶的假设</h2><p><strong>假设一：</strong></p><p>$u\left( x \right) =B<em>0+\sum</em>{k=1}^{+\infty}{B<em>k\cos \left( k\omega </em>0x \right)}+\sum<em>{k=1}^{+\infty}{C</em>k\sin \left( k\omega _0x \right)}$</p><blockquote><p>这里往往称 $B<em>{0}$为直流分量， $\omega</em>{0}$为基波频率，而 $k\omega_{0}$为k次谐波频率。</p></blockquote>
<p>那么热传导方程的解是下面这个公式：</p><p>$u\left( x,t \right) =B<em>0+\sum</em>{k=1}^{+\infty}{B<em>k\cos \left( k\omega </em>0x \right) e^{-{K\omega <em>0}^2t}}+\sum</em>{k=1}^{+\infty}{C<em>k\sin \left( k\omega </em>0x \right) e^{-{K\omega _0}^2t}}$</p><blockquote class="markdown-alert-note"><header>NOTE</header>
<p>这里 $e^{-{K\omega _0}^2t}$上面是大K哦，和小k不是同一个，是一个系数。</p></blockquote>
<p><strong>假设二：</strong></p><p>如果任意一个函数 $u\left( x \right)$都可以分解为 $B<em>0+\sum</em>{k=1}^{+\infty}{B<em>k\cos \left( k\omega </em>0 \right)}+\sum<em>{k=1}^{+\infty}{C</em>k\sin \left( k\omega _0 \right)}$。那就能找到任意函数的热传导方程的解。</p><p>在这里就把问题转化为——<strong>如何把一个函数 $u\left( x \right)$分解为 $B<em>0+\sum</em>{k=1}^{+\infty}{B<em>k\cos \left( k\omega </em>0 x\right)}+\sum<em>{k=1}^{+\infty}{C</em>k\sin \left( k\omega _0 x\right)}$这种形式</strong></p>
<h3 id="31--b0">3.1 如何计算 $B_0$</h3><p>$u\left( x \right) =B<em>0+\sum</em>{k=1}^{+\infty}{B<em>k\cos \left( k\omega </em>0 x\right)}+\sum<em>{k=1}^{+\infty}{C</em>k\sin \left( k\omega _0 x\right)}$</p><blockquote class="markdown-alert-important"><header>IMPORTANT</header>
<p><strong>如何计算 $B_0$?两边同时积分：</strong></p></blockquote>
<p>$\int<em>0^{\frac{2\mathrm{\pi}}{\mathrm{\omega}</em>0}}{\mathrm{f}\left( \mathrm{x} \right)}\mathrm{dx}=\int<em>0^{\frac{2\mathrm{\pi}}{\mathrm{\omega}</em>0}}{\mathrm{B}<em>0}\mathrm{dx}+\sum</em>{\mathrm{k}=1}^{+\infty}{\int<em>0^{\frac{2\mathrm{\pi}}{\mathrm{\omega}</em>0}}{\mathrm{B}<em>{\mathrm{k}}\cos \left( \mathrm{k\omega}</em>0 x\right)}}\mathrm{dx}+\sum<em>{\mathrm{k}=1}^{+\infty}{\int</em>0^{\frac{2\mathrm{\pi}}{\mathrm{\omega}<em>0}}{\mathrm{C}</em>{\mathrm{k}}\sin \left( \mathrm{k\omega}_0 x \right)}}\mathrm{dx}$</p><p>然后可以证明：</p><p>$\sum<em>{\mathrm{k}=1}^{+\infty}{\int</em>0^{T<em>0}{\mathrm{B}</em>{\mathrm{k}}\cos \left( \mathrm{k\omega}_0x \right)}}\mathrm{dx}$=0;</p><p>$\sum<em>{\mathrm{k}=1}^{+\infty}{\int</em>0^{T<em>0}{\mathrm{C}</em>{\mathrm{k}}\sin \left( \mathrm{k\omega}_0 x\right)}}\mathrm{dx}$=0;</p>
<p>所以最后可以的到$B_0$</p><p>$B<em>0=\frac{\int</em>0^{T<em>0}{u\left( \mathrm{x} \right)}\mathrm{dx}}{T</em>0}$</p><h4 id="311---summathrmk1inftyint0t0mathrmbmathrmkcos-left-mathrmkomega0-xrightmathrmdx0-">3.1.1 如何证明 $ \sum<em>{\mathrm{k}=1}^{+\infty}{\int</em>0^{T<em>0}{\mathrm{B}</em>{\mathrm{k}}\cos \left( \mathrm{k\omega}_0 x\right)}}\mathrm{dx}=0 $</h4><blockquote class="markdown-alert-important"><header>IMPORTANT</header>
<p>因为 $T_0$是基波周期，导致积分后的 $sin(2k\pi)$在k为正整数的时候一直为0</p></blockquote>
<p>$\int<em>0^{\frac{2\mathrm{\pi}}{\mathrm{\omega}</em>0}}{\mathrm{B}<em>{\mathrm{k}}\cos \left( \mathrm{k\omega}</em>0x \right)}\mathrm{dx}
\
=B<em>k\left[ \frac{\sin \left( k\omega </em>0x \right)}{k\omega <em>0} \right] </em>{0}^{\frac{2\pi}{\omega <em>0}}
\
=B</em>k\left( \frac{\sin \left( k\omega <em>0\frac{2\pi}{\omega </em>0} \right)}{k\omega <em>0}-\frac{\sin \left( k\omega </em>0*0 \right)}{k\omega <em>0} \right) 
\
=B</em>k\left( \frac{\sin \left( 2\pi k \right)}{k\omega <em>0}-\frac{\sin \left( 0 \right)}{k\omega </em>0} \right) =B_k\left( 0-0 \right) =0$</p><p>所以最后它的级数 $\sum<em>{\mathrm{k}=1}^{+\infty}{\int</em>0^{\frac{2\mathrm{\pi}}{\mathrm{\omega}<em>0}}{\mathrm{B}</em>{\mathrm{k}}\cos \left( \mathrm{k\omega}_0 x\right)}}\mathrm{dx}$也为0。</p><h4 id="312--summathrmk1inftyint0tmathrmcmathrmksin-left-mathrmkomega0-xrightmathrmdx0">3.1.2 如何证明 $\sum<em>{\mathrm{k}=1}^{+\infty}{\int</em>0^T{\mathrm{C}<em>{\mathrm{k}}\sin \left( \mathrm{k\omega}</em>0 x\right)}}\mathrm{dx}=0$</h4><p>$\int<em>0^{\frac{2\mathrm{\pi}}{\mathrm{\omega}</em>0}}{\mathrm{C}<em>{\mathrm{k}}\sin \left( \mathrm{k\omega}</em>0x \right)}\mathrm{dx}
\
=c<em>k\left[ \frac{\cos \left( k\omega </em>0x \right)}{-k\omega <em>0} \right] </em>{0}^{\frac{2\mathrm{\pi}}{\mathrm{\omega}<em>0}}=c</em>k\left( \frac{\cos \left( k\omega <em>0\frac{2\mathrm{\pi}}{\mathrm{\omega}</em>0} \right)}{-k\omega <em>0}-\frac{\cos \left( k\omega </em>00 \right)}{-k\omega <em>0} \right) 
\
=c</em>k\left( \frac{\cos \left( 2k\mathrm{\pi} \right)}{-k\omega <em>0}-\frac{\cos \left( 0 \right)}{-k\omega </em>0} \right) =c<em>k\left( \frac{1}{-k\omega </em>0}-\frac{1}{-k\omega _0} \right) =0$</p><h3 id="32--bk">3.2 如何计算 $B_k$</h3><blockquote class="markdown-alert-important"><header>IMPORTANT</header>
<p><strong>如何计算 $B<em>k$，两边同乘以 $\cos \left(a \omega </em>0x \right) $再做积分</strong></p></blockquote>
<p>$\int<em>0^{T</em>0}{u\left( x \right) \cos \left(a \omega <em>0x \right) dx}=\int</em>0^{T<em>0}{B</em>0\cos \left( \omega <em>0x \right) dx}+\sum</em>{k=1}^{+\infty}{\int<em>0^{T</em>0}{B<em>k\cos \left( k\omega </em>0x \right) \cos \left( \omega <em>0x \right) dx}}+\sum</em>{k=1}^{+\infty}{\int<em>0^{T</em>0}{C<em>k\sin \left( k\omega </em>0x \right) \cos \left( \omega _0x \right) dx}}$</p><p>这里先假设以下这四个公式成立：</p><ol start="1"><li><p>$\int<em>0^{T</em>0}{\cos \left( k<em>1\omega </em>0x \right) \cos \left( k<em>2\omega </em>0x \right) dx}=0$，前提条件$k<em>1\neq k</em>2$</p></li><li><p>$\int<em>0^{T</em>0}{\cos \left( k<em>1\omega </em>0x \right) \sin \left( k<em>2\omega </em>0x \right) dx}=0$，前提条件$k<em>1\neq k</em>2$</p></li><li><p>$\int<em>0^{T</em>0}{\cos ^2\left( k\omega <em>0x \right) dx}=\frac{T</em>0}{2}$</p></li><li><p>$\int<em>0^{T</em>0}{\sin^2\left( k\omega <em>0x \right) dx}=\frac{T</em>0}{2}$</p></li></ol><p>那么上述式子可以得出：</p><p>$\int<em>0^{T</em>0}{u\left( x \right) \cos \left( a\omega <em>0x \right) dx}=\int</em>0^{T<em>0}{B</em>0\cos \left( a\omega <em>0x \right) dx}+\sum</em>{k=1}^{+\infty}{\int<em>0^{T</em>0}{B<em>k\cos \left( k\omega </em>0x \right) \cos \left( a\omega <em>0x \right) dx}}+\sum</em>{k=1}^{+\infty}{\int<em>0^{T</em>0}{C<em>k\sin \left( k\omega </em>0x \right) \cos \left( a\omega <em>0x \right) dx}}
\
\int</em>0^{T<em>0}{u\left( x \right) \cos \left( a\omega </em>0x \right) dx}=0+0+\frac{T<em>0}{2}B</em>a+0=\frac{T<em>0}{2}B</em>a
\
B<em>a=\small{\frac{2}{T</em>0}}\int<em>0^{T</em>0}{u\left( x \right) \cos \left( a\omega _0x \right) dx}$</p><p>也就是说 $B<em>k=\small{\frac{2}{T</em>0}}\int<em>0^{T</em>0}{u\left( x \right) \cos \left( k\omega _0x \right) dx}$</p><blockquote class="markdown-alert-important"><header>IMPORTANT</header>
<p>这四个函数不难证明，只是繁琐而已。需要用到高中三角函数的几个公式。</p><p>$\cos \alpha \cos \beta =\frac{1}{2}\left[ \cos \left( \alpha +\beta \right) +\cos \left( \alpha -\beta \right) \right] $</p><p>$\cos \alpha \sin \beta =\frac{1}{2}\left[ \sin \left( \alpha +\beta \right) -\sin \left( \alpha -\beta \right) \right] $</p><p>$\cos ^2\alpha =\frac{1+\cos 2\alpha}{2}$</p><p>$\sin^2\alpha =\frac{1-\cos 2\alpha}{2}$</p></blockquote>
<h4 id="321--int0t0cos-left-k1omega-0x-right-cos-left-k2omega-0x-right-dx0-k1neq-k2">3.2.1 证明 $\int<em>0^{T</em>0}{\cos \left( k<em>1\omega </em>0x \right) \cos \left( k<em>2\omega </em>0x \right) dx}=0$，前提条件 $k<em>1\neq k</em>2$</h4><blockquote class="markdown-alert-important"><header>IMPORTANT</header>
<p>利用 $\cos \alpha \cos \beta =\frac{1}{2}\left[ \cos \left( \alpha +\beta \right) +\cos \left( \alpha -\beta \right) \right] $这个公式，以及 $sin2k \pi=0,cos2k\pi=1$的特性去求解即可。</p></blockquote>
<p>$\int<em>0^{T</em>0}{\cos \left( k<em>1\omega </em>0x \right) \cos \left( k<em>2\omega </em>0x \right) dx}
\
=\int<em>0^{T</em>0}{\frac{1}{2}\left[ \cos \left( k<em>1\omega </em>0x+k<em>2\omega </em>0x \right) +\cos \left( k<em>1\omega </em>0x-k<em>2\omega </em>0x \right) \right] dx}
\
=\frac{1}{2}\left[ \int<em>0^{T</em>0}{\cos \left( k<em>1\omega </em>0x+k<em>2\omega </em>0x \right) dx}+\int<em>0^{T</em>0}{\cos \left( k<em>1\omega </em>0x-k<em>2\omega </em>0x \right) dx} \right] 
\
=\frac{1}{2}\left[ \frac{\sin \left( k<em>1\omega </em>0x+k<em>2\omega </em>0x \right)}{k<em>1\omega </em>0+k<em>2\omega </em>0}\mid<em>{0}^{T</em>0}+\frac{\sin \left( k<em>1\omega </em>0x-k<em>2\omega </em>0x \right)}{k<em>1\omega </em>0-k<em>2\omega </em>0}\mid<em>{0}^{T</em>0} \right] 
\
=\frac{1}{2}\left[ \left( \frac{\sin \left( k<em>1\omega </em>0T<em>0+k</em>2\omega <em>0T</em>0 \right)}{k<em>1\omega </em>0+k<em>2\omega </em>0}-\frac{\sin \left( k<em>1\omega </em>00+k<em>2\omega </em>00 \right)}{k<em>1\omega </em>0+k<em>2\omega </em>0} \right) +\left( \frac{\sin \left( k<em>1\omega </em>0T<em>0-k</em>2\omega <em>0T</em>0 \right)}{k<em>1\omega </em>0-k<em>2\omega </em>0}-\frac{\sin \left( k<em>1\omega </em>00-k<em>2\omega </em>00 \right)}{k<em>1\omega </em>0-k<em>2\omega </em>0} \right) \right] 
\
=\frac{1}{2}\left[ \left( \frac{\sin 2\left( k<em>1+k</em>2 \right) \pi}{k<em>1\omega </em>0+k<em>2\omega </em>0}-\frac{\sin \left( 0 \right)}{k<em>1\omega </em>0+k<em>2\omega </em>0} \right) +\left( \frac{\sin 2\left( k<em>1-k</em>2 \right) \pi}{k<em>1\omega </em>0-k<em>2\omega </em>0}-\frac{\sin \left( 0 \right)}{k<em>1\omega </em>0-k<em>2\omega </em>0} \right) \right] =0$</p><h4 id="322--int0t0cos-left-k1omega-0x-right-sin-left-k2omega-0x-right-dx0--k1neq-k2">3.2.2 证明 $\int<em>0^{T</em>0}{\cos \left( k<em>1\omega </em>0x \right) \sin \left( k<em>2\omega </em>0x \right) dx}=0$ ，前提条件 $k<em>1\neq k</em>2$</h4><blockquote class="markdown-alert-important"><header>IMPORTANT</header>
<p>利用 $\cos \alpha \sin \beta =\frac{1}{2}\left[ \sin \left( \alpha +\beta \right) -\sin \left( \alpha -\beta \right) \right] $这个公式，以及 $sin2k \pi=0,cos2k\pi=1$的特性去求解即可。</p></blockquote>
<p>$\int<em>0^{T</em>0}{\cos \left( k<em>1\omega </em>0x \right) \sin \left( k<em>2\omega </em>0x \right) dx}
\
=\int<em>0^{T</em>0}{\frac{1}{2}\left[ \sin \left( k<em>1\omega </em>0x+k<em>2\omega </em>0x \right) -\sin \left( k<em>1\omega </em>0x-k<em>2\omega </em>0x \right) \right] dx}
\
=\frac{1}{2}\left[ \frac{-\cos \left( k<em>1\omega </em>0x+k<em>2\omega </em>0x \right)}{k<em>1\omega </em>0+k<em>2\omega </em>0}\mid<em>{0}^{T</em>0}-\frac{-\cos \left( k<em>1\omega </em>0x-k<em>2\omega </em>0x \right)}{k<em>1\omega </em>0-k<em>2\omega </em>0}\mid<em>{0}^{T</em>0} \right] 
\
=\frac{1}{2}\left[ \left( \frac{-\cos \left( k<em>1\omega </em>0T<em>0+k</em>2\omega <em>0T</em>0 \right)}{k<em>1\omega </em>0+k<em>2\omega </em>0}-\frac{-\cos \left( k<em>1\omega </em>00+k<em>2\omega </em>00 \right)}{k<em>1\omega </em>0x+k<em>2\omega </em>0x} \right) -\left( \frac{-\cos \left( k<em>1\omega </em>0T<em>0-k</em>2\omega <em>0T</em>0 \right)}{k<em>1\omega </em>0-k<em>2\omega </em>0}-\frac{-\cos \left( k<em>1\omega </em>00-k<em>2\omega </em>00 \right)}{k<em>1\omega </em>0-k<em>2\omega </em>0} \right) \right] 
\
=\frac{1}{2}\left[ \left( \frac{-\cos 2\left( k<em>1+k</em>2 \right) \pi}{k<em>1\omega </em>0+k<em>2\omega </em>0}-\frac{-\cos \left( 0 \right)}{k<em>1\omega </em>0x+k<em>2\omega </em>0x} \right) -\left( \frac{-\cos 2\left( k<em>1-k</em>2 \right) \pi}{k<em>1\omega </em>0-k<em>2\omega </em>0}-\frac{-\cos \left( 0 \right)}{k<em>1\omega </em>0-k<em>2\omega </em>0} \right) \right] 
\
=\frac{1}{2}\left[ \left( \frac{-1}{k<em>1\omega </em>0+k<em>2\omega </em>0}-\frac{-1}{k<em>1\omega </em>0x+k<em>2\omega </em>0x} \right) -\left( \frac{-1}{k<em>1\omega </em>0-k<em>2\omega </em>0}-\frac{-1}{k<em>1\omega </em>0-k<em>2\omega </em>0} \right) \right] =0$</p>
<h4 id="323--int0t0cos-2left-komega-0x-right-dxfract02">3.2.3 证明 $\int<em>0^{T</em>0}{\cos ^2\left( k\omega <em>0x \right) dx}=\frac{T</em>0}{2}$</h4><blockquote class="markdown-alert-important"><header>IMPORTANT</header>
<p>利用 $\cos ^2\alpha =\frac{1+\cos 2\alpha}{2}$这个公式去代， $\int<em>0^{T</em>0}{\frac{\cos 2k\omega _0x}{2}dx}$ 这个式子在3.2.1里面证明过了等于0。</p></blockquote>
<p>$\int<em>0^{T</em>0}{\cos ^2\left( k\omega <em>0x \right) dx}
\
=\int</em>0^{T<em>0}{\frac{1+\cos 2k\omega </em>0x}{2}dx}=\int<em>0^{T</em>0}{\frac{1}{2}dx}+\int<em>0^{T</em>0}{\frac{\cos 2k\omega <em>0x}{2}dx}
\
=\int</em>0^{T<em>0}{\frac{1}{2}dx}+0
\
=\frac{T</em>0}{2}$</p>
<h4 id="324--int0t0sin2left-komega-0x-right-dxfract02">3.2.4 证明 $\int<em>0^{T</em>0}{\sin^2\left( k\omega <em>0x \right) dx}=\frac{T</em>0}{2}$</h4><p>$\int<em>0^{T</em>0}{\sin ^2\left( k\omega <em>0x \right) dx}
\
=\int</em>0^{T<em>0}{\frac{1-\cos 2\alpha}{2}dx=}\int</em>0^{T<em>0}{\frac{1}{2}dx}-\int</em>0^{T<em>0}{\frac{\cos 2k\omega </em>0x}{2}dx}
\
=\int<em>0^{T</em>0}{\frac{1}{2}dx}-0
\
=\frac{T_0}{2}$</p><h3 id="33--ck">3.3 如何计算 $C_k$</h3><blockquote class="markdown-alert-tip"><header>TIP</header>
<p>这里和计算 $B_k$时的思路类似</p></blockquote>
<p>$\int<em>0^{T</em>0}{u\left( x \right) \sin \left( a\omega <em>0x \right) dx}=\int</em>0^{T<em>0}{B</em>0\sin \left( a\omega <em>0x \right) dx}+\sum</em>{k=1}^{+\infty}{\int<em>0^{T</em>0}{B<em>k\cos \left( k\omega </em>0x \right) \sin \left( a\omega <em>0x \right) dx}}+\sum</em>{k=1}^{+\infty}{\int<em>0^{T</em>0}{C<em>k\sin \left( k\omega </em>0x \right) \sin \left( a\omega <em>0x \right) dx}}
\
=0+0+\frac{T</em>0}{2}C_a$</p><p>最后可得 $C<em>k=\frac{2}{T</em>0}\int<em>0^{T</em>0}{u\left( x \right) \sin \left( k\omega _0x \right) dx}$</p><h3 id="34-">3.4 总结</h3><p>如果有一个 $f\left( x \right) =B<em>0+\sum</em>{k=1}^{+\infty}{B<em>k\cos \left( k\omega </em>0x \right)}+\sum<em>{k=1}^{+\infty}{C</em>k\sin \left( k\omega _0x \right)}$</p><p>$T_0$是基波周期等于 $\frac{2\pi}{\omega}$</p><p>则</p><p>$B<em>0=\frac{\int</em>0^{T<em>0}{f\left( \mathrm{x} \right)}\mathrm{dx}}{T</em>0}$</p><p>$B<em>k=\small{\frac{2}{T</em>0}}\int<em>0^{T</em>0}{f\left( x \right) \cos \left( k\omega _0x \right) dx}$</p><p>$C<em>k=\frac{2}{T</em>0}\int<em>0^{T</em>0}{f\left( x \right) \sin \left( k\omega _0x \right) dx}$</p><p>以此解热传导方程可得：</p><p>$f\left( x,t \right) =B<em>0+\sum</em>{k=1}^{+\infty}{B<em>k\cos \left( k\omega </em>0x \right) e^{-{K\omega <em>0}^2t}}+\sum</em>{k=1}^{+\infty}{C<em>k\sin \left( k\omega </em>0x \right) e^{-{K\omega _0}^2t}}$</p><blockquote class="markdown-alert-note"><header>NOTE</header>
<p>这里 $e^{-{K\omega _0}^2t}$上面是大K哦，和小k不是同一个，是一个系数。</p></blockquote>
<h2 id="4-">4. 后续</h2><p>傅里叶当年提交这篇论文之后被法国科学院拒绝了。</p><p>这个推理中有一个收敛性的问题。</p><p>这里默认了</p><p>$f\left( x \right) =B<em>0+\sum</em>{k=1}^{+\infty}{B<em>k\cos \left( k\omega </em>0x \right)}+\sum<em>{k=1}^{+\infty}{C</em>k\sin \left( k\omega _0x \right)}$</p><p>问题是为什么 $f(x)$可以写成这样呢？</p><p>傅里叶想到了这个问题，他当年写了一小句：我认为对于常规的方波，三角波，是能够证明收敛性的。</p><p>但是他没有证明，只是说了“我觉得可以”。</p><p>从他1805年提出这篇论文，直到1832年才有另外一个人，叫做“狄利赫里”才把它基本上解决了，这部分内容放到下一节再聊。</p></div><p style="text-align:right"><a href="https://blog.flyyingpiggy2020.cn/posts/basic/fourier_transform#comments">看完了？说点什么呢</a></p></div>]]></description><link>https://blog.flyyingpiggy2020.cn/posts/basic/fourier_transform</link><guid isPermaLink="true">https://blog.flyyingpiggy2020.cn/posts/basic/fourier_transform</guid><dc:creator><![CDATA[Lu Xianfan]]></dc:creator><pubDate>Fri, 07 Nov 2025 07:43:11 GMT</pubDate></item></channel></rss>