
基础语法
文本格式
这是一段普通文本。这是粗体,这是斜体,这是粗斜体。
这是 行内代码,用于标记变量名如 uint8_t 或函数名 uart_init()。
链接和图片
自动链接:https://example.com
引用
这是一段引用。
引用可以包含粗体和
代码。这是嵌套引用。
列表
无序列表:
- 第一项
- 第二项
- 嵌套项 A
- 嵌套项 B
- 第三项
有序列表:
- 步骤一
- 步骤二
- 步骤三
水平线
GFM 扩展语法
表格
| 芯片 | 架构 | Flash | RAM | 特点 |
|---|---|---|---|---|
| STM32F103 | Cortex-M3 | 64KB | 20KB | 经典入门 |
| nRF52832 | Cortex-M4 | 512KB | 64KB | BLE 低功耗 |
| ESP32 | Xtensa LX6 | 4MB | 520KB | Wi-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)
行内公式
欧拉公式 被称为数学中最美的公式。
电阻分压公式:
块级公式
傅里叶变换:
RC 低通滤波器的传递函数:
其截止频率为:
ADC 量化公式:
其中 为 ADC 位数, 为参考电压。
标题锚点
以下标题都应该自动生成可点击的锚点链接:
这是三级标题
这是四级标题
这是五级标题
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))时需特别小心。公式:总线传输时间 (N 为字节数,11 bits/byte for 8N1)
| 优化项 | 方法 | RAM 收益 | Flash 收益 |
|---|---|---|---|
const 修饰 | 只读数据移到 Flash | ||
-Os 编译 | 编译器优化 | 无 | 减少 40%+ |
gc-sections | 剔除死代码 | 减少 5-15% | 减少 5-15% |