STM32——EEPROM

STM32——EEPROM


宗旨:技术的学习是有限的,分享的精神是无限的。


一、I2C接口读写EEPROMAT24C02

       ——主模式,分别用作主发送器和主接收器。通过查询事件的方式来确保正常通信。

1I 2C接口初始化

        与其他对GPIO 复用的外设一样,它先调用了用户函数I2C_GPIO_Confi g() 配置好 I 2 C 所用的 I/O端口,然后再调用用户函数 I2C_Mode_Confi gu() 设置 I 2 C 的工作模式,并使能相关外设的时钟。

void I2C_EE_Init(void)
{I2C_GPIO_Config();I2C_Mode_Config();/* 根据头文件 i2c_ee.  14 h 中的定义来选择 EEPROM 要写入的地址 */
#ifdef EEPROM_Block0_ADDRESS /* 选择 EEPROM Block0 来写入 */EEPROM_ADDRESS = EEPROM_Block0_ADDRESS;
#endif
#ifdef EEPROM_Block1_ADDRESS  /* 选择 EEPROM Block1 来写入 */EEPROM_ADDRESS = EEPROM_Block1_ADDRESS;
#endif
#ifdef EEPROM_Block2_ADDRESS  /* 选择 EEPROM Block2 来写入 */EEPROM_ADDRESS = EEPROM_Block2_ADDRESS;
#endif
#ifdef EEPROM_Block3_ADDRESS  /* 选择 EEPROM Block3 来写入 */EEPROM_ADDRESS = EEPROM_Block3_ADDRESS;
#endif
}

1)EEPROM地址

        AT24C02:256字节,高四位硬性规定,最低位是R/W(传输方向选择位),在制作硬件时,我们可以根据需要改变的是地址位中的 A2、A1、A0 位。原理图上面全接地,所以它的地址为 :0xA0 或 0xA1。

2GPIO端口初始化

static void I2C_GPIO_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;/* 使能与 I2C1 有关的时钟 */RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);/*  配置SCL SDA引脚速率输出方式 */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;  // 开漏输出GPIO_Init(GPIOB, &GPIO_InitStructure);
}


3I2C模式初始化

typedef struct
{uint32_t I2C_ClockSpeed;uint16_t I2C_Mode;uint16_t I2C_DutyCycle;uint16_t I2C_OwnAddress1;uint16_t I2C_Ack;uint16_t I2C_AcknowledgedAddress;
} I2C_InitTypeDef;

1I2C_Mode本成员是选择 I 2 C 的使用方式,有 I 2 C 模式(I2C_Mode_I2C)和SMBus 模式。(I2C_Mode_SMBusDevice、I2C_Mode_SMBusHost)

2I2C_DutyCycle设置的是 I 2 C 的 SCL 线时钟的占空比。在 STM32 的 I 2 C 占空比配置中有两个选择,分别为高电平时间和低电平时间之比为16 :9 (I2C_DutyCycle_16_9)和 2 :1( I2C_DutyCycle_2)。

3I2C_OwnAddress1本 成 员 配 置 的 是 STM32 的 I 2 C 设 备 自 己 的 地 址, 每个 连 接 到 I 2 C 总线上的设备都要有一个自己的地址,作为主机也不例外。这个地址可以被配置为 7 位和 10 位地址。我们把这个地址设置为 0x0A (自定义宏I2C1_OWN_ADDRESS7 的值)。

4I2C_Ack_Enable本成员关于 I 2 C 应答设置,设置为使能则每接收到一个字节就返回一个应答信号。配置为允许应答(I2C_Ack_Enable),这是绝大多数遵循 I 2 C标准的设备通信的要求,改为禁止应答 (I2C_Ack_Disable)往往会导致通信错误。

5I2C_AcknowledgeAddress本成员选择 I 2 C 的寻址模式是 7 位还是 10 位地址。这需要根据实际连接到 I 2C 总线上设备的地址进行选择。与 EEPROM 进行通信,使用的为 7 位寻址模式(I2C_AcknowledgedAddress_7bit)。

