返回博客
Markdown 渲染测试

Markdown 渲染测试

2026-04-22测试, Markdown

基础语法

文本格式

这是一段普通文本。这是粗体这是斜体这是粗斜体

这是 行内代码,用于标记变量名如 uint8_t 或函数名 uart_init()

链接和图片

这是一个链接

自动链接:https://example.com

引用

这是一段引用。

引用可以包含粗体代码

这是嵌套引用。

列表

无序列表:

  • 第一项
  • 第二项
    • 嵌套项 A
    • 嵌套项 B
  • 第三项

有序列表:

  1. 步骤一
  2. 步骤二
  3. 步骤三

水平线


GFM 扩展语法

表格

芯片架构FlashRAM特点
STM32F103Cortex-M364KB20KB经典入门
nRF52832Cortex-M4512KB64KBBLE 低功耗
ESP32Xtensa LX64MB520KBWi-Fi + BLE

删除线

这段文字被删除了

任务列表

  • 硬件原理图设计
  • PCB Layout
  • 固件开发
  • 量产测试

脚注

嵌入式系统1通常运行在资源受限的环境中。ARM Cortex-M2 是最常用的嵌入式处理器架构。

代码高亮

C 语言

#include <stdint.h>
#include <stdbool.h>

#define LED_PIN     13
#define UART_BAUD   115200

typedef struct {
    uint32_t baudrate;
    uint8_t  data_bits;
    uint8_t  stop_bits;
    bool     parity;
} uart_config_t;

static volatile uint32_t tick_count = 0;

void SysTick_Handler(void)
{
    tick_count++;
}

int main(void)
{
    uart_config_t config = {
        .baudrate  = UART_BAUD,
        .data_bits = 8,
        .stop_bits = 1,
        .parity    = false,
    };

    uart_init(&config);
    gpio_set_output(LED_PIN);

    while (1) {
        gpio_toggle(LED_PIN);
        delay_ms(500);
        uart_printf("Tick: %lu\r\n", tick_count);
    }
}

Python

import serial
import struct
import time

def calculate_crc16(data: bytes) -> int:
    """Calculate Modbus CRC-16"""
    crc = 0xFFFF
    for byte in data:
        crc ^= byte
        for _ in range(8):
            if crc & 0x0001:
                crc = (crc >> 1) ^ 0xA001
            else:
                crc >>= 1
    return crc

class ModbusRTU:
    def __init__(self, port: str, baudrate: int = 9600):
        self.ser = serial.Serial(port, baudrate, timeout=1)

    def read_holding_registers(self, addr: int, reg: int, count: int) -> list[int]:
        frame = struct.pack('>BBHH', addr, 0x03, reg, count)
        crc = calculate_crc16(frame)
        frame += struct.pack('<H', crc)
        self.ser.write(frame)
        time.sleep(0.1)
        response = self.ser.read(5 + count * 2)
        return list(struct.unpack(f'>{count}H', response[3:-2]))

if __name__ == "__main__":
    mb = ModbusRTU("/dev/ttyUSB0", 115200)
    values = mb.read_holding_registers(1, 0x0000, 4)
    print(f"Registers: {values}")

JavaScript / TypeScript

interface SensorData {
  temperature: number;
  humidity: number;
  timestamp: Date;
}

async function fetchSensorData(url: string): Promise<SensorData[]> {
  const response = await fetch(url);
  if (!response.ok) {
    throw new Error(`HTTP ${response.status}: ${response.statusText}`);
  }
  return response.json();
}

const formatReading = (data: SensorData): string =>
  `${data.temperature.toFixed(1)}°C / ${data.humidity.toFixed(0)}% @ ${data.timestamp}`;

Bash

#!/bin/bash
# Build and flash firmware
set -e

PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)"
BUILD_DIR="${PROJECT_DIR}/build"

