前言:

咱们做嵌入式开发经常用到EEPROM,但是EEPROM的大小不同会需要不同代码来适配,这不利于快捷开发。在此本人分享自己优化总结后一段代码给大家,该代码通用读写24C02、24C16、24C32、24C64等EEPROM,只需在宏定义做相应芯片型号定义,则可使用。
注意!该代码适用于STM32F030的I2C2,如果需要用I2C1或者芯片型号是STM32F0XX其他系列的,需要做相应的驱动代码改动。


C文件代码:


/* Includes ------------------------------------------------------------------*/
#include "bs_iic.h"uint32_t AT24Cxx_Timeout;
uint8_t AT24Cxx_Address=0;
uint8_t AT24Cxx_DataNum=0;/*
主机模式
普通模式  100kHZ
I2C时钟频率32000KHz
使用模拟滤波器
不使用数字滤波器
上升时间100ns
下降时间10ns
*/
uint32_t AT24Cxx_TIMEOUT_UserCallback(void)
{/* Block communication and all processes *//*  while (1){   }*/return AT24Cxx_FAIL;
}void I2C2_Init(void)
{I2C_InitTypeDef I2C_InitStruct;GPIO_InitTypeDef GPIO_InitStructure;I2C_DeInit(I2C1);//RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK);RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
//  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_1);GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_1);RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);I2C_InitStruct.I2C_Ack=I2C_Ack_Enable;I2C_InitStruct.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit;I2C_InitStruct.I2C_AnalogFilter=I2C_AnalogFilter_Enable;I2C_InitStruct.I2C_DigitalFilter=0x00;I2C_InitStruct.I2C_Mode=I2C_Mode_I2C;I2C_InitStruct.I2C_OwnAddress1=0x00;//0x55;//I2C_InitStruct.I2C_Timing=0x30E32E44;//0x20D22E37;I2C_Init(I2C2,&I2C_InitStruct);//RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK);I2C_Cmd(I2C2, ENABLE);
}void AT24CXX_Init(void)
{I2C2_Init();AT24Cxx_Address = AT24Cxx_HW_Address;
}uint32_t AT24Cxx_WaitEepromStandbyState(void)
{__IO uint32_t sEETrials = 0;/* Configure CR2 register : set Slave Address and end mode */I2C_TransferHandling(AT24Cxx_I2C, AT24Cxx_Address,0, I2C_AutoEnd_Mode,I2C_No_StartStop);  do{ /* Initialize sEETimeout */AT24Cxx_Timeout = AT24Cxx_FLAG_TIMEOUT;/* Clear NACKF */I2C_ClearFlag(AT24Cxx_I2C, I2C_ICR_NACKCF | I2C_ICR_STOPCF);/* Generate start */I2C_GenerateSTART(AT24Cxx_I2C, ENABLE);/* Wait until timeout elapsed */while (AT24Cxx_Timeout-- != 0); /* Check if the maximum allowed numbe of trials has bee reached */if (sEETrials++ == AT24Cxx_MAX_TRIALS_NUMBER){/* If the maximum number of trials has been reached, exit the function */return AT24Cxx_TIMEOUT_UserCallback();}}while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_NACKF) != RESET);/* Clear STOPF */I2C_ClearFlag(AT24Cxx_I2C, I2C_ICR_STOPCF);/* Return sEE_OK if device is ready */return AT24Cxx_OK;
}uint32_t AT24Cxx_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t* NumByteToWrite)
{uint32_t DataNum = 0;
#if defined(AT24C04) || defined(AT24C08)|| defined(AT24C16) || defined(AT24C32)|| defined(AT24C64) I2C_TransferHandling(AT24Cxx_I2C, AT24Cxx_Address, 2, I2C_Reload_Mode, I2C_Generate_Start_Write);
#elseI2C_TransferHandling(AT24Cxx_I2C, AT24Cxx_Address, 1, I2C_Reload_Mode, I2C_Generate_Start_Write);
#endifAT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT;while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_TXIS) == RESET){if((AT24Cxx_Timeout--) == 0) {return AT24Cxx_TIMEOUT_UserCallback();}}#if defined(AT24C04) || defined(AT24C08)|| defined(AT24C16) || defined(AT24C32)|| defined(AT24C64) /* Send MSB of memory address */I2C_SendData(AT24Cxx_I2C, (uint8_t)((WriteAddr & 0xFF00) >> 8));  /* Wait until TXIS flag is set */AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT;while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_TXIS) == RESET){if((AT24Cxx_Timeout--) == 0) {return AT24Cxx_TIMEOUT_UserCallback();}}
#endif/* Send LSB of memory address  */I2C_SendData(AT24Cxx_I2C, (uint8_t)(WriteAddr & 0x00FF));/* Wait until TCR flag is set */AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT;while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_TCR) == RESET){if((AT24Cxx_Timeout--) == 0) {return AT24Cxx_TIMEOUT_UserCallback();}}/* Update CR2 : set Slave Address , set write request, generate Start and set end mode */I2C_TransferHandling(AT24Cxx_I2C, AT24Cxx_Address, (uint8_t)(*NumByteToWrite), I2C_AutoEnd_Mode, I2C_No_StartStop);while (DataNum != (*NumByteToWrite)){      /* Wait until TXIS flag is set */AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT;while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_TXIS) == RESET){if((AT24Cxx_Timeout--) == 0) {return AT24Cxx_TIMEOUT_UserCallback();}}  /* Write data to TXDR */I2C_SendData(AT24Cxx_I2C, (uint8_t)(pBuffer[DataNum]));/* Update number of transmitted data */DataNum++;   }  /* Wait until STOPF flag is set */AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT;while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_STOPF) == RESET){if((AT24Cxx_Timeout--) == 0) {return AT24Cxx_TIMEOUT_UserCallback();}}   /* Clear STOPF flag */I2C_ClearFlag(AT24Cxx_I2C, I2C_ICR_STOPCF);return AT24Cxx_OK;
}void AT24Cxx_WriteBuffer(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite)
{uint16_t NumOfPage = 0, NumOfSingle = 0, count = 0;uint16_t Addr = 0;Addr = WriteAddr % AT24Cxx_PAGESIZE;count = AT24Cxx_PAGESIZE - Addr;NumOfPage =  NumByteToWrite / AT24Cxx_PAGESIZE;NumOfSingle = NumByteToWrite % AT24Cxx_PAGESIZE;/*!< If WriteAddr is sEE_PAGESIZE aligned  */if(Addr == 0) {/*!< If NumByteToWrite < sEE_PAGESIZE */if(NumOfPage == 0) {/* Store the number of data to be written */AT24Cxx_DataNum = NumOfSingle;/* Start writing data */AT24Cxx_WritePage(pBuffer, WriteAddr, (uint8_t*)(&AT24Cxx_DataNum));AT24Cxx_WaitEepromStandbyState();}/*!< If NumByteToWrite > sEE_PAGESIZE */else  {while(NumOfPage--){/* Store the number of data to be written */AT24Cxx_DataNum = AT24Cxx_PAGESIZE;        AT24Cxx_WritePage(pBuffer, WriteAddr, (uint8_t*)(&AT24Cxx_DataNum)); AT24Cxx_WaitEepromStandbyState();WriteAddr +=  AT24Cxx_PAGESIZE;pBuffer += AT24Cxx_PAGESIZE;}if(NumOfSingle!=0){/* Store the number of data to be written */AT24Cxx_DataNum = NumOfSingle;          AT24Cxx_WritePage(pBuffer, WriteAddr, (uint8_t*)(&AT24Cxx_DataNum));AT24Cxx_WaitEepromStandbyState();}}}/*!< If WriteAddr is not sEE_PAGESIZE aligned  */else {/*!< If NumByteToWrite < sEE_PAGESIZE */if(NumOfPage== 0) {/*!< If the number of data to be written is more than the remaining space in the current page: */if (NumByteToWrite > count){/* Store the number of data to be written */AT24Cxx_DataNum = count;        /*!< Write the data conained in same page */AT24Cxx_WritePage(pBuffer, WriteAddr, (uint8_t*)(&AT24Cxx_DataNum));AT24Cxx_WaitEepromStandbyState();      /* Store the number of data to be written */AT24Cxx_DataNum = (NumByteToWrite - count);          /*!< Write the remaining data in the following page */AT24Cxx_WritePage((uint8_t*)(pBuffer + count), (WriteAddr + count), (uint8_t*)(&AT24Cxx_DataNum));AT24Cxx_WaitEepromStandbyState();        }      else      {/* Store the number of data to be written */AT24Cxx_DataNum = NumOfSingle;         AT24Cxx_WritePage(pBuffer, WriteAddr, (uint8_t*)(&AT24Cxx_DataNum));AT24Cxx_WaitEepromStandbyState();        }     }/*!< If NumByteToWrite > sEE_PAGESIZE */else{NumByteToWrite -= count;NumOfPage =  NumByteToWrite / AT24Cxx_PAGESIZE;NumOfSingle = NumByteToWrite % AT24Cxx_PAGESIZE;if(count != 0){  /* Store the number of data to be written */AT24Cxx_DataNum = count;         AT24Cxx_WritePage(pBuffer, WriteAddr, (uint8_t*)(&AT24Cxx_DataNum));AT24Cxx_WaitEepromStandbyState();WriteAddr += count;pBuffer += count;} while(NumOfPage--){/* Store the number of data to be written */AT24Cxx_DataNum = AT24Cxx_PAGESIZE;          AT24Cxx_WritePage(pBuffer, WriteAddr, (uint8_t*)(&AT24Cxx_DataNum));AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT;AT24Cxx_WaitEepromStandbyState();WriteAddr +=  AT24Cxx_PAGESIZE;pBuffer += AT24Cxx_PAGESIZE;  }if(NumOfSingle != 0){/* Store the number of data to be written */AT24Cxx_DataNum = NumOfSingle;           AT24Cxx_WritePage(pBuffer, WriteAddr, (uint8_t*)(&AT24Cxx_DataNum)); AT24Cxx_WaitEepromStandbyState();}}}
}uint32_t AT24Cxx_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead)
{  uint32_t NumbOfSingle = 0, Count = 0, DataNum = 0, StartCom = 0;/* Get number of reload cycles */Count = (*NumByteToRead) / 255;  NumbOfSingle = (*NumByteToRead) % 255;
#if defined(AT24C04) || defined(AT24C08)|| defined(AT24C16) || defined(AT24C32)|| defined(AT24C64)  /* Configure slave address, nbytes, reload and generate start */I2C_TransferHandling(AT24Cxx_I2C, AT24Cxx_Address, 2, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
#elseI2C_TransferHandling(AT24Cxx_I2C, AT24Cxx_Address, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
#endif/* Wait until TXIS flag is set */AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT;while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_TXIS) == RESET){if((AT24Cxx_Timeout--) == 0) {return AT24Cxx_TIMEOUT_UserCallback();}}#if defined(AT24C04) || defined(AT24C08)|| defined(AT24C16) || defined(AT24C32)|| defined(AT24C64)  /* Send MSB of memory address */I2C_SendData(AT24Cxx_I2C, (uint8_t)((ReadAddr & 0xFF00) >> 8));/* Wait until TXIS flag is set */AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT;  while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_TXIS) == RESET){if((AT24Cxx_Timeout--) == 0)return AT24Cxx_TIMEOUT_UserCallback();}
#endif/* Send LSB of memory address  */I2C_SendData(AT24Cxx_I2C, (uint8_t)(ReadAddr & 0x00FF));/* Wait until TC flag is set */AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT;while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_TC) == RESET){if((AT24Cxx_Timeout--) == 0) return AT24Cxx_TIMEOUT_UserCallback();}  /* If number of Reload cycles is not equal to 0 */if (Count != 0){/* Starting communication */StartCom = 1;/* Wait until all reload cycles are performed */while( Count != 0){ /* If a read transfer is performed */if (StartCom == 0)      {/* Wait until TCR flag is set */AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT; while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_TCR) == RESET){if((AT24Cxx_Timeout--) == 0) return AT24Cxx_TIMEOUT_UserCallback();}}      /* if remains one read cycle */if ((Count == 1) && (NumbOfSingle == 0)){/* if starting communication */if (StartCom != 0){/* Configure slave address, end mode and start condition */I2C_TransferHandling(AT24Cxx_I2C, AT24Cxx_Address, 255, I2C_AutoEnd_Mode, I2C_Generate_Start_Read);}else{/* Configure slave address, end mode */I2C_TransferHandling(AT24Cxx_I2C, AT24Cxx_Address, 255, I2C_AutoEnd_Mode, I2C_No_StartStop);          }}else {/* if starting communication */if (StartCom != 0){/* Configure slave address, end mode and start condition */I2C_TransferHandling(AT24Cxx_I2C, AT24Cxx_Address, 255, I2C_Reload_Mode, I2C_Generate_Start_Read);}else{/* Configure slave address, end mode */I2C_TransferHandling(AT24Cxx_I2C, AT24Cxx_Address, 255, I2C_Reload_Mode, I2C_No_StartStop);          } }/* Update local variable */StartCom = 0;      DataNum = 0;/* Wait until all data are received */while (DataNum != 255){        /* Wait until RXNE flag is set */AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT;while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_RXNE) == RESET){if((AT24Cxx_Timeout--) == 0) return AT24Cxx_TIMEOUT_UserCallback();}/* Read data from RXDR */pBuffer[DataNum]= I2C_ReceiveData(AT24Cxx_I2C);/* Update number of received data */DataNum++;(*NumByteToRead)--;}      /* Update Pointer of received buffer */ pBuffer += DataNum;  /* update number of reload cycle */Count--;}/* If number of single data is not equal to 0 */if (NumbOfSingle != 0){            /* Wait until TCR flag is set */AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT;   while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_TCR) == RESET){if((AT24Cxx_Timeout--) == 0) return AT24Cxx_TIMEOUT_UserCallback();}/* Update CR2 : set Nbytes and end mode */I2C_TransferHandling(AT24Cxx_I2C, AT24Cxx_Address, (uint8_t)(NumbOfSingle), I2C_AutoEnd_Mode, I2C_No_StartStop);/* Reset local variable */DataNum = 0;/* Wait until all data are received */while (DataNum != NumbOfSingle){        /* Wait until RXNE flag is set */AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT;while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_RXNE) == RESET){if((AT24Cxx_Timeout--) == 0) return AT24Cxx_TIMEOUT_UserCallback();}/* Read data from RXDR */pBuffer[DataNum]= I2C_ReceiveData(AT24Cxx_I2C);/* Update number of received data */DataNum++;(*NumByteToRead)--;} }}   else{/* Update CR2 : set Slave Address , set read request, generate Start and set end mode */I2C_TransferHandling(AT24Cxx_I2C, AT24Cxx_Address, (uint32_t)(NumbOfSingle), I2C_AutoEnd_Mode, I2C_Generate_Start_Read);/* Reset local variable */DataNum = 0;/* Wait until all data are received */while (DataNum != NumbOfSingle){/* Wait until RXNE flag is set */AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT; while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_RXNE) == RESET){if((AT24Cxx_Timeout--) == 0) return AT24Cxx_TIMEOUT_UserCallback();}/* Read data from RXDR */pBuffer[DataNum]= I2C_ReceiveData(AT24Cxx_I2C);/* Update number of received data */DataNum++;(*NumByteToRead)--;}    }  /* Wait until STOPF flag is set */AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT;while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_STOPF) == RESET){if((AT24Cxx_Timeout--) == 0) return AT24Cxx_TIMEOUT_UserCallback();}/* Clear STOPF flag */I2C_ClearFlag(AT24Cxx_I2C, I2C_ICR_STOPCF);/* If all operations OK, return sEE_OK (0) */return AT24Cxx_OK;
}/************************ (C) COPYRIGHT LKL0305 ****************END OF FILE****/

