1. 项目概述:从芯片到成品,打造一个精准可控的时钟
几年前,我第一次接触DS1302这颗芯片,是为了给一个老旧的设备加上断电也能走时的功能。当时市面上各种实时时钟模块琳琅满目,但DS1302以其极低的功耗、简单的三线接口和内置的31字节RAM,在众多DIY和嵌入式项目中脱颖而出。它不像一些更现代的RTC芯片那样集成度高、功能花哨,但正是这种“纯粹”和“经典”,让它成为了学习实时时钟原理和进行时间相关项目开发的绝佳起点。
这个“DS1302可调时钟”项目,核心就是围绕这颗经典的实时时钟芯片,构建一个完整的、功能可定制的电子时钟系统。它不仅仅是一个显示时间的装置,更是一个可以让你深入理解时间数据流、串行通信协议(SPI的一种变体)以及人机交互(如按键调整)的实践平台。最终,你可以得到一个能够通过按键调整年、月、日、时、分、秒,并且在主电源断开后依靠备用电池(通常是一颗纽扣电池)继续精准走时的独立时钟。无论是用于桌面摆件、集成到更大的智能家居系统中,还是作为学习嵌入式开发的练手项目,它都具有很高的实用价值和教学意义。
2. 核心芯片DS1302深度解析与选型考量
2.1 DS1302芯片工作原理与内部架构
DS1302是美国DALLAS公司(现并入MAXIM)推出的一款涓流充电时钟芯片。说它“经典”,是因为其设计思路清晰,功能模块划分明确,非常适合作为理解RTC的入门芯片。
它的核心是一个实时时钟/日历,能够提供秒、分、时、日、月、年等信息,对于小于31天的月份,月末日期会自动调整,并且具备闰年补偿功能,有效期到2100年。这意味着你不需要在软件里处理复杂的闰年判断逻辑,芯片硬件已经帮你搞定了。
除了最核心的计时功能,DS1302还有几个让我在项目中经常用到的亮点:
- 31字节静态RAM:这简直是个宝藏。你可以把一些需要掉电保存的配置参数、运行状态或者简单的日志信息存在这里。比如,我常用来存储时钟的显示模式(12小时制还是24小时制)、闹钟设置、甚至是一个简单的计数器。它通过芯片内部的备用电池供电保持,数据非常可靠。
- 涓流充电器:这个功能允许芯片在主电源VCC存在时,以一个很小的电流(可编程)给后备电池充电。这大大延长了电池的使用寿命,对于需要长期运行的设备来说是个福音。你可以通过配置寄存器来选择是否启用充电功能以及充电电流的大小。
- 简单的三线接口:它采用一种类似SPI但又不完全相同的串行通信协议,只需要三根线(CE、I/O、SCLK)就能与单片机(如Arduino、STM32、51单片机等)进行数据交换。这极大地节省了微控制器宝贵的IO引脚。
其内部工作原理可以简单理解为:一个高精度的32.768kHz石英晶体振荡器提供时间基准,经过内部的分频和计数电路,转换成我们需要的秒、分、时等时间单位,并存储在相应的寄存器中。单片机通过串行接口读取这些寄存器,就能获取当前时间;写入这些寄存器,就能设置时间。
注意:DS1302对32.768kHz晶振的负载电容有要求,通常为6pF或12.5pF。在PCB布局时,晶振应尽量靠近芯片的X1和X2引脚,走线短且对称,并严格按照数据手册推荐的值连接匹配电容,这是保证时钟走时精度的物理基础。我曾因为用了劣质晶振或电容值不匹配,导致时钟一天能快慢几十秒,排查了很久。
2.2 为何在众多RTC芯片中选择DS1302?
市面上RTC芯片很多,比如更精确的DS3231(内置温补,精度极高)、接口更现代的PCF8563(I2C接口)等。为什么很多项目,尤其是入门和教学项目,依然青睐DS1302呢?
- 学习成本低:它的通信协议简单明了,时序图清晰。自己动手用GPIO模拟这个通信过程,是对理解串行通信底层时序的绝佳锻炼。相比之下,I2C协议虽然只有两根线,但其复杂的起始、停止、应答机制对初学者来说可能更抽象。
- 接口独立:三线接口不占用常见的I2C或SPI总线,当你的系统主控的I2C或SPI总线已经被其他设备占用时,DS1302可以独立连接,互不干扰。
- 功能“刚刚好”:对于大部分时钟应用,秒、分、时、日、月、年、星期这些信息已经足够。DS1302没有集成温度传感器、多种报警等复杂功能,这让它的寄存器映射非常简洁,编程控制起来思路清晰。
- 成本与易得性:它价格低廉,在各大电子元器件平台都能轻松买到,相关的模块也非常普及。
当然,它也有缺点,最主要是精度依赖外部晶振。环境温度变化会导致晶振频率漂移,从而影响走时精度。对于精度要求极高的场合(比如每天误差要求小于1秒),DS1302可能不太适合,需要选择DS3231这类内置温度补偿晶振的芯片。但对于大部分日常应用和DIY项目,DS1302的精度是完全可接受的,通过定期软件校准(比如每周通过网络对时一次)可以很好地弥补。
3. 硬件系统设计与核心电路搭建
3.1 最小系统电路与关键外围器件
要让DS1302跑起来,一个稳定的最小系统电路是基础。下图展示了其核心连接,但这里我们用文字详细拆解每个部分的作用和选型理由。
电源部分 (VCC & VCC1 & VCC2):
- VCC (主电源):接系统正极,通常是+5V或+3.3V,取决于你的主控单片机电平。DS1302工作电压范围宽(2.0V至5.5V),兼容性强。
- VCC1 (主电源输入):通常直接与VCC相连。
- VCC2 (备用电源输入):这是关键!接一颗3V的纽扣电池(如CR2032)。当VCC掉电或低于VCC2时,芯片会自动切换到由VCC2供电,保证时钟持续运行和数据不丢失。这里必须在VCC2引脚和电池正极之间串联一个肖特基二极管(如1N5817)。这个二极管的作用是防止主电源VCC通过芯片内部电路反向给电池充电,造成电池损坏或意外消耗。这是很多初学者容易忽略的保护电路。
振荡电路 (X1 & X2):
- 32.768kHz晶振:这是时钟的心脏。务必选择负载电容匹配的晶振(通常6pF)。精度一般选20ppm的即可。
- 匹配电容C1, C2:通常两个电容值相等,根据晶振负载电容CL计算。例如,若晶振CL=12.5pF,PCB杂散电容估算为3pF,则每个匹配电容C ≈ 2 * (CL - Cstray) ≈ 2 * (12.5 - 3) = 19pF,可取标称值18pF或22pF。电容质量会影响起振和稳定性,建议用NPO/C0G材质的瓷片电容。
通信接口 (CE, I/O, SCLK):
- 这三根线直接连接到单片机的任意GPIO口。由于DS1302的通信速率不高(最高约2MHz),对GPIO速度无特殊要求。为了增强抗干扰能力,可以在每条线上串联一个100欧姆左右的电阻,并靠近DS1302端放置一个20pF-100pF的对地电容,尤其是在布线较长或环境嘈杂时。
备份电池与涓流充电:
- 电池负极接地。涓流充电功能通过配置芯片内部的“涓流充电寄存器”来启用。你可以选择充电二极管和限流电阻的组合,从而设定充电电流。例如,典型配置是启用一个二极管并选择2K欧姆电阻,充电电流约为0.5mA。除非你确定需要,否则不建议长期对可充电电池(如LIR2032)进行涓流充电,对于不可充电的CR2032,务必禁用涓流充电功能,否则可能引发电池漏液甚至爆炸风险。
3.2 显示与交互模块选型搭配
时钟需要显示,也需要调整。这里的选择决定了项目的最终形态和用户体验。
显示方案选择:
- LED数码管:经典、亮度高、成本低,适合做复古风格的桌面时钟。需要驱动电路(如74HC595移位寄存器)和限流电阻。优点是编程简单,显示效果醒目。
- LCD液晶屏:如1602、2004字符液晶,可以显示更多信息(如星期、温度附加信息)。需要并行或I2C/SPI转接板,编程有现成库,接口简单。
- OLED显示屏:如0.96寸或1.3寸SSD1306驱动的OLED。这是我个人最推荐的选择。它分辨率更高,可以显示自定义图形、字体,视觉效果现代,且功耗极低。通过I2C或SPI接口与单片机连接,有成熟的Arduino库或其他平台的驱动。
- TFT彩屏:功能最强大,可以显示丰富的图形界面、动画等,但成本高、驱动复杂、功耗大,适合作为综合性的信息显示终端,而不仅仅是时钟。
交互方案选择:
- 独立按键:最直接、最可靠的方式。通常需要3-4个按键:模式键(切换调整项)、加键、减键、确认键。需要配置单片机的GPIO为上拉输入模式,并做好软件消抖。
- 旋转编码器:用户体验更佳,通过旋转调整数值,按下确认。只需要一个器件就能完成所有调整操作,节省IO口,且操作有“质感”。编程上需要处理A、B相的脉冲序列。
- 红外遥控:适合做壁挂或摆件,无需直接接触设备调整。需要增加一个红外接收头(如VS1838),并编写相应的红外解码程序。好处是可以在一定距离内调整,显得更“高级”。
在我的项目中,我常常采用“OLED + 旋转编码器”的组合。OLED显示界面美观,可以设计多级菜单来调整时间、日期、闹钟等;旋转编码器操作直观流畅,一个器件解决所有输入问题,硬件连接也简洁。
4. 软件驱动与通信协议实现详解
4.1 深入理解DS1302的串行通信时序
DS1302使用一种单字节双向传输的协议。通信由CE(片选,有的资料叫RST)引脚拉高启动,由CE拉低结束。在CE为高期间,通过SCLK时钟脉冲的配合,在I/O引脚上逐位读写数据。
关键时序要点(必须严格遵守):
- 数据建立时间 (tDS):在
SCLK上升沿之前,需要写入的数据位必须在I/O上稳定一段时间(典型值50ns)。这意味着你的单片机需要在SCLK变高之前,提前设置好I/O引脚的电平。 - 数据保持时间 (tDH):在
SCLK上升沿之后,写入的数据位还需要保持一段时间(典型值50ns)。 - 数据读取时间:DS1302在
SCLK的下降沿将下一位数据输出到I/O线上。因此,你的单片机应该在SCLK下降沿之后,延迟一个短暂时间(确保数据稳定),再去读取I/O引脚的状态。
一个完整的字节传输过程(例如写一个命令字节):
- 单片机拉高
CE引脚。 - 单片机准备命令字节(包含读写位、目标寄存器地址)。
- 循环8次(从低位LSB开始发送): a. 单片机根据命令字节的当前位,设置
I/O引脚为输出模式,并输出相应电平(0或1)。 b. 等待一小段时间(满足tDS)。 c. 单片机产生一个SCLK上升沿。DS1302在此时钟上升沿采样I/O线上的数据位。 d. 保持I/O电平(满足tDH)。 e. 单片机拉低SCLK,为下一个位周期做准备。 - 如果是读操作,则在每次
SCLK下降沿后,单片机将I/O引脚切换为输入模式,并读取其电平,组合成数据字节。
实操心得:很多驱动代码出问题,都是时序不满足导致的。尤其是用软件模拟时序时,单片机执行每条指令都有时间,需要用
__nop()空指令或微秒级延时函数来精确控制SCLK高低电平的宽度以及数据建立/保持时间。最好的方法是使用示波器或逻辑分析仪抓取CE、SCLK、I/O三根线的波形,对照数据手册的时序图逐一检查,这是最可靠的调试方法。
4.2 寄存器映射与时间数据格式解析
与DS1302通信,本质上是读写其内部的寄存器。这些寄存器有统一的地址编码格式。
命令字节格式 (8位)
1 | A5 A4 A3 A2 A1 A0 | RD/WR | 0- 最高位
Bit7:必须为1。 Bit6-Bit1:寄存器地址。从00000到11111,对应不同的RAM和时钟寄存器。Bit0:读写控制位。1表示读,0表示写。- 最低位
Bit0后的0:实际传输时,命令字节是从最低位开始发送的,所以这个0是填充位。
关键时钟/日历寄存器地址:
- 秒寄存器:0x80 (写) / 0x81 (读)
- 分寄存器:0x82 / 0x83
- 时寄存器:0x84 / 0x85
- 日寄存器:0x86 / 0x87
- 月寄存器:0x88 / 0x89
- 星期寄存器:0x8A / 0x8B
- 年寄存器:0x8C / 0x8D
- 控制寄存器:0x8E / 0x8F (用于写保护控制)
- 涓流充电寄存器:0x90 / 0x91
数据格式(BCD码): DS1302存储的时间数据是二进制编码的十进制数。每个字节的高4位和低4位分别代表一个十进制数字。
- 例如,十进制数
25,用BCD码表示就是0010 0101(十六进制0x25)。0010是十位的2,0101是个位的5。 - 秒寄存器的
Bit7是时钟暂停位(CH)。为1时振荡器停止,时钟冻结;为0时振荡器启振。每次上电或初始化时,务必检查并清除此位,否则时钟不走! - 时寄存器的
Bit7用于选择12/24小时制。为1是12小时制,此时Bit5是AM/PM位(1=PM);为0是24小时制。 - 控制寄存器的
Bit7是写保护位(WP)。为1时,禁止写入任何时钟/日历寄存器;为0时允许写入。在写入时间前,必须先清除WP位(写0);写入完成后,建议重新置位WP位(写1)以防止误操作。
下面是一个用C语言编写的向DS1302写入一个字节的函数示例(假设基于51单片机或类似平台):
// 引脚定义 sbit DS1302_CE = P1^0; sbit DS1302_IO = P1^1; // 注意:此引脚需要双向操作 sbit DS1302_SCLK = P1^2; void DS1302_WriteByte(unsigned char dat) { unsigned char i; for(i=0; i<8; i++) { DS1302_SCLK = 0; // 先将时钟拉低 // 设置IO为输出方向(具体函数取决于单片机,此处示意) SET_IO_AS_OUTPUT(); // 输出数据位 (从最低位LSB开始) DS1302_IO = dat & 0x01; dat >>= 1; // 准备下一位 // 短暂延时,满足数据建立时间tDS _nop_(); _nop_(); _nop_(); DS1302_SCLK = 1; // 产生上升沿,DS1302采样数据 // 短暂延时,满足数据保持时间tDH _nop_(); _nop_(); _nop_(); // 循环末尾,SCLK会被拉低,开始下一位 } DS1302_SCLK = 0; // 最后确保时钟线回到低电平 }读取字节的函数与之类似,但需要在SCLK下降沿后读取IO状态,并且要注意在读操作前,需要先向DS1302发送命令字节(包含读指令和地址),然后IO线方向会由DS1302控制输出数据。
5. 功能实现与系统软件架构
5.1 时间读取、设置与显示逻辑
有了底层的读写函数,我们就可以构建更高层的功能了。一个健壮的时钟程序通常包含以下几个模块:
DS1302初始化模块:
- 上电后,首先拉低
CE和SCLK。 - 读取控制寄存器,检查写保护位
WP,如果需要设置时间,则先清除WP。 - 读取秒寄存器,检查时钟暂停位
CH,如果为1,则清除它以使振荡器工作。 - 根据需要配置涓流充电寄存器(通常默认禁用)。
- 上电后,首先拉低
时间读取与转换模块:
- 编写一个函数
Read_DS1302_Time(),依次读取秒、分、时、日、月、年、星期寄存器。 - 读取到的原始数据是BCD码,需要转换成单片机容易处理的十进制数。转换公式:
十进制 = (BCD >> 4) * 10 + (BCD & 0x0F)。 - 处理12/24小时制标志位,统一转换为24小时制在内部处理,显示时再根据设置转换。
- 将转换后的时间值存入一个全局的结构体变量中,供其他模块使用。
- 编写一个函数
时间设置模块:
- 提供一个函数
Set_DS1302_Time(),接收十进制格式的年、月、日、时、分、秒、星期参数。 - 将十进制数转换为BCD码。转换公式:
BCD = ((十进制 / 10) << 4) | (十进制 % 10)。 - 清除写保护位
WP。 - 依次将BCD码数据写入对应的寄存器。
- 重新使能写保护位
WP。
- 提供一个函数
显示驱动模块:
- 根据你选择的显示器件(如OLED),编写对应的显示驱动函数。
- 编写一个
Display_Time()函数,从全局时间结构体中获取数据,进行格式化(例如,在个位数前补零),然后调用OLED的显示函数将时间字符串或数字绘制到屏幕上。 - 可以设计不同的显示页面,比如大字体时间、包含日期和星期的完整信息、设置菜单等。
用户交互模块:
- 编写按键或编码器的扫描函数,检测用户的输入动作。
- 实现一个简单的状态机来管理时钟的工作模式。例如:
- 正常显示模式:显示时间,等待用户按下“设置”键。
- 设置模式:进入后,光标在“年”上闪烁,用户通过“加/减”键调整,按“确认”键进入下一项(月->日->时->分->秒),全部设置完成后自动退出并调用
Set_DS1302_Time()函数写入新时间。
5.2 掉电记忆与额外功能拓展
DS1302的31字节RAM是这个项目的“彩蛋”。我们可以用它来实现一些实用的增强功能。
掉电记忆应用示例: 假设我们想让时钟记住用户选择的12/24小时制格式。
- 在RAM中定义一个地址(如0x00)来存储这个设置。
#define DISPLAY_FORMAT_ADDR 0x00。 - 初始化时,从
DISPLAY_FORMAT_ADDR读取一个字节。如果是0xFF(RAM初始值),则使用默认格式(如24小时制),并将默认值写回。如果是0x00或0x01,则按读取的值设置格式。 - 当用户在菜单中更改格式后,除了更新软件状态,还要调用
DS1302_WriteRAM(DISPLAY_FORMAT_ADDR, format_value)将新值存入RAM。 - 这样,即使完全断电再上电,时钟也能恢复用户上次的设置。
拓展功能思路:
- 简易闹钟:利用RAM存储闹钟时间(时、分)。在主循环中,不断对比当前时间和闹钟时间,如果匹配,则控制一个蜂鸣器响铃或LED闪烁。可以存储多个闹钟。
- 计时/倒计时:利用RAM存储计时器的开始时间或倒计时的目标时间。结合单片机的定时器中断进行精确计时。
- 事件记录:用RAM作为循环缓冲区,记录最近几次的开关机时间或其他事件,用于简单诊断。
这些拓展充分利用了DS1302的特性,让一个简单的时钟项目变得更有深度和实用性。
6. 系统调试、精度校准与常见问题排查
6.1 硬件焊接与上电检查清单
在给系统上电前,花几分钟做一次彻底的硬件检查,能避免很多莫名其妙的故障。
- 电源与接地:用万用表测量VCC和GND之间是否有短路?电压是否正确(5V或3.3V)?备用电池电压是否正常(≥2.5V)?VCC2引脚上的保护二极管方向是否正确(阴极接VCC2,阳极接电池正极)?
- 晶振电路:检查32.768kHz晶振是否焊牢?两个匹配电容的值是否正确且焊接良好?可以用示波器探头(高阻抗)轻轻点测X1或X2引脚,看是否有近似32.768kHz的正弦波(幅度较小,约0.3-0.6Vpp)。注意:探头负载可能会影响振荡,如果停振了,说明电路可能处于临界状态,需要检查电容值或晶振质量。
- 通信线路:检查CE、I/O、SCLK三根线是否与单片机连接正确,没有虚焊或接错。上拉电阻(如果用了)是否接好?
- 显示与输入模块:检查OLED/数码管、按键/编码器的电源和信号线连接是否正确。
上电后,先不忙写程序,测量几个关键点电压:
- DS1302的VCC和VCC1引脚电压。
- VCC2引脚电压(应略低于电池电压,因为有二极管压降)。
- 晶振两脚对地电压,应大致为电源电压的一半左右,如果一高一低或都为0,可能未起振。
6.2 软件调试与通信验证
硬件检查无误后,开始软件调试。建议分步进行:
第一步:测试通信编写一个最简单的测试程序:尝试向DS1302的控制寄存器(地址0x8E)写入0x00(解除写保护),然后立刻读回来。如果读写值一致,说明通信基本正常。如果不一致,问题可能出在:
- 时序问题:用逻辑分析仪抓取三线波形,严格对照数据手册时序图检查
tDS,tDH,tCLK等参数是否满足。软件延时是否足够? - IO方向问题:
I/O线是双向的。写操作时,单片机必须设置为输出模式;读操作时,在发送完读命令字节后,必须将单片机该引脚设置为高阻输入或带上拉的输入模式,否则会和DS1302的输出冲突。 - 引脚配置问题:检查单片机引脚是否配置正确(如推挽输出、上拉输入等)。
第二步:测试时钟启振读取秒寄存器(地址0x81),检查其最高位(Bit7,CH位)。如果读出的值& 0x80结果为0x80,说明时钟振荡器被停止了。你需要向秒寄存器(地址0x80)写入一个值,其中最高位为0(例如0x00),来启动振荡器。等待至少1秒钟,再读取秒寄存器,其最低位应该开始变化了(因为秒数在增加)。
第三步:完整读写测试编写一个循环:先设置一个特定时间(例如2023年12月31日23时59分55秒),然后连续读取并打印时间,观察秒数是否每秒递增,日期时间是否正确进位。
6.3 走时精度校准与常见问题速查
即使电路和程序都正确,时钟也可能走不准。以下是常见原因和校准方法:
影响精度的主要因素:
- 晶振本身误差:32.768kHz晶振存在标称误差,如±20ppm(百万分之二十)。一天的理论误差为
86400秒 * 20e-6 ≈ ±1.73秒。 - 负载电容不匹配:PCB布线产生的杂散电容和外部匹配电容共同构成负载电容。与晶振要求的负载电容不匹配会导致频率偏移。
- 温度漂移:晶振频率会随温度变化。DS1302没有温度补偿,因此环境温度变化是走时误差的主要来源。
软件校准方法: DS1302本身没有数字校准寄存器。但我们可以通过计算“误差率”在软件中进行补偿,这是一个非常实用的技巧。
- 测量误差:让时钟连续运行一段时间(比如一周),记录它与标准时间(如网络时间)的累计误差秒数。
- 计算补偿值:误差 = 实际运行秒数 × 误差率。例如,运行7天(604800秒),快了10秒,则误差率 = 10 / 604800 ≈ 16.5 ppm(偏快)。
- 软件补偿:在每次读取DS1302时间后,在软件中根据运行时长进行加减。可以在每秒中断里,对一个32位的“软件补偿计数器”进行累加。当累计到一定值时,对显示的时间进行“跳秒”(加一秒或减一秒)。例如,如果误差是每天慢2秒,我们可以让“软件补偿计数器”每累计43200个“秒中断”后(即12小时),就让显示的时间额外增加1秒。
常见问题速查表:
| 现象 | 可能原因 | 排查步骤 |
|---|---|---|
| 读取的时间全是0或乱码 | 1. 通信失败 2. 时钟未启振 | 1. 用逻辑分析仪检查通信时序。 2. 检查秒寄存器CH位,并尝试写入0启动。 3. 检查电源和接地。 |
| 时钟不走,但通信正常 | 1. 晶振未起振 2. 晶振或电容损坏 | 1. 用示波器检查X1/X2引脚波形。 2. 更换晶振和匹配电容试试。 |
| 时间设置后,断电再上电恢复初始值 | 1. 备用电池没电或未接 2. VCC2电路错误 3. 写保护未解除 | 1. 测量电池电压。 2. 检查VCC2二极管方向。 3. 检查设置时间时是否先清除了控制寄存器的WP位。 |
| 走时误差非常大(一天几分钟) | 1. 晶振负载电容严重不匹配 2. 晶振质量差 | 1. 检查并调整匹配电容值。 2. 更换一个质量好的晶振。 |
| 显示闪烁或乱码 | 1. 电源不稳定 2. 通信受干扰 3. 显示驱动代码有bug | 1. 检查电源纹波,可在VCC和GND间加一个10uF电解电容并联一个0.1uF瓷片电容。 2. 缩短通信线,或加入上拉电阻和小电容滤波。 3. 检查显示刷新逻辑,避免在主循环中阻塞太久。 |
| 按键调整不灵敏或连击 | 1. 未做消抖处理 2. 按键扫描频率不合适 | 1. 在按键检测代码中加入软件消抖(检测到按下后延时10-20ms再确认)。 2. 确保按键扫描周期在10-50ms之间。 |
最后,分享一个我调试时的小技巧:在程序中添加一个“调试模式”,通过串口将每次从DS1302读出的原始BCD码、转换后的十进制数、以及关键寄存器的值打印出来。这比单纯看显示更能洞察底层数据的变化,对于定位通信、数据格式转换方面的问题非常有效。把硬件和软件的问题分离开,是快速解决问题的关键。这个DS1302可调时钟项目,从芯片手册研读到最终产品调试,完整走一遍,你对嵌入式系统的时间管理、低速串行通信、人机交互设计会有非常扎实的理解。