6I2C_ClockSpeed本成员设置的是 I 2 C 的传输速率,在调用初始化函数时,函数会根据我们输入的数值经过运算后把分频值写入到 I 2 C 的时钟控制寄存器。而我们写入的这个参数值不得高于 400 kHz。——400000

对结构体成员赋值完成后,我们调用库函数 I2C_Init() 根据我们的配置对 I 2 C 进行初始化, 并调用库函数 I2C_Cmd() 使能I 2 C 外设。 

static void I2C_Mode_Configu(void)
{I2C_InitTypeDef I2C_InitStructure;I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;  /* I2C 配置 */I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;  /* 高电平数据稳定,低电平数据变化 SCL  时钟线的占空比 */I2C_InitStructure.I2C_OwnAddress1 = I2C1_OWN_ADDRESS7;I2C_InitStructure.I2C_Ack = I2C_Ack_Enable ;I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;  /* I2C 的寻址模式 */I2C_InitStructure.I2C_ClockSpeed = I2C_Speed;  /* 通信速率 */I2C_Init(I2C1, &I2C_InitStructure);  /* I2C1 初始化 */I2C_Cmd(I2C1, ENABLE);  /* 使能 I2C1 */
}

二、对EEPROM的读写操作

void I2C_Test(void)
{u16 i;printf("写入的数据\n\r");for ( i = 0; i <= 255; i++ ) //填充缓冲{I2c_Buf_Write[i] = i;printf("0x%02X ", I2c_Buf_Write[i]);if (i % 16 == 15){printf("\n\r");}}I2C_EE_BufferWrite( I2c_Buf_Write, EEP_Firstpage, 256);  //将 I2c_Buf_Write 中顺序递增的数据写入 EERPOM 中printf("\n\r 写成功\n\r");printf("\n\r 读出的数据\n\r");I2C_EE_BufferRead(I2c_Buf_Read, EEP_Firstpage, 256);  //将 EEPROM 读出数据顺序保持到 I2c_Buf_Read 中//将 I2c_Buf_Read 中的数据通过串口打印for (i = 0; i < 256; i++){if (I2c_Buf_Read[i] != I2c_Buf_Write[i]){printf("0x%02X ", I2c_Buf_Read[i]);printf("错误:I2C EEPROM 写入与读出的数据不一致\n\r");return;}printf("0x%02X ", I2c_Buf_Read[i]);if (i % 16 == 15){printf("\n\r");}}printf("I2C(AT24C02)读写测试成功\n\r");
}

        功能是把数值 0 ~ 255 按顺序填入缓冲区数组,并通过串口打印到终端,接着通过用户函数I2C_EE_BufferWrite()把缓冲区的数据写入EEPROM。写入成功之后,利用用户函数 I2C_EE_BufferRead() 把数据读取出来,进行校验,判断数据是否被正确写入。 

