尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

51单片机噪声监测系统设计:LCD1602+ADC0832完整实现

51单片机噪声监测系统设计:LCD1602+ADC0832完整实现 简介本资源是一套完整的单片机毕业设计项目资料面向电子信息、自动化等专业的本科生及单片机初学者解决环境噪声实时监测与阈值报警的典型嵌入式应用问题。资源包共64个文件涵盖Keil C51源程序工程含.c/.h/.a51文件、Proteus 8.10仿真工程含.pdsprj/.pdsbak、论文材料doc/docx格式的设计说明与课程设计文档、配套技术手册ADC0832、LCD1602等模块PDF资料以及安装教程、视频操作指南mp4、答辩技巧等实用内容压缩包大小为29.84MB。已有185人学习下载资料结构清晰、模块对应明确包含硬件原理图说明、软件流程图、仿真验证截图、阈值设置交互逻辑详解及声光报警触发机制分析特别适合用于课程设计、毕设参考或嵌入式入门实战训练。 一套单片机课程设计核心难点从来不是跑通某个外设而是把采集—处理—显示—告警这条完整链路想明白。今天就以一套经典的51LCD1602ADC0832噪声监测系统为例从需求拆解讲到仿真联调把每一步为什么这么设计的逻辑一起理清楚。这套方案我在实际项目里反复用过稳定性和可复现性都很高无论你是做课程设计、毕业设计还是想快速搭建一个环境监测原型都能直接参考。1. 噪声监测到底在测什么先把工程需求拆清楚1.1 声压、分贝与噪声监测的关系很多人一上来就纠结怎么让单片机认识噪声其实工程上的噪声监测测的并不是声音本身而是声压级。声音是空气压力的波动人耳能感知的动态范围非常大从刚刚能听到的微弱声响到让人耳朵疼痛的强噪声压力比值跨越了百万倍直接显示线性声压值没有任何实际意义。所以声学界引入了分贝dB这个对数标尺用声压级SPL来表示声音的强弱。这里必须理解两个常用参考值0dB SPL对应声压20微帕μPa这是人耳在1kHz频率下刚好能听到的声压而94dB SPL对应的声压恰好是1帕Pa。为什么94dB这个值常出现因为大多数驻极体麦克风的灵敏度指标是以94dB SPL即1Pa声压为基准标定的。比如一支常见的驻极体麦克风灵敏度量级在-40dBV/Pa含义是在1Pa声压输入时输出电压约为10mV因为0dBV1V-40dBV即0.01V。搞清楚这个关系后面整个信号链的增益计算才有依据。对于我们这套系统噪声监测的结果最终要落到当前环境大约多少分贝这个数值上。单片机不能直接测dB值要通过ADC采集电压、再通过标定曲线映射到声压级。把这条链路理顺了代码怎么写、电路怎么调方向就全对了。1.2 把标题里的每个模块映射到具体功能项目标题511602AD0832LEDx2BZKEY3看起来是元件清单罗列实际上每一类器件都对应一个不可省略的功能单元硬件模块数量功能定位STC89C52/AT89S52单片机1系统主控完成采样控制、数据处理、逻辑判断LCD1602液晶1显示实时声压级dB值、阈值设置、工作状态ADC083218位逐次逼近ADC将麦克风调理电路输出的模拟电压转成数字量麦克风前置放大电路1声信号转电信号并进行幅度调理标题中未展示但必不可少LED指示灯2双色或双LED状态指示如绿正常、红超标有源蜂鸣器1噪声超标时声音告警独立按键3阈值加、阈值减、模式切换/确认从这张表能看出LED和蜂鸣器构成了告警输出层按键构成了人机交互层1602是信息展示层ADC0832是模拟前端与数字核心的桥梁。整套系统就是一个典型的小型数据采集与告警终端。后续无论换成STM32还是ESP32这套架构思路都是完全通用的变的是驱动代码和采样精度。1.3 性能指标先定下来别等做完才想动手之前务先把核心指标定清楚否则后面每一步都会摇摆。我建议三个硬指标声压级测量范围40dB~120dB SPL这个范围覆盖了安静办公室到高噪车间的大部分场景。分辨率ADC0832是8位分辨率参考电压5V时量化步进约19.6mV。如果按10mV/dB来标定分辨率大约2dB作为教学级噪声监测完全够用。如果追求更高精度可以换10位甚至12位ADC但51平台用8位是最经典、最好调的组合。响应时间从噪声突变到LED/蜂鸣器动作建议不超过500ms。这决定主循环和采样滤波的时间预算。把这三个值写在一张纸上所有设计和调试都拿它们来对照就不会出现显示值跳得飞快完全没法看或者声音变了半天才反应这种常见问题。2. 模拟信号链从驻极体麦克风到ADC0832输入端的完整调理2.1 为什么必须加前置放大不能把麦克风直接接ADC麦克风的输出信号通常是毫伏级交流信号。以灵敏度-40dBV/Pa的驻极体话筒为例在正常说话声约60dB SPL即0.02Pa下输出只有0.2mV左右即便在90dB SPL约0.63Pa的嘈杂环境输出也不过6.3mV。而ADC0832在5V参考电压下1个LSB约19.6mV。如果直接采集连最低位都无法有效驱动读回来的数字要么是0、要么是乱跳。所以前置放大是必需环节不是可选项。同时还要明白麦克风输出是交流信号有正有负而ADC0832的输入范围是0~Vref单极性。因此放大电路不能只是简单放大还需要把信号整体抬升到一个直流偏置点之上通常偏置到Vref/22.5V附近。这就是典型的交流耦合直流偏置同相放大结构。2.2 完整的麦克风调理电路我实际使用的方案是驻极体麦克风通过偏置电阻接入工作点输出经隔直电容耦合到运放的同相输入端运放构成同相放大输出端再经过一个RC低通滤波送ADC0832。关键元器件取值驻极体麦克风偏置电阻R1取4.7kΩ~10kΩ。驻极体头内部有场效应管需要外部提供漏极电流这个电阻同时决定工作点和灵敏度。取小一点可提高灵敏度但噪声也增大10kΩ是入门稳妥值。隔直电容C1取10μF/16V电解电容或1μF薄膜电容。它与输入阻抗构成高通滤波器截止频率要低于20Hz以免衰减低频声音信息。同相输入端对地电阻R2取100kΩ那么C11μF时f_L1/(2π×100k×1μF)≈1.6Hz非常合适。同相放大增益由R3和R4决定G1R4/R3。我常用R31kΩ、R4100kΩ增益约101倍这样90dB SPL时输出约0.63V6.3mV×101加上2.5V偏置后约3.13V距离5V满量程还有余量。120dB SPL时理论值约2V20mV×101加偏置后4.5V已经接近满量程上限这恰好形成自然的动态范围上限防止信号削顶失真太严重。运放选型上LM358是教科书选择单电源5V供电输出摆幅接近轨到轨实际到3.5V左右没问题增益带宽积1MHz对于音频带宽完全够用。如果手头有LMV358或MCP6002这类轨到轨运放信号动态范围还能再扩大一些。2.3 输出端滤波与ADC接口很多人在放大电路和ADC之间不加任何处理导致采样值抖动剧烈。放大后的信号仍包含高频噪声和工频干扰需要简单低通滤波。我通常在运放输出和ADC输入端之间串联1kΩ电阻再接一个0.1μF电容到地构成截止频率约1.6kHz的低通滤波器f1/(2π×1k×0.1μF)注意严格说还要考虑ADC输入阻抗但ADC0832输入漏电流极小这个简化足够。这个滤波网络有两个作用一是滤除带外噪声二是利用ADC0832内部采样电容的充电过程让输入源阻抗不至于过高导致采样值偏低。这是一个容易被忽略的细节ADC0832在采样阶段会给内部电容充电如果源阻抗太高充电不充分结果会系统性偏低。串联1kΩ电阻正好兼顾滤波和驱动能力实测效果稳定。2.4 分贝标定计算标定是整个系统从能量出来到数值得有意义的关键一步。我采用以下标定流程将放大后信号经RMS-to-DC转换或峰值检波得到直流电平。课程设计里更常见的是直接用ADC采集信号调理后的包络电压值。假设ADC读数对应电压U_adc偏置电压U_bias2.5V那么信号幅度U_sigU_adc对应的电压值减去2.5V。该幅度对应声压P U_sig / (G × S_mic)其中S_mic是麦克风灵敏度V/Pa。声压级L 20 × log10(P / 20μPa)。这里要注意如果你在Proteus里仿真没有真实的麦克风而是用信号发生器直接给一个正弦波那么标定逻辑可以简化为直接记录不同输入电压对应的显示dB值形成查表关系。具体做法是给ADC输入端加0.5V、1.0V、1.5V……4.5V直流电压记录显示值然后用分段线性插值做标定。仿真阶段先把这套表做好焊接实物后只需要调整麦克风灵敏度系数就能把真实声压映射到准确dB值上。3. 核心驱动ADC0832的时序逻辑与读写实现3.1 ADC0832引脚与工作原理ADC0832是8位逐次逼近型ADC双通道单端输入或单通道差分输入需要用4根线跟单片机连接CS片选低有效、CLK时钟、DI数据输入配置通道用、DO数据输出读取转换结果用。它没有传统的并行数据总线靠SPI兼容串行时序工作。这也是很多初学者第一次接触串行ADC时容易卡壳的地方。关键是要明白它的配置时序每次转换开始单片机通过DI引脚向ADC发送3个配置位第一位置1表示起始位第二位置1表示单端输入、0表示差分输入第三位选择通道。配置完后在第5个CLK下降沿之后ADC开始在DO引脚上输出转换结果。这里有个很实用的小知识ADC0832先输出最高位MSB first的数据紧接着再输出一遍最低位优先LSB first的数据两次结果应该完全一致。你可以在代码里把两次结果做比对如果不一致说明时序或信号有问题直接丢弃这次采样。这个特性相当于免费的传输校验非常实用。3.2 驱动代码实现驱动代码的核心就是严格按照时序图来翻转CLK。下面是我在51上反复使用的稳定版本用的是P1口的低三位sbit ADC_CS P1^0; sbit ADC_CLK P1^1; sbit ADC_DI P1^2; sbit ADC_DO P1^3; unsigned char ADC0832_Read(unsigned char ch) { unsigned char i, dat_msb 0, dat_lsb 0; ADC_CS 0; ADC_CLK 0; // 起始位 单端模式 通道选择 ADC_DI 1; ADC_CLK 1; ADC_CLK 0; // start bit ADC_DI 1; ADC_CLK 1; ADC_CLK 0; // single-ended ADC_DI ch; ADC_CLK 1; ADC_CLK 0; // ch: 0-CH0, 1-CH1 // 第4个时钟沿让ADC完成通道配置 ADC_CLK 1; ADC_CLK 0; // 读取8位数据MSB first for(i 0; i 8; i) { ADC_CLK 1; ADC_CLK 0; dat_msb (dat_msb 1) | ADC_DO; } // 读取8位数据LSB first for(i 0; i 8; i) { dat_lsb (dat_lsb 1) | (ADC_DO 7); ADC_CLK 1; ADC_CLK 0; } ADC_CS 1; // 两次结果一致才返回否则返回0表示异常 if(dat_msb dat_lsb) return dat_msb; return 0; }这段代码有几个细节值得说明DI和DO是分时复用的配置阶段单片机通过DI发送转换阶段ADC通过DO输出但两者是独立的物理引脚接的时候不要接错。第二个循环里dat_lsb的移位方向是右移因为数据是从最低位开始先到所以按位或到高位再右移正好还原出原始值。如果你把两个循环的移位方向写反了读回来的数据就会像镜像一样错乱。最后做数据校验。实测中偶尔会出现两次读数不一致尤其是时钟线受干扰或接线过长这时候直接丢弃这一帧等下一拍再采样。对噪声监测这种慢变信号来说完全不影响响应速度。3.3 采样周期与时间预算ADC0832完成一次转换需要多少个时钟周期从启动到MSB输出结束大约是17个CLK加上LSB phase总共25个CLK左右。如果CLK频率取250kHz一次转换大约100μs。51单片机用12MHz晶振时机器周期1μs循环里每引脚翻转加延时一个CLK周期大约4~8μs总耗时在200μs以内。有了这个时间预算你可以在主循环里安排每50ms采样一次兼顾响应速度和显示刷新率。50ms对应20Hz的采样频率对噪声监测应用足够。有人会问声音波形本身是20Hz~20kHz20Hz采样不是完全混叠了吗这里的采样对象不是原始音频波形而是经过放大滤波和峰值检波之后的包络信号包络的变化速率远低于音频频率所以20Hz采样没有任何问题。搞清楚这一点你就不会纠结50ms采一次会不会漏掉噪声尖峰了。4. 数据处理与核心逻辑滤波、显示、告警与按键交互4.1 去极值平均滤波为什么不用简单平均ADC0832的8位数据自带量化噪声加上电网和空间电磁干扰直接读出来的值通常会在±3~±5个LSB之间跳动。如果直接用这个值去换算分贝显示数值会闪烁得让人崩溃。解决思路就是数字滤波。最简单的是滑动平均连续采N次取平均但问题是对突发尖峰鲁棒性差。比如采样窗口内出现一次电火花干扰读值冲到250平均后整组数据都被拉高。我推荐去极值平均滤波连续采样10次去掉一个最大值、去掉一个最小值剩下8个取平均。这种滤波在51平台开销很小却对脉冲干扰有极好的抑制效果而且比纯平均的延迟更小。滤波代码可以这样写unsigned int filter_adc(void) { unsigned char i, j, temp; unsigned char buf[10]; unsigned int sum 0; for(i 0; i 10; i) { buf[i] ADC0832_Read(0); } // 简单选择法排序 for(i 0; i 9; i) { for(j i 1; j 10; j) { if(buf[j] buf[i]) { temp buf[i]; buf[i] buf[j]; buf[j] temp; } } } // 去掉首尾各一个极值取中间8个求和 for(i 1; i 9; i) { sum buf[i]; } return sum / 8; }这段代码排序本身也要消耗时间但10个元素的排序在51上也就是几十微秒完全可接受。如果感觉排序开销大可以简化为只找最大最小并剔除效果差不多。4.2 从ADC值到dB的换算策略在代码层面分贝换算有很多种策略我推荐分段线性插值而非统一公式。原因很简单传感器的灵敏度、运放增益、偏置电压都存在误差统一公式算出来的dB值往往偏差大而分段插值可以吸收这些误差。做法是手动标定5~6个点比如输入电压0.5V对应40dB、1.0V对应50dB、2.0V对应60dB……把这些点做成数组存到code区。运行时先在数组中查找ADC值所处的区间然后线性插值。如果系统做进一步升级还可以用Excel拟合一条对数曲线把系数存进单片机但对51来说浮点运算开销不小分段插值的整数运算更划算。换算时要注意ADC值减偏置的问题。因为信号被抬到了2.5V偏置ADC读数约128时对应0dB输入静音实际换算前需要先减去偏置对应的ADC值。但这里的偏置是直流工作点不是零点。更稳妥的做法是标定时直接把ADC读数128对应空载状态考虑进去显示为空闲状态或0dB提示。4.3 LCD1602显示与告警联动逻辑1602显示的内容可以分成三行逻辑实际物理上两行第一行显示SPL: xx.x dB第二行显示ALARM: ON/OFF以及当前阈值。为了让界面更像真实声级计可以在第一行末尾加一个小图标模拟动态变化比如用单个字符位置显示*号随数值大小左右移动。显示刷新频率不用太快每秒刷4次足够人眼看起来流畅又不会因为过于频繁导致画面闪烁。每次刷新前需要先清屏或光标归位否则会叠加出残影。告警逻辑的核心是滞回控制这是最容易忽略的工程细节。如果阈值设在80dB实际噪声在79.5~80.5dB之间波动不加密的话蜂鸣器会反复开启关闭。解决方法是设两个阈值开启阈值80dB关闭阈值75dB。只有超过80才报警回落到75以下才解除。5dB的滞回区间人耳完全感受不到延迟但能彻底消除继电器和蜂鸣器疲劳问题。两个LED的逻辑绿色LED常亮表示系统运行且噪声正常红色LED配合蜂鸣器在超标时点亮。简单设计可以让绿色LED接P2^0红色LED接P2^1蜂鸣器接P2^2。按键分配KEY1阈值加、KEY2阈值减、KEY3在运行模式和阈值设置模式之间切换。长按KEY3超过1秒进入设置模式短按确认退出这种交互逻辑编写起来简单且不易误触。4.4 主程序流程设计主程序不要用复杂的多任务操作系统一个简洁循环就够初始化设置定时器0为50ms定时中断作为采样节拍初始化1602显示启动画面约1秒。主循环检查采样标志位若有50ms节拍到来执行一次ADC滤波采样、dB换算、刷新显示、告警判断。扫描按键处理阈值修改和模式切换。循环往复。判断逻辑放在主循环里定时器中断只负责置标志位。这样ADC读取过程中的时序不会被中断打扰读取结果更稳定。这是51项目里比较推荐的做法。如果把ADC转换放到中断里做中断嵌套和时序抖动会让ADC读数变差而且排错难度指数增加。5. Proteus仿真搭建从零把系统跑起来的关键操作5.1 器件选型和电路绘制Proteus仿真这套电路时器件清单如下单片机选AT89C51或AT89C52它们的行为与STC89C52基本一致仿真上完全兼容。LCD1602直接从库中选LM016L这是Proteus里最常用的1602模型引脚定义与实物常用接法完全一致。ADC0832Proteus的ADC0832模型在Analog ICs分类下也有专门的ADC0832模型可以直接使用。运放用LM358Proteus里有对应的仿真模型。信号源不需要真的麦克风模型用正弦信号发生器SINE模拟麦克风输出频率取1kHz幅度从10mV~200mV可调。注意信号发生器输出是双极性的要经过隔直电容后再送入运放输入端不然会让运放工作点错乱。绘制电路时LCD1602数据口接到P0口要接10kΩ上拉排阻否则P0开漏输出无法驱动高电平。这是Proteus仿真和实物共用的硬规则上拉排阻忘记接的话LCD显示会出现满屏方块或者完全无显示。5.2 用虚拟信号源模拟噪声输入仿真阶段的核心技巧用正弦信号发生器来模拟不同响度的声音。信号发生器幅值对应麦克风输出的mV级别信号频率选1kHz因为人耳对1kHz附近最敏感而且声级计标定通常以1kHz为基准。实际操作步骤信号发生器幅值设置为5mV对应安静环境约40~50dB用虚拟示波器观察ADC输入端电压应该在2.5V偏置上下小幅波动LCD显示值应在低位。把幅值调到20mV对应较嘈杂环境约70~80dB观察LCD显示是否上升告警LED是否在阈值附近动作。继续加大到50mV以上对应高噪声环境蜂鸣器应稳定报警。在仿真中一个容易忽略的问题是ADC0832时钟频率上限。Proteus模型对CLK最大频率有限制如果单片机CLK翻转太快仿真结果会出现读数错乱。解决方法是把ADC_CLK这一路的延时调大一点。我在仿真中用的CLK半周期延时放到了8μs左右比实物保守一些实测稳定工作。5.3 仿真中常遇到的三个坑第一个坑是LCD1602不显示。检查方法量一下LCD第3脚VEE电压如果是0V调节对比度电位器如果VEE正常而不显示检查RS、RW、E三个控制脚是否接对还不行就查P0口上拉排阻。另外一个常见原因是初始化时序不对1602上电后需要等待15ms以上再发送第一条命令Proteus里上电瞬间时间模拟未必精确建议复位后加一个50ms的delay。第二个坑是ADC0832读数恒为0或恒为255。恒为0通常是片选线或时钟线接反或通道选择位配置不对恒为255多是输入电压超过Vref范围。在仿真里可以放一个电压表表笔点到ADC输入端看电压是否在0~5V之间这一步能快速锁定问题出在模拟前端还是数字时序。第三个坑是蜂鸣器在仿真里不发声。Proteus的有源蜂鸣器模型在低电平驱动时输出波形无声你需要确认驱动逻辑是低电平有效还是高电平有效。通常简单处理是PNP三极管驱动基极低电平导通。仿真里直接用一个逻辑探头观察P2^2引脚电平是否翻转如果翻转而蜂鸣器无声就换用无源蜂鸣器模型并加一个1kHz方波驱动或者直接用逻辑状态代替声音输出。6. 实物调试排查把仿真验证过的逻辑搬到真实硬件的必经之路6.1 供电与参考电压的稳定性实物与仿真最大的差异在供电。仿真里电源是理想电压源5V纹丝不动实物如果拿USB供电或开关电源供电纹波可能在50~100mV这直接影响ADC的精确度。ADC0832的Vref如果直接用VCC电源纹波会直接折进转换结果表现为采样值周期性波动。我的做法是给ADC的Vref独立供电用TL431或AMS1117-3.3把基准电压单独稳到2.5V或3.3V再配合0.1μF和10μF两级去耦电容。这样至少能消除大部分电源纹波的影响。如果你不想增加元件最低限度也要在VCC和GND之间加一个100μF电解电容并联一个0.1μF陶瓷电容让电源纹波控制在可接受范围。6.2 麦克风灵敏度与增益的调试流程实物焊接后先用信号发生器而不是真实声音调试模拟前端。断开麦克风把信号发生器的正弦波通过隔直电容接到运放输入端从10mV开始用示波器逐级测量运放输出确认增益和偏置正确。这一步的目的是把模拟前端的变量和数字部分隔离先确保模拟链路干净可靠。确认模拟链路没问题后接上麦克风播放稳定的噪声源比如手机播放一个1kHz、70dB的标准音频很多手机APP可以生成观察ADC读数和LCD显示值。如果显示值比预期低可能是麦克风灵敏度太低需要把偏置电阻调小或增大放大倍数如果显示值接近满量程甚至饱和则减小增益。注意一个容易误导的现象直接用嘴对着麦克风吹气或大声喊话时显示值剧烈跳动这并不代表系统线性度差因为人声的瞬时动态范围本身很大而且近距离呼吸会产生强烈的风噪声。调试时应该用稳定音源或白噪声而不是靠人喊。6.3 阈值设置与滞回效果验证设置阈值后要测试滞回效果。具体方法是播放一个可以缓慢增加音量的噪声源接近阈值时观察是否出现蜂鸣器咔哒咔哒反复通断。如果反复通断说明滞回区间没生效检查代码里关闭阈值是否设得比开启阈值低。我实际调试中踩过这样一个坑开启阈值和关闭阈值都写在flash里但主循环里读出来的阈值总是同一个值查了半天发现设置关闭阈值时按键扫描逻辑里忘了更新显示导致看起来设置成功了实际参数根本没改进去。后来我把当前阈值和保存阈值分开设置模式下先改当前值退出设置时才写入存储并把当前值实时显示在1602第二行问题立刻解决。6.4 参考地线与信号完整性做噪声监测系统信号完整性比想象中重要。麦克风前置放大电路的地线和数字部分的地线最好采用单点接地或星型接地避免数字电流通过地线环路耦合到模拟输入端。如果在调试中发现显示值存在周期性跳变且跳变频率是50Hz或100Hz大概率是工频干扰。处理方法一是检查地线布局二是在运放输出端加大滤波电容0.1μF改成0.47μF三是给整个系统使用屏蔽线连接麦克风。这些措施按顺序执行每次只改一处并观察效果不要一次全上否则定位不了问题根源。7. 经验体会与扩展思路这套系统做完之后我个人最大的体会是51平台虽然老但它把整个信号采集链条拉得很直白。你在STM32上可以用DMA加ADC加定时器交叉触发但很多初学者根本不清楚ADC采样保持、转换时间、数据寄存器读取这些底层动作而用51加ADC0832所有时序都得自己一条一条地写每一步都逼着你弄懂芯片到底在干什么。这种笨拙恰恰是打基础最好的方式。如果后续想往产品级或更高阶的方向扩展我会从三个方向入手第一把ADC换成12位的MCP3208或ADS1118分辨率从8位提升到12位配合STM32的硬件SPI采样精度能上一个台阶第二在软件里加入真正的时间加权也就是Fast/Slow档位切换对应声级计标准中的125ms和1s时间计权这需要把采样数据存成环形队列再做指数平滑第三把1602换成OLED屏增加电池供电和低功耗模式同时把阈值设置改为EEPROM掉电保存这样就能做成一款便携式的环境噪声记录仪。如果你打算把这个项目作为毕设或课程设计的出发点建议不要只停留在跑通层面。可以额外加一个PC端上位机通过串口把声压级数据实时上传画出一条时间-分贝曲线这个增量从技术难度上看不大但能让整个系统从能显示变成能分析展示效果会好很多。关键是上位机的串口协议与单片机的数据结构完全由你定义这也是面试或答辩时最有说服力的亮点。本文还有配套的精品资源点击获取
返回列表