【前言】
================================================================================
FRDM-MCXA366 I3C 温度传感器 + SLCD 显示开发文档
================================================================================
1. 概述
--------------------------------------------------------------------------------
本文档说明如何在 NXP FRDM-MCXA366 开发板上,通过 I3C 总线读取 P3T1755
数字温度传感器,并在 OD-6010 段码液晶屏(SLCD)上显示温度值。
显示格式:C XX.X(摄氏度单位 + 1位小数)
工程路径:
~/Documents/MCUXpressoIDE_25.6.136/workspace/frdmmcxa366_i3c_master_read_sensor_p3t1755/
2. 硬件
--------------------------------------------------------------------------------
2.1 开发板
项目 型号/规格
开发板 NXP FRDM-MCXA366
MCU MCXA366 (Cortex-M33, 96MHz)
调试器 板载 MCU-LINK (CMSIS-DAP)
2.2 温度传感器
型号 NXP P3T1755
接口 I3C (I3C0)
默认地址 0x48 (7-bit)
动态地址 0x08 (分配后)
2.3 SLCD 面板
型号 OD-6010
位数 6 位段码
COM 4 (COM13-COM16, Duty 1/4)
前极引脚 LCD_P16-P27 (12 pins)
后极引脚 LCD_P28-P31 (COM13-COM16)
小数点 每个 digit 上方 3 个 (DP1-DP3),下方 3 个 (DP4-DP6)
2.4 引脚连接
I3C 总线(由 MCUXpresso Pin Tool 自动配置):
I3C0_SDA --> P1_8
I3C0_SCL --> P1_9
I3C0_PUR --> P0_2 (内置上拉,无需外部上拉电阻)
SLCD 引脚(P0_12-P0_27 --> LCD_P16-P31):
SLCD Pin MCU GPIO LCD Pin 用途
------- -------- ------- ----
P01 P0_12 LCD_P16 Digit 1 segment
P02 P0_13 LCD_P17 Digit 2 segment
P03 P0_14 LCD_P18 Digit 3 segment
P04 P0_15 LCD_P19 Digit 4 segment
P05 P0_16 LCD_P20 Digit 5 segment (E/F/G)
P06 P0_17 LCD_P21 Digit 5 segment (A/B/C/D) + DP2
P07 P0_18 LCD_P22 Digit 6 segment
P08 P0_19 LCD_P23 Digit 6 segment
P09 P0_20 LCD_P24 Digit 6 segment
P10 P0_21 LCD_P25 Digit 6 segment
P11 P0_22 LCD_P26 Digit 6 segment
P12 P0_23 LCD_P27 Digit 6 segment
LCD_P28 P0_24 COM13 Backplane (Phase A)
LCD_P29 P0_25 COM14 Backplane (Phase B)
LCD_P30 P0_26 COM15 Backplane (Phase C)
LCD_P31 P0_27 COM16 Backplane (Phase D)
slcd_lcd_gpio_seg_pin 数组(board/hardware_init.c)
将逻辑 PIN 索引映射到 LCD 引脚号:
const uint8_t slcd_lcd_gpio_seg_pin[] = {
16, 17, 18, 19, 20, 21, // P01-P06 --> LCD_P16-P21
22, 23, 24, 25, 26, 27 // P07-P12 --> LCD_P22-P27
};
3. 开发环境
--------------------------------------------------------------------------------
IDE MCUXpresso IDE 25.6.136
SDK NXP MCUXpresso SDK (支持 MCXA366)
调试服务器 LinkServer(随 IDE 安装,v25.6.131)
操作系统 macOS
LinkServer 已知问题:v25.6.131 设备库缺少 MCXA366,
配置设备时选择 MCXA346 代替(引脚布局相同)。
4. 项目结构
--------------------------------------------------------------------------------
frdmmcxa366_i3c_master_read_sensor_p3t1755/
source/
i3c_master_read_sensor_p3t1755.c 主程序(I3C + SLCD 温度显示)
board/
app.h SLCD 宏定义(duty cycle、backplane 配置)
app.c
hardware_init.c BOARD_InitHardware(), slcd_lcd_gpio_seg_pin[]
pin_mux.c BOARD_InitSLCDPins(), BOARD_InitI3CPins()
clock_config.c 时钟配置
slcd/
slcd_engine.c SLCD_Engine_Show_Num(), SLCD_Engine_Show_Icon()
slcd_engine.h tSLCD_Engine 结构体、函数声明
OD-6010.c 面板配置:ICON 表、Digit 段映射表
OD-6010.h ICON 枚举(ICON_DP1-DP6, ICON_END 等)
drivers/
fsl_slcd.c NXP SLCD 驱动(寄存器级)
fsl_slcd.h SLCD API、phase 定义
drivers/fsl_p3t1755.c & .h P3T1755 传感器驱动
5. SLCD 驱动框架
--------------------------------------------------------------------------------
5.1 层次结构
应用层 (i3c_master_read_sensor_p3t1755.c)
|
v
SLCD_Engine (slcd_engine.c)
| SLCD_Engine_Show_Num(), SLCD_Engine_Show_Icon()
v
SLCD_SetLCDPin() 回调
| 映射逻辑引脚到硬件寄存器
v
NXP fsl_slcd.c / fsl_slcd.h
| 寄存器级操作 SLCD_SetFrontPlaneOnePhase()
v
MCXA366 SLCD 外设 (LCD0)
5.2 初始化顺序
BOARD_InitHardware()
|- CLOCK_SetupFRO16KClocking() 提供 SLCD 时钟源(FRO16K = 16KHz)
|- BOARD_InitSLCDPins() 配置 P0_12-P0_27 为 LCD 功能
|- RESET_ReleasePeripheralReset() 释放 SLCD 外设复位
|- SLCD_InitHardware()
| |- SLCD_GetDefaultConfig()
| |- 配置时钟: kSLCD_AltClockSource5 (FRO16K), 预分频 16 --> ~1KHz 帧率
| |- SLCD_Init(LCD, &config)
| |- BOARD_SetSlcdBackPlanePhase() 配置 LCD_P28-P31 为 backplane
| |- SLCD_StartDisplay(LCD)
| |- SLCD_Engine_Init(&slcdEngine, SLCD_SetLCDPin)
|- I3C_MasterInit() I3C 总线初始化
5.3 Backplane 配置
4 个 COM 引脚配置为不同 phase,循环扫描:
void BOARD_SetSlcdBackPlanePhase(void)
{
SLCD_SetBackPlanePhase(LCD, 28, kSLCD_PhaseAActivate); // LCD_P28 = COM13 = Phase A
SLCD_SetBackPlanePhase(LCD, 29, kSLCD_PhaseBActivate); // LCD_P29 = COM14 = Phase B
SLCD_SetBackPlanePhase(LCD, 30, kSLCD_PhaseCActivate); // LCD_P30 = COM15 = Phase C
SLCD_SetBackPlanePhase(LCD, 31, kSLCD_PhaseDActivate); // LCD_P31 = COM16 = Phase D
}
Phase 与 COM 对应关系:
Phase A --> bit0 --> COM13 (LCD_P28)
Phase B --> bit1 --> COM14 (LCD_P29)
Phase C --> bit2 --> COM15 (LCD_P30)
Phase D --> bit3 --> COM16 (LCD_P31)
5.4 ICON 回调:SLCD_SetLCDPin()
应用层不直接操作寄存器,通过回调函数将 SLCD 引脚号映射为 MCU GPIO:
static void SLCD_SetLCDPin(lcd_set_type_t type, uint32_t lcd_pin,
uint8_t pin_val, int32_t on)
{
// lcd_pin: 1-12 (逻辑 PIN 索引)
// gpio_pin: 对应 LCD_P16-P27
uint8_t gpio_pin = slcd_lcd_gpio_seg_pin[lcd_pin - 1];
if (type == SLCD_Set_Num) {
// 数字显示:直接写全部 phase(覆盖)
SLCD_SetFrontPlaneSegments(LCD, gpio_pin, on ? pin_val : 0);
} else {
// ICON 显示:逐 phase 设置(read-modify-write,不破坏其他 phase)
for (int i = 0; i < 8; ++i) {
if (pin_val & (1U << i)) {
SLCD_SetFrontPlaneOnePhase(LCD, gpio_pin,
(slcd_phase_index_t)i, on);
}
}
}
}
关键:ICON 模式下 SLCD_SetFrontPlaneOnePhase 是 read-modify-write,
不会破坏同一引脚上其他 phase 的设置。这使得可以安全地为小数点单独添加 phase。
6. OD-6010 面板配置
--------------------------------------------------------------------------------
6.1 Digit 与 PIN 映射
每个 7 段 digit 由 7 个 segment (A-G) 组成,映射到两个 SLCD PIN:
Digit PIN (A/B/C/D) PIN (E/F/G) 对应 LCD Pin
----- -------------- ------------ -------------
POS1 (C) PIN1 PIN2 LCD_P16, LCD_P17
POS2 (tenths) PIN3 PIN4 LCD_P18, LCD_P19
POS3 (ones) PIN5 PIN6 LCD_P20, LCD_P21
POS4 (tens) PIN7 PIN8 LCD_P22, LCD_P23
POS5 PIN9 PIN10 LCD_P24, LCD_P25
POS6 PIN11 PIN12 LCD_P26, LCD_P27
6.2 小数点配置
OD-6010 每个 digit 位置有上下两个小数点,共 6 对:
ICON PIN LCD Pin 位置
----- ----- ------- ----
ICON_DP1 PIN8 LCD_P23 上方
ICON_DP2 PIN6 LCD_P21 上方
ICON_DP3 PIN4 LCD_P19 上方
ICON_DP4 PIN10 LCD_P25 下方
ICON_DP5 PIN12 LCD_P27 下方
ICON_DP6 PIN2 LCD_P17 下方
温度显示小数点使用 ICON_DP6(对应 Digit 1 位置下方)。
6.3 修改 ICON PIN 映射
编辑 slcd/OD-6010.c 中 SLCD_Icon[] 数组的 ICON 部分
(共 37 项,前 36 项为 digit segments,第 37-42 项为 ICON):
/* 6 icons: DP1-DP3 = above digits, DP4-DP6 = below digits */
SLCD_ENGINE_PIN_VAL(__SLCD_PIN8, __SLCD_P_COM), /* P1 = ICON_DP1 = above */
SLCD_ENGINE_PIN_VAL(__SLCD_PIN6, __SLCD_P_COM), /* P2 = ICON_DP2 = above */
SLCD_ENGINE_PIN_VAL(__SLCD_PIN4, __SLCD_P_COM), /* P3 = ICON_DP3 = above */
SLCD_ENGINE_PIN_VAL(__SLCD_PIN10, __SLCD_P_COM), /* P4 = ICON_DP4 = below */
SLCD_ENGINE_PIN_VAL(__SLCD_PIN12, __SLCD_P_COM), /* P5 = ICON_DP5 = below */
SLCD_ENGINE_PIN_VAL(__SLCD_PIN2, __SLCD_P_COM), /* P6 = ICON_DP6 = below */
SLCD_ENGINE_PIN_VAL(pin, phase) 宏定义为:
#define SLCD_ENGINE_PIN_VAL(pin, val) (((uint16_t)(pin) << 8) | ((uint16_t)(val) << 0))
// pin: 1-12
// val: phase bitmask, __SLCD_P_COM = 0x01 (Phase A)
7. P3T1755 温度传感器
--------------------------------------------------------------------------------
7.1 I3C 地址分配
P3T1755 出厂默认地址为 0x48 (7-bit)。
上电后通过 CCC (Common Command Code) 分配动态地址:
// 1. Reset dynamic address (RSTDAA)
I3C_MasterTransferBlocking(I3C0, { slave=0x7E, data=[0x06] }) // CCC_RSTDAA
// 2. Set dynamic address (SETDASA) - 分配 0x08
I3C_MasterTransferBlocking(I3C0, { slave=0x7E, data=[0x87] }) // CCC_SETDASA
I3C_MasterTransferBlocking(I3C0, { slave=0x7E, data=[0x10] }) // 0x08 << 1
// 3. 确认地址
I3C_MasterTransferBlocking(I3C0, { slave=0x08, data=[0x10] }) // 0x08 << 1
7.2 读取温度
使用 SDK 驱动 P3T1755_ReadTemperature(),内部调用 I3C_WriteSensor()
和 I3C_ReadSensor() 通过 I3C 总线读取 16-bit 温度寄存器。
8. 温度显示逻辑
--------------------------------------------------------------------------------
8.1 显示格式
POS1 POS2 POS3 POS4
[ C ] [ tenth ] [ ones ] [ tens ]
.(DP6) <-- 小数点在个位数字下方
温度值 27.3℃ --> 显示 C 2.7.(个位 2,十位 7,小数点在下)
8.2 数值解析
static void SLCD_DisplayTemperature(double temperature)
{
// 1. 范围限制:-99.9 ~ 999.9
// 2. 四舍五入到 1 位小数
temperature += 0.05;
temp_tenths = (int16_t)(temperature * 10.0); // 例: 27.35 --> 273
digit3 = (temp_tenths / 100) % 10; // 273/100 = 2 --> 个位
digit4 = (temp_tenths / 10) % 10; // 273/10 = 27 --> 7 (tenths)
digit5 = temp_tenths % 10; // 273%10 = 3 (tens)
// 3. 显示
SLCD_Engine_Show_Letter('C', NUM_POS1, 1); // "C"
SLCD_Engine_Show_Num(digit5, NUM_POS2, 1); // 小数位
SLCD_Engine_Show_Num(digit4, NUM_POS3, 1); // 个位
SLCD_Engine_Show_Num(digit3, NUM_POS4, 1); // 十位
SLCD_Engine_Show_Icon(ICON_DP6, 1); // 小数点(下方)
}
8.3 负温度
负温度时,digit 3(个位)的 segment G 亮起显示负号。
9. 如何调试
--------------------------------------------------------------------------------
9.1 查看 SLCD 寄存器
通过 IDE 的 FreeMASTER 或调试器 Memory 窗口查看 LCD0->WF[0-11]
(waveform 寄存器),确认每个 PIN 的 phase 设置。
9.2 单独测试某个 ICON
在 main() 或任意位置直接调用:
SLCD_Engine_Show_Icon(&slcdEngine, ICON_DP6, 1); // 点亮
SLCD_Engine_Show_Icon(&slcdEngine, ICON_DP6, 0); // 熄灭
9.3 测试不同小数点位置
修改 i3c_master_read_sensor_p3t1755.c 中 SLCD_DisplayTemperature() 里的
ICON_DP6 为:
- ICON_DP1 ~ ICON_DP3:显示在数字上方
- ICON_DP4 ~ ICON_DP6:显示在数字下方
10. 常见问题
--------------------------------------------------------------------------------
Q: 小数点位置不对(显示在数字上方而不是下方)
原因:使用了 ICON_DP1-DP3(上方小数点)
解决:温度显示使用 ICON_DP6(下方小数点,P6=PIN2=LCD_P17)
Q: I3C 读取温度失败
排查步骤:
1. 确认 P3T1755 正确连接到 I3C 总线(SCL/SDA)
2. 确认动态地址分配成功(PRINTF 日志检查)
3. 用示波器/逻辑分析仪测量 I3C 总线波形
Q: SLCD 无显示
排查步骤:
1. 确认 FRO16K 时钟配置正确(CLOCK_SetupFRO16KClocking)
2. 确认 backplane phase 配置正确(LCD_P28-P31)
3. 确认 SLCD 引脚(P0_12-P0_27)在 pin_mux 中配置为 LCD 功能
11 效果图:

12. 参考文件
--------------------------------------------------------------------------------
source/i3c_master_read_sensor_p3t1755.c 主程序源码
board/hardware_init.c 硬件初始化、slcd_lcd_gpio_seg_pin[]
board/app.h SLCD 宏定义
slcd/OD-6010.c 面板配置(ICON 表、Digit 映射)
slcd/slcd_engine.c SLCD 引擎(显示数字、图标)
drivers/fsl_slcd.h NXP SLCD API、phase 定义
MCXA366 Reference Manual SLCD 外设寄存器详情
P3T1755 Datasheet 温度传感器规格
OD-6010 User Manual 面板段码映射
我要赚赏金
