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

荆州建设网站网店名字创意

荆州建设网站,网店名字创意,深圳网站建设维护,霸县网站建设目录 基础知识回顾#xff1a; SPI外设简介 SPI框图 主模式全双工连续传输 非连续传输 初始化SPI外设 核心代码 - 交换一个字节 硬件接线图 Code 程序配置过程 MySPI.c MySPI.h W25Q64.c W25Q64.h W25Q64_Ins.h main.c 基础知识回顾#xff1a; 【STM32】SP…目录 基础知识回顾 SPI外设简介 SPI框图 主模式全双工连续传输 非连续传输 初始化SPI外设 核心代码 - 交换一个字节 硬件接线图 Code 程序配置过程 MySPI.c MySPI.h W25Q64.c W25Q64.h W25Q64_Ins.h main.c 基础知识回顾 【STM32】SPI通信 【STM32】软件SPI读写W25Q64芯片 学习视频【STM32入门教程-2023版 细致讲解 中文字幕】 https://www.bilibili.com/video/BV1th411z7sn/?p39share_sourcecopy_webvd_source8af85e60c2df9af1f0fd23935753a933 SPI外设简介 STM32内部集成了硬件SPI收发电路可以由硬件自动执行时钟生成、数据收发等功能减轻CPU的负担可配置8位/16位数据帧、高位先行/低位先行时钟频率 fPCLK / (2, 4, 8, 16, 32, 64, 128, 256)支持多主机模型、主或从操作可精简为半双工/单工通信支持DMA兼容I2S协议音频STM32F103C8T6硬件SPI资源SPI1APB2、SPI2APB1 SPI框图 简化结构 TDR数据整体转入移位寄存器的时刻置TXE标志位移位寄存器数据整体转入RDR的时刻置RXNE标志位 TDR、RDR、TXE、RXNE几个关键词 主模式全双工连续传输 非连续传输 非连续传输的整体步骤 第一个字节 等待TXE为1写入发送的数据至TDR等待RXNE为1读取RDR接收的数据交换下一个字节重复上述4步骤 第二个字节 等待TXE为1写入发送的数据至TDR等待RXNE为1读取RDR接收的数据交换下一个字节重复上述4步骤 第...个字节 …… 我们可以将标红的4步骤封装成一个函数每调用一次就交换一个字节妙哉~妙哉~ 初始化SPI外设 讲解看注释即可 /*** 函 数SPI初始化* 参 数无* 返 回 值无* 注意事项此函数需要用户实现内容实现SS、SCK、MOSI和MISO引脚的初始化*/ void MySPI_Init(void) {/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); //开启SPI1的时钟 /*GPIO初始化*///SS PA4 从机选择引脚GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP; //推挽输出GPIO_InitStructure.GPIO_Pin GPIO_Pin_4;GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOA, GPIO_InitStructure); //将PA4引脚初始化为推挽输出//SCK GPIO_Pin_5、MOSI GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP; //复用推挽输出GPIO_InitStructure.GPIO_Pin GPIO_Pin_5 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOA, GPIO_InitStructure); //将PA5、PA7引脚初始化为复用推挽输出//MISO PA6 上拉输入 GPIO_InitStructure.GPIO_Mode GPIO_Mode_IPU; //上拉输入GPIO_InitStructure.GPIO_Pin GPIO_Pin_6 ;GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOA, GPIO_InitStructure); //将PA6引脚初始化为上拉输入/*初始化SPI外设*/SPI_InitTypeDef SPI_InitStructure;SPI_InitStructure.SPI_Mode SPI_Mode_Master; //主机SPI_InitStructure.SPI_Direction SPI_Direction_2Lines_FullDuplex; //双线全双工模式SPI_InitStructure.SPI_DataSize SPI_DataSize_8b; //8位数据帧SPI_InitStructure.SPI_FirstBit SPI_FirstBit_MSB; //高位先行SPI_InitStructure.SPI_BaudRatePrescaler SPI_BaudRatePrescaler_128; //波特率预分频器目前时钟频率 72MHz/128 562.5KHz如果是SPI2的外设就是用36M/128SPI_InitStructure.SPI_CPOL SPI_CPOL_Low; //模式0CPOL时钟极性空闲默认低电平SPI_InitStructure.SPI_CPHA SPI_CPHA_1Edge;//时钟相位选择1Edge就是CPHA0第一个边沿采样SPI_InitStructure.SPI_NSS SPI_NSS_Soft; //外设的NSS引脚一般用不到所以就选软件模式SPI_InitStructure.SPI_CRCPolynomial 7; //CRC校验的多项式我们用不到就填默认值7SPI_Init(SPI1, SPI_InitStructure);//使能SPI外设SPI_Cmd(SPI1, ENABLE);// /*设置默认电平*/MySPI_W_SS(1); // SS置高, 默认不选中从机 // MySPI_W_SCK(0); // 计划使用模式0, 默认低电平 // MOSI 没有明确规定MISO是输入引脚不用输出电平状态} 核心代码 - 交换一个字节 /*** 函 数SPI交换传输一个字节使用SPI模式0* 参 数ByteSend 要发送的一个字节* 返 回 值接收的一个字节*/ uint8_t MySPI_SwapByte(uint8_t ByteSend) {while ( SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) ! SET ); //等待TXE为1SPI_I2S_SendData(SPI1, ByteSend); //ByteSend写入到TDR寄存器之后自动转入移位寄存器一旦寄存器有数据了时序波形自动产生while ( SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) ! SET ); //等待RXNE1表示收到一个字节也表示发送时序产生完成return SPI_I2S_ReceiveData(SPI1); //读取RDR }硬件接线图 硬件接线和上一篇文章相同 SPI相关库函数 void SPI_I2S_DeInit(SPI_TypeDef* SPIx); void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct); void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState); void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState); void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState); void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data); uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx); void SPI_DataSizeConfig(SPI_TypeDef* SPIx, uint16_t SPI_DataSize);FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG); void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLyinAG); ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT); void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT); Code 代码只需要再上一篇文章稍作修改即可 W25Q64的C文件和H文件内容都没有变只修改了MySPI.c文件 根据上述非连续传输的步骤编写代码废话就不讲了直接看代码注释 程序配置过程 ①配置相关引脚的复用功能使能SPIx时钟 void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct); ②初始化SPIx,设置SPIx工作模式 void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct); ③使能SPIx void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState); ④SPI传输数据 void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data); uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx) ; ⑤查看SPI传输状态 SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) ————————————————                             版权声明本文为博主原创文章遵循 CC 4.0 BY-SA 版权协议转载请附上原文出处链接和本声明。                          原文链接https://blog.csdn.net/weixin_53762042/article/details/117134887 MySPI.c #include MySPI.h/*引脚配置层*/ /*硬件SPI*//*** 函 数SPI写SS引脚电平* 参 数BitValue 协议层传入的当前需要写入SS的电平范围0~1* 返 回 值无* 注意事项此函数需要用户实现内容当BitValue为0时需要置SS为低电平当BitValue为1时需要置SS为高电平*/ void MySPI_W_SS(uint8_t BitValue) //CS引脚(SS引脚)PA4从机选择引脚还是用软件模拟的 {GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)BitValue); //根据BitValue设置SS引脚的电平 }// SPI速度非常快操作完引脚就不需要加延时了/*输出引脚配置为推挽输出输入引脚配置为浮空或上拉输入对主机来说时钟、主机输出、片选都是输出引脚---推挽输出主机输入MISO---输出引脚---选择上拉输入 从机(W25Q64)的DO输出是主机输入---PA6 */ /*** 函 数SPI初始化* 参 数无* 返 回 值无* 注意事项此函数需要用户实现内容实现SS、SCK、MOSI和MISO引脚的初始化*/ void MySPI_Init(void) {/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); //开启SPI1的时钟 /*GPIO初始化*///SS PA4 从机选择引脚GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP; //推挽输出GPIO_InitStructure.GPIO_Pin GPIO_Pin_4;GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOA, GPIO_InitStructure); //将PA4引脚初始化为推挽输出//SCK GPIO_Pin_5、MOSI GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP; //复用推挽输出GPIO_InitStructure.GPIO_Pin GPIO_Pin_5 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOA, GPIO_InitStructure); //将PA5、PA7引脚初始化为复用推挽输出//MISO PA6 上拉输入 GPIO_InitStructure.GPIO_Mode GPIO_Mode_IPU; //上拉输入GPIO_InitStructure.GPIO_Pin GPIO_Pin_6 ;GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOA, GPIO_InitStructure); //将PA6引脚初始化为上拉输入/*初始化SPI外设*/SPI_InitTypeDef SPI_InitStructure;SPI_InitStructure.SPI_Mode SPI_Mode_Master; //主机SPI_InitStructure.SPI_Direction SPI_Direction_2Lines_FullDuplex; //双线全双工模式SPI_InitStructure.SPI_DataSize SPI_DataSize_8b; //8位数据帧SPI_InitStructure.SPI_FirstBit SPI_FirstBit_MSB; //高位先行SPI_InitStructure.SPI_BaudRatePrescaler SPI_BaudRatePrescaler_128; //波特率预分频器目前时钟频率 72MHz/128 562.5KHz如果是SPI2的外设就是用36M/128SPI_InitStructure.SPI_CPOL SPI_CPOL_Low; //模式0CPOL时钟极性空闲默认低电平SPI_InitStructure.SPI_CPHA SPI_CPHA_1Edge;//时钟相位选择1Edge就是CPHA0第一个边沿采样SPI_InitStructure.SPI_NSS SPI_NSS_Soft; //外设的NSS引脚一般用不到所以就选软件模式SPI_InitStructure.SPI_CRCPolynomial 7; //CRC校验的多项式我们用不到就填默认值7SPI_Init(SPI1, SPI_InitStructure);//使能SPI外设SPI_Cmd(SPI1, ENABLE);// /*设置默认电平*/MySPI_W_SS(1); // SS置高, 默认不选中从机 // MySPI_W_SCK(0); // 计划使用模式0, 默认低电平 // MOSI 没有明确规定MISO是输入引脚不用输出电平状态}/*协议层*//*** 函 数SPI起始* 参 数无* 返 回 值无*/ void MySPI_Start(void) {MySPI_W_SS(0); //拉低SS开始时序 }/*** 函 数SPI终止* 参 数无* 返 回 值无*/ void MySPI_Stop(void) {MySPI_W_SS(1); //拉高SS终止时序 }//交换一个字节(读写一个字节)W25Q64系列支持模式0和模式3 //这里选择模式0 //ByteSend是传进来的参数通过交换一个字节发送出去接受 //硬件SPI - 发送同时接收 /*** 函 数SPI交换传输一个字节使用SPI模式0* 参 数ByteSend 要发送的一个字节* 返 回 值接收的一个字节*/ uint8_t MySPI_SwapByte(uint8_t ByteSend) {while ( SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) ! SET ); //等待TXE为1SPI_I2S_SendData(SPI1, ByteSend); //ByteSend写入到TDR寄存器之后自动转入移位寄存器一旦寄存器有数据了时序波形自动产生while ( SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) ! SET ); //等待RXNE1表示收到一个字节也表示发送时序产生完成return SPI_I2S_ReceiveData(SPI1); //读取RDR }MySPI.h #ifndef __MYSPI_H__ #define __MYSPI_H__#include stm32f10x.h // Device headervoid MySPI_Init(void); void MySPI_Start(void); void MySPI_Stop(void); uint8_t MySPI_SwapByte(uint8_t ByteSend);#endifW25Q64.c #include W25Q64.hvoid W25Q64_Init(void) {MySPI_Init(); }/*读取ID第一个字节厂商ID。设备ID第二个字节存储器类型第三个字节容量*/ /*** 函 数W25Q64读取ID号* 参 数MID 工厂ID使用输出参数的形式返回* 参 数DID 设备ID使用输出参数的形式返回* 返 回 值无*/ void W25Q64_ReadID(uint8_t *MID, uint16_t *DID) {MySPI_Start();MySPI_SwapByte(W25Q64_JEDEC_ID); // 0x9F, 读取ID号码指令这里的返回值没有意义就不需要了*MID MySPI_SwapByte(W25Q64_DUMMY_BYTE); // 这次交换把数据给主机接收的数据是厂商ID变量*MID发送的数据任意给一般给0xFF// 这里是在通信通信是有时序的不同时间调用相同的函数意义就是不一样的*DID MySPI_SwapByte(W25Q64_DUMMY_BYTE); // 设备ID的高八位第三次交换*DID 8; // 高八位移到左边*DID | MySPI_SwapByte(W25Q64_DUMMY_BYTE); // 设备ID的低八位(用或运算整合数据)MySPI_Stop(); }/*** 函 数W25Q64写使能* 参 数无* 返 回 值无*/ void W25Q64_WriteEnable(void) {MySPI_Start(); //SPI起始MySPI_SwapByte(W25Q64_WRITE_ENABLE); //交换发送 写使能的指令MySPI_Stop(); //SPI终止 }// 发送指令码05发完指令码读取状态寄存器查看是否是忙状态最低位BUSY1是忙0是不忙 /*** 函 数W25Q64等待忙* 参 数无* 返 回 值无*/ void W25Q64_WaitBusy(void) // 等待busy位为0 {uint32_t Timeout;MySPI_Start(); //SPI起始MySPI_SwapByte(W25Q64_READ_STATUS_REGISTER_1); //交换发送读状态寄存器1的指令Timeout 100000; //给定超时计数时间while ((MySPI_SwapByte(W25Q64_DUMMY_BYTE) 0x01) 0x01) //循环等待忙标志位{Timeout --; //等待时计数值自减if (Timeout 0) //自减到0后等待超时{/*超时的错误处理代码可以添加到此处*/break; //跳出等待不等了}}MySPI_Stop(); //SPI终止 } /*注意W25Q64_WaitBusy,事前等待事后等待事后等待只需要再写入操作前调用事前等待在写入操作和读取操作之前都得调用 *//*** 函 数W25Q64页编程* 参 数Address 页编程的起始地址范围0x000000~0x7FFFFF* 参 数DataArray 用于写入数据的数组指针传递数组* 参 数Count 要写入数据的数量范围0~256* 返 回 值无* 注意事项写入的地址范围不能跨页*/ void W25Q64_PageProgram(uint32_t Address, uint8_t *DataArray, uint16_t Count) {uint16_t i;W25Q64_WriteEnable(); //写入操作前必须先写使能MySPI_Start(); //SPI起始MySPI_SwapByte(W25Q64_PAGE_PROGRAM); //交换发送页编程的指令MySPI_SwapByte(Address 16); //交换发送地址23~16位MySPI_SwapByte(Address 8); //交换发送地址15~8位MySPI_SwapByte(Address); //交换发送地址7~0位for (i 0; i Count; i ) //循环Count次{MySPI_SwapByte(DataArray[i]); //依次在起始地址后写入数据}MySPI_Stop(); //SPI终止W25Q64_WaitBusy(); //等待忙事后等待比较保险 }/*** 函 数W25Q64扇区擦除4KB* 参 数Address 指定扇区的地址范围0x000000~0x7FFFFF* 返 回 值无*/ void W25Q64_SectorErase(uint32_t Address) {W25Q64_WriteEnable(); //写使能MySPI_Start(); //SPI起始MySPI_SwapByte(W25Q64_SECTOR_ERASE_4KB); //交换发送扇区擦除的指令MySPI_SwapByte(Address 16); //交换发送地址23~16位MySPI_SwapByte(Address 8); //交换发送地址15~8位MySPI_SwapByte(Address); //交换发送地址7~0位MySPI_Stop(); //SPI终止W25Q64_WaitBusy(); //等待忙不忙就退出这个函数了 }/*** 函 数W25Q64读取数据* 参 数Address 读取数据的起始地址范围0x000000~0x7FFFFF* 参 数DataArray 用于接收读取数据的数组通过输出参数返回* 参 数Count 要读取数据的数量范围0~0x800000* 返 回 值无*/ void W25Q64_ReadData(uint32_t Address, uint8_t *DataArray, uint32_t Count) {uint32_t i;MySPI_Start(); //SPI起始MySPI_SwapByte(W25Q64_READ_DATA); //交换发送读取数据的指令MySPI_SwapByte(Address 16); //交换发送地址23~16位MySPI_SwapByte(Address 8); //交换发送地址15~8位MySPI_SwapByte(Address); //交换发送地址7~0位for (i 0; i Count; i ) //循环Count次{DataArray[i] MySPI_SwapByte(W25Q64_DUMMY_BYTE); //依次在起始地址后读取数据}MySPI_Stop(); //SPI终止 } W25Q64.h #ifndef __W25Q64_H__ #define __W25Q64_H__#include stm32f10x.h // Device header #include MySPI.h #include W25Q64_Ins.h //指令的头文件void W25Q64_Init(void); void W25Q64_ReadID(uint8_t *MID, uint16_t *DID); void W25Q64_PageProgram(uint32_t Address, uint8_t *DataArray, uint16_t Count); void W25Q64_SectorErase(uint32_t Address); void W25Q64_ReadData(uint32_t Address, uint8_t *DataArray, uint32_t Count);#endif W25Q64_Ins.h #ifndef __W25Q64_INS_H #define __W25Q64_INS_H#define W25Q64_WRITE_ENABLE 0x06 //写使能 #define W25Q64_WRITE_DISABLE 0x04 //写失能 #define W25Q64_READ_STATUS_REGISTER_1 0x05 //读状态寄存器1 #define W25Q64_READ_STATUS_REGISTER_2 0x35 #define W25Q64_WRITE_STATUS_REGISTER 0x01 #define W25Q64_PAGE_PROGRAM 0x02 //页编程 #define W25Q64_QUAD_PAGE_PROGRAM 0x32 #define W25Q64_BLOCK_ERASE_64KB 0xD8 #define W25Q64_BLOCK_ERASE_32KB 0x52 #define W25Q64_SECTOR_ERASE_4KB 0x20 //扇区擦除 #define W25Q64_CHIP_ERASE 0xC7 #define W25Q64_ERASE_SUSPEND 0x75 #define W25Q64_ERASE_RESUME 0x7A #define W25Q64_POWER_DOWN 0xB9 #define W25Q64_HIGH_PERFORMANCE_MODE 0xA3 #define W25Q64_CONTINUOUS_READ_MODE_RESET 0xFF #define W25Q64_RELEASE_POWER_DOWN_HPM_DEVICE_ID 0xAB #define W25Q64_MANUFACTURER_DEVICE_ID 0x90 #define W25Q64_READ_UNIQUE_ID 0x4B #define W25Q64_JEDEC_ID 0x9F //读取ID号 #define W25Q64_READ_DATA 0x03 #define W25Q64_FAST_READ 0x0B #define W25Q64_FAST_READ_DUAL_OUTPUT 0x3B #define W25Q64_FAST_READ_DUAL_IO 0xBB #define W25Q64_FAST_READ_QUAD_OUTPUT 0x6B #define W25Q64_FAST_READ_QUAD_IO 0xEB #define W25Q64_OCTAL_WORD_READ_QUAD_IO 0xE3#define W25Q64_DUMMY_BYTE 0xFF //无用数据#endif main.c #include stm32f10x.h // Device header #include Delay.h #include OLED.h #include W25Q64.huint8_t MID; uint16_t DID;uint8_t ArrayWrite[] {0x01, 0x02, 0x03, 0x04}; //定义要写入数据的测试数组 //uint8_t ArrayWrite[] {0x11, 0x22, 0x33, 0x44}; //定义要写入数据的测试数组 uint8_t ArrayRead[4]; //定义要读取数据的测试数组int main(void) {/*模块初始化*/OLED_Init(); //OLED初始化W25Q64_Init(); //W25Q64初始化/*显示静态字符串*/OLED_ShowString(1, 1, MID: DID:);OLED_ShowString(2, 1, W:);OLED_ShowString(3, 1, R:);/*显示ID号*/W25Q64_ReadID(MID, DID); //获取W25Q64的ID号指针 返回输出参数OLED_ShowHexNum(1, 5, MID, 2); //显示MID显示厂商IDOLED_ShowHexNum(1, 12, DID, 4); //显示DID显示设备ID/*W25Q64功能函数测试*/W25Q64_SectorErase(0x000000); //扇区擦除写之前先进行扇区擦除操作W25Q64_PageProgram(0x000000, ArrayWrite, 4); //将写入数据的测试数组写入到W25Q64中W25Q64_ReadData(0x000000, ArrayRead, 4); //读取刚写入的测试数据到读取数据的测试数组中/*显示数据*/OLED_ShowHexNum(2, 3, ArrayWrite[0], 2); //显示写入数据的测试数组OLED_ShowHexNum(2, 6, ArrayWrite[1], 2);OLED_ShowHexNum(2, 9, ArrayWrite[2], 2);OLED_ShowHexNum(2, 12, ArrayWrite[3], 2);OLED_ShowHexNum(3, 3, ArrayRead[0], 2); //显示读取数据的测试数组OLED_ShowHexNum(3, 6, ArrayRead[1], 2);OLED_ShowHexNum(3, 9, ArrayRead[2], 2);OLED_ShowHexNum(3, 12, ArrayRead[3], 2);while (1){} } 烧录代码测试OLED显示写入数据和读出数据一致~ 还可以参考上一篇文章的测试步骤一一尝试  参考测试的文章 【STM32】软件SPI读写W25Q64芯片 原创笔记码字不易欢迎点赞收藏~
http://www.zqtcl.cn/news/214719/

