基于CircuitPython与ItsyBitsy M4打造可编程宏键盘:从硬件到代码全解析
1. 项目概述打造你的专属输入利器在键盘这个看似成熟的领域里我们真的满足于厂商提供的“标准答案”吗对于视频剪辑师、程序员、设计师或者硬核游戏玩家来说一套固定的键位布局和功能往往意味着效率的妥协。真正的生产力工具应该能贴合你的肌肉记忆和工作流而不是让你去适应它。这就是为什么基于微控制器的自定义键盘项目在创客和极客社区中经久不衰。今天我们要深入探讨的正是这样一个将控制权完全交还给使用者的项目利用Adafruit ItsyBitsy M4 Express微控制器和Pimoroni Keybow机械键盘套件构建一个完全由你定义功能的USB机械键盘。这个项目的核心魅力在于它不仅仅是一个“键盘”而是一个可编程的输入平台。你可以让12个机械轴中的每一个都不仅仅是触发一个字符——它可以是一串复杂的宏命令比如一键编译部署、一个系统媒体控制播放/暂停、音量调节甚至是启动特定软件的组合键。这一切都通过CircuitPython这种对开发者极其友好的微控制器编程语言来实现让你用写Python脚本的轻松感来驾驭硬件的强大功能。我选择ItsyBitsy M4作为核心看中的是其ATSAMD51 Cortex-M4内核带来的充沛性能120MHz主频192KB RAM足以流畅处理键盘扫描、RGB灯效和USB HID通信。而Keybow套件则提供了即插即用的高品质Kailh机械轴、PBT键帽和带有集成式DotStar RGB LED的PCB省去了从零开始焊接轴体和设计电路的麻烦。整个项目的目标用户非常明确任何希望提升数字工作效率、热爱DIY、或对嵌入式Python开发感兴趣的爱好者。无论你是想为OBS直播打造一个场景切换台还是为Blender设计一套专属的建模快捷键这个项目都能为你提供一个坚实、可高度定制的起点。接下来我将从硬件适配、软件编程到深度定制一步步拆解如何将这个想法变为现实。2. 核心硬件解析与选型思路2.1 微控制器为什么是ItsyBitsy M4在众多微控制器中选定ItsyBitsy M4是经过一番考量的。首先USB HID功能是刚需。我们需要一块能够被计算机识别为标准键盘或鼠标设备的芯片。ItsyBitsy M4内置的USB控制器可以完美实现这一点无需额外的USB转串口芯片减少了复杂度和潜在的不稳定性。其次性能与I/O口的平衡。键盘扫描是一个周期性任务需要实时检测12个按键的状态防抖处理同时还要驱动12颗DotStar RGB LED每个LED需要24位数据。如果主频太低在运行复杂的灯光动画时按键响应就可能出现延迟。M4的120MHz主频和充足的RAM确保了即使代码中加入一些动态光效主循环依然能保持高速运行提供跟手的输入体验。其丰富的数字和模拟I/O口23个GPIO也为我们连接所有按键和LED预留了充足的空间。最后CircuitPython的官方支持。Adafruit作为CircuitPython的主要维护者为其自家硬件提供了最稳定、最及时的支持。这意味着相关的HID库、DotStar驱动库都经过了充分测试我们不必在底层驱动上耗费精力可以专注于业务逻辑——也就是定义每个键的行为。注意虽然原项目也支持ItsyBitsy M0但我强烈推荐使用M4版本。M0ATSAMD21只有48MHz主频和32KB RAM在运行包含灯光效果的复杂代码时可能会比较吃力尤其是当你想要实现一些流畅的渐变或响应式光效时。多花一点预算选择M4能为后续的创意扩展留出更多余地。2.2 键盘套件Pimoroni Keybow的利与弊Pimoroni Keybow本质上是一个为树莓派Zero设计的“帽子”HAT。它集成了12个机械轴插座、12个贴片LED驱动电路以及一个2x20pin的树莓派GPIO排母。选择它作为基础有三大优势集成度高无需单独为每个按键焊接二极管和电阻LED驱动电路也已内置大大降低了硬件搭建难度和失败率。品质可靠配套的Kailh机械轴手感和寿命都有保障PBT键帽不易打油DotStar LEDAPA102的亮度和色彩一致性远优于常见的WS2812B NeoPixel。结构完整套件包含亚克力外壳和螺丝支柱让成品看起来更专业而非一堆飞线的实验品。然而它的设计初衷是连接树莓派其引脚定义与ItsyBitsy M4并不兼容。这就是本项目需要解决的核心硬件难题制作一个转接板Adapter Board将Keybow的引脚信号“翻译”成ItsyBitsy能理解的信号。原教程给出了两种方案使用Adafruit Perma-Proto Bonnet进行手工飞线焊接或者使用定制PCB。这两种方案的选择直接决定了你的制作体验和最终成品的可靠性。2.3 转接方案深度对比手工飞线 vs. 定制PCB这是项目初期最重要的决策点两种方案各有明确的适用场景。方案一Perma-Proto Bonnet手工飞线这是一种通用原型板上面有与树莓派Zero一致的穿孔焊盘。你需要在其上焊接排针并用电线手工连接Keybow的每个信号点到ItsyBitsy对应的引脚。优点材料易得一块原型板、排针、导线成本最低适合即时验证想法或一次性项目。焊接过程本身也是很好的硬件练习。缺点可靠性是最大挑战。18根飞线12个按键2个LED信号电源和地会产生一个“线团”任何一根线虚焊或短路都可能导致整个键盘失灵。排查故障异常困难。此外成品体积臃肿不易装入Keybow原装外壳。实操心得如果选择此方案务必使用30AWG的硅胶线或绕接线它们更柔软、耐弯折。焊接时先在所有连接点上“搪锡”预上焊锡再用烙铁头同时加热焊盘和导线完成连接这样比直接焊接更牢固。每完成3-4根线的连接就用万用表的蜂鸣档检查一次通断和有无短路不要等到全部焊完再检查。方案二定制PCB印刷电路板这是原项目作者John Park设计好的专用转接板你只需要从PCB打样厂如嘉立创、JLCPCB下单生产然后像拼乐高一样将排针和ItsyBitsy焊上去即可。优点专业、可靠、美观。所有连接通过PCB内部的铜层完成不存在虚焊或短路风险。结构紧凑能完美装入原装外壳。焊接工作量极小仅需焊接3排排针成功率高。缺点需要等待PCB生产和邮寄通常3-7天有额外的打板费用约20-50元人民币。对于只想体验过程的初学者前期准备时间稍长。我的强烈建议除非你极度享受手工焊接的乐趣或预算极其紧张否则请直接选择定制PCB方案。它节省的调试时间和带来的可靠性提升远超其成本。本次指南后续的硬件组装部分我将以PCB方案为主进行详解因为它代表了更优的实践路径。3. 硬件组装全流程与核心细节3.1 物料清单与工具准备在开始动手前请清点以下所有物料和工具缺一不可。核心物料清单Adafruit ItsyBitsy M4 Express 微控制器 x1Pimoroni Keybow Mini 机械键盘套件 x1 (包含外壳、螺丝、轴体、键帽)ItsyBitsy Keybow 定制PCB文件 (从项目页面下载Gerber文件) x12x20Pin 双排直针排母 (用于连接Keybow) x11x14Pin 单排直针排母 x2 (用于焊接ItsyBitsy)M2.5*6mm 尼龙螺丝及支柱套件 (用于固定PCB和外壳)必要工具清单电烙铁与焊锡建议使用可调温烙铁设置到320°C-350°C搭配含松香芯的细径焊锡0.8mm。焊锡膏/助焊剂对于排针这类多引脚元件少量助焊剂能让焊接更流畅、焊点更光亮。吸锡线或吸锡器用于修正焊错或焊锡过多的引脚。精密镊子夹持小元件和调整位置。剪线钳/水口钳用于修剪排针过长的部分。万用表用于焊接后的电路通断测试这是保证成功的关键。放大镜或台灯良好的照明是精细焊接的保障。3.2 PCB焊接步骤详解拿到打样好的PCB后你会看到板子上有三组主要的焊盘一组2x20的大焊盘对应树莓派Zero、两组1x14的长条焊盘对应ItsyBitsy两侧引脚以及一些用于指示的丝印。步骤1焊接树莓派排针将2x20Pin的排母插入PCB背面即有丝印标注“Pi Header”的一面确保排针的短针一端穿过PCB。然后将Keybow主板像插在树莓派上一样插到这个排母上。这个操作非常巧妙Keybow本身成为了一个完美的“焊接夹具”它能确保所有40根排针都与PCB保持绝对垂直没有歪斜。此时翻转PCB在正面将每个排针的焊盘焊牢。焊完后Keybow可以轻松取下。步骤2焊接ItsyBitsy排针与关键技巧接下来焊接两组14Pin的单排排母。这里有一个追求极致薄厚的技巧原装排针的黑色塑料底座有一定厚度可能导致组装后ItsyBitsy部分凸起影响外壳闭合。我们可以将其移除。用指甲或小刀轻轻从侧面撬起黑色塑料底座将其与金属针脚分离。你会得到两排“光秃秃”的金属针。将这些金属针依次插入PCB上对应的1x14孔位。由于没有塑料固定它们很容易歪倒。我的方法是在PCB正面元件面贴上一点蓝丁胶或美纹纸胶带将针脚暂时固定住。翻转PCB从背面焊接。焊接时用镊子或烙铁头轻轻将针脚推向孔洞使其顶端与PCB背面平齐然后再加锡焊牢。这样焊接后ItsyBitsy就能以最低的高度安装在PCB上。焊接完成后用剪线钳仔细修剪背面过长的针脚并用锉刀或砂纸轻轻打磨掉毛刺防止短路。步骤3安装与焊接ItsyBitsy M4现在将ItsyBitsy M4像插插座一样插到刚刚焊好的两排光秃针脚上。务必注意方向ItsyBitsy的USB接口应朝向PCB上标有“USB”字样的一端。插到底后从PCB背面将ItsyBitsy的每个引脚与针脚焊牢。由于空间狭小建议使用尖头烙铁并确保没有焊锡桥接到相邻引脚上。焊接完成后再次检查所有引脚并用万用表蜂鸣档抽查几个关键引脚如VUSB、GND、SCK、MOSI与ItsyBitsy上对应测试点的通断。3.3 电路检查与功能测试在装入外壳前必须进行彻底的上电前检查这是避免烧毁元件的最后防线。视觉检查在强光下从各个角度观察PCB背面检查是否有焊锡桥接两个不该连接的焊盘被焊锡连在一起特别是ItsyBitsy引脚间距很小很容易短路。万用表通断测试电源短路测试将万用表调到蜂鸣档表笔分别接触PCB上任意一个5V或VHI测试点和GND测试点。此时万用表应该绝对静默不发出蜂鸣声。如果蜂鸣说明电源与地直接短路必须排查干净后才能通电。信号线通断测试参照原理图或引脚映射表用万用表逐一测试每个按键信号点从Keybow排针到ItsyBitsy对应GPIO是否导通。例如测试Keybow上对应第一个按键的引脚与ItsyBitsy的A2引脚是否连通。上电测试通过USB线将组装好的PCB连接到电脑。此时ItsyBitsy应该被识别为一个USB设备如果已刷入CircuitPython会显示CIRCUITPY盘符。观察ItsyBitsy其板载的RGB LED应正常点亮CircuitPython下为绿色呼吸灯。如果LED不亮或异常闪烁立即断电。观察Keybow12颗DotStar LED可能会亮起或闪烁这取决于其内部上电状态属于正常现象。如果某个LED异常发热或不亮则可能对应信号线接反或短路。完成以上检查后你可以暂时不装轴体和键帽直接将Keybow PCB插到转接板上进行后续的软件测试。这样即使有问题也方便拆卸排查。4. CircuitPython环境配置与核心库解析4.1 固件烧录与开发环境搭建ItsyBitsy M4到手后第一步是将其从默认的UF2引导模式刷入CircuitPython固件将其变成一个可编程的Python设备。下载固件访问 circuitpython.org/downloads 在搜索框输入“ItsyBitsy M4 Express”找到最新稳定版的.uf2文件并下载。进入引导模式用数据线连接ItsyBitsy和电脑。快速双击板子上的复位Reset按钮。此时板载RGB LED将变为绿色电脑上会出现一个名为ITSYBOOT的U盘。刷入固件将下载好的.uf2文件直接拖入ITSYBOOT盘符。完成后ITSYBOOT盘会消失取而代之的是一个名为CIRCUITPY的新盘符。这表明CircuitPython已成功运行。开发工具选择虽然Mu编辑器对初学者友好但我更推荐使用VS Code搭配CircuitPython插件。它提供了代码自动补全、语法高亮、串口监视器等强大功能效率更高。你只需在VS Code中安装“CircuitPython”扩展它就能自动识别CIRCUITPY盘并允许你直接在编辑器中保存代码到板子同时打开串行终端查看调试信息。4.2 理解并安装必要的库文件CircuitPython的强大之处在于其丰富的库生态系统。我们的键盘项目依赖于几个核心库它们并非内置需要手动放入CIRCUITPY盘下的lib文件夹。下载库合集访问 circuitpython.org/libraries 下载与你的CircuitPython版本号匹配的“Adafruit CircuitPython Library Bundle”。例如固件是7.x就下载7.x的合集。识别所需库打开下载的zip文件找到lib文件夹。我们的项目需要从中复制以下库文件或文件夹到ItsyBitsy的lib目录中adafruit_bus_device/(文件夹)adafruit_dotstar.mpyadafruit_hid/(文件夹) -这是实现键盘功能的核心adafruit_led_animation.mpy(可选用于高级灯光效果)neopixel.mpy(DotStar与NeoPixel驱动类似有时需要)simpleio.mpy关键技巧如何避免“ImportError”如果你在串口监视器中看到类似ModuleNotFoundError: No module named adafruit_hid的错误99%的原因是库文件没有正确放置。请确保1. 库文件放在了CIRCUITPY根目录下的lib文件夹内如果没有就新建一个。2. 对于像adafruit_hid这样的库它是一个包含多个.mpy文件的文件夹你必须复制整个文件夹而不是只复制其中一个文件。4.3 核心代码结构与原理解读将项目提供的code.py代码保存到CIRCUITPY盘根目录后ItsyBitsy会自动重启并运行。我们来深入理解这段代码是如何工作的。import usb_hid from adafruit_hid.keyboard import Keyboard from adafruit_hid.keycode import Keycode from adafruit_hid.consumer_control import ConsumerControl from adafruit_hid.consumer_control_code import ConsumerControlCode这几行导入语句是键盘功能的基石。usb_hid模块使设备具备HID能力。Keyboard和Keycode类负责发送标准键盘按键如A-Z, Ctrl, Alt。ConsumerControl和ConsumerControlCode则用于发送媒体控制命令如音量调节、播放暂停这是通过操作系统另一套HID协议实现的。dots dotstar.DotStar(board.SCK, board.MOSI, 12, brightness0.4)这行代码初始化了DotStar LED灯带。board.SCK和board.MOSI是ItsyBitsy上硬件SPI的时钟和数据引脚这正是我们通过转接板连接到Keybow LED接口的引脚。12代表LED数量brightness0.4设置了初始亮度范围0.0-1.0避免电流过大。按键扫描逻辑 代码为12个按键分别创建了DigitalInOut对象并设置为上拉输入pullPull.UP。这意味着当按键未按下时单片机读取到的是高电平True当按键按下触点接通GND引脚被拉低读取到低电平False。 主循环while True不断遍历这12个引脚的状态。通过一个switch_state列表来记录每个按键上一次的状态从而实现“按下”和“释放”事件的精确检测并发送相应的HID命令。键位映射字典keymap 这是整个项目的“大脑”定义了每个按键索引0-11的三元属性(LED颜色, 命令类型, 键值)。keymap { (0): (AMBER, MEDIA, ConsumerControlCode.PLAY_PAUSE), (4): (BLUE, KEY, (Keycode.GUI, Keycode.C)), # CtrlC (Windows) / CmdC (Mac) }命令类型MEDIA类型使用cc.send()发送媒体控制码KEY类型使用kbd.press()和kbd.release()模拟键盘按键。键值可以是单个Keycode也可以是一个元组来实现组合键如(Keycode.CONTROL, Keycode.C)代表CtrlC。5. 深度自定义从键位到光效5.1 物理布局与软件映射的协调Keybow的12个按键物理上是3x4的矩阵。但在代码中它们的索引顺序0-11如何对应物理位置取决于orientation方向变量和key_dots列表。orientation 0(纵向/竖向)按键索引从上到下、从左到右排列。即左上角为0其下方为1再下方为2第一列最下方为3第二列顶部为4以此类推。orientation 1(横向/横向)按键索引从右下角开始从右到左、从下到上排列。这是为了适配Keybow外壳的默认横向摆放方式。key_dots列表则定义了每个按键索引所控制的DotStar LED的序号。这是因为Keybow PCB上的LED序号排列可能与按键的物理顺序不一致。这个映射确保了当你按下左上角的键时亮起的是左上角的LED而不是别的灯。自定义第一步你需要根据自己组装外壳的方式横放还是竖放以及你期望的按键功能布局来调整orientation和keymap字典中索引与功能的对应关系。我建议先用一段测试代码让每个按键按下时在串口打印出自己的索引号从而确认物理按键与软件索引的对应关系。5.2 创建你的专属键位层原代码的键位映射只是一个示例。真正的威力在于你可以将其改造成任何你想要的工具。场景一视频剪辑快捷键板针对Adobe Premierekeymap { (0): (GREEN, KEY, [Keycode.C]), # 剃刀工具 (1): (GREEN, KEY, [Keycode.V]), # 选择工具 (2): (BLUE, KEY, [Keycode.LEFT_ARROW]), # 左移一帧 (3): (BLUE, KEY, [Keycode.RIGHT_ARROW]),# 右移一帧 (4): (RED, KEY, (Keycode.CONTROL, Keycode.K)), # 剪切点 (CtrlK) (5): (RED, KEY, (Keycode.SHIFT, Keycode.D)), # 添加默认转场 (ShiftD) (6): (YELLOW, KEY, [Keycode.SPACE]), # 播放/暂停 (7): (YELLOW, KEY, (Keycode.ALT, Keycode.SHIFT, Keycode.D)), # 音频关键帧 (AltShiftD) # ... 更多按键 }场景二程序员宏键盘keymap { (0): (CYAN, KEY, (Keycode.CONTROL, Keycode.SHIFT, Keycode.P)), # VS Code: 命令面板 (1): (CYAN, KEY, (Keycode.F5)), # 启动调试 (2): (MAGENTA, KEY, [Keycode.F9]), # 切换断点 (3): (MAGENTA, KEY, (Keycode.CONTROL, Keycode.SLASH)), # 注释/取消注释 (4): (BLUE, KEY, (Keycode.CONTROL, Keycode.D)), # 选择相同词 (5): (BLUE, KEY, [Keycode.F12]), # 转到定义 (6): (GREEN, KEY, (Keycode.CONTROL, Keycode.S)), # 保存 (7): (GREEN, KEY, (Keycode.CONTROL, Keycode.F)), # 查找 # 甚至可以定义常用代码片段宏需要更复杂的字符串输入功能 }对于发送字符串如print(“Hello”)需要使用adafruit_hid中的KeyboardLayoutUS库并调用keyboard.write(“Hello”)方法。5.3 高级灯光效果与状态反馈静态颜色只是基础。利用adafruit_led_animation库你可以让键盘“活”起来。1. 按键呼吸灯效果 修改代码在按键按下时不是简单地切换颜色而是启动一个淡入淡出的呼吸灯动画。import adafruit_led_animation.animation.pulse as pulse_anim # 为每个LED创建一个脉冲动画对象 pulse_anims [] for i in range(12): pulse_anims.append(pulse_anim.Pulse(dots, speed0.1, colorkeymap[i][0], period2))然后在按键处理逻辑中按下时调用pulse_anims[button].animate()释放时停止动画并恢复默认颜色。2. 层切换指示灯 如果你实现了多层功能通过一个“层切换”键可以用不同颜色的静态光或动态光效来指示当前处于哪一层。例如游戏层用红色波浪效果办公层用蓝色呼吸效果。3. 系统状态联动进阶 通过CircuitPython的usb_cdc串行通信功能可以让ItsyBitsy与电脑上的一个后台Python脚本通信。这样键盘灯光就可以反映电脑状态比如CPU温度高时亮红色收到新邮件时闪烁绿色静音时显示橙色等。这需要一定的PC端编程知识但潜力无限。6. 故障排查与性能优化实录6.1 常见问题与解决方案在制作和使用过程中你几乎一定会遇到以下一些问题。这里是我的排查清单问题现象可能原因排查步骤与解决方案电脑无法识别USB设备或识别为未知设备。1. USB线仅支持充电。2. CircuitPython固件损坏或型号不对。3. ItsyBitsy硬件故障。1.换一根确认能传输数据的USB线这是最常见的原因。2. 重新进入引导模式双击Reset刷写正确的固件。3. 尝试将ItsyBitsy单独连接电脑看能否识别。按键无反应但LED灯正常。1. 按键引脚焊接或映射错误。2. 代码中pins列表定义与硬件连接不符。3. 按键消抖逻辑过于敏感或迟钝。1. 使用万用表蜂鸣档检查从Keybow按键焊点到ItsyBitsy对应GPIO是否导通。2. 在代码开头添加print(“Pin状态:”, [switches[i].value for i in range(12)])在串口监视器查看按键按下时对应引脚值是否从True变为False。3. 调整主循环末尾的time.sleep(0.01)消抖延时尝试0.005到0.02之间的值。单个或部分LED不亮或颜色错乱。1. DotStar数据线MOSI或时钟线SCK连接错误。2. LED序列号映射错误key_dots列表。3. 电源功率不足。1. 检查PCB上SCK和MOSI线是否连接正确牢固。2. 运行一个简单的测试程序让所有LED依次亮起红色确认每个LED的物理序号。3. DotStar全白时功耗最大。尝试降低全局亮度brightness0.2或使用电脑后置USB口供电更强。按下按键后电脑响应缓慢或一次触发多个命令。1. 代码主循环阻塞。2. 按键机械抖动导致多次触发。3. USB通信缓冲区溢出。1. 避免在while True主循环中执行耗时操作如复杂计算、网络请求。2. 确保消抖逻辑switch_state工作正常。可改为检测“下降沿”从高到低才视为一次有效按下。3. 检查代码是否在短时间内发送了过多HID命令。确保每次kbd.press()都有对应的kbd.release()。代码保存后键盘功能失效ItsyBitsy盘符消失。代码存在语法错误导致CircuitPython崩溃。1. 重新拔插USB让板子重启。2. 如果CIRCUITPY盘符不出现再次进入引导模式刷固件。3. 使用串口监视器如VS Code的CircuitPython插件或PuTTY查看具体的错误信息它会在启动时打印出来。6.2 代码性能与稳定性优化当你的代码越来越复杂特别是加入了动画效果后可能会遇到性能瓶颈。以下是一些优化技巧减少全局查找在while True循环中频繁调用keymap[button][0]这样的字典和列表索引是有开销的。可以在循环开始前将常用值赋给局部变量。使用ticks_ms()替代time.sleep()进行非阻塞延迟如果你需要实现一个闪烁效果不要用time.sleep(0.5)这会阻塞整个主循环。可以使用time.monotonic()或ticks_ms()来记录时间戳在循环中判断时间间隔是否到达从而实现非阻塞的定时任务。优化灯光更新adafruit_dotstar库的show()方法在每次更改LED颜色后调用会将数据发送给LED。如果你在一次循环中修改了多个LED的颜色应该在所有修改完成后只调用一次show()而不是每改一个颜色就调用一次。管理内存CircuitPython有垃圾回收机制但在长时间运行中如果不断创建新的对象如在循环内定义列表可能导致内存碎片。尽量复用已有的对象。6.3 关于外壳与人体工学的最后思考Keybow原装的亚克力外壳美观但较薄。长时间使用你可能希望有更好的输入角度。我的解决方案是3D打印一个带倾角的外壳在Thingiverse等网站上有许多为Keybow设计的可打印外壳模型找一个带6-9度倾角的版本能显著提升手感。添加防滑垫在底板贴上高质量的橡胶脚垫防止键盘在桌面上滑动。键帽个性化Keybow原装键帽是平胸无刻的。你可以购买一套XDA或DSA高度的球帽并自己用贴纸或雕刻定义键位打造完全个性化的视觉外观。这个项目的终点不是一个固定的产品而是一个随着你需求不断进化的工具。从最基础的媒体控制到复杂的自动化宏再到与电脑状态联动的智能灯光它的可能性只受限于你的想象力。CircuitPython的低门槛让你可以快速迭代而ItsyBitsy M4的强劲性能保证了这一切都能流畅运行。最重要的是你获得了一个完全贴合自己思维模式和操作习惯的输入设备这种效率提升和掌控感是任何市售键盘都无法给予的。

相关新闻

最新新闻

日新闻

周新闻

月新闻