目录

整体系统设计

一、串口接收模块

二、串口发送模块

三、按键消抖模块

四、ROM模块


本设计工程文件下载链接(包含注释):https://download.csdn.net/download/qq_33231534/12450178


整体系统设计

本设计主要是对ADC和DAC的使用,主要实现功能流程为:首先通过串口向FPGA发送控制信号,控制DAC芯片tlv5618进行DA装换,转换的数据存在ROM中,转换开始时读取ROM中数据进行读取转换。其次用按键控制adc128s052进行模数转换100次,模数转换数据存储到FIFO中,再从FIFO中读取数据通过串口输出显示在pc上。其整体系统框图如下:

图1:FPGA数据采集系统整体框图

从图中可以看出,该系统主要包括9个模块:串口接收模块、按键消抖模块、按键控制模块、ROM模块、DAC驱动模块、ADC驱动模块、同步FIFO模块、FIFO控制模块、串口发送模块。各个模块的作用如下:

(1)串口接收模块(UART_Byte_Rx.v):完成串口数据接收,将串行数据转换成并行数据输出。

(2)按键消抖模块(key_filter.v):进行按键消抖,可输出一个脉冲按键按下标志和按键按下时间标志。

(3)按键控制模块(key_ctrl.v):当在DA一直输出模拟信号时,按下按键控制ADC转换100次。

(4)ROM模块(single_port_rom.v):存储DA转换的数据,可存放正弦波形数据。

(5)DAC驱动模块(dac_driver.v):数模转换驱动模块,与外部DAC芯片相连,提供DAC芯片时钟和数据信号等。

(6)ADC驱动模块(adc_driver.v):模数转换驱动模块,与外部ADC芯片相连,提供ADC芯片时钟和控制信号等。

(7)同步FIFO模块(sync_fifo.v):存放ADC转换后的数据。

(8)FIFO控制模块(fifo_ctrl.v):当FIFO中有数据时,将FIFO中的数据转换成可以UART串口发送的数据。

(9)串口发送模块(Uart_Byte_Tx.v):经过FIFO控制模块转换的数据通过串口发送模块发送到串口,显示在pc端。

(10)DAC控制模块(dac_ctrl.v):当接收串口指定的指令时,开始将ROM的正弦数据进行DAC转换。


一、串口接收模块

前面已经写过串口接收模块,这里可以直接拿来用。这里串口发送数据格式包含:1位起始位、8位数据位、1位停止位,无校验位。该模块接口列表入下:

表1.1:串口接收模块接口列表
信号名称 I/O 位数 功能描述
clk I 1 系统时钟50MHz
rst_n I 1 系统复位
rs232_tx I 1 串口串行数据发送数据口
baud_set I 3 波特率选择信号
data_byte O 8 并行数据输出
rx_done O 1 接收1字节数据完成标志

代码如下:UART_Byte_Rx.v

