1. 项目背景与芯片选型
在嵌入式Linux开发中,GPIO扩展是常见需求。AW9523这颗国产芯片我用了三年多,它完美解决了树莓派、全志H3等开发板GPIO不足的问题。这颗芯片通过I2C接口可扩展出16个双向IO口,每个口都能独立配置为输入/输出模式,输出还支持4mA/8mA/16mA三级驱动能力调节。
为什么选择AW9523而不是常见的PCA9555?实测下来有三个优势:一是内置LED驱动模式,PWM调光不占CPU资源;二是中断响应速度比NXP的方案快30%;三是价格只有进口芯片的60%。去年给工厂做设备监控系统时,我用它同时驱动了12个继电器和4个光电开关,稳定性比预想的要好得多。
2. 硬件连接与设备树配置
2.1 硬件电路设计要点
AW9523的典型电路接法要注意三个关键点:
- I2C上拉电阻建议用2.2KΩ(实测1.8KΩ会导致波形畸变)
- 中断引脚必须接10KΩ上拉,芯片内部是开漏输出
- VCC引脚要加0.1μF去耦电容,布局时尽量靠近芯片
我的实际接线方案:
- SDA/SCL接开发板I2C1总线
- INT接GPIO25(配置为下降沿触发)
- A0/A1地址线接地,芯片地址固定为0x58
2.2 设备树配置详解
Linux4.4内核需要手动添加设备节点。这是我在全志H3平台用的配置片段:
dts复制&i2c1 {
aw9523: gpio-expander@58 {
compatible = "awinic,aw9523";
reg = <0x58>;
gpio-controller;
#gpio-cells = <2>;
interrupt-parent = <&pio>;
interrupts = <1 9 IRQ_TYPE_EDGE_FALLING>; /* PB9 */
aw9523,pwm-mode = <1>; /* 开启PWM模式 */
aw9523,reset-gpios = <&pio 1 7 GPIO_ACTIVE_LOW>; /* PB7 */
};
};
重点参数说明:
compatible必须严格对应驱动中的定义- 中断配置的第三个参数表示触发方式
- pwm-mode=1时,P0口会切换为PWM输出通道
踩坑记录:早期内核版本需要手动添加驱动代码,4.4.189之后主线内核已包含标准驱动,但需要确认CONFIG_GPIO_AW9523配置项是否开启
3. 驱动加载与功能测试
3.1 内核驱动编译
如果内核没有预编译驱动,需要手动配置:
bash复制make menuconfig
路径:Device Drivers -> GPIO Support -> AW9523 GPIO expander
编译后查看驱动是否加载:
bash复制dmesg | grep aw9523
[ 5.672310] aw9523 0-0058: found AW9523 GPIO expander
3.2 基础功能测试
验证GPIO读写:
bash复制# 导出GPIO (chip base为动态分配)
echo 488 > /sys/class/gpio/export # P0_0
echo out > /sys/class/gpio/gpio488/direction
echo 1 > /sys/class/gpio/gpio488/value
PWM功能测试:
c复制// 需要ioctl操作,示例代码片段
struct pwm_args pargs = {
.period_ns = 1000000, // 1kHz
.duty_cycle_ns = 300000 // 30%占空比
};
ioctl(fd, PWM_SET_ARGS, &pargs);
4. 高级应用与性能优化
4.1 中断处理实战
配置中断的关键步骤:
- 在设备树设置正确的中断引脚
- 驱动中实现irq_chip结构体
- 用户空间通过poll/epoll监控中断
实测数据:
- 中断响应延迟:平均28μs(标准GPIO为15μs)
- 中断抖动:±5μs(需配合RT-Preempt补丁)
4.2 驱动能力调节
通过寄存器配置驱动电流:
bash复制# 设置P1_4为16mA驱动
i2cset -y 1 0x58 0x05 0x0F
寄存器地址映射:
- 0x05: P0端口驱动设置
- 0x06: P1端口驱动设置
每个bit对应4mA步进(0x0F=16mA)
5. 常见问题排查手册
5.1 I2C通信失败
典型症状:
code复制i2c i2c-1: sendbytes: NAK bailout.
排查步骤:
- 用i2cdetect检测设备地址
bash复制
i2cdetect -y 1 - 检查上拉电阻阻值(示波器看波形)
- 确认VCC电压(3.3V±5%)
5.2 GPIO方向设置异常
现象:输出模式无法改变电平
解决方法:
- 检查是否处于PWM模式
bash复制cat /sys/kernel/debug/aw9523/status - 重置配置寄存器
bash复制
i2cset -y 1 0x58 0x02 0xFF
6. 生产环境部署建议
经过三年多工业现场验证,总结出以下经验:
-
电磁干扰防护:
- 所有IO口接100Ω电阻+TVS二极管
- I2C总线使用屏蔽双绞线
-
长期运行建议:
bash复制# 每24小时自动复位芯片 echo 1 > /sys/class/gpio/gpioX/value sleep 0.1 echo 0 > /sys/class/gpio/gpioX/value -
温度监控:
python复制# 读取芯片温度(通过I2C寄存器) def read_temp(): return i2c_read_byte(0x58, 0x20) - 40
实测在-40℃~85℃范围内工作正常,但建议在高温环境下降低PWM频率至500Hz以下。