echo "Building firmware..."
mkdir -p "$BUILD_DIR"
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -Os \
    -ffunction-sections -fdata-sections \
    -Wl,--gc-sections \
    -T linker.ld \
    -o "$BUILD_DIR/firmware.elf" \
    src/*.c

arm-none-eabi-size "$BUILD_DIR/firmware.elf"

echo "Flashing..."
nrfjprog --program "$BUILD_DIR/firmware.hex" --sectorerase
nrfjprog --reset
echo "Done!"

JSON

{
  "device": "smart-sensor",
  "version": "1.2.0",
  "config": {
    "sample_rate": 100,
    "ble_enabled": true,
    "log_level": "info",
    "sensors": ["temperature", "humidity", "pressure"]
  }
}

无语言标识的代码块

region `RAM' overflowed by 2048 bytes
region `FLASH' overflowed by 15360 bytes

数学公式(KaTeX)

行内公式

欧拉公式 eiπ+1=0e^{i\pi} + 1 = 0 被称为数学中最美的公式。

电阻分压公式:Vout=Vin×R2R1+R2V_{out} = V_{in} \times \frac{R_2}{R_1 + R_2}

块级公式

傅里叶变换:

F(ω)=f(t)ejωtdtF(\omega) = \int_{-\infty}^{\infty} f(t) \, e^{-j\omega t} \, dt

RC 低通滤波器的传递函数:

H(s)=11+sRC=11+jωRCH(s) = \frac{1}{1 + sRC} = \frac{1}{1 + j\omega RC}

其截止频率为:

fc=12πRCf_c = \frac{1}{2\pi RC}

ADC 量化公式:

D=round(VinVref×2n)D = \text{round}\left(\frac{V_{in}}{V_{ref}} \times 2^{n} \right)

其中 nn 为 ADC 位数,VrefV_{ref} 为参考电压。

标题锚点

以下标题都应该自动生成可点击的锚点链接:

这是三级标题

这是四级标题

这是五级标题

HTML 内嵌

点击展开详细信息

这是折叠内容,可以包含:

  • 列表项
  • 粗体文本
  • 代码片段
// 折叠内容中的代码块
void hidden_function(void) {
    printf("You found me!\n");
}
提示:这是一个自定义 HTML 容器,用于验证 HTML 透传功能。

长代码块

/**
 * @brief  Modbus RTU frame parser - complete implementation
 * @param  frame  Raw UART received data
 * @param  len    Frame length in bytes
 * @retval 0 on success, negative on error
 */
int modbus_parse_frame(const uint8_t *frame, uint16_t len)
{
    if (len < 4) return -1;  // Minimum: addr(1) + func(1) + CRC(2)

    uint8_t  slave_addr = frame[0];
    uint8_t  func_code  = frame[1];
    uint16_t crc_recv   = (frame[len - 1] << 8) | frame[len - 2];
    uint16_t crc_calc   = modbus_crc16(frame, len - 2);

    if (crc_recv != crc_calc) {
        LOG_ERROR("CRC mismatch: recv=0x%04X calc=0x%04X", crc_recv, crc_calc);
        return -2;
    }

    if (slave_addr != g_config.slave_addr && slave_addr != 0x00) {
        return -3;  // Not addressed to us (and not broadcast)
    }

    switch (func_code) {
        case MODBUS_FUNC_READ_COILS:           return handle_read_coils(frame, len);
        case MODBUS_FUNC_READ_DISCRETE:        return handle_read_discrete(frame, len);
        case MODBUS_FUNC_READ_HOLDING:         return handle_read_holding(frame, len);
        case MODBUS_FUNC_READ_INPUT:           return handle_read_input(frame, len);
        case MODBUS_FUNC_WRITE_SINGLE_COIL:    return handle_write_coil(frame, len);
        case MODBUS_FUNC_WRITE_SINGLE_REG:     return handle_write_reg(frame, len);
        case MODBUS_FUNC_WRITE_MULTI_COILS:    return handle_write_multi_coils(frame, len);
        case MODBUS_FUNC_WRITE_MULTI_REGS:     return handle_write_multi_regs(frame, len);
        default:
            return modbus_send_exception(slave_addr, func_code, MODBUS_EX_ILLEGAL_FUNC);
    }
}

Mermaid 图表

流程图

flowchart TD
    A[需求分析] --> B[方案选型]
    B --> C[硬件设计]
    B --> D[软件开发]
    C --> E[硬件验证]
    D --> F[联调测试]
    E --> F
    F --> G{测试通过?}
    G -->|是| H[量产准备]
    G -->|否| C
    H --> I[批量生产]

时序图

sequenceDiagram
    participant MCU
    participant Sensor as I2C Sensor
    participant BLE as BLE Stack

    MCU->>Sensor: I2C Read (0x68, 0x00)
    Sensor-->>MCU: ACK + Data (6 bytes)
    MCU->>MCU: Parse accel/gyro data
    MCU->>BLE: Update GATT Characteristic
    BLE-->>MCU: Write confirmed
    Note over BLE: Phone app receives notification

状态图

stateDiagram-v2
    [*] --> Idle
    Idle --> Active : Button press
    Active --> Sampling : Timer tick
    Sampling --> Processing : Data ready
    Processing --> Active : Result sent
    Active --> LowPower : 30s timeout
    LowPower --> Idle : Deep sleep
    Idle --> [*] : Power off

混合内容

下面这段结合了多种语法:

注意:在 ARM Cortex-M 上,非对齐访问 uint32_t 类型的变量可能导致 Hard Fault。 使用 __attribute__((packed)) 时需特别小心。

公式:总线传输时间 T=N×11baudrateT = \frac{N \times 11}{baudrate}(N 为字节数,11 bits/byte for 8N1)

优化项方法RAM 收益Flash 收益
const 修饰只读数据移到 FlashΔRAM=size\Delta RAM = -sizeΔFlash=+size\Delta Flash = +size
-Os 编译编译器优化减少 40%+
gc-sections剔除死代码减少 5-15%减少 5-15%

Footnotes

  1. 嵌入式系统是指嵌入到更大系统中、执行特定功能的计算机系统。

  2. ARM Cortex-M 是 ARM 公司设计的低功耗微控制器处理器核心系列。