一、内核驱动开发:hello 模块实现
- 驱动程序代码
#include <linux/init.h> #include <linux/module.h> static int __init hello_init(void) { printk(KERN_INFO "hello kernel\n"); return 0; } module_init(hello_init); static void __exit hello_exit(void) { printk(KERN_INFO "bye kernel\n"); } module_exit(hello_exit); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("树莓派3B+ hello驱动模块"); MODULE_ALIAS("HelloModule"); MODULE_AUTHOR("Philon");
- 编译配置(Makefile)
obj-m := hello.o KERNEL_VERSION := $(shell uname -r) KDIR := /lib/modules/$(KERNEL_VERSION)/build PWD := $(shell pwd) all:$(MAKE) -C $(KDIR) M=$(PWD) modulesclean:$(MAKE) -C $(KDIR) M=$(PWD) clean
- 模块模块指令
- 加载:
sudo insmod hello.ko
- 查看输出:
dmesg | tail
- 卸载:
sudo rmmod hello
4.PWM 驱动问题说明
尝试实现 PWM 呼吸灯驱动时,发现旧版源码中的pwm_set_clock
等函数已被新版内核废弃。替换为pwm_enable
等新接口后编译通过,但装载内核时无法调用 PWM 资源,推测是设备树未正确声明 PWM 控制器导致。
二、Python 应用开发:PWM 呼吸灯
- 硬件连接
- 编码方式:BCM 编码
- 引脚分配:白色 LED 接 BCM13(PWM1),黄色 LED 接 BCM18(PWM0)
- 供电:通过树莓派 GPIO 口提供 5V 与 GND
2.完整代码:
import RPi.GPIO as GPIO
import timeGPIO.setmode(GPIO.BCM)
OUT1, OUT2 = 13, 18
GPIO.setup(OUT1, GPIO.OUT)
GPIO.setup(OUT2, GPIO.OUT)pwm1 = GPIO.PWM(OUT1, 60)
pwm2 = GPIO.PWM(OUT2, 60)try:pwm1.start(0)pwm2.start(0)for _ in range(3):# 白灯呼吸效果for dc in range(0, 101, 5):pwm1.ChangeDutyCycle(dc)time.sleep(0.1)for dc in range(100, -1, -5):pwm1.ChangeDutyCycle(dc)time.sleep(0.1)# 黄灯呼吸效果for dc in range(0, 101, 5):pwm2.ChangeDutyCycle(dc)time.sleep(0.1)for dc in range(100, -1, -5):pwm2.ChangeDutyCycle(dc)time.sleep(0.1)
finally:pwm1.stop()pwm2.stop()GPIO.cleanup()
三、超声波测距系统
-
硬件接线注意事项
| 引脚 | 功能 | 接线要求 |
|------|------|----------|
| Vcc | 电源正极 | 接树莓派 5V 引脚,避免独立供电 |
| GND | 电源负极 | 连接树莓派 GND |
| Trig | 触发信号 | 接 BCM23(输出模式) |
| Echo | 回声信号 | 需通过 1kΩ+2kΩ 电阻分压后接 BCM24(输入模式),防止 5V 信号烧毁 GPIO | -
测距原理
- 树莓派向 Trig 发送 10μs 高电平脉冲,HC-SR04 接收到信号后发射超声波,同时将 Echo 置高;
- 接收到反射波时 Echo 置低,通过测量高电平持续时间计算距离:
距离 = (高电平时间 × 34300cm/s) / 2
3.代码实现
import RPi.GPIO as GPIO
import timeGPIO.setmode(GPIO.BCM)
TRIG, ECHO = 23, 24
GPIO.setup(TRIG, GPIO.OUT)
GPIO.setup(ECHO, GPIO.IN)def measure_distance():GPIO.output(TRIG, True)time.sleep(0.00001)GPIO.output(TRIG, False)while GPIO.input(ECHO) == 0:start = time.time()while GPIO.input(ECHO) == 1:stop = time.time()time_diff = stop - startreturn (time_diff * 34300) / 2if __name__ == '__main__':try:while True:dist = measure_distance()print(f"距离:{dist:.2f} cm")time.sleep(1)except KeyboardInterrupt:print("测量停止")GPIO.cleanup()
四、超声波测距滤波算法分析
- 平均值滤波
- 原理:对 N 次测量值取算术平均,公式为
Y = (X₁+X₂+…+Xₙ)/N
。 - 优点:实现简单,有效抑制随机噪声;
- 缺点:对突变信号响应慢,不适用于动态场景(如移动物体测距)。
2.卡尔曼滤波
- 原理:基于状态空间模型,通过递归估计动态系统状态,同时考虑测量噪声与过程噪声。
- 核心优势:
- 动态适应性强,可实时修正温度漂移、环境干扰等误差;
- 无需存储历史数据,计算效率高,适合实时系统;
- 能处理非线性误差,更贴合超声波测距的实际场景(如声波折射、反射干扰)。
- 缺点:需建立精确的系统模型,初始参数调优难度较高。
3.方案选择
推荐采用卡尔曼滤波。超声波测距易受环境噪声、温度变化影响,且需实时更新距离数据,卡尔曼滤波可通过系统状态预测与修正,提供更稳定的测量结果。若硬件资源有限,可采用加权移动平均滤波作为简化方案。