H文件代码:

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __BS_I2C_H
#define __BS_I2C_H/* Includes ------------------------------------------------------------------*/
#include "stm32f0xx.h"#define AT24Cxx_FLAG_TIMEOUT         ((uint32_t)0x2000)
#define AT24Cxx_LONG_TIMEOUT         ((uint32_t)(10 * AT24Cxx_FLAG_TIMEOUT))#define AT24Cxx_MAX_TRIALS_NUMBER     300#define AT24Cxx_OK                    0
#define AT24Cxx_FAIL                  1
#define AT24Cxx_I2C                   I2C2//AT24C01 AT24C02           一页  8Byte
//AT24C04 AT24C08 AT24C16   一页  16Byte
//AT24C32 AT24C64           一页  32Byte
//-------注意!!!本代码只适用24C64及以下的EEPROM ,大于8K的ROM不能使用此代码--------------
#define AT24C02   //定义你使用的芯片型号#if defined(AT24C01) || defined(AT24C02)#define AT24Cxx_PAGESIZE              8
#elif defined(AT24C04) || defined(AT24C08)|| defined(AT24C16) #define AT24Cxx_PAGESIZE              16
#else#define AT24Cxx_PAGESIZE              32
#endif#define AT24Cxx_HW_Address            0xAE//0xA0  这个注意对应你的硬件地址!!!!extern void AT24CXX_Init(void);
extern void AT24Cxx_WriteBuffer(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite);
extern uint32_t AT24Cxx_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead);#endif