//-------------------------------------------------------------------
//https://blog.csdn.net/qq_33231534 PHF的CSDN
//File name:           UART_Byte_Rx.v
//Last modified Date:  2020/5/22
//Last Version:
//Descriptions:        工业级别串口数据接收模块,防干扰。对每位数据内部采样16个点,
//                     对中间6位数据进行判定数据是1还是0
//-------------------------------------------------------------------module UART_Byte_Rx(input                   clk         ,//系统时钟50MHzinput                   rst_n       ,//系统复位input                   rs232_tx    ,//串口串行数据发送数据口input       [  2: 0]    baud_set    ,//波特率选择信号output  reg [  7: 0]    data_byte   ,//并行数据输出output  reg             rx_done      //接收1字节数据完成标志,rx_done可以作为输出有效信号使用
);reg   [ 13: 0]         baud_c   ;//波特率对应计数次数(4800bps-10416),(9600bps-5208),(19200bps-2604),//(38400bps-1302),(57600bps-868),(115200bps-434)reg                    rs232_tx_ff0     ;
reg                    rs232_tx_ff1     ;
reg                    rs232_tx_ff2     ;
wire                   tx_neg_flag      ;
reg                    add_flag         ;reg   [ 13: 0]         cnt0             ;
reg   [  3: 0]         cnt1             ;
reg   [  9: 0]         cnt2             ;
reg   [  3: 0]         cnt3             ;
reg   [  2: 0]         cnt_0            ;
reg   [  2: 0]         cnt_1            ;wire                   add_cnt0         ;
wire                   end_cnt0         ;
wire                   add_cnt1         ;
wire                   end_cnt1         ;
wire                   add_cnt2         ;
wire                   end_cnt2         ;
wire                   add_cnt3         ;
wire                   end_cnt3         ;//查找表
always  @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginbaud_c <= 5208;endelse begincase(baud_set)0:      baud_c = 14'd10416;1:      baud_c = 14'd5208 ;2:      baud_c = 14'd2604 ;3:      baud_c = 14'd1302 ;4:      baud_c = 14'd868  ;5:      baud_c = 14'd434  ;default:baud_c = 14'd5208 ;//默认9600bpsendcaseend
end//打两拍 防止亚稳态,同时scan negedge
always  @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginrs232_tx_ff0 <= 1;rs232_tx_ff1 <= 1;rs232_tx_ff2 <= 1;endelse beginrs232_tx_ff0 <= rs232_tx;rs232_tx_ff1 <= rs232_tx_ff0;rs232_tx_ff2 <= rs232_tx_ff1;end
end
//扫描下降沿
assign tx_neg_flag = rs232_tx_ff2 && !rs232_tx_ff1;//计数标志信号
always  @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginadd_flag <= 0;endelse if(tx_neg_flag) beginadd_flag <= 1;endelse if(rx_done)beginadd_flag <= 0;end
end//计数器,计数1bit数据长度
always @(posedge clk or negedge rst_n)beginif(!rst_n)begincnt0 <= 0;endelse if(add_cnt0)beginif(end_cnt0)cnt0 <= 0;elsecnt0 <= cnt0 + 1'b1;end
endassign add_cnt0 = add_flag;
assign end_cnt0 = add_cnt0 && cnt0==baud_c-1;//计数器,计数8位接收数据长度
always @(posedge clk or negedge rst_n)begin if(!rst_n)begincnt1 <= 0;endelse if(add_cnt1)beginif(end_cnt1)cnt1 <= 0;elsecnt1 <= cnt1 + 1'b1;end
endassign add_cnt1 = end_cnt0;
assign end_cnt1 = add_cnt1 && cnt1== 8;//比特内部采样点时钟计数
always @(posedge clk or negedge rst_n)beginif(!rst_n)begincnt2 <= 0;endelse if(add_cnt2)beginif(end_cnt2)cnt2 <= 0;elsecnt2 <= cnt2 + 1'b1;end
endassign add_cnt2 = add_flag;
assign end_cnt2 = add_cnt2 && (cnt2== (baud_c/16)-1 || end_cnt0);   //一个bit数据中16个采样点计数
always @(posedge clk or negedge rst_n)beginif(!rst_n)begincnt3 <= 0;endelse if(add_cnt3)beginif(end_cnt3)cnt3 <= 0;elsecnt3 <= cnt3 + 1'b1;end
endassign add_cnt3 = add_cnt2 && cnt2== (baud_c/16)-1;
assign end_cnt3 = end_cnt0 || (end_cnt2 && cnt3==16-1);   //比特内选取6个采样点是0或1计数
always  @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)begincnt_0 <= 0;cnt_1 <= 0;endelse if(add_flag) beginif(cnt3>=6 && cnt3<=11)beginif(cnt2==baud_c/16/2 && rs232_tx_ff1==0)cnt_0 <= cnt_0 + 1'b1;else if(cnt2==baud_c/16/2 && rs232_tx_ff1==1)cnt_1 <= cnt_1 + 1'b1;endelse if(end_cnt0)begincnt_0 <= 0;cnt_1 <= 0;endendelse begincnt_0 <= 0;cnt_1 <= 0;end
end//输出并行数据data_byte
always  @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)begindata_byte <= 0;endelse if(end_cnt0 && cnt1>0 && cnt1 <9) beginif(cnt_0 >= cnt_1)data_byte[cnt1-1] = 0;else if(cnt_0 < cnt_1)data_byte[cnt1-1] = 1;end
end//输出接收完成标志信号
always  @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginrx_done <= 0;endelse if(end_cnt1) beginrx_done <= 1;endelse beginrx_done <= 0;end
endendmodule

