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

张家港市住房和城乡建设局网站果蔬网站规划建设方案

张家港市住房和城乡建设局网站,果蔬网站规划建设方案,天河怎样优化网站建设,机械类简单的毕业设计1. 简介 1.1 SPI总线介绍 SPI 是英语Serial Peripheral interface的缩写#xff0c;顾名思义就是串行外围设备接口。是Motorola(摩托罗拉)首先在其MC68HCXX系列处理器上定义的。 SPI#xff0c;是一种高速的#xff0c;全双工#xff0c;同步的通信总线#xff0c;并且在…1. 简介 1.1 SPI总线介绍 SPI 是英语Serial Peripheral interface的缩写顾名思义就是串行外围设备接口。是Motorola(摩托罗拉)首先在其MC68HCXX系列处理器上定义的。 SPI是一种高速的全双工同步的通信总线并且在芯片的管脚上只占用四根线节约了芯片的管脚同时为PCB的布局上节省空间提供方便主要应用在 EEPROMFLASH实时时钟AD转换器还有数字信号处理器和数字信号解码器之间。 SPI主从模式         SPI分为主、从两种模式一个SPI通讯系统需要包含一个且只能是一个主设备一个或多个从设备。提供时钟的为主设备Master接收时钟的设备为从设备SlaveSPI接口的读写操作都是由主设备发起。当存在多个从设备时通过各自的片选信号进行管理。 SPI是全双工且SPI没有定义速度限制一般的实现通常能达到甚至超过10 Mbps SPI信号线 SPI接口一般使用四条信号线通信SDI数据输入SDO数据输出SCK时钟CS片选 MISO 主设备输入/从设备输出引脚。该引脚在从模式下发送数据在主模式下接收数据。MOSI 主设备输出/从设备输入引脚。该引脚在主模式下发送数据在从模式下接收数据。SCLK串行时钟信号由主设备产生。CS/SS从设备片选信号由主设备控制。它的功能是用来作为“片选引脚”也就是选择指定的从设备让主设备可以单独地与特定从设备通讯避免数据线上的冲突。 硬件上为4根线。 SPI一对一 SPI一对多 SPI数据发送接收 SPI主机和从机都有一个串行移位寄存器主机通过向它的SPI串行寄存器写入一个字节来发起一次传输。 首先拉低对应SS信号线表示与该设备进行通信 主机通过发送SCLK时钟信号来告诉从机写数据或者读数据 这里要注意SCLK时钟信号可能是低电平有效也可能是高电平有效因为SPI有四种模式这个我们在下面会介绍 主机(Master)将要发送的数据写到发送数据缓存区(Menory)缓存区经过移位寄存器(0~7)串行移位寄存器通过MOSI信号线将字节一位一位的移出去传送给从机同时MISO接口接收到的数据经过移位寄存器一位一位的移到接收缓存区。 从机(Slave)也将自己的串行移位寄存器(0~7)中的内容通过MISO信号线返回给主机。同时通过MOSI信号线接收主机发送的数据这样两个移位寄存器中的内容就被交换。 SPI只有主模式和从模式之分没有读和写的说法外设的写操作和读操作是同步完成的。如果只进行写操作主机只需忽略接收到的字节反之若主机要读取从机的一个字节就必须发送一个空字节来引发从机的传输。也就是说你发一个数据必然会收到一个数据你要收一个数据必须也要先发一个数据。 SPI工作模式 根据时钟极性CPOL及相位CPHA不同SPI有四种工作模式。时钟极性(CPOL)定义了时钟空闲状态电平 CPOL0为时钟空闲时为低电平CPOL1为时钟空闲时为高电平 时钟相位(CPHA)定义数据的采集时间。 CPHA0:在时钟的第一个跳变沿上升沿或下降沿进行数据采样。CPHA1:在时钟的第二个跳变沿上升沿或下降沿进行数据采样。 1.2 W25QXX芯片介绍 W25QXX芯片是华邦公司推出的大容量SPI FLASH产品该系列有W25Q16/32/62/128等。本例程使用W25Q64W25Q64容量为64Mbits8M字节8MB的容量分为128个块(Block)块大小为64KB每个块又分为16个扇区(Sector)扇区大小为4KBW25Q64的最小擦除单位为一个扇区即4KB因此在选择芯片的时候必须要有4K以上的SRAM可以开辟4K的缓冲区。W25Q64的擦写周期多达10万次具有20年的数据保存期限。 下表是W25QXX的常用命令表 常用指令 写使能(Write Enable) (06h) 向FLASH发送0x06 写使能命令即可开启写使能首先CS片选拉低控制写入字节函数写入命令CS片选拉高。 扇区擦除指令(Sector Erase) (0x20h) 扇区擦除指令数据写入前必须擦除对应的存储单元该指令先拉低/CS引脚电平,接着传输“20H”指令和要24位要擦除扇区的地址。 读命令(Read Data) (03h) 读数据指令可从存储器依次一个或多个数据字节该指令通过主器件拉低/CS电平使能设备开始传输然后传输“03H”指令接着通过DI管脚传输24位地址从器件接到地址后寻址存储器中的数据通过DO引脚输出。每传输一个字节地址自动递增所以只要时钟继续传输可以不断读取存储器中的数据。 状态读取命令(Read Status Register) 读状态寄存器1(05H)状态寄存器235H,状态寄存器315H 写入命令0x05即可读取状态寄存器的值。 写入命令(Page Program) (02h) 在对W25Q128 FLASH的写入数据的操作中一定要先擦出扇区在进行写入否则将会发生数据错误。 W25Q128 FLASH一次性最大写入只有256个字节。 在进行写操作之前一定要开启写使能(Write Enable)。 当只接收数据时不但能只检测RXNE状态 必须同时向发送缓冲区发送数据才能驱动SCK时钟跳变。 2. 硬件设计 LED2指示灯用来提示系统运行状态S1按键用来控制W25Q64数据写入S2按键用来控制W25Q64数据读取串口1用来打印写入和读取的数据信息 LED2指示灯 S1和S2按键 USART1SPIW25Q64 3、STM32CubeMX设置 RCC设置外接HSE时钟设置为72MPE5(LED2)设置为GPIO推挽输出模式、上拉、高速、默认输出电平为高电平USART1选择为异步通讯方式波特率设置为115200Bits/s传输数据长度为8Bit无奇偶校验1位停止位PE3,PE4设置为GPIO输入模式、上拉模式激活SPI2选择全双工主机模式 不使能硬件NSS STM32有硬件NSS(片选信号)可以选择使能也可以使用其他IO口接到芯片的NSS上进行代替其中SIP2的片选NSS SPI2_NSSPB12 如果片选引脚没有连接 SPI1_NSSPA4或者SPI2_NSSPB12则需要选择软件片选 NSS管脚及我们熟知的片选信号作为主设备NSS管脚为高电平从设备NSS管脚为低电平。当NSS管脚为低电平时该spi设备被选中可以和主设备进行通信。在stm32中每个spi控制器的NSS信号引脚都具有两种功能即输入和输出。所谓的输入就是NSS管脚的信号给自己。所谓的输出就是将NSS的信号送出去给从机。 对于NSS的输入又分为软件输入和硬件输入。 软件输入 NSS分为内部管脚和外部管脚通过设置spi_cr1寄存器的ssm位和ssi位都为1可以设置NSS管脚为软件输入模式且内部管脚提供的电平为高电平其中SSM位为使能软件输入位。SSI位为设置内部管脚电平位。同理通过设置SSM和SSI位1和0则此时的NSS管脚为软件输入模式但内部管脚提供的电平为0。若从设备是一个其他的带有spi接口的芯片并不能选择NSS管脚的方式则可以有两种办法一种是将NSS管脚直接接低电平。另一种就是通过主设备的任何一个gpio口去输出低电平选中从设备。 硬件输入 主机接高电平从机接低电平。 左键对应的软件片选引脚选择GPIO_Output(输出模式),然后点击GPIO设置一下备注。 我这里虽然PB12是SPI2的硬件片选NSS但是我想用软件片选所以关闭了硬件NSS PB12设置为GPIO推挽输出模式、上拉、高速片选引脚 SPI配置默认如下 SPI配置中设置格式为Motorla格式数据长度为8bitMSB先输出。 分频为256分频则波特率为140KBits/sCPOL设置为HIGHCPHA设置为第二个边沿。 不开启CRC检验NSS为软件控制。 其他为默认设置。 输入工程名选择工程路径不要有中文选择MDK-ARM V5勾选Generated periphera initialization as a pair of ‘.c/.h’ files per IP 点击GENERATE CODE生成工程代码 4、程序编程 在stm32f1xx_hal_spi.h头文件中可以看到spi的操作函数。分别对应轮询中断和DMA三种控制方式。 轮询 最基本的发送接收函数就是正常的发送数据和接收数据中断 在SPI发送或者接收完成的时候会进入SPI回调函数用户可以编写回调函数实现设定功能DMA DMA传输SPI数据 利用SPI接口发送和接收数据主要调用以下两个函数 HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);//发送数据 /* *hspi: 选择SPI1/2比如hspi1hspi2 *pData 需要发送的数据可以为数组 Size 发送数据的字节数1 就是发送一个字节数据 Timeout 超时时间就是执行发送函数最长的时间超过该时间自动退出发送函数 */ HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);//接收数据 /* *hspi: 选择SPI1/2比如hspi1hspi2 *pData 接收发送过来的数据的数组 Size 接收数据的字节数1 就是接收一个字节数据 Timeout 超时时间就是执行接收函数最长的时间超过该时间自动退出接收函数 */SPI接收回调函数 HAL_SPI_TransmitReceive_IT(hspi1, TXbuf,RXbuf,CommSize); 当SPI上接收出现了 CommSize个字节的数据后中断函数会调用SPI回调函数 HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) 用户可以重新定义回调函数编写预定功能即可在接收完成之后便会进入回调函数 在spi.c文件下可以看到SPI2的初始化函数片选管脚的初始化在gpio.c中 void MX_SPI2_Init(void){hspi2.Instance SPI2;hspi2.Init.Mode SPI_MODE_MASTER; //设置为主模式hspi2.Init.Direction SPI_DIRECTION_2LINES; //双线模式hspi2.Init.DataSize SPI_DATASIZE_8BIT; // 8位数据长度hspi2.Init.CLKPolarity SPI_POLARITY_HIGH; //串行同步时钟空闲状态为高电平hspi2.Init.CLKPhase SPI_PHASE_2EDGE; //第二个跳变沿采样hspi2.Init.NSS SPI_NSS_SOFT; //NSS软件控制hspi2.Init.BaudRatePrescaler SPI_BAUDRATEPRESCALER_256; //分配因子256hspi2.Init.FirstBit SPI_FIRSTBIT_MSB; //MSB先行hspi2.Init.TIMode SPI_TIMODE_DISABLE; //关闭TI模式hspi2.Init.CRCCalculation SPI_CRCCALCULATION_DISABLE; //关闭硬件CRC校验hspi2.Init.CRCPolynomial 10;if (HAL_SPI_Init(hspi2) ! HAL_OK){Error_Handler();} }void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle){GPIO_InitTypeDef GPIO_InitStruct {0};if(spiHandle-InstanceSPI2){__HAL_RCC_SPI2_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE();/**SPI2 GPIO Configuration PB13 ------ SPI2_SCKPB14 ------ SPI2_MISOPB15 ------ SPI2_MOSI */GPIO_InitStruct.Pin GPIO_PIN_13|GPIO_PIN_15;GPIO_InitStruct.Mode GPIO_MODE_AF_PP;GPIO_InitStruct.Speed GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB, GPIO_InitStruct);GPIO_InitStruct.Pin GPIO_PIN_14;GPIO_InitStruct.Mode GPIO_MODE_INPUT;GPIO_InitStruct.Pull GPIO_NOPULL;HAL_GPIO_Init(GPIOB, GPIO_InitStruct);} } 创建包含W25Q64芯片的相关操作函数及驱动函数的文件w25qxx.c和w25qxx.h #ifndef _W25QXX_H_ #define _W25QXX_H_#include main.h #include spi.h #include usart.h#define W25Q64 0XC816extern uint16_t W25QXX_TYPE; //修改CS片选引脚W25Qx_Enable(),W25Qx_Disable()分别为使能和失能SPI设备即拉低和拉高/CS电平 #define W25Qx_Enable() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_RESET) #define W25Qx_Disable() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_SET)#define W25X_WriteEnable 0x06 #define W25X_WriteDisable 0x04 #define W25X_ReadStatusReg1 0x05 #define W25X_ReadStatusReg2 0x35 #define W25X_ReadStatusReg3 0x15 #define W25X_WriteStatusReg1 0x01 #define W25X_WriteStatusReg2 0x31 #define W25X_WriteStatusReg3 0x11 #define W25X_ReadData 0x03 #define W25X_FastReadData 0x0B #define W25X_FastReadDual 0x3B #define W25X_PageProgram 0x02 #define W25X_BlockErase 0xD8 #define W25X_SectorErase 0x20 #define W25X_ChipErase 0xC7 #define W25X_PowerDown 0xB9 #define W25X_ReleasePowerDown 0xAB #define W25X_DeviceID 0xAB #define W25X_ManufactDeviceID 0x90 #define W25X_JedecDeviceID 0x9F #define W25X_Enable4ByteAddr 0xB7 #define W25X_Exit4ByteAddr 0xE9void W25QXX_Init(void); uint16_t W25QXX_ReadID(void); uint8_t W25QXX_ReadSR(uint8_t regno); void W25QXX_Write_SR(uint8_t regno,uint8_t sr); void W25QXX_Write_Enable(void); void W25QXX_Write_Disable(void); void W25QXX_Read(uint8_t* pBuffer,uint32_t ReadAddr,uint16_t NumByteToRead); void W25QXX_Write_Page(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite); void W25QXX_Write_NoCheck(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite); void W25QXX_Write(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite);void W25QXX_Erase_Chip(void); void W25QXX_Erase_Sector(uint32_t Dst_Addr); void W25QXX_Wait_Busy(void); void W25QXX_PowerDown(void); void W25QXX_WAKEUP(void); #endif #include w25qxx.h #include stdio.huint16_t W25QXX_TYPE;void W25QXX_Init(void) {W25Qx_Disable();//MX_SPI2_Init();W25QXX_TYPE W25QXX_ReadID(); //读取芯片IDprintf1(FLASH ID:%X\r\n,W25QXX_TYPE);if(W25QXX_TYPE 0xc816)printf1(FLASH TYPE:W25Q64\r\n); }//读取芯片ID uint16_t W25QXX_ReadID(void) {uint16_t ID;uint8_t id[2]{0};uint8_t cmd[4] {W25X_ManufactDeviceID,0x00,0x00,0x00};//读取ID命令 0x90 W25Qx_Enable();//芯片使能HAL_SPI_Transmit(hspi2,cmd,4,1000);//spi发送读取ID命令超时1000msHAL_SPI_Receive(hspi2,id,2,1000); //spi读取ID存放在数组id中超时1000msW25Qx_Disable(); //取消片选 ID (((uint16_t)id[0])8)|id[1];return ID; }//读取片区 uint8_t W25QXX_ReadSR(uint8_t regno) {uint8_t byte0,cmd0;switch(regno){case 1:cmd W25X_ReadStatusReg1;break;case 2:cmd W25X_ReadStatusReg2;break;case 3:cmd W25X_ReadStatusReg3;break;default:cmd W25X_ReadStatusReg1;break;}W25Qx_Enable();HAL_SPI_Transmit(hspi2,cmd,1,1000);HAL_SPI_Receive(hspi2,byte,1,1000);W25Qx_Disable();return byte; }//写片区 void W25QXX_Write_SR(uint8_t regno,uint8_t sr) {uint8_t cmd0;switch(regno){case 1:cmd W25X_WriteStatusReg1;break;case 2:cmd W25X_WriteStatusReg2;break;case 3:cmd W25X_WriteStatusReg3;break;default:cmd W25X_WriteStatusReg1;break;}W25Qx_Enable();HAL_SPI_Transmit(hspi2,cmd,1,1000);HAL_SPI_Receive(hspi2,sr,1,1000);W25Qx_Disable(); }//写使能 void W25QXX_Write_Enable(void) {uint8_t cmd W25X_WriteEnable; //写使能命令 0x06W25Qx_Enable();HAL_SPI_Transmit(hspi2,cmd,1,1000);W25Qx_Disable(); }void W25QXX_Write_Disable(void) {uint8_t cmd W25X_WriteDisable; //写失能命令 0x04W25Qx_Enable();HAL_SPI_Transmit(hspi2,cmd,1,1000);W25Qx_Disable(); }void W25QXX_Read(uint8_t* pBuffer,uint32_t ReadAddr,uint16_t NumByteToRead) {uint8_t cmd[4] {0};cmd[0] W25X_ReadData; //读取命令cmd[1] ((uint8_t)(ReadAddr16));cmd[2] ((uint8_t)(ReadAddr8));cmd[3] ((uint8_t)ReadAddr);W25Qx_Enable();HAL_SPI_Transmit(hspi2,cmd,4,1000);if(HAL_SPI_Receive(hspi2,pBuffer,NumByteToRead,1000) ! HAL_OK){printf1(SPI read failed!\r\n);}W25Qx_Disable(); }void W25QXX_Write_Page(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite) {uint8_t cmd[4] {0};if(NumByteToWrite 256){NumByteToWrite 256;printf1(写数据量过大超过一页的大小\n);}W25QXX_Write_Enable();W25Qx_Enable();cmd[0] W25X_PageProgram;cmd[1] ((uint8_t)(WriteAddr16));cmd[2] ((uint8_t)(WriteAddr8));cmd[3] ((uint8_t)WriteAddr);HAL_SPI_Transmit(hspi2,cmd,4,1000);HAL_SPI_Transmit(hspi2,pBuffer,NumByteToWrite,1000);W25Qx_Disable();W25QXX_Wait_Busy(); }void W25QXX_Write_NoCheck(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite) {uint16_t pageremain;pageremain 256 - WriteAddr%256;if(NumByteToWrite pageremain)pageremain NumByteToWrite;while(1){W25QXX_Write_Page(pBuffer,WriteAddr,pageremain);if(NumByteToWrite pageremain)break;else{pBuffer pageremain;WriteAddr pageremain;NumByteToWrite - pageremain;if(NumByteToWrite 256)pageremain 256;elsepageremain NumByteToWrite;}} }uint8_t W25QXX_BUFFER[4096]{0}; void W25QXX_Write(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite) {uint32_t secpos;uint16_t secoff;uint16_t secremain;uint16_t i;uint8_t *W25QXX_BUF;W25QXX_BUF W25QXX_BUFFER;secpos WriteAddr/4096; //扇区地址secoff WriteAddr%4096; //在扇区里的偏移secremain 4096-secoff; //扇区剩余空间大小printf1(WriteAddr:0x%X,NumByteToWrite:%d\r\n,WriteAddr,NumByteToWrite);if(NumByteToWrite secremain) //不大于4K字节secremain NumByteToWrite;while(1){W25QXX_Read(W25QXX_BUF,secpos*4096,4096); //读取整个扇区内容for(i0;isecremain;i) //校验数据 {if(W25QXX_BUF[secoffi] ! 0xff) //需要擦除break;}if(i secremain) //需要擦除{W25QXX_Erase_Sector(secpos); //擦除扇区for(i0;isecremain;i){printf1(4\r\n);W25QXX_BUF[isecoff] pBuffer[i];}W25QXX_Write_NoCheck(W25QXX_BUF,secpos*4096,4096); //写入整个扇区}else{W25QXX_Write_NoCheck(pBuffer,WriteAddr,secremain); //写入扇区剩余空间}if(NumByteToWrite secremain) //写入结束了break;else //写入未结束{secpos; //扇区地址增1secoff 0; //偏移位置为0 pBuffer secremain; //指针偏移WriteAddr secremain; //写地址偏移NumByteToWrite - secremain; //字节数递减if(NumByteToWrite 4096)secremain 4096; //下个扇区还没是写不完elsesecremain NumByteToWrite; //下个扇区可以写完了}} }void W25QXX_Erase_Chip(void) {uint8_t cmd W25X_ChipErase;W25QXX_Write_Enable();W25QXX_Wait_Busy();W25Qx_Enable();HAL_SPI_Transmit(hspi2,cmd,1,1000);W25Qx_Disable();W25QXX_Wait_Busy(); }//擦除扇区 void W25QXX_Erase_Sector(uint32_t Dst_Addr) {uint8_t cmd[4] {0};Dst_Addr * 4096;W25QXX_Write_Enable();//写使能W25QXX_Wait_Busy();W25Qx_Enable();cmd[0] W25X_SectorErase;cmd[1] ((uint8_t)(Dst_Addr16));cmd[2] ((uint8_t)(Dst_Addr8));cmd[3] ((uint8_t)Dst_Addr);HAL_SPI_Transmit(hspi2,cmd,4,1000);W25Qx_Disable();W25QXX_Wait_Busy(); }void W25QXX_Wait_Busy(void) {while((W25QXX_ReadSR(1)0x01)0x01); }void W25QXX_PowerDown(void) {uint8_t cmd W25X_PowerDown;W25Qx_Enable();HAL_SPI_Transmit(hspi2,cmd,1,1000);W25Qx_Disable();HAL_Delay(1); }void W25QXX_WAKEUP(void) {uint8_t cmd W25X_ReleasePowerDown;W25Qx_Enable();HAL_SPI_Transmit(hspi2,cmd,1,1000);W25Qx_Disable();HAL_Delay(1); }在main.c文件下编写SPI测试代码 uint8_t wData[0x100]; uint8_t rData[0x100]; uint32_t i; unsigned char tx_buf[256];int main(void) { uint8_t key;W25QXX_Init();for(i0;i0x100;i){wData[i] 0xff-i;rData[i] 0;} while (1){key KEY_Scan(0);if(key 1){printf1(S1 write data...\r\n);W25QXX_Erase_Sector(0);//擦除扇区W25QXX_Write(wData,0,256);printf1(S1 write data success\r\n);}if(key 2){printf1(S2 read data...\r\n);W25QXX_Read(rData,0,256);for(i0;i256;i){printf1(0x%02X ,rData[i]);}}HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_5);HAL_Delay(500);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */ } 5、下载验证 编译无误下载到开发板后可以看到LED2指示灯不断闪烁当按下S1按键后数据写入到W25Q64芯片内当按下S2按键后读取W25Q64芯片的值同时串口打印出相应信息
http://www.zqtcl.cn/news/700131/

