基于STM32设计的数字电子秤
1. 项目介绍
称重计量是现在社会活动中不可缺少的部分,随着国际交流的发展,称重计量的国际间的统一显得越来越重要。
电子称重技术是现代称重计量和控制系统工程的重要基础之一。近年来,随着现代科技进步,电子称重技术取得了突飞猛进的发展,电子秤在计量领域中也占有越来越重要的地位。尤其是商用电子衡器,以其准确度高、反应灵敏、性能稳定、结构简单、环境适应性强、便于与电子计算机结合而实现称重计量与过程控制自动化等特点,而被广泛用于工商贸易、能源交通、冶金矿山、轻工食品、医药卫生、航空航天等领域。
电子秤的工作原理首先是通过称重传感器采集到被测物体的重量并将其转换成电压信号,输出电压信号通常很小,需要通过前端信号处理电路进行准确的线性放大。放大后的模拟电压信号经A/D转换电路转换成数字量,被送入到主控电路的单片机中,再经过单片机控制OLED显示屏,从而显示出被测物体的重量,在实际应用中为提高数据采集的精度,并尽量减少外界电气干扰还需要在传感器与A/D芯片之间加上信号调理电路。
当前项目是采用采用STM32+称重模块+OLED实现了简单的电子秤项目,称重模块上采用24位的ADC芯片,精度较高。实现了称重,校准、去皮等功能。
硬件介绍:
MCU:STM32F103ZET6,只要是STM32F1X系列本工程代码都通用的。
称重模块: 淘宝购买的称重模块
OLED: SPI接口的0.96寸OLED屏,采用的是中景园电子的OLED屏。
完整工程下载地址: https://download.csdn.net/download/xiaolong1126626497/63993934
视频演示地址: https://live.csdn.net/v/182608
项目运行效果:
2. 项目实现
2.1 称重传感器
称重传感器就是一个压力传感器,其又叫做悬臂梁压力传感器。安装时需要一端固定,另一端受力。其内部有四个应变电阻片,共同组成了一个电桥,当受力端施加压力时,传感器壳体会发生形变,从而影响应变电阻片的阻值。
下面是称重传感器的原理图:
称重传感器实物图:
称重传感器是采用 CS1237 作为转换芯片,用于把微小的电压信号转换为具有 24 位精度的数字信号。模块信号输入端可以接受差分信号,内部具有可编程运算放大器用于放大输入端的弱小信号。模块内置温度传感器,可粗略估计周围温度。模块可用于多种工业过程控制场合,比如电子秤,血液计,智能变换器等。
CS1237中有1路ADC,集成了1路差分输入,信号输入可以是差分输入信号AINP、AINN,也可以是温度传感器的输出信号,输入信号的切换由寄存器(ch_sel[1:0])控制。
CS1237是采用2线SPI串行通信,通过SCLK和DRDY/DOUT可以实现数据的接收以及功能配置。
实现代码如下:
#include "ADC-CS1237.h"static long AD_Res_Last=0; //上一轮的ADC数值保存
/*
定义CS1237使用的GPIO口
CLK PB14 时钟线
OUT PB15 数据输出线
*/
void CS1237_GPIO_INIT(void)
{RCC->APB2ENR |= 0x01 << 3; //打开PB口GPIOB->CRH &= 0xF0FFFFFF; //寄存器清零GPIOB->CRH |= 0x03000000; //通用推挽输出 50MHzGPIOB->ODR |= 1<< 14; //拉高CLK电平
}void CS1237_DRDY(void) //配置PB15为输入
{GPIOB->CRH &= 0x0FFFFFFF; //寄存器清零GPIOB->CRH |= 0x80000000; //上下拉输入模式
}void CS1237_DOUT(void) //配置PB15为输出
{GPIOB->CRH &= 0x0FFFFFFF; //寄存器清零GPIOB->CRH |= 0x30000000; //通用推挽输出 50MHz
}//CS1237进入低功耗模式
void CS1237_Power_Down(void)
{CLK_HIGHdelay_us(200); //CLK上拉时间应超过100us,恢复后下拉时间至少10us
}
//配置CS1237芯片
void Con_CS1237(void)
{u8 i;u8 dat;u8 count_i=0; //溢出计时器dat = CS_CON; // 0100 1000CS1237_DOUT();OUT_HIGHdelay_ms(310); //上电建立时间CS1237_DRDY(); //配置PB15为输入 CLK_LOW //时钟拉低while(INT) //芯片准备好数据输出 时钟已经为0,数据也需要等CS1237全部拉低为0才算都准备好{printf("123\r\n");delay_ms(100); //10HZ下转换时间是100mscount_i++;if(count_i > 150){CLK_HIGH;CS1237_DOUT();OUT_HIGHreturn; //超时,则直接退出程序}}for(i=0;i<29;i++) // 1 - 29{One_CLK;}CS1237_DOUT();CLK_HIGH;delay_us(6);OUT_HIGH;CLK_LOW;delay_us(6); //30CLK_HIGH;delay_us(6);OUT_HIGH;CLK_LOW;delay_us(6); //31CLK_HIGH;delay_us(6);OUT_LOW;CLK_LOW;delay_us(6); //32CLK_HIGH;delay_us(6);OUT_LOW;CLK_LOW;delay_us(6); //33CLK_HIGH;delay_us(6);OUT_HIGH;CLK_LOW;delay_us(6); //34CLK_HIGH;delay_us(6);OUT_LOW;CLK_LOW;delay_us(6); //35CLK_HIGH;delay_us(6);OUT_HIGH;CLK_LOW;delay_us(6); //36One_CLK; //37 写入了0x65for(i=0;i<8;i++) // 38 - 45个脉冲了,写8位数据{CLK_HIGH;delay_us(6);if(dat&0x80)OUT_HIGHelseOUT_LOWdat <<= 1;CLK_LOW;delay_us(6);}CS1237_DRDY();One_CLK; //46个脉冲拉高数据引脚
}//读取芯片的配置数据
u8 Read_CON(void)
{u8 i;u8 dat=0; //读取到的数据u8 count_i=0; //溢出计时器CS1237_DOUT();OUT_HIGHCS1237_DRDY(); //配置PB15为输入 CLK_LOW //时钟拉低while(INT) //芯片准备好数据输出 时钟已经为0,数据也需要等CS1237全部拉低为0才算都准备好{delay_ms(100);count_i++;if(count_i > 150){CLK_HIGH;CS1237_DOUT();OUT_HIGH;return 1; //超时,则直接退出程序}}for(i=0;i<29;i++) // 1 - 29{One_CLK;}CS1237_DOUT();CLK_HIGH;delay_us(6);OUT_HIGH;CLK_LOW;delay_us(6);//30CLK_HIGH;delay_us(6);OUT_LOW;CLK_LOW;delay_us(6);//31CLK_HIGH;delay_us(6);OUT_HIGH;CLK_LOW;delay_us(6);//32CLK_HIGH;delay_us(6);OUT_LOW;CLK_LOW;delay_us(6);//33CLK_HIGH;delay_us(6);OUT_HIGH;CLK_LOW;delay_us(6);//34CLK_HIGH;delay_us(6);OUT_HIGH;CLK_LOW;delay_us(6);//35CLK_HIGH;delay_us(6);OUT_LOW;CLK_LOW;delay_us(6);//36One_CLK;//37 写入了0x56CS1237_DRDY();dat=0;for(i=0;i<8;i++) // 38 - 45个脉冲了,读取数据{One_CLK;dat <<= 1;if(INT)dat++;}One_CLK; //46个脉冲拉高数据引脚return dat;
}//读取ADC数据,返回的是一个有符号数据
long Read_CS1237(void)
{u8 i;long dat=0; //读取到的数据u16 count_i=0; //溢出计时器CS1237_DOUT();OUT_HIGH //等待模拟输入信号建立CLK_LOW; //时钟拉低CS1237_DRDY();while(INT) //芯片准备好数据输出 时钟已经为0,数据也需要等CS1237拉低为0才算都准备好{// printf("等待1\r\n");delay_ms(10);count_i++;if(count_i > 300){CLK_HIGH;CS1237_DOUT();OUT_HIGH;return 0; //超时,则直接退出程序}}CS1237_DOUT();OUT_HIGH //端口锁存1,CS1237_DRDY();dat=0;for(i=0;i<24;i++) //获取24位有效转换{CLK_HIGH;delay_us(6);dat <<= 1;if(INT)dat ++;CLK_LOW;delay_us(6); }for(i=0;i<3;i++) //一共输入27个脉冲{One_CLK;}CS1237_DOUT();OUT_HIGH;//先根据宏定义里面的有效位,丢弃一些数据i = 24 - ADC_Bit;//i表示将要丢弃的位数dat >>= i;//丢弃多余的位数return dat;
}//初始化ADC相关参数
int Init_CS1237(void)
{Con_CS1237();//配置CS1237if(Read_CON() != CS_CON)//如果读取的ADC配置出错,则重启{printf("读取错误\r\n");return 0;}delay_us(10000);AD_Res_Last = Read_CS1237();AD_Res_Last = Read_CS1237();AD_Res_Last = Read_CS1237();return 0;
}//数字一阶滤波器 滤波系数A,小于1。上一次数值B,本次数值C out = b*A + C*(1-A)
//下面这个程序负责读取出最终ADC数据
long Read_18Bit_AD(void) //18位的
{float out,c;out = AD_Res_Last;c = Read_CS1237();if(c!=0) // 读到正确数据{out = out*Lv_Bo + c*(1-Lv_Bo);AD_Res_Last = out;//把这次的计算结果放到全局变量里面保护}return AD_Res_Last;
}
2.2 OLED显示屏
OLED显示屏是0.96寸 SPI接口显示屏,采用SSD1306驱动,兼容3.3V或5V电源输入,非常常见,淘宝一搜一大堆,当前选择的是中景园电子的OLED显示屏。
在调试设备或者测试数据时,有时候需要实时观察数据的变化,加入显示屏可以把观察设备的运行情况,数据变化等。在成本和难易程度上,OLED显示屏是非常适合初学者去学习与应用的。
OLED视频实物图:
示例代码:
#include "OLED.H"
#include "oled_font.h"/*
定义OLED使用的GPIO口
D0 PA5 时钟线
D1 PA1 数据输出线
RES PA2 复位线
DC PA3 数据/命令选择线
CS PA4 片选线
*/void OLED_GPIO_INIT(void)
{RCC->APB2ENR |= 1<<2; //打开PA口GPIOA->CRL &= 0xFF00000F; //寄存器清零GPIOA->CRL |= 0x00333330; //通用推挽输出 50MHzGPIOA->ODR |=0x003E;
}void OLED_Init(void)
{OLED_GPIO_INIT(); //GPIO口初始化OLED_RES_HIGH;delay_ms(100);OLED_RES_LOW;delay_ms(200); //延迟,由于单片机上电初始化比OLED快,所以必须加上延迟,等待OLED上电初始化完成OLED_RES_HIGH;delay_ms(200);OLED_WR_Byte(0xAE,OLED_CMD); //关闭显示OLED_WR_Byte(0x2e,OLED_CMD); //关闭滚动OLED_WR_Byte(0x00,OLED_CMD); //设置低列地址OLED_WR_Byte(0x10,OLED_CMD); //设置高列地址OLED_WR_Byte(0x40,OLED_CMD); //设置起始行地址OLED_WR_Byte(0xB0,OLED_CMD); //设置页地址OLED_WR_Byte(0x81,OLED_CMD); // 对比度设置,可设置亮度OLED_WR_Byte(0xFF,OLED_CMD); // 265 OLED_WR_Byte(0xA1,OLED_CMD); //设置段(SEG)的起始映射地址;column的127地址是SEG0的地址OLED_WR_Byte(0xA6,OLED_CMD); //正常显示;0xa7逆显示OLED_WR_Byte(0xA8,OLED_CMD); //设置驱动路数OLED_WR_Byte(0x3F,OLED_CMD); //1/64dutyOLED_WR_Byte(0xC8,OLED_CMD); //重映射模式,COM[N-1]~COM0扫描OLED_WR_Byte(0xD3,OLED_CMD); //设置显示偏移OLED_WR_Byte(0x00,OLED_CMD); //无偏移OLED_WR_Byte(0xD5,OLED_CMD); //设置震荡器分频(默认)OLED_WR_Byte(0x80,OLED_CMD); OLED_WR_Byte(0xD8,OLED_CMD); //设置 area color mode off(没有)OLED_WR_Byte(0x05,OLED_CMD);OLED_WR_Byte(0xD6,OLED_CMD); //放大显示OLED_WR_Byte(0x00,OLED_CMD);OLED_WR_Byte(0xD9,OLED_CMD); //设置 Pre-Charge Period(默认)OLED_WR_Byte(0xF1,OLED_CMD);OLED_WR_Byte(0xDA,OLED_CMD); //设置 com pin configuartion(默认)OLED_WR_Byte(0x12,OLED_CMD);OLED_WR_Byte(0xDB,OLED_CMD); //设置 Vcomh,可调节亮度(默认)OLED_WR_Byte(0x30,OLED_CMD);OLED_WR_Byte(0x8D,OLED_CMD); //设置OLED电荷泵OLED_WR_Byte(0x14,OLED_CMD); //开显示OLED_WR_Byte(0xA4,OLED_CMD); // Disable Entire Display On (0xa4/0xa5)OLED_WR_Byte(0xA6,OLED_CMD); // Disable Inverse Display On (0xa6/a7) OLED_WR_Byte(0xAF,OLED_CMD); //开启OLED面板显示OLED_Clear(); //清屏OLED_Set_Pos(0,0); //画点
}void OLED_Write_Byte(u8 data)
{u8 i; //定义变量for(i = 0; i < 8; i++) //循环8次{OLED_D0_LOW //将时钟线拉低delay_us(1); //延迟 if(data & 0x80) //数据从高位-->低位依次发送OLED_D1_HIGH //数据为为1elseOLED_D1_LOW //数据位为0 data <<= 1; //数据左移1位OLED_D0_HIGH //时钟线拉高,把数据发送出去delay_us(1); //延迟}}/*@brief 对OLED写入一个字节@param dat:数据cmd:1,写诶数据;0,写入命令@retval 无*/
void OLED_WR_Byte(u8 dat,u8 cmd)
{if(cmd) //如果cmd为高,则发送的是数据OLED_DC_HIGH //将DC拉高else //如果cmd为低,则发送的是命令OLED_DC_LOW //将DC拉低OLED_CS_LOW; //片选拉低,选通器件OLED_Write_Byte(dat); //发送数据OLED_CS_HIGH //片选拉高,关闭器件 OLED_DC_HIGH //DC拉高,空闲时为高电平
}/*@brief 设置数据写入的起始行、列@param x: 列的起始低地址与起始高地址;0x00~0x0f:设置起始列低地址(在页寻址模式);0x10~0x1f:设置起始列高地址(在页寻址模式)y:起始页地址 0~7@retval 无*/
void OLED_Set_Pos(u8 x, u8 y)
{ OLED_WR_Byte(0xb0+y,OLED_CMD);//写入页地址OLED_WR_Byte((x&0x0f),OLED_CMD); //写入列的地址 低半字节OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);//写入列的地址 高半字节
} /*@brief 开显示@param 无@retval 无*/
void OLED_Display_On(void)
{OLED_WR_Byte(0X8D,OLED_CMD); //设置OLED电荷泵OLED_WR_Byte(0X14,OLED_CMD); //使能,开OLED_WR_Byte(0XAF,OLED_CMD); //开显示
}/*@brief OLED滚屏函数,范围0~1页,水平向左@param 无@retval 无*/
void OLED_Scroll(void)
{OLED_WR_Byte(0x2E,OLED_CMD); //关闭滚动OLED_WR_Byte(0x27,OLED_CMD); //水平向左滚动OLED_WR_Byte(0x00,OLED_CMD); //虚拟字节OLED_WR_Byte(0x00,OLED_CMD); //起始页 0OLED_WR_Byte(0x00,OLED_CMD); //滚动时间间隔OLED_WR_Byte(0x01,OLED_CMD); //终止页 1OLED_WR_Byte(0x00,OLED_CMD); //虚拟字节OLED_WR_Byte(0xFF,OLED_CMD); //虚拟字节OLED_WR_Byte(0x2F,OLED_CMD); //开启滚动
}/*@brief 关显示@param 无@retval 无*/
void OLED_Display_Off(void)
{OLED_WR_Byte(0XAE,OLED_CMD); //关显示OLED_WR_Byte(0X8D,OLED_CMD); //设置OLED电荷泵OLED_WR_Byte(0X10,OLED_CMD); //失能,关
} /*@brief 清屏@param 无@retval 无*/
void OLED_Clear(void)
{ u8 i,n; //定义变量for(i=0;i<8;i++) { OLED_WR_Byte (0xb0+i,OLED_CMD); //从0~7页依次写入OLED_WR_Byte (0x00,OLED_CMD); //列低地址OLED_WR_Byte (0x10,OLED_CMD); //列高地址 for(n=0;n<128;n++){OLED_WR_Byte(0,OLED_DATA); //写入 0 清屏}}
}/*@brief 显示一个字符@param x:起始列y:起始页,SIZE = 16占两页;SIZE = 12占1页chr:字符@retval 无*/
void OLED_ShowChar(u8 x,u8 y,u8 chr)
{ u8 c=0,i=0; c=chr-' '; //获取字符的偏移量 if(x>Max_Column-1){x=0;y=y+2;} //如果列数超出了范围,就从下2页的第0列开始if(SIZE ==16) //字符大小如果为 16 = 8*16{OLED_Set_Pos(x,y); //从x y 开始画点for(i=0;i<8;i++) //循环8次 占8列OLED_WR_Byte(F8X16[c*16+i],OLED_DATA); //找出字符 c 的数组位置,先在第一页把列画完OLED_Set_Pos(x,y+1); //页数加1for(i=0;i<8;i++) //循环8次OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA); //把第二页的列数画完}else //字符大小为 6 = 6*8{ OLED_Set_Pos(x,y+1); //一页就可以画完for(i=0;i<6;i++) //循环6次 ,占6列OLED_WR_Byte(F6x8[c][i],OLED_DATA); //把字符画完}
}/*@brief 计算m^n@param m:输入的一个数n:输入数的次方@retval result:一个数的n次方*/
u16 oled_pow(u8 m,u8 n)
{u16 result=1; while(n--)result*=m; return result;
} /*@brief 在指定的位置,显示一个指定长度大小的数@param x:起始列y:起始页num:数字len:数字的长度size:显示数字的大小@retval 无*/
void OLED_ShowNum(u8 x,u8 y,u16 num,u16 len,u16 size)
{ u8 t,temp; //定义变量u8 enshow=0; //定义变量for(t=0;t<len;t++){temp=(num/oled_pow(10,len-t-1))%10; //取出输入数的每个位,由高到低if(enshow==0&&t<(len-1)) //enshow:是否为第一个数;t<(len-1):判断是否为最后一个数{if(temp==0) //如果该数为0 {OLED_ShowChar(x+(size/2)*t,y,' '); //显示 0 ;x+(size2/2)*t根据字体大小偏移的列数(8)continue; //跳过剩下语句,继续重复循环(避免重复显示)}else enshow=1; }OLED_ShowChar(x+(size/2)*t,y,temp+'0'); //显示一个位;x+(size2/2)*t根据字体大小偏移的列数(8)}
} /*@brief 显示字符串@param x:起始列y:起始页*chr:第一个字符首地址@retval 无*/
void OLED_ShowString(u8 x,u8 y,u8 *chr)
{u8 j=0; //定义变量while (chr[j]!='\0') //如果不是最后一个字符{ OLED_ShowChar(x,y,chr[j]); //显示字符x+=8; //列数加8 ,一个字符的列数占8if(x>=128){x=0;y+=2;} //如果x大于等于128,切换页,从该页的第一列显示j++; //下一个字符}
}/*@brief 显示中文@param x:起始列;一个字体占16列y:起始页;一个字体占两页no:字体的序号@retval 无*/
void OLED_ShowCHinese(u8 x,u8 y,u8 no,u8 w,u8 h)
{ u8 t,k,addr0=(h/8)*no; //定义变量for(k=0;k<h/8;k++){OLED_Set_Pos(x,y+k); //从 x y 开始画点,先画第一页for(t=0;t<w;t++) //循环16次,画第一页的16列{OLED_WR_Byte(FONT_X[addr0][t],OLED_DATA);//画no在数组位置的第一页16列的点}addr0++; }
}/*@brief 显示图片@param x0:起始列地址y0:起始行地址x1:终止列地址y1:终止行地址BMP[]:存放图片代码的数组@retval 无*/
void OLED_DrawBMP(u8 x0, u8 y0,u8 x1, u8 y1,u8 BMP[])
{ u8 j=0; //定义变量u8 x,y; //定义变量if(y1%8==0) y=y1/8; //判断终止页是否为8的整数倍else y=y1/8+1;for(y=y0;y<y1;y++) //从起始页开始,画到终止页{OLED_Set_Pos(x0,y); //在页的起始列开始画for(x=x0;x<x1;x++) //画x1 - x0 列{OLED_WR_Byte(BMP[j++],OLED_DATA); //画图片的点 }}
}
基于STM32设计的数字电子秤相关推荐
- 基于STM32设计的健康检测设备(测温心率计步)
1. 项目介绍 本文介绍的项目是基于STM32设计的健康检测设备,支持体温测量,心率检测,支持运动计步(采用MPU6050陀螺仪实现),支持WIFI传输数据到手机APP打印显示. 硬件环境介绍: MC ...
- 基于STM32设计的指针式电子钟与万年历
1. 项目简介 这是基于STM32设计的一个指针式电子钟+万年历小项目,采用3.5寸的LCD屏显示时钟,日历.温度.天气,支持触摸屏调整设置时间,设置闹钟,查看日历等等.整体项目主要是技术点就是LCD ...
- 基于STM32设计的小说阅读器(翻页、字体切换、颜色切换、语音播报)
一.环境介绍 小车主控MCU: STM32F103ZET6 STM32程序开发IDE: keil5 STM32程序风格: 采用寄存器方式开发,注释齐全,执行效率高,方便移植 硬件包含: 一块STM ...
- 基于STM32设计的人体健康监护系统(华为云IOT)
一.设计需求 1.1 设计需求总结 根据需求,要求设计一款基于 STM32 的人体健康监护系统.采用系统模块化思路进行,将多个数模传感器收集到的数据和操作指令一并送至 STM32 中心处理器进行处理分 ...
- 基于STM32设计的老人监护系统
一.设计需求 1.1 项目背景 21世纪以来,随着科技的发展,在人们的生活水平不断的提升的同时中国老龄化人口问题日益严重,再加上社会经济的发展.许多子女外出打工,使得越来越多的空巢老人得不到及时有效的 ...
- 基于STM32设计的炉温温度检测仪
炉温检测在现代工业生产中十分重要,因为炉温过高或过低都会对产品质量产生影响,甚至影响工厂的正常运作.因此,设计一款能够精准测量炉温并显示结果的检测仪器具有很大的实用价值. 本项目采用了STM32F10 ...
- 基于STM32设计智能称重系统(华为云IOT)
伴随着网络技术,各种通讯技术,传感器技术的飞速发展,物联网技术成为了当今技术领域发展为迅速的技术.而物联网技术的核心仍然是以互联网技术为基础的,物联网是新一代信息技术的重要组成部分,也是信息化时代的重 ...
- 基于STM32设计物联网在线智能称重系统(OneNet)_2022
1. 前言 本设计的模型来源于物流.矿山.高速公路等场合,车辆称重地螃的智能化升级要求.需要结合这些场合,设计基于物联网的智能在线称重方案,开发智能称重控制器,合理选择部署多个重量传感器和必要的算法. ...
- 基于STM32设计的避障寻迹小车
一.前言 1.1 项目背景 根据美国玩具协会在一项研究中,过去几年全球玩具销售增长与GDP的世界平均水平大致相同.但全球玩具市场的内部结构已经占据了巨大的位置变化:传统玩具的市场份额正在下降,高科技电 ...
- 基于STM32设计的老人防摔倒报警设备(OneNet)
1. 前言 我国独生子女,以及人口老龄化等问题,正逐渐成为一个重大的社会问题,老年人机体能力的下降,摔倒引起的安全和危害愈来愈突出,国家和社会越来越关注老年人的健康和安全,开发一个能够实时检测出老年人 ...
最新文章
- C++ Double Ended Queues(双向队列)
- 如何优雅地辞退互联网企业的老员工?
- 机器学习基础-吴恩达-coursera-(第一周学习笔记)----Introduction and Linear Regression
- 嵌入式算法-傅里叶变换算法
- linux下编译安装ntfs,linux下编译安装ntfs
- 截网页全屏图的方法-截网页全屏软件-Web2Pic Pro
- python中path的用法,python中path的用法
- arduino 实现时钟和计算器
- ip切换及时刷新交换机的arp表方法
- 网页中添加QQ链接,别人一点就能和我进行QQ聊天
- 《指弹:November.28th》
- 宝马上海车展全球首发新车;宁德时代宣布锂电产业最大规模碳中和规划;玛氏中国冰淇淋本土化生产 | 美通企业周刊...
- Android Webview完美支持播放各种视频。(解决无法播放优酷视频的问题以及周末无法播放优酷视频的问题)
- IntelliJ IDEA -2017.3.2(Ultimate Edition)的激活方式
- 解决关于win10下eclipse代码格式化不生效问题
- APP安全的防护方法
- 语法基础课——第一讲 习题
- word2010 论文引用/文献插入 保姆级图解
- Spring - 装配bean
- 嵌入式C语言设计模式 --- 原型模式