其仿真图形如下:


二、串口发送模块

这里和串口接收模块对应,发送的是8位数据,外加1位起始位和1位停止位。该模块接口信号列表如下:

表2.1:串口发送模块接口信号列表
信号名称 I/O 位数 功能描述
clk I 1 系统时钟50MHz
rst_n I 1 系统复位
send_en I 1 发送使能
data_byte I 8 发送的数据
baud_set I 3 波特率设置
rs232_tx O 1 FPGA将数据转换成串行数据发出
tx_done O 1 发送数据完毕标志
uart_state O 1 串口发送状态,1为忙,0为空闲

代码如下:Uart_Byte_Tx.v


//-------------------------------------------------------------------
//https://blog.csdn.net/qq_33231534 phf的CSDN
//File name:           Uart_Byte_Tx.v
//Last modified Date:  2020/5/22
//Last Version:
//Descriptions:        串口发送模块,8位数据位、1位起始位和1位停止位、无校验位
//-------------------------------------------------------------------
module Uart_Byte_Tx(input                   clk         , //系统时钟input                   rst_n       , //系统复位input                   send_en     , //发送使能input   [ 7 : 0 ]       data_byte   , //发送的数据input   [ 2 : 0 ]       baud_set    , //波特率设置output  reg             rs232_tx    , //FPGA将数据转换成串行数据发出output  reg             tx_done     , //发送数据完毕标志output  reg             uart_state    //串口发送状态,1为忙,0为空闲
);reg   [ 13: 0]         baud_c   ;//(4800bps-10416),(9600bps-5208),(19200bps-2604),//(38400bps-1302),(57600bps-868),(115200bps-434)
wire  [  9: 0]         data_out      ;
reg   [ 15: 0]         cnt0          ; //1bit数据长度计数
reg   [  3: 0]         cnt1          ; //发送一字节数据对每个字节计数
wire                   add_cnt0      ; //计数器cnt0加一条件
wire                   add_cnt1      ; //计数器cnt1加一条件
wire                   end_cnt0      ; //计数器cnt0结束条件
wire                   end_cnt1      ; //计数器cnt1结束条件
reg   [  7: 0]         data_byte_ff  ; //发送使能时将发送的数据寄存下来//波特率查找表
always  @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginbaud_c <= 5208;endelse begincase(baud_set)0:      baud_c = 14'd10416;1:      baud_c = 14'd5208 ;2:      baud_c = 14'd2604 ;3:      baud_c = 14'd1302 ;4:      baud_c = 14'd868  ;5:      baud_c = 14'd434  ;default:baud_c = 14'd5208 ;//默认9600bpsendcaseendend//串口状态标志,0为空闲,1为忙
always  @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginuart_state <= 0;endelse if(send_en) beginuart_state <= 1;endelse if(end_cnt1)beginuart_state <= 0;endelse beginuart_state <= uart_state;end
end//1bit数据长度计数
always @(posedge clk or negedge rst_n)beginif(!rst_n)begincnt0 <= 0;endelse if(add_cnt0)beginif(end_cnt0)cnt0 <= 0;elsecnt0 <= cnt0 + 1'b1;end
endassign add_cnt0 = uart_state==1;
assign end_cnt0 = add_cnt0 && cnt0== baud_c-1;//发送一字节数据对每个字节计数
always @(posedge clk or negedge rst_n)begin if(!rst_n)begincnt1 <= 0;endelse if(add_cnt1)beginif(end_cnt1)cnt1 <= 0;elsecnt1 <= cnt1 + 1'b1;end
endassign add_cnt1 = end_cnt0;
assign end_cnt1 = add_cnt1 && cnt1== 10-1;//串口发送结束标志
always  @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)begintx_done <= 0;endelse if(end_cnt1) begintx_done <= 1;endelse begintx_done <= 0;end
end//发送使能时将发送的数据寄存下来
always  @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)begindata_byte_ff <= 0;endelse if(send_en) begindata_byte_ff <= data_byte;end
end//发送串行数据到串口
always  @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginrs232_tx <= 1;endelse if(uart_state && cnt0==0) beginrs232_tx <= data_out[cnt1];end
end
assign data_out = {1'b1,data_byte_ff,1'b0};endmodule