相关文章:

  • wordpress menu icon咸阳seo
  • php制作网站网站开发与客户沟通
  • 百度网站建设平台微盟微商城官网
  • 三明网站seo上海中学分数线
  • 青岛谷歌网站建设网站建站公司排名
  • 成都旅游网站建设规划windows优化大师官方
  • 福永网站建设公司哪家好财务公司承兑汇票
  • 青岛快速建站模板制作公司网页什么价位
  • 网站建设公司的经营范围wordpress设置文本编辑器
  • 做网站用微软雅黑侵权吗wordpress 同类文章
  • 免费下载建设银行官方网站自己做网站犯法吗
  • 手机网站html代码附近做广告牌的店
  • 建设和优化网站的步骤wordpress 模板 含数据库
  • 太原制作网站的工作室wordpress弹幕播放器
  • 英语网站开发菏泽做网站优化的
  • 宜昌建设网站公司做网站语言服务器 空间
  • 湖南做网站价格广州网站建设哪家便宜
  • 建筑工程素材资源网站中山做网站建设联系电话
  • 做网站关键词集团网站群建设方案
  • 网站开发有哪些课程网站开发好要租服务器吗
  • 鲜花店网站建设的规模设想网站之间的差异
  • 网站怎么在百度做推广郑州建网站
  • 机关门户网站建设顺义做网站
  • 网站开发公司东莞环球军事头条
  • 企业网站管理系统添加教程如何用python开发网页
  • 公司网站建设需要资质wordpress admin
  • 万维网网站301重定向怎么做国家城乡建设规划部网站
  • 现在的网站内容区域做多宽俄文网站开发翻译
  • 上海闵行建设局官方网站做电影网站的流程
  • 怎样做水族馆网站wordpress第三方订阅地址