当前位置: 首页 > news >正文

STM32 单片机 - ADC 和 DMA

一、ADC 介绍

ADC (analog-to-digital converter):模数转换器 - 将模拟信号转换为数字信号

模拟信号:连续周期变化的信号,在时间和数值上都是连续变化的物理量。

数字信号:以离散的 0 和 1 组成的信号,在时间和数值上都是离散的物理量。

图 1 模拟信号和数字信号

ADC 一般使用在电路中电流和电压的检测,以及传感器中数据的转换

STM32U575RIT6 可以使用 ADC1 和 ADC4 两个外设控制器进行模数转换


二、ADC1 和 ADC4 

2.1 模数转换原理

图 2 ADC1 和 ADC4

ADC 的采样位数:本质是采样精度,是将模拟信号转化为数字信号后的位数;

ADC1 转化后的数字信号是 14 位,ADC4 转化后的数字信号是 12 位

数据寄存器:存储转换后的数字信号

图 3 逐次逼近法原理图
图 4 逐次逼近法原理

ADC 转化使用的是 逐次逼近法

逐次逼近法:循环使用二分查找(折半查找)

AD4 的转化数字信号时 12 位,转换后的数字信号范围时 0 ~ 2¹²-1

2.2 模数转换公式

电压模拟信号转换 -> 电压数字信号 为例,使用 12 位的 ADC4

ADC转换后的数字信号 = 4096 / 3.3v * 1.2v

4096:采样位数的 ADC 最大转化范围(2¹²=4096,2¹⁴=16384)

3.3v:参考电压 / 供电电压

1.2v:待测电压

待测电压的数字信号 = (2^(ADC的采样位数) / 参考电压) * 待测电压的模拟信号

2.3 采样时机和偏移补偿

图 5 采样时机和偏移补偿图示

        采样时机指的是ADC的采样保持电路在何时对模拟输入信号进行“采样”(捕获瞬时电压值)的精确时间点。

        偏移补偿,也称为失调电压校准,目的是消除ADC输出代码中存在的固定的、系统的直流偏差。如果ADC采样发生偏移,此时采样得到的数据可能不是很准确,就需要使用硬件提供的偏移补偿机制(校准机制)初始化采样时机


三、ADC 采样模式

3.1 ADC1 的内部框图

图 6 ADC1 连接图
图 7 ADC1 描述

3.2 ADC4 内部框图

图 8 ADC4 连接图
图 9 ADC4 描述

3.3 ADC 的转化模式(采样模式)

图 10 ADC 的五种采样模式

单通道单次转化模式

        只使用 ADC 模数转换器中的一个独立通道,将输入到通道中的模拟信号转换为数字信号,并只转换一次就结束


单通道连续转换模式

        只使用 ADC 模数转换器中的一个独立通道,将输入到通道中的模拟信号转换为数字信号,结束一次后,自动进行下一次转化


单通道连续转化模式 = while(1) + 单通道单次转化模式


多通道单次转化模式

        使用 ADC 模数转换器的多个通道,并都输入模拟信号,ADC 转换器根据通道的顺序,依次转换为数字信号,每个通道只转换一次


多通道连续转换模式

        使用 ADC 模数转换器的多个通道,并都输入模拟信号,ADC 转换器根据通道的顺序,依次转换为数字信号,所有通道转化完后,回到初始通道重新依次转换


多通道连续转化模式 = while(1) + 多通道单次转化模式


间隔转化模式(间隔触发模式)

        给对应通道一个触发信号(触发源)后,ADC 模数转换器开始一次对通道中的模拟信号转换为数字信号。


ADC的转化模式:独立模式(单通道模式)扫描模式(多通道模式)触发模式


四、分析电路图

图 11 电路图分析

拓展板电压检测引脚:PB1


五、CubeMX 配置