void I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite)
{u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;Addr = WriteAddr % I2C_PageSize;count = I2C_PageSize - Addr;NumOfPage = NumByteToWrite / I2C_PageSize;NumOfSingle = NumByteToWrite % I2C_PageSize;/* If WriteAddr is I2C_PageSize aligned */if (Addr == 0){/* If NumByteToWrite < I2C_PageSize */if (NumOfPage == 0){I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);I2C_EE_WaitEepromStandbyState();}/* If NumByteToWrite > I2C_PageSize */else{while (NumOfPage--){I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);I2C_EE_WaitEepromStandbyState();WriteAddr += I2C_PageSize;pBuffer += I2C_PageSize;}if (NumOfSingle != 0){I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);I2C_EE_WaitEepromStandbyState();}}}/* If WriteAddr is not I2C_PageSize aligned */else{/* If NumByteToWrite < I2C_PageSize */if (NumOfPage == 0){I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);I2C_EE_WaitEepromStandbyState();}/* If NumByteToWrite > I2C_PageSize */else{NumByteToWrite -= count;NumOfPage = NumByteToWrite / I2C_PageSize;NumOfSingle = NumByteToWrite % I2C_PageSize;if (count != 0){I2C_EE_PageWrite(pBuffer, WriteAddr, count);I2C_EE_WaitEepromStandbyState();WriteAddr += count;pBuffer += count;}while (NumOfPage--){I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);I2C_EE_WaitEepromStandbyState();WriteAddr += I2C_PageSize;pBuffer += I2C_PageSize;}if (NumOfSingle != 0){I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);I2C_EE_WaitEepromStandbyState();}}}
}

        AT24C02 的 EEPROM 分为 32 页,每页可存储8个字节的数据,若在同一页写入超过 8 字节,则超过的部分会被写在该页的起始地址,这样部分数据会被覆盖。为了把连续的缓冲区数组按页写入 EEPROM,就需要对缓冲区进入分页处理。I2C_EE_BufferWrite() 函数根据我们输入的缓冲区大小参数 NumByteToWrite,计算出我们需要写入多少页,并计算写入位置。分页处理好之后,调用 I2C_EE_PageWrite() 函数,这个函数是与 EEPROM 进行 I 2 C通信的最底层函数,它与 STM32 的 I 2 C 库函数使用密切相关。

void I2C_EE_PageWrite(u8* pBuffer, u8 WriteAddr, u8 NumByteToWrite)
{while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));I2C_GenerateSTART(I2C1, ENABLE);  /* Send START condition */while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));  /* Test on EV5 and clear it */I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);  /* Send EEPROM address for write */while (!I2C_CheckEvent(I2C1,  I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));  /* Test on EV6 and clear it */I2C_SendData(I2C1, WriteAddr);  /* Send the EEPROM's internal address to write to */while (! I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));  /* Test on EV8 and clear it */while (NumByteToWrite--)  /* While there is data to be written */{I2C_SendData(I2C1, *pBuffer);    /* Send the current byte */pBuffer++;    /* Point to the next byte to be written */while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED) );    /* Test on EV8 and clear it */}I2C_GenerateSTOP(I2C1, ENABLE);  /* Send STOP condition */
}

1EEPROM页写入时序

这个页写入的函数是根据 EEPROM 的页写入时序来编写的。

调用库函数I2C_Generate START() 产生 I 2 C 的通信起始信号 S。

调用库函数I2C_Send7bitAddress() 把前面条件编译中赋值的变量EEPROM_ADDRESS 地 址 通 过 I 2 C1接口发送出去,数据传输方向为STM32的I2 C发送数据(I2C_Direction_Transmitter)。

调 用 库 函 数I2C_SendData() , 请 注 意 这 个 库 函 数 的 输 入 参 数 为WriteAddr,根据 EEPROM 的页写入时序,发送完 I 2 C 的地址后的第一个数据并不就是要写入 EEPROM 的数据, EEPROM 对这个数据解释为将要对存储矩阵写入的地址,这个参数 WriteAddr 是在我们调用 I2C_EE_PageWrite() 函数时作为参数输入的。这个库函数实际上是把数据传输到数据寄存器,再由 I 2 C 模块根据 I 2 C 协议发送出
去。

调用I2C_SendData() 函数,向 EEPROM 发送要写入的数据,根据EEPROM 的页写入时序,这些数据将会被写入到前面发送的页地址中,若连续写入超过一页的最大字节数(8个),则多出来的数据会重新从该页的起始地址连续写入,覆盖前面的数据。

调用库函数I2C_Generate STOP() 产生 I 2 C 传输结束信号,完成一次 I2 C 通信。

 