仿真波形如下:


三、按键消抖模块

这是使用按键必须的模块。其信号列表入下,此模块可通用。

表3.1:按键消抖模块信号列表
信号名称 I/O 位数 功能描述
clk I 1 系统时钟50MHz
rst_n I 1 系统复位
key_in I 1 按键输入
key_flag O 1 输出一个脉冲按键有效信号
key_state O 1 输出按键状态,1为未按下,0为按下

代码如下:key_filter.v

//-------------------------------------------------------------------
//https://blog.csdn.net/qq_33231534 潘洪峰的CSDN博客
//File name:           key_filter.v
//Last modified Date:  2020/5/22
//Last Version:
//Descriptions:        按键消抖模块
//-------------------------------------------------------------------module key_filter(input                   clk         ,//系统时钟50MHzinput                   rst_n       ,//系统复位input                   key_in      ,//按键输入output   reg            key_flag    ,//输出一个脉冲按键有效信号output   reg            key_state    //输出按键状态,1为未按下,0为按下
);parameter IDLE      = 4'b0001      ;//空闲状态,读取按键按下的下降沿,读取到下降沿转到下一个状态
parameter FILTER1   = 4'b0010      ;//计数20ms状态,计数结束转到下一个状态
parameter STABLE    = 4'b0100      ;//数据稳定状态,等待按键松开上升沿,读取到上升沿转到下一个状态
parameter FILTER2   = 4'b1000      ;//计数20ms状态,计数结束转到空闲状态parameter TIME_20MS = 20'd1000_000 ;reg   [  3: 0]         state_c      ;//寄存器改变状态
reg   [  3: 0]         state_n      ;//现在状态wire                   IDLE_to_FILTER1  ;//IDLE状态转到FILTER1状态条件
wire                   FILTER1_to_STABLE;//FILTER1状态转到STABLE状态条件
wire                   STABLE_to_FILTER2;//STABLE状态转到FILTER2状态条件
wire                   FILTER2_to_IDLE  ;//FILTER2状态转到IDLE状态条件reg                    key_in_ff0   ;
reg                    key_in_ff1   ;
reg                    key_in_ff2   ;wire                   key_in_pos   ;//检测上升沿标志
wire                   key_in_neg   ;//检测下降沿标志reg   [ 19: 0]         cnt          ;
wire                   add_cnt      ;
wire                   end_cnt      ;//状态机第一段,状态转换
always  @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginstate_c <= IDLE;endelse beginstate_c <= state_n;end
end//状态机第二段,状态转换条件
always  @(*)begincase(state_c)IDLE   :beginif(IDLE_to_FILTER1)state_n = FILTER1;elsestate_n = state_c;endFILTER1:beginif(FILTER1_to_STABLE)state_n = STABLE;elsestate_n = state_c;endSTABLE :beginif(STABLE_to_FILTER2)state_n = FILTER2;elsestate_n = state_c;endFILTER2:beginif(FILTER2_to_IDLE)state_n = IDLE;elsestate_n = state_c;enddefault:state_n = IDLE;endcase
end//状态转换条件
assign IDLE_to_FILTER1   = key_in_neg   ;
assign FILTER1_to_STABLE = state_c==FILTER1 && end_cnt;
assign STABLE_to_FILTER2 = key_in_pos   ;
assign FILTER2_to_IDLE   = state_c==FILTER2 && end_cnt;//打两拍,防止亚稳态
always  @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginkey_in_ff0 <= 1;key_in_ff1 <= 1;key_in_ff2 <= 1;endelse beginkey_in_ff0 <= key_in;key_in_ff1 <= key_in_ff0;key_in_ff2 <= key_in_ff1;end
end//下降沿和上升沿检测
assign key_in_pos = (state_c==STABLE) ?(key_in_ff1 && !key_in_ff2):1'b0;
assign key_in_neg = (state_c==IDLE) ?(!key_in_ff1 && key_in_ff2):1'b0;//计数20ms
always @(posedge clk or negedge rst_n)beginif(!rst_n)begincnt <= 0;endelse if(add_cnt)beginif(end_cnt)cnt <= 0;elsecnt <= cnt + 1'b1;endelse begincnt <= 0;end
endassign add_cnt = state_c==FILTER1 || state_c==FILTER2;
assign end_cnt = add_cnt && cnt== TIME_20MS-1;//key_flag按键按下输出一个脉冲信号
always  @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginkey_flag <= 0;endelse if(state_c==FILTER1 && end_cnt) beginkey_flag <= 1;endelse beginkey_flag <= 0;end
end//key_state按键按下状态信号
always  @(posedge clk or negedge rst_n)beginif(rst_n==1'b0)beginkey_state <= 1;endelse if(state_c==STABLE || state_c==FILTER2) beginkey_state <= 0;endelse beginkey_state <= 1;end
end
endmodule

四、ROM模块

这里先跳过按键控制模块,先将一些基本模块叙述完,再叙述控制模块。

ROM模块是一个只读存储器,有三种方法编写这个模块。
(1)使用quartus具有的IP核(我用的是quartus prime 17.1),选择1-PORT,进行参数设置


(2)新建一个verilog HDL文件,选择Edit—>Insert Template,按照下图选择可直接生成模板,可直接使用。


(3)自己编写一个ROM文件,自己编写的和(2)方法生成代码一样,可设定数据位宽和地址宽度。

注意代码中ROM初始化语句:$readmemb("./sin_12bit.txt", rom);通过读取外部文件进行初始化,初始化文件可以自己手打或者Excel或者matlab生成。其中$readmemb("./sin_12bit.txt", rom);语句用法在本人博客下也有介绍,需要可以去看看。

其生成的verilog文件如下:single_port_rom.v

module single_port_rom
#(parameter DATA_WIDTH=12, parameter ADDR_WIDTH=12)
(input [(ADDR_WIDTH-1):0] addr,input clk, output reg [(DATA_WIDTH-1):0] q
);// Declare the ROM variablereg [DATA_WIDTH-1:0] rom[2**ADDR_WIDTH-1:0];initialbegin$readmemb("./sin_12bit.txt", rom);endalways @ (posedge clk)beginq <= rom[addr];endendmodule

仿真图形如下:

里边的数据是我在matlab上生成的sin函数12位波形文件。可以看到其在clk上升沿时读出对应地址的数据。

基于FPGA的数据采集系统(一)相关推荐

  1. 基于FPGA的数据采集系统

    目录 一.理论基础 二.核心程序 三.测试结果 一.理论基础 数据采集是指将模拟量采集转换成数字量后,再由计算机进行存储.处理.显示或打印的过程,相应的系统称为数据采集系统.随着科技进步,人们对数据采 ...

  2. 基于FPGA多通道数据采集系统verilog设计

    本设计实现多通道数据采集系统,该系统包括多通道数据采集和数据传输,使用verilog语言设计. 本设计实现功能:采集8路16位的AD数据,并发送到串口助手. 该设计架构图如下: 顶层模块代码如下: m ...

  3. stm32采集脉冲信号_基于STM32+FPGA的数据采集系统的设计与实现

    引言 由于火控系统工作环境特殊,所需采集信号复杂多样,传统的以微控制器或PC为主的采集系统往往难以胜任.针对上述问题,提出了一种基于STM32+FPGA的数据采集系统的设计方案,该方案不仅能够完成对多 ...

  4. 基于MQTT的数据采集系统

    基于MQTT的数据采集系统 1.实验目的 本次研究推出一款实用的轻量型智能家居系统,本系统采用STM32为主控芯片,将MQTT通信协议移植到STM32中,将其作为一个MQTTClient.该系统的核心 ...

  5. 基于单片机的数据采集系统

    摘 要:本文以AT89C51单片机为核心,设计一个基于单片机的数据采集系统.系统可以采集16路模拟量,精度为12位,16路开关量和2路脉冲量,并将采集到的数据每隔一分钟通过串口发送到PC机. 关键字: ...

  6. 基于FPGA的高速数据采集系统实现

    欢迎订阅<FPGA学习入门100例教程>.<MATLAB学习入门100例教程> 目录 一.理论基础 二.核心程序 2.1锁存器模块 2.2双口地址计数器模块 2.3双口RAM模 ...

  7. labview数据采集保存mysql_【源程序】基于Labview多通道数据采集系统 数据库存储...

    多通道数据采集系统包括采集温度.转速等信号,具有登录.数据采集.数据存储.数据分析等: 数据存储等等采用数据库完成,利用Labview完成与数据库的交互! 登录界面:输入用户名及密码,具有添加用户.编 ...

  8. 基于Python的数据采集系统

    因为年底公司确实是没有什么事情干(是要被开除了嘛),真的是闲的慌啊...最近一直在研究python的语法,但是感觉没有什么目标,所以也没有好好的研究,所以嘛,先定个小目标,做起来可能就会有些动力了,因 ...

  9. 基于labview的温湿度数据采集_【零偏原创】基于FPGA的多路SPI接口并行数据采集系统...

    摘 要:本文简述了SPI协议,建立了基于FPGA的SPI接口电路模型,并说明其输入输出端口和数据发送和接收过程,仿真验证了在主状态机控制下10个SPI接口并行采集数据,并在FPGA开发板上进行验证. ...

  10. 基于ZigBee的物联网环境数据采集系统

    1.概述 鉴于ZigBee技术适合用于数据采集系统的的特点, 提出了基于ZigBee的数据采集系统的设计方案, 着重探讨ZigBee节点的硬件设计及其组网设计. 并详细讨论了基于CC2530芯片的数据 ...

最新文章

  1. mysql中的时间函数---运维常用
  2. 时间序列 线性回归 区别_时间序列分析的完整介绍(带R)::线性过程I
  3. NYOJ---ASCII码排序
  4. 装完金蝶电脑无限重启_金蝶财务软件快捷键大全,提高工作效率!
  5. css样式优先级和权重问题
  6. 【Mac + Appium + Python3.6学习(四)】之常用的IOS自动化测试API总结
  7. php 批量删除挂马文件夹,PHP批量挂马脚本
  8. 【指纹识别】基于matlab GUI指纹识别匹配门禁系统【含Matlab源码 587期】
  9. C语言软盘,如何使用编程的方法--创建1.44兆软盘镜像的几种方法。。。(之一 C语言法)...
  10. 全网最全的划分VLAN的方法,走过路过不要错过
  11. 软件工程(速成)——第四章 总体设计
  12. 环形10个树洞兔子c语言设计,[阅读打卡]I am a Bunny+提高孩子的欣赏能力我是一只小兔子,我的名字叫尼古拉斯 我住在一个树洞里面 在春天的时候,我喜欢看美丽的花儿,有...
  13. 求证三角形中r/R=4sinA/2sinB/2sinC/2=cosA+cosB+cosC-1
  14. java 接口 实验报告_java-接口练习实验报告
  15. SGE上的qsub以及作业的状态查看
  16. Spring Boot网上图书商城
  17. 用计算机唱歌 丑八怪乐谱,得力计算器乐谱丑八怪 | 手游网游页游攻略大全
  18. C/C++语言100题练习计划 88——猜数游戏(二分查找实现)
  19. Win_XP_SP3系统下成功安装WinccV6.0_SP3a 经验分享
  20. 利用opencv带你玩转人脸识别-上篇(读取图片,灰度转换,尺寸修改,绘制矩形快速入门)

热门文章

  1. php设计网站课程报告,在线课程网站设计与实现-开题报告
  2. 指针变量占用的内存空间大小说明
  3. [语义分割]CTNet: Context-based Tandem Network for Semantic Segmentation
  4. 铁流:浪潮思科合资,高通中国设厂背后有什么故事
  5. 在哈尔滨的寒风中EOJ 3461【组合数学】
  6. 编写程序将电子邮件EmailAddressBook.txt和电话簿TeleAddressBook.txt合并为一个完整的通讯录AddressBook.txt(Address.py)
  7. DASCTF X CBCTF 2022九月挑战赛 dino3d
  8. android 获取设备ID(DeviceID)
  9. 迷你西游最新服务器是哪个,迷你西游公测新开服务器“万佛朝宗”公告
  10. 计算机社团收获作文,写智慧校园的优秀作文