图 12 配置 PB1 引脚为 ADC4_IN19
图 13 参数设置
  • ADCs_Common_Settings(ADC 通用设置)
    • Mode(模式):Independent mode(独立模式(每个通道都是独立的)
  • ADC_Settings(ADC 设置)
    • Clock Prescaler(时钟分频):Asynchronous clock mode divided by 1(时钟分频(时钟频率 -> 影响 ADC 模数转化的速率)
    • Resolution(采样精度):ADC 12 - bit resolution(采样精度(转化后的数字信号的位数):12 位
    • Data Alignment(数据对齐方式):Right alignment(数据对齐方式:右对齐
    • Sequencer(序列器):Sequencer set to not fully configurable
    • Scan Conversion Mode(输入转化模式):Forward(输入转化模式:标准模式(标准转化速率模式)
    • Continuous Conversion Mode(连续转化模式):Disabled
    • Discontinuous Conversion Mode(不连续转化模式):Disabled
    • DMA Continuous Requests(DMA 连续请求):Disabled
    • End Of Conversion Selection(转换结束选择):End of single conversion
    • Overrun behaviour(数据保存的机制):Overrun data preserved(数据保存的机制:转化后的数字信号被存储到数据寄存器中可以使用追加 / 覆盖的方式
    • Low Power Auto Wait(低功耗自动等待):Disabled
    • Low Power Auto Off(低功耗自动关闭):Low power disabled and auto off disabled
    • SamplingTime Common 1(通用采样时间 1):1.5 Cycles(通用的采样时间:1.5 轮转化一次,轮的具体时间需要根据时钟频率来计算 理论上,采样时间越长,采样得到的数据越准确
    • SamplingTime Common 2(通用采样时间 2):1.5 Cycles
    • Trigger Frequency(触发频率):Low frequency
    • External Trigger Conversion Source(外部触发转换源):Regular Conversion launched by software(使用间隔触发模式时,需要设置
    • External Trigger Conversion Edge(外部触发转换沿):None
    • Oversampling Mode(过采样模式):Disabled
    • Sampling Time(采样时间):Sampling time common 1(使用采样时间 1)

六、API 接口

ADC 采样和转化流程:

  1. 开启 ADC 采样校准模式
  2. 开启 ADC 采样转化功能
  3. 等待采样+转化结束,数字信号被存放到数据寄存器中
  4. 从数据寄存器中读取数字信号
  5. 通过模数转化公式,将数字信号转换为模拟信号,并在串口终端打印

注意:ADC 的校准采样必须在开启采样前或者关闭采样后

6.1 HAL_ADC_Start 函数

HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef *hadc)

功能:

        HAL库提供的用于开启ADC采样转化功能的函数

参数

        hadc:ADC4外设控制器的句柄

返回值:

        函数执行成功,返回HAL_OK

        函数执行失败,返回错误码

6.2 HAL_ADC_GetValue 函数

uint32_t HAL_ADC_GetValue(const ADC_HandleTypeDef *hadc)

功能:

        HAL库提供的用于获取转化完毕的数字信号的函数

参数:

        hadc:ADC4外设控制器的句柄

返回值:

        返回成功获取的数字信号

6.3 HAL_ADC_PollForConversion 函数

HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef *hadc, uint32_t Timeout)

功能:

         HAL库提供的用于阻塞等待ADC采样+转化完毕,数据被存放到数据寄存器中的函数

参数:

        hadc:ADC4外设控制器的句柄 Timeout:超时检测时间,当前函数的最大阻塞时间

返回值:

        当ADC采样+转化数据完毕后,表示这个函数执行成功,函数执行成功,返回HAL_OK

        当ADC采样+转化数据没结束时,此时这个函数处于阻塞状态

        函数执行失败,返回错误码

HAL_MAX_DELAY 宏

#define HAL_MAX_DELAY      0xFFFFFFFFU

6.4 HAL_ADC_Stop 函数

HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef *hadc)

功能:

        HAL库提供的用于关闭ADC采样转化功能的函数

参数:

        hadc:ADC4外设控制器的句柄

返回值:

        函数执行成功,返回HAL_OK

        函数执行失败,返回错误码

6.5 HAL_ADCEx_Calibration_Start 校准采样函数

HAL_StatusTypeDef 
HAL_ADCEx_Calibration_Start
(ADC_HandleTypeDef *hadc, uint32_t CalibrationMode, uint32_t SingleDiff)

功能:

        HAL库提供的用于校准ADC采样的函数(此函数只需要开启一次即可

参数:

        hadc:ADC4外设控制器的句柄

        CalibrationMode:校准模式的设置

                ADC_CALIB_OFFSET 偏移量校准方式(最基础的)

                ADC_CALIB_OFFSET_LINEARITY 硬件线性化校准(高级的) 线性化校准比偏移量校准更准确,一般使用一些高精度仪器上

        SingleDiff:输入的模拟信号的选择

                ADC_SINGLE_ENDED:输入单端信号(一个信号就代表一个电信号)                 ADC_DIFFERENTIAL_ENDED:输入差分信号(两个信号代表一个电信号)

返回值:

        函数执行成功,返回HAL_OK

        函数执行失败,返回错误码


七、代码编写

7.1 单通道单次转换模式

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
int fputc(int ch,FILE* stream)
{HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,5);return ch;
}
/* USER CODE END 0 */
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* Configure the System Power */SystemPower_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_ADC4_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 *///STM32U575RIT6需要手动开启VDD电源管理单元的功能HAL_PWREx_EnableVddA();HAL_PWREx_EnableVddIO2();HAL_ADCEx_Calibration_Start(&hadc4,ADC_CALIB_OFFSET,ADC_SINGLE_ENDED);uint32_t buf=0;float value=0;//开启ADC转换功能,开启连续转化只需要执行一次开始,后续自动执行//HAL_ADC_Start(&hadc4);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){//开启ADC转换功能HAL_ADC_Start(&hadc4);//等待采样结束和转化完毕HAL_ADC_PollForConversion(&hadc4,HAL_MAX_DELAY);buf=HAL_ADC_GetValue(&hadc4);value=buf*3.3/4096;printf("Vbat: digital=%d,analog=%lf\n",buf,value);HAL_Delay(1000);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}

7.2 单通道连续转换模式

int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* Configure the System Power */SystemPower_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_ADC4_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 *///STM32U575RIT6需要手动开启VDD电源管理单元的功能HAL_PWREx_EnableVddA();HAL_PWREx_EnableVddIO2();HAL_ADCEx_Calibration_Start(&hadc4,ADC_CALIB_OFFSET,ADC_SINGLE_ENDED);uint32_t buf=0;float value=0;//开启ADC转换功能,开启连续转化只需要执行一次开始,后续自动执行HAL_ADC_Start(&hadc4);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){//开启ADC转换功能//HAL_ADC_Start(&hadc4);//等待采样结束和转化完毕HAL_ADC_PollForConversion(&hadc4,HAL_MAX_DELAY);buf=HAL_ADC_GetValue(&hadc4);value=buf*3.3/4096;printf("Vbat: digital=%d,analog=%lf\n",buf,value);HAL_Delay(1000);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}

7.3 多通道单次转换模式

int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* Configure the System Power */SystemPower_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_ADC4_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 *///STM32U575RIT6需要手动开启VDD电源管理单元的功能HAL_PWREx_EnableVddA();HAL_PWREx_EnableVddIO2();HAL_ADCEx_Calibration_Start(&hadc4,ADC_CALIB_OFFSET,ADC_SINGLE_ENDED);uint32_t buf[2]={0};float value[2]={0};//开启ADC转换功能,开启连续转化只需要执行一次开始,后续自动执行//HAL_ADC_Start(&hadc4);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){for(int i=0;i<2;i++){//开启ADC转换功能HAL_ADC_Start(&hadc4);//等待采样结束和转化完毕HAL_ADC_PollForConversion(&hadc4,HAL_MAX_DELAY);buf[i]=HAL_ADC_GetValue(&hadc4);value[i]=buf[0]*3.3/4096;}printf("Vbat: digital=%d,analog=%lf\n",buf[0],4*value[0]);printf("INT9: digital=%d,analog=%lf\n",buf[1],value[1]);HAL_Delay(1000);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}

7.4 多通道连续转换模式

int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* Configure the System Power */SystemPower_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_ADC4_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 *///STM32U575RIT6需要手动开启VDD电源管理单元的功能HAL_PWREx_EnableVddA();HAL_PWREx_EnableVddIO2();HAL_ADCEx_Calibration_Start(&hadc4,ADC_CALIB_OFFSET,ADC_SINGLE_ENDED);uint32_t buf[2]={0};float value[2]={0};//开启ADC转换功能,开启连续转化只需要执行一次开始,后续自动执行HAL_ADC_Start(&hadc4);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){for(int i=0;i<2;i++){//开启ADC转换功能//HAL_ADC_Start(&hadc4);//等待采样结束和转化完毕HAL_ADC_PollForConversion(&hadc4,HAL_MAX_DELAY);buf[i]=HAL_ADC_GetValue(&hadc4);value[i]=buf[0]*3.3/4096;}printf("Vbat: digital=%d,analog=%lf\n",buf[0],4*value[0]);printf("INT9: digital=%d,analog=%lf\n",buf[1],value[1]);HAL_Delay(1000);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}

八、DMA 介绍

DMA (General purpose direct memory access controller):通用可编程直接内存访问控制器

内存:广义的内存,包括虚拟内存地址和物理内存地址

DMA 本质是硬件缓冲区(FIFO)


DMA 的作用

        减轻 CPU 的压力,将简单的数据存储工作交给 DMA 去做,让 CPU 只负责逻辑处理和数据处理。

图 14 DMA 图示

1. GPDMA 支持 16 个独立通道,每个通道都可以用来独立暂存数据

2. GPDMA 的通道用于数据的暂存和传输

        单通道传输模式:使用一个通道进行数据传输

        多通道传输模式:使用多个通道进行数据传输

        同一时刻,只能使用一个 DMA 通道进行数据传输

3. 使用 DMA 通道传输数据前,需要向 DMA 发送使用请求

        谁先发送 DMA 通道请求,谁先使用 DMA 通道

4. DMA 通道具有优先级等级,优先级等级高的 DMA 通道线传输数据,分为 4 个等级:

        (1)低优先级

        (2)中优先级

        (3)高优先级

        (4)超高优先级

5. 使用 DMA 通道传输数据,一端是 Source 源设备(发送端),一端是 Destination 目标设备(接收端)

6. 使用 DMA 通道传输数据时,有 4 种数据传输方向:

        (1)内存 -> 外设

        (2)外设 -> 内存

        (3)内存 -> 内存

        (4)外设 -> 外设        例如:串口的 IDR 寄存器 -> GPIO 的 ODR 寄存器

7. 使用 DMA 通道传输数据时,有数据传输标志位:

        (1)数据没有传输完成标志位

        (2)数据传输完成一半标志位

        (3)数据全部传输完成标志位

8. 使用 DMA 通道传输数据时,可以设置 DMA 通道为不同模式:

        (1)标准传输模式 - 内存地址连续时使用

        (2)链表传输模式 - 聚集分散模式,物理内存地址不连续时使用 

9. 使用 DMA 通道传输数据时,DMA 通道具备的单次最大传输数据范围

        (1)通道 0 - 11 的大小:2 个字 - 8 个字节

        (2)通道 12 - 15 的大小:4 个字 - 16 个字节

        一般使用 1 / 2 / 4 / 8 个字节为单次传输大小

10. 使用 DMA 通道传输数据时,DMA 内部有两个输出端口(源设备 -> DMA 通道 -> 目标设备)

        (1)输出端口 port0

        (2)输出端口 port1

        源设备发送数据 -> DMA 通道 -> port0 -> 目标设备

        注意:源设备和目标设备使用的输出端口必须是同一个

11. 使用 DMA 通道并非将 GPIO 引脚复用为 DMA 的功能,DMA 只是一个缓冲区,使用时只需要将数据放到 DMA 通道中即可

12. DMA 通道的单次传输模式连续传输模式

        单次传输模式:使用 DMA 通道传输完一次数据后,DMA 通道自动关闭,如果需要继续从 DMA 通道传输数据,需要手动开启 DMA 通道;

        连续传输模式:使用 DMA 通道传输完一次数据后,DMA 通道不自动关闭,而回自动继续传输数据。

        一般使用连续传输模式,传输完一次完整数据后,手动关闭 DMA 通道


串口的不定长接收 = 串口的接收中断 + 串口的空闲中断

串口的不定长接收 = 串口的 DMA 通道 + 串口的空闲中断

图 15 DMA 内部框图
图 16

buf 的地址偏移问题:

        DMA 通道从 USART1_RDR 寄存器中读取 1 个字节的数据缓存到 DMA 通道中,再将七写入 buf 中,每次写入前必须将 buf 的地址指针向后偏移 1 个字节才能正确完整存储数据,如果不偏移每次写入会覆盖前一次写入的 1 字节数据;对读取 USART1_RDR 寄存器来说,它的物理地址是固定的,所以对它不用地址偏移。


九、CubeMX 配置

图 17 配置引脚和 DMA 通道使能

配置 USART1 模式,选择 GPDMA 中的 1 个通道并将其设置为 Standard Request Mode.

图 18 DMA 一个通道的相关参数

上图是 DMA 其中一个通道的相关参数解释

图 19 DMA 通道参数的设置

按照上图一样设置 DMA 通道的参数


地址偏移:

        如果从DMA通道读取数据/向DMA通道中写入数据的角色是 连续的内存地址,就需要开启对应的地址偏移

        如果从DMA通道读取数据/向DMA通道中写入数据的角色是 固定的物理地址,就不需要开启对应的地址偏移

图 20 打开串口的中断使能

打开 USART1 的串口终端使能


十、API 接口

10.1 HAL_UART_Transmit_DMA 函数

HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)

功能:

        HAL库提供的用于开启通过DMA通道存储串口接收数据的函数(串口接收到的数据,会被存储到DMA通道中)

        USART1_RDR -> DMA

参数:

        huart:USART1的句柄对象 p

        Data:已经放入到DMA通道中的数据(从DMA通道中读取出来的数据)

        Size:需要从DMA通道中读取的数据的大小,单位为字节

返回值:

        函数执行成功,返回HAL_OK

        函数执行失败,返回错误码

10.2 HAL_UART_DMAStop 函数

HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart)

功能:

        HAL库提供的用于手动关闭串口使用的DMA 在

        串口使用DMA通道传输完完整数据后,需要手动关闭DMA通道

参数:

        huart:USART1的句柄对象

返回值:

        函数执行成功,返回HAL_OK

        函数执行失败,返回错误码

十一、代码编写

main.c

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint8_t buf[1024];
//中断标志
volatile int flag=0;int fputc(int ch,FILE* stream)
{HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,1);return ch;
}
/* USER CODE END 0 */
 /* Initialize all configured peripherals */MX_GPIO_Init();MX_GPDMA1_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 *//* USER CODE END 2 *///开启串口使用DMA通道接收中断HAL_UART_Receive_DMA(&huart1,buf,sizeof(buf));//开启空闲中断__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);/* Infinite loop *//* USER CODE BEGIN WHILE */while (1){if(flag==1){printf("buf=%s\n",buf);memset(buf,0,sizeof(buf));flag=0;}/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}

stm32u5xx_it.c

void USART1_IRQHandler(void)
{/* USER CODE BEGIN USART1_IRQn 0 */extern volatile int flag;extern uint8_t buf[1024];/* USER CODE END USART1_IRQn 0 */HAL_UART_IRQHandler(&huart1);/* USER CODE BEGIN USART1_IRQn 1 */if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)){__HAL_UART_CLEAR_FLAG(&huart1,UART_CLEAR_IDLEF);//手动关闭DMA通道HAL_UART_DMAStop(&huart1);//逻辑代码flag=1;//重新开启HAL_UART_Receive_DMA(&huart1,buf,sizeof(buf));}/* USER CODE END USART1_IRQn 1 */
}
http://www.dtcms.com/a/400985.html

相关文章:

  • 公司展示网站模板中山网站上排名
  • 做网站时如何将前端连接到后台网站定制二次开发
  • 双鸭山网站开发建设网站用图片需要版权
  • 学生个人网站制作软件找建设网站公司吗
  • 在网站上如何做天气预报栏中山网站建设哪家便宜
  • 一个网站如何做桌面快捷链接html静态网站下载
  • 成都网站网站建设网站推广优化排名seo
  • 要怎么做网站动图学生网站作品
  • 张家港外贸网站建设百度不收录网站
  • 尚云网站建设做的好点的外贸网站有哪些
  • 电脑上wap网站策划书模板范文
  • 网站页面设计多少钱深圳上市公司网站建设公司
  • 二次元网站开发的意义网易企业邮箱官网登录
  • 城市中国商业网站平台口碑好的免费网站建设
  • 企业建设企业网站的好处网站域名费用怎么做帐
  • 淘宝网站建设单子好接吗优化设计五年级上册语文答案
  • 网站建设解决方案服务商wordpress 图片相册
  • 怎样查看网站点击量搜索引擎网址有哪些
  • 淘宝联盟返利网站怎么做三门峡集团网站建设
  • 网站在建设中模板下载科技素材
  • 企业展示型网站建设方案在线网页设计器
  • 网站开发博客关系的网站
  • 外贸网站建设十大标准外贸网站建站小刘网站建设
  • 好习惯网站做恐怖网站
  • 网站建设合同封皮如何申请域名和ip地址
  • 免费零食网站模板山东网站建设运行工资
  • 汕头网站制作公司广东建设中标网站
  • 万网发布网站纯静态企业网站
  • 综合服务平台一站式服务平台网站开发紫金网站制作
  • 广告网站定制打开百度网址