2I2C事件检测

        在 I 2 C的通信过程中,会产生一系列的事件,出现事件后在相应的寄存器中会产生标志位。

         若发出了起始信号,会产生事件 5(EV5),即 STM32 的 I 2 C成为主机模式;继续发送完 I 2C 设备寻址并得到应答后,会产生 EV6,即 STM32 的 I 2C 成为数据发送端;之后发送数据完成会产生 EV8 等。我们在做出 I 2 C 通信操作时,可以通过循环调用库函数I2C_CheckEvent()进行事件查询,以确保上一操作完成后才进行下一操作。

 

3、等到EEPROM内部写入完成

void I2C_EE_WaitEepromStandbyState(void)
{vu16 SR1_Tmp = 0;do{I2C_GenerateSTART(I2C1, ENABLE);    /* Send START condition */SR1_Tmp = I2C_ReadRegister(I2C1, I2C_Register_SR1);    /* Read I2C1 SR1 register */I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS,  I2C_Direction_Transmitter);    /* Send EEPROM address for write */}while (!(I2C_ReadRegister(I2C1, I2C_Register_SR1) & 0x0002));I2C_ClearFlag(I2C1, I2C_FLAG_AF);  /* Clear AF flag */I2C_GenerateSTOP(I2C1, ENABLE);  /* STOP condition */
}

        利用了 EEPROM 在接收完数据后,启动内部周期写入数据的时间内不会对主机的请求做出应答的特性。所以利用这个函数循环发送起始信号,若检测到 EEPROM 的应答,则说明 EEPROM 已经完成上一步的数据写入,进入 Standby 状态,可以进行下一步的操作了。

 

 三、EEPROM读

void I2C_EE_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead)
{
//*((u8 *)0x4001080c) |=0x80;while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); // Added by Najoua/* Send START condition */I2C_GenerateSTART(I2C1, ENABLE);
//*((u8 *)0x4001080c) &=~0x80;/* Test on EV5 and clear it */while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));/* Send EEPROM address for write */I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);/* Test on EV6 and clear it */while (!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));/* Clear EV6 by setting again the PE bit */I2C_Cmd(I2C1, ENABLE);/* Send the EEPROM's internal address to write to */I2C_SendData(I2C1, ReadAddr);/* Test on EV8 and clear it */while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));/* Send STRAT condition a second time */I2C_GenerateSTART(I2C1, ENABLE);/* Test on EV5 and clear it */while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));/* Send EEPROM address for read */I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Receiver);/* Test on EV6 and clear it */while (!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));/* While there is data to be read */while (NumByteToRead){if (NumByteToRead == 1){/* Disable Acknowledgement */I2C_AcknowledgeConfig(I2C1, DISABLE);/* Send STOP Condition */I2C_GenerateSTOP(I2C1, ENABLE);}/* Test on EV7 and clear it */if (I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)){/* Read a byte from the EEPROM */*pBuffer = I2C_ReceiveData(I2C1);/* Point to the next location where the byte read will besaved */pBuffer++;/* Decrement the read bytes counter */NumByteToRead--;}}/* Enable Acknowledgement to be ready for another reception */I2C_AcknowledgeConfig(I2C1, ENABLE);
}

四、使用 I2 C读写EEPROM流程总结

(1)配置 I/O 端口,确定并配置 I 2 C 的模式,使能 GPIO 和 I 2 C 时钟。

(2)写 :

① 检测 SDA 是否空闲。

② 按 I 2 C 协议发出起始信号。

③ 发出 7 位器件地址和写模式。

④ 要写入的存储区首地址。

⑤ 用页写入方式或字节写入方式写入数据。

⑥ 发送 I 2 C 通信结束信号。

每个操作之后要检测“事件”是否成功。写完后检测 EEPROM 是否进入Standby状态。

(3)读 :

① 检测 SDA 是否空闲。

② 按 I 2 C 协议发出起始信号。

③ 发出 7 位器件地址和写模式(伪写)。

④ 发出要读取的存储区首地址。

⑤ 重发起始信号。

⑥ 发出 7 位器件地址和读模式。

⑦ 接收数据。