相关文章:

  • 网站建设 更新 维护淮北矿业工程建设公司网站
  • 网站开发 平台宝应做网站
  • 网站开发开题报告广州的兼职网站建设
  • 辽宁同鑫建设网站网站后期维护费用
  • 政法网站建设有哪些不足广州网站建设信息科技有限公司
  • 营销型网站 平台海口智能建站价格
  • 网站空间过期电商网站建设比较好的
  • seo公司 彼亿营销舆情优化公司
  • diango是做网站的后端吗网页怎么做成app
  • 思勤传媒网站建设公司如何查询网站的外链
  • 网站设计思路文案范文专业手机网站建设多少钱
  • 有部分网站打不开网站服务内容怎么写
  • 百度安全网站检测好看的免费的小说网站模板
  • 锡山区住房和城乡建设局网站免费ppt模板下载简约
  • 建设银行 杭州招聘网站建设工程有限公司是干什么的
  • 做网站必须购买空间吗?3点新闻发布
  • 济南集团网站建设流程东莞做网站公司首选
  • 有需要做网站推广找我网站怎么 备案
  • 怎么把网站放到服务器上站长工具seo综合查询外部链接数量
  • 做网站上市的公司开一家公司最低注册资金
  • 仙居谁认识做网站的有哪些好的网站建设
  • 互动广告机网站建设怀集网站建设
  • 好的 做网站的软件公司pinterest app下载
  • 公司网站报价邯郸软件定制
  • 产品毕业设计代做网站资料库网站源码
  • 交易类网站做支付宝功能建设银行网站收款怎么打明细
  • 广州找人做网站做网站网关备案
  • 网站的布局方式有哪些内容免费ppt模板下载公众号
  • 色91Av做爰网站获胜者网站建设
  • 企业做网站要多少钱简单网页设计模板网站