主程序代码:

#include "stm32f0xx.h"
#include "bs_iic.h"int main(void)
{//app_run();//-----------IIC2-测试代码-----uint8_t read_b[64]={0};uint8_t wirte_b[64]={1,2,3,4,4,4,8,5,22,66,88,77};AT24CXX_Init();while(1){uint16_t r_num=10;uint16_t w_num=10;AT24Cxx_ReadBuffer(read_b,0,&r_num);//注意!这里num在读取数据后减少对应长度AT24Cxx_WriteBuffer(wirte_b,0,w_num);if(wirte_b[0]<250)wirte_b[0]++;elsewirte_b[0]=0;}}

STM32F030 IIC2通用读写24C02、24C16、24C32、24C64等例程相关推荐

  1. fm24c16c语言程序,单片机读写24C01~24C16程序

    单片机读写24C01~24C16程序,24C02 read / write process 关键字:单片机读写24C01~24C16程序 单片机读写24C01~24C16程序 AT89S52 晶振频率 ...

  2. STM32CubeMX(5)——IIC读写24c02

    0.序 我用的一个PCA9536老是出问题,怀疑是IIC应答或者停止位出问题了,所以特地来仔细看看IIC的原理和操作. (已经排除软件问题,是硬件电路问题) 本文使用软件模拟IIC,没有使用硬件自带I ...

  3. 16F877A和24C02通信汇编语言,PIC16f877A读写24c02程序

    PIC16f877A读写24c02程序 来源:-- 作者:-- 浏览:389 时间:2016-08-10 14:18 标签: 摘要: PIC16f877A读写24c02程序 #include  #in ...

  4. 单片机flash通用读写库:TZFlash

    单片机flash通用读写库:TZFlash 本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明. 说明 本文发布单片机flash通用读写库TZFlash,有两 ...

  5. spi flash通用读写软IP

    spi flash通用读写模块,有两个模块,分别为spiflash控制模块和spi控制模块 spiflash控制模块RTL代码如下: //功能描述 //这是一个spiflash的控制程序 //写选择( ...

  6. 24C16 与24C64系列 存储器的区别

    在偶然一次情况下发现24C16的程序无法读写24C64,经过观察发现24C64的读写时序与24C16存在区别.区别在于24C16发送的地址是一个8位的,然后24C64需要的地址是一个16位的,发现这个 ...

  7. 【STM32CubeMX学习】I2C读写24C02

    目录 1.I2C总线 2.I2C驱动编写 3.24C02 4.EEPROM读写函数编写 5.验证 1.I2C总线 I2C总线有两根线:时钟线SCL.数据线SDA,当总线空闲时,两根线都处于高电平. I ...

  8. 24c02 汇编语言,单片机读写24C02的汇编程序

    ;简洁的24C02读写汇编程序 ;-------------------------------------------- I2C_SDA          EQU P1.6   ; PIN 5 I2 ...

  9. STM32读写24C02遇到的问题

    这几天在弄I2C,读取24C02的数据.我默默的敲完了代码,然后仿真. 代码就下面两行,就是写一个字节,然后读取. I2C_EE_BufferWrite( &write,100, 1); I2 ...

最新文章

  1. UVA 11235 Frequent values(RMQ)
  2. linux man命令_CentOS Linux中的man命令
  3. python实现多语言语种识别_用Python进行语言检测
  4. findler mac 隐藏文件_fiddler使用实例之----------查找隐藏的真实地址!!!!
  5. 用Prim和Kruskal两种算法,求解最小生成树
  6. 一行Python代码统计词频
  7. linux系统下部署go语言环境
  8. [原创] Wireshark工具培训
  9. Highcharts使用=====通过指定日期显示曲线
  10. snoopy php https_php使用snoopy与curl模拟登陆的实例分享
  11. httpclient4.X 设置代理请求(包含账号密码)
  12. 6.无线射频基础知识介绍_无线射频工作原理
  13. windows embed sapi php,19.1 嵌入式SAPI
  14. 八键电话号码的字母组合
  15. 【Angular4】constructor ngOnInit
  16. php中Sessionopen,php使用session提示[function.session-start]: open解决方法
  17. 2021年上海第一批高新技术企业上海熙有网络科技集团榜上有名
  18. 函数极限的24种定义
  19. 利用U盘PE系统修复win7系统的启动引导文件
  20. echarts绘制3D地图

热门文章

  1. G1D17-研究方向rce45-49不快乐就去敲敲代码
  2. Memory Analyzer Tool 1 Shallow heap Retained heap dominator tree(控制树)
  3. SISR深度学习主要方法简述
  4. WIFI AP和STATION
  5. 小区宽带不能上网的解决办法
  6. linux内核网络TIME_WAIT
  7. Android Studio使用技巧系列教程(二)
  8. [C++11 多线程同步] --- 线程同步概述
  9. datastage 如何把db2的varchar列数据抽取到mysql的longtext列
  10. 第五章 全连接神经网络