类似写操作,每个操作之后要检测“事件”是否成功。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/466571.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linus Torvalds谈ECC内存的重要性 痛斥英特尔正在扼杀它

新年假期&#xff0c;Linus Torvalds在邮件列表中发表的一篇火热的帖子引发技术社区关注&#xff0c;人们借此讨论ECC内存的重要性&#xff0c;Torvalds在文章中抨击了英特尔在这方面的”坏政策”&#xff0c;因为特定的市场细分使ECC内存不那么普及。Linus认为&#xff0c;纠错…

加密和解密算法的兩個實現

最近一段時間,集團加強了資安方面的管理,所有敏感的配置字節都必須經過加密處理,把最近用到的幾個加解密類整理了一下,以做備忘. 其實這兩個類實現的方法差不多,只是有些細微區別: 對稱加密演算法類 SymmetricMethodHelperusing System;using System.IO;using System.Security.…

47.leetcode36_valid_suduko

1.题目分析 Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could be partially filled, where empty cells are filled with the character .. A partially filled sudoku which is valid. Note: A valid Sudoku board (partia…

STM32——SPI接口

STM32——SPI接口 宗旨&#xff1a;技术的学习是有限的&#xff0c;分享的精神是无限的。 一、SPI协议【SerialPeripheral Interface】 串行外围设备接口&#xff0c;是一种高速全双工的通信总线。在ADC/LCD等与MCU间通信。 1、SPI信号线 SPI 包含 4 条总线&#xff0c;SPI 总…

这两种printf()函数重定向方法,太实用了

作者&#xff1a;echobright原文链接&#xff1a;https://blog.csdn.net/qq_29344757/article/details/75363639在前面学习了STM32的串口编程&#xff0c;通过USART1向计算机的串口调试助手打印数据&#xff0c;或者接收计算机串口调试助手的数据&#xff0c;接下来我们可以实现…

浅析Linux 64位系统虚拟地址和物理地址的映射及验证方法

前言有好久没更新了&#xff0c;这段时间发生了挺多大喜事哈。但是也还是有挺久没更新了&#xff0c;不得不意识到自己是个小菜鸡&#xff0c;就算是小菜鸡也要做一只快乐小菜鸡。就算更新慢但是我依然会持续更新&#xff0c;因为更文使我快乐。虚拟内存先简单介绍一下操作系统…

C语言指针:从底层原理到花式技巧,用图文和代码帮你讲解透彻

一、前言二、变量与指针的本质三、指针的几个相关概念四、指向不同数据类型的指针五、总结一、前言如果问C语言中最重要、威力最大的概念是什么&#xff0c;答案必将是指针&#xff01;威力大&#xff0c;意味着使用方便、高效&#xff0c;同时也意味着语法复杂、容易出错。指针…

ARM

ARM 宗旨&#xff1a;技术的学习是有限的&#xff0c;分享的精神是无限的。 1 、ARM处理器的特点 ARM 处理器具有耗电少&#xff0c;功能强大&#xff0c;16 位/32 位双指令集等众多优点。主要有以下六个主要特点&#xff1a; ① 体积小、低功耗&#xff0c;低成本和高性能&am…

解决一个I2C读写问题

之前写关于I2C相关的文章排查一个触摸屏驱动问题MTK 平台TP调试遇坑1、问题今天遇到一个问题&#xff0c;我们有一个芯片&#xff0c;I2C读写失败&#xff0c;导致录音有问题&#xff0c;而且是偶现的。log提示看到是返回 -6<3>[ 730.336308] (3)[2085:tinycap]es7243_…

用多媒体库 Bass.dll 播放 mp3 [9] - 绘制波形图

本例效果图:代码文件:unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls, ExtCtrls, ComCtrls;typeTForm1 class(TForm)OpenDialog1: TOpenDialog;PaintBox1: TPaintBox;Button1: TButton;Button2: TBut…

我是如何使用wireshark软件的

长按二维码识别关注技术共享|资料共享|沟通交流01简介这篇文章介绍一个好用的抓包工具Wireshark&#xff0c; 用来获取网络数据封包&#xff0c;包括HTTP、TCP、UDP等网络协议包。开始界面wireshark是捕获机器上的某一块网卡的网络包&#xff0c;当你的机器上有多块网卡的时候&…

BZOJ4681 [jsoi2010]旅行

时间限制&#xff1a; 3S空间限制&#xff1a; 256M具体思路:DPf[i][j][k]表示1-i,前L条路上用了 j条,L后的路上换了k条的最小代价枚举一下L就有了一个复杂度O(nlognk^3)的做法AC代码#include<bits/stdc.h> using namespace std; #define INF 100000000 #define P pair&l…

IIC踩过的坑

读取IT8563WE时&#xff0c;读取第一次正确&#xff0c;第二次错误&#xff0c;第三次正确&#xff0c;第四次错误。。。。。。看到读取成功之后&#xff0c;SDA信号没有被正确拉高&#xff0c;电平大概只有一半。再次读取&#xff0c;主机设置读模式时&#xff0c;从机会发送N…

1万字30张图说清TCP协议

本篇文章较长&#xff0c;大家先看下目录1、简介2、TCP协议头3、TCP 数据包的编号&#xff08;SEQ&#xff09;4、三次握手建立连接5、四次挥手断开连接6、TCP可靠性的保证7、滑动窗口技术9、窗口滑动的数据重发9、TCP 流控制10、网线“断”了怎么办01简介TCP(Transmission Con…

Spring源码解析(二)BeanDefinition的Resource定位

IOC容器的初始化过程主要包括BeanDefinition的Resource定位、载入和注册。在实际项目中我们基本上操作的都是ApplicationContex的实现&#xff0c;我们比较熟悉的ClassPathXmlApplicationContext、FileSystemXmlApplicationContext、XmlWebapplicationContext等。ApplicationCo…

单片机(MCU)如何才能不死机之对齐访问(Aligned Access)

从一个结构体说起。如下&#xff0c;在 STM32F0 的程序中&#xff0c;我们定义了一个结构体My_Struct &#xff0c;那么这个结构体占用多少内存呢&#xff1f;struct Struct_Def { uint8_t Var_B; uint16_t Var_W0; uint16_t Var_W1; uint32_t Var_DW; }; struct Struct_Def My…

小米的隔空充电,看起来好酷

昨天是1月29号&#xff0c;昨天小米发布了一个隔空充电技术&#xff0c;很火爆&#xff0c;大胆想&#xff0c;如果有一条无线充电的高速公路&#xff0c;那电动汽车还担心没有电吗&#xff1f;—— 雷总的微博原文隔空充电技术&#xff1a;如科幻电影一般&#xff0c;拿着手机…

同事用void把我给秀翻了!

1、聊一聊今天跟大家推荐的这首歌最近应该挺火的&#xff0c;不过没办法插入AGA的原版歌曲&#xff0c;大家觉得不错可以去找找原版歌曲收录一下。昨天建立了"最后一个bug"技术交流群,由于群成员超过200就无法直接通过群二维码加入&#xff0c;如果大家想加入扫描下面…

Spring Boot之自定义属性

选择Spring Boot主要是考虑到它既能兼顾Spring的强大功能&#xff0c;还能实现快速开发的便捷。我想大多数人也是出于这个原因选择了Spring Boot,如果不是特殊应用场景&#xff0c;就只需要在application.properties中完成一些属性配置就能开启各模块的应用。而不像传统的XML配…

一个老工程师的工作经历和思考

在这里不敢以”资深”工程师自居&#xff0c;因为学历和技术水平确实一般。为什么说“老”呢&#xff1f;因为工作时间确实够长&#xff0c;已经接近20年。下面把自身工作和学习经历和大家分享一下&#xff0c;使初学者能够得到一些有用的东西。2000年毕业&#xff0c;机械电子…