收拾东西的时候又看到之前收拾的vfd相关的盒子,偶然又加的群,又买了两种屏试水。

大的买屏还送vfd变压器,这玩意卖的少,一个5块,不买血亏!不知道什么时候开始早已没有DIY是省钱这种观念了。草。。。


一.灯丝驱动

我拿到变压器,按照之前的电路,简单用洞洞板焊接了一个,由于做的时候没有拍照,也不想拆开盒子了。原理图见之前的帖子。

调试的时候出了两个问题:

1.没加电解电容,电路储能不够,不能起震。后加一470uF电容。

2.由于我没有120mH那么大的电感,我用的100uH的,C13按照470pF似乎没有起震。手里没有示波器看不到状况。总之,换成0.1uF后工作了,这个电路我也分析不出来频率理论式是多少了,但是这个电容和电感肯定是决定震荡频率的。其他值都是这个电路的。

老王提供的原理图,尚未验证这组值,但是群友似乎采用了。准备做小那块板再验证一下。

不过我最后控制的时候效仿该电路加了一个pmos控制灯丝电路通断。5V进入电路,MCU和改FUTABA VFD驱动共用该电源,再经pmos控制输入灯丝电路。

FUTABA手册里说,VH即栅极阳极电压(这里的VEE)应该先于或者与驱动同时断电,这样设计没问题。

和我之前手工绕的变压器不同的是,这个电路输出灯丝交流电压大概只有1.3Vac。难道是之前匝数太多啦?反正上一版由于三极管,变压器和PT6311发热比较严重,

5V供电时电流达到了0.8A。基本同样的电路这个板只有0.2A。可能是自己绕制的变压器和这个差比较远吧。这个功耗大导致上一板开板计划搁浅。烂尾了。下次使用这个变压器再做吧。

二.MCU驱动程序

这次没用stm8,因为封装(tssop20)的原因,不方便在洞洞板上焊接了。再有就是群友提供的驱动亦是stc8的,我直接使用stc12稍稍改了引脚就驱动了这个屏。

三.时钟总体设计

方案:FUTABA VFD + DS3231 + stc15w404as + 3D打印外壳

1.mcu,15的mcu直接把以前作废的航模接受机锯下核心板,供电测试可以烧录程序。再改引脚这个u也成功驱动了。下面也没有时钟的内部图了,一是因为洞洞板焊接,二是主要的,我洞洞板也是从以前废板上裁下来的,手头连洞洞板也没了。由于是方案验证,也不想制板甚至开板了。作给下版再考虑吧。

2.DS3231,这玩意浪费时间不短!用的这块就是上次的vfd时钟上拆下来的。之前给它接的电池都挂了,0v电压。给那块板供电板子不工作,拔了电池才工作。其实这块芯片备用电池这里内部可能出了问题。导致我后来花很长世间调试掉电走时。

3.总体思路,开定时器刷屏,读温度时间,通过串口交互完成授时等操作。

四.坑

1.FUTABA驱动,原作者可能是基于其他FUTABA的板改的,有些地方我没搞懂就又去找手册自己琢磨了好久,还是想利用那些图标。最后也没用上,但是大致又搞了一遍这个驱动显示原理。

感觉和lcd1602这种屏很像。自带部分ascii字库,花圈的是CGRAM,用户自定义码。其它是CGROM,固化在驱动内的。

Basically flowchart of commands:

1.有很多种ram,拣几个用到的说。CGRAM(character generator RAM)上面说了是自定义字符,一共有8个,可以反复更新,再引用时可以通过先写到CGRAM立即更新到DCRAM显示,或者通过相关方法以编号的形式引用。

DCRAM(data control RAM),每个显示符最终写入交由硬件执行显示的RAM,写给它硬件就去查表显示了。ADRAM(additional data RAM),额外的字符RAM,用于显示下图标记的icon。这个是写入立即生效,不用写入DCRAM。

2.FUTABA 驱动

   #include "futaba_vfd.h"
/*
3 //typical:
4 @1. VFD_Write_CGRAM(0x00,VFD_CGRAM[0]);//VFD_CGRAM[0]:assign character
5 VFD_Write_DCRAM(0x01,0x00); //0x01:assign position 0x00:(dat?dat:VFD_CGRAM[0])
6 in this way,first write to cgram and then write to dcram to display soon
7
8 VFD_Write_DCRAM(0x01,'1'); //0x01:pos '1':the char to display
9 it's convenient,but it doesn't work appropriately when only write 1 char.so repeat it!
10 */ sbit VFD_SCK = P1^; //VFD SPI SCLK
sbit VFD_DAT = P1^; //VFD SPI MOSI
sbit VFD_CS = P1^; //VFD chip select
sbit VFD_RST = P5^; //VFD reset //G1,G2,G3,G4,G5,G6,G7,G8,G9,G10,G11,G12,G13,G14
unsigned char xdata VFD_DCRAM[] = {0x07,'','','-','S','T','-','','','G','I','N','K' }; //DCRAM
unsigned char xdata VFD_CGRAM[][] = { //CGRAM
0x08,0x1c,0x3e,0x00,0x3e, //left arrow
0x3e,0x00,0x3e,0x1c,0x08, //right arrow
0x28,0x2c,0x2e,0x2c,0x28, //up arrow
0x0a,0x1a,0x2a,0x1a,0x0a, //down arrow
0xff,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00
};
//NC,TIME_D1,SHIFT_D1,CLOCK_D1,HD_D1,USB_D1,LOCK_D1,DOLBY_D1,MUTE_D1,TU1_D1,TU2_D1,MP3_D1,LOOP_D1, repeat addr:1_D0,:2_D0,:3_d0
unsigned char xdata VFD_ADRAM[] = {};//{0x00,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02}; //ADRAM unsigned int xdata VFD_BRT_DATA; // display duty //---------------------------------------------------------------------------------------//
void Delay_10uS() //@12.000MHz
{
unsigned char i; i = ;
while (--i);
}
void Delay_5mS() //@12.000MHz
{
unsigned char i, j; _nop_();
_nop_();
i = ;
j = ;
do
{
while (--j);
} while (--i);
}
void Delay_1S() //@12.000MHz
{
unsigned char i, j, k; _nop_();
_nop_();
i = ;
j = ;
k = ;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
//---------------------------------------------------------------------------------------//
//Wtite data to VFD's CIG
void VFD_Write_Data(unsigned char DAT)
{
unsigned char i;
for(i=;i<;i++)
{
VFD_SCK = ;
VFD_DAT = DAT&0x01;
Delay_10uS();
VFD_SCK = ;
Delay_10uS();
DAT >>= ;
}
} //Initialize the CIG
void VFD_Init(void)
{
unsigned char i , j; VFD_RST = ; //reset the CIG
Delay_5mS();
VFD_RST = ;
Delay_5mS(); VFD_CS=;
VFD_Write_Data(0xe0); //Set the display timing
VFD_Write_Data(0x0d); //
VFD_CS=; VFD_CS=;
VFD_Write_Data(0xe4); //Set the dimming data
VFD_Write_Data();
VFD_CS=; VFD_CS=;
VFD_Write_Data(0x40); //write CGRAM
for (i=;i<;i++)
{
for(j=;j<;j++)
{
VFD_Write_Data(VFD_CGRAM[i][j]); //CGRAM
}//????display at once ??
}
VFD_CS=; VFD_CS=;
VFD_Write_Data(0x20); //write DCRAM
for(i=;i<;i++)
{
VFD_Write_Data(VFD_DCRAM[i]); //DCRAM
}
VFD_CS=; VFD_CS=;
VFD_Write_Data(0X60); //write ADRAM
for(i=;i<;i++)
{
VFD_Write_Data(VFD_ADRAM[i]); //ADRAM
}
VFD_CS=; VFD_CS=;
VFD_Write_Data(0xe8); //all display on
VFD_CS=;
}
void VFD_Clr(void)
{
// VFD_CS=0;
// VFD_Write_Data(0x60 | AD_COLON1); //ADRAM
// VFD_Write_Data(0x03); //ADRAM
// VFD_Write_Data(0x03);
// VFD_Write_Data(0x60 | AD_COLON2); //ADRAM
// VFD_Write_Data(0x03); //ADRAM
// VFD_Write_Data(0x03);
// VFD_Write_Data(0x60 | AD_COLON3); //ADRAM
// VFD_Write_Data(0x03); //ADRAM
// VFD_Write_Data(0x03); //ADRAM
// VFD_CS=1;
VFD_CS=;
VFD_Write_Data(0x20|0x0); //DCRAM
VFD_Write_Data();
// VFD_Write_CGRAM(0x00,VFD_CGRAM[4]);
VFD_CS=;
}
//set VFD display on or off , 0-off , 1-on
void VFD_Disp_On_Off(bit on_off_flag)
{
VFD_CS=;
VFD_Write_Data(0xe8 | (((unsigned char)(~on_off_flag))<<));
VFD_CS=;
} //Set the display dimming data
void VFD_Brt_Set(unsigned char BRT_DAT)
{
VFD_CS=;
VFD_Write_Data(0xe4); //display dimming set command
VFD_Write_Data(BRT_DAT);
VFD_CS=;
} //Load DCRAM buffer to VFD's DCRAM
void VFD_DCRAM_Load(void)
{
unsigned char i;
VFD_CS=;
VFD_Write_Data(0x20); //write DCRAM
for(i=;i<;i++)
{
VFD_Write_Data(VFD_DCRAM[i]); //DCRAM
}
VFD_CS=;
}
//Write data to fixed DCRAM address
void VFD_Write_DCRAM(unsigned char addr , unsigned char dat)
{
VFD_CS=;
VFD_Write_Data(0x20 | addr); //write DCRAM
VFD_Write_Data(dat); //DCRAM
VFD_CS=;
}
//Load CGRAM buffer to VFD's CGRAM
void VFD_CGRAM_Load(void)
{
unsigned char i , j;
VFD_CS=;
VFD_Write_Data(0x40); //write CGRAM
for (i=;i<;i++)
{
for(j=;j<;j++)
{
VFD_Write_Data(VFD_CGRAM[i][j]); //CGRAM
}
}
VFD_CS=;
}
//Write data to fixed CGRAM address
void VFD_Write_CGRAM(unsigned char addr , unsigned char *dat)
{
unsigned char i;
VFD_CS=;
VFD_Write_Data(0x40 | addr); //write CGRAM
for(i=;i<;i++)
{
VFD_Write_Data(*dat++); //CGRAM
}
VFD_CS=;
}
//Load ADRAM buffer to VFD's ADRAM
void VFD_ADRAM_Load(void)
{
unsigned char i;
VFD_CS=;
VFD_Write_Data(0x60); //ADRAM
for (i=;i<;i++)
{
VFD_Write_Data(VFD_ADRAM[i]); //ADRAM
}
VFD_CS=;
}
//Write data to fixed ADRAM address
void VFD_Write_ADRAM(unsigned char ad_dat , bit on_off_flag)
{
unsigned char ad_dat_temp;
VFD_CS=;
VFD_Write_Data(0x60 | ad_dat); //ADRAM
if((ad_dat == AD_COLON1) || (ad_dat == AD_COLON2) || (ad_dat == AD_COLON3)) ad_dat_temp = 0x01;
else ad_dat_temp = 0x02;
on_off_flag ? VFD_Write_Data(ad_dat_temp) : VFD_Write_Data(0x00); //ADRAM
VFD_CS=;
}

(1)显示某个字符,若字符为字库内的,可直接使用内码。

如,

VFD_Write_DCRAM(0x01,'1'); //0x01:pos '1':the char to display

交由其自行转换为码字地址。

或者直接给DCRAM写入字符地址,

VFD_Write_DCRAM(0x01,);//0x01:pos 0:the char's address

即显示这个字符。

(2)CGRAM显示

其实上面那行代码显示的就是CGRAM,CGRAM和CGROM共用一页地址,只是低8个给RAM了。所以按地址方式赋值是可以显示用户字符和字库字符的。

还有一种方式,

VFD_Write_CGRAM(0x00,VFD_CGRAM[]);//VFD_CGRAM[0]:assign character
VFD_Write_DCRAM(0x01,0x00); //0x01:assign position 0x00:(dat?dat:VFD_CGRAM[0])

采用写入CGRAM并立即更新到DCRAM的方式,当DCRAM的字符参数为0时,写入的就是最近写入的CGRAM。经验证这两行代码的确可行,但是在手册上没有明确找到这个流程。

行业既定规则?也有可能是我没看到。

3.DS3231掉电走时

前面也说到了,这里调试了很久都不能掉电走时。

学到新的就是这个芯片其实RST脚根本不需要上电复位,这个脚设计来是接按键的。许多设计直接将这个脚悬空。

VBAT这个脚我尝试过接锂电池,甚至直接接了5v一样不走时。

调试到最后我差点就把这个芯片换成之前买的DS12C887,这个自带电池总归可以掉电走时了吧?

但是就在快下手时突然有了新思路,我直接用电池给这个芯片供电不就行了?反正3231工作时电流是微安级的。

找来以前从pos机拆下的小锂电,接一个充电模块,该模块电源输入加一路前面提到的pmos控制,尚未测试电池可以管多久。反正我现在是每天给它充电5min。

这部分还自己写了程序,后来想其实可以用3231的闹钟功能。这种思路似乎可以用于不支持备用电池供电的芯片?但是大多芯片其实都有这个vbat脚的。

4.main.c

 #include <STC15.h>
#include <string.h>
#include "futaba_vfd.h"
#include "ds3231.h"
//#include "myiicForDs3231.h" //for init rst sbit vpwr=P1^;
sbit batcharge=P1^;
//uart
unsigned char xdata RxBuffer[]={};
unsigned char UART_RX_NUM=;
//display
bit reflash_flag=;
bit dateOrTemp;
unsigned char normalTime[];//mth day wk hr min sec
//charging
u8 lastChargeHour,lastChargeDay,chargingMinute;
bit chargingFlag;
//---------------------------------------------------------------------------------------//
void Uart_Init(void); //115200bps@12.000MHz
void Uart_Init(void); //115200bps@12.000MHz
void Uart_Send_String(unsigned char *str);
void Tim0_Init(void);//2ms void DataDel(u8 *str,u8 len);
void CMD_Compare(void);
//---------------------------------------------------------------------------------------// //---------------------------------------------------------------------------------------//
void main(void)
{
u8 i,lastMin;
u8 cnt_min; Uart_Init();
Tim0_Init();
VFD_Init();
//DS3231IIC_Init();//do not need rst !!!
//ModifyTime(4,12,5,11,21,0);// 4-12 w5 tm11-21-00
Uart_Send_String("VFD Init done");
get_show(normalTime);
for (i=;i<;i++){
if (i==){
VFD_DCRAM[]=normalTime[]+'';//week
VFD_DCRAM[]='-';
}
else{
VFD_DCRAM[*i+]=normalTime[i]/+'';
VFD_DCRAM[*i+]=normalTime[i]%+'';
}
}
lastChargeHour=normalTime[];//record first boot hour as last charge hour
lastChargeDay=(normalTime[]+);//record first boot day-1 as last charge day
lastMin=normalTime[]; //record last min VFD_Write_ADRAM(AD_COLON2,);
VFD_Write_ADRAM(AD_COLON3,);
VFD_DCRAM_Load();
vpwr=;//switch on pmos
batcharge=;//turn off charging bat
while()
{
if (reflash_flag){//display interval
reflash_flag=; get_time(&normalTime[]);//hr min sec
if (lastMin!=normalTime[]){//pass 1 min??
lastMin=normalTime[]; //update "last"min get_date(normalTime);//read mth day wk
dateOrTemp=!dateOrTemp;//bit switch
if (dateOrTemp){ //1 for date for (i=;i<;i++){
VFD_DCRAM[*i+]=normalTime[i]/+'';
VFD_DCRAM[*i+]=normalTime[i]%+'';
}
VFD_DCRAM[]=normalTime[]+'';//week
VFD_DCRAM[]='-';
}
else{ //0 for temp
//strncpy(&VFD_DCRAM[1],(const char*)"Temp",4);
get_show_Temperature(normalTime);
VFD_DCRAM[]='T';
VFD_DCRAM[]=normalTime[]/ + '';
VFD_DCRAM[]=normalTime[]% + '';
VFD_DCRAM[]=0x19;//dot
VFD_DCRAM[]='C'; }
if ((lastChargeHour==normalTime[])&&(lastChargeDay!=normalTime[])){//update charging reg
lastChargeDay=normalTime[];//update the day of last charging
chargingFlag=;
}
if (chargingFlag){//charging???
batcharge=;//turn on charging
if (++chargingMinute>=){
chargingMinute=;
chargingFlag=;
batcharge=;//turn off charging
}
}
}
//update hr min sec
for (i=;i<;i++){
VFD_DCRAM[*i+]=normalTime[i]/+'';
VFD_DCRAM[*i+]=normalTime[i]%+'';
}
if ((normalTime[]>=)||(normalTime[]<=)){//auto dimming
VFD_Brt_Set();
}else VFD_Brt_Set(); VFD_DCRAM_Load();
}
//other
if(UART_RX_NUM&0x80)//uart catch
{
CMD_Compare();
}
}
}
void Tim0_Isr()interrupt
{
static u8 cnt_500ms;
if (++cnt_500ms>=){
cnt_500ms=;
reflash_flag=;
//Uart_Send_String(".5s");
}
}
void Uart0_Isr()interrupt
{
unsigned char res=;
if (RI)
{
RI=;
res=SBUF;
if ((UART_RX_NUM&0x80)==)//?????
{
if (UART_RX_NUM&0x40)//?????????
{
if (res!=0x0a)UART_RX_NUM=;//?? rst
else UART_RX_NUM|=0x80; //????
}
else
{
if (res==0x0d)UART_RX_NUM|=0x40;//?????
else
{
RxBuffer[UART_RX_NUM&0x3f]=res;//????
UART_RX_NUM++;
if (UART_RX_NUM>)UART_RX_NUM=;
}
}
}
}
}
//---------------------------------------------------------------------------------------//
void DataDel(u8 *str,u8 len)
{
u8 i;
for (i=;i<len-;i++)
str[i]=str[i+];
}
void CMD_Compare(void) //
{
u8 tmp[]={};
u8 i,len; len=UART_RX_NUM&0x3f;//get the length
Uart_Send_String("\r\nWhat you have in put is:\r\n");
Uart_Send_String(RxBuffer);
Uart_Send_String("\r\n");
//get cmd
// for (i=0;i<8;i++)
// tmp[i]=RxBuffer[i];
strncpy(tmp,(const char*)RxBuffer,); //cmd explaine
if (strcmp("cmd_time",(const char*)tmp)==)
{
Uart_Send_String("now modify time!\r\n");
DataDel(RxBuffer,len);//del cmd to get data
//combine the data && transport from ascii to value
//ModifyTime(4,12,5,11,21,0);// 4-12 w5 tm11-21-00
ModifyTime((RxBuffer[]-'')* + RxBuffer[]-'', //month
(RxBuffer[]-'')* + RxBuffer[]-'',//day
(RxBuffer[]-''), //week
(RxBuffer[]-'')* + RxBuffer[]-'',//hr
(RxBuffer[]-'')* + RxBuffer[]-'',//min
(RxBuffer[]-'')* + RxBuffer[]-'');//sec
}
else if (strcmp("cmd_dimm",(const char*)tmp)==)
{
Uart_Send_String("now modify brightness!\r\n");
DataDel(RxBuffer,len);//del cmd to get data
i=(RxBuffer[]-'')*+(RxBuffer[]-'')*+(RxBuffer[]-'');
VFD_Brt_Set(i);
Uart_Send_String("dimming (0-240):");Uart_Send_String(RxBuffer);
}
else if (strcmp("cmd_svfd",(const char*)tmp)==)
{
Uart_Send_String("switch on or off vfd!\r\n");
DataDel(RxBuffer,len);//del cmd to get data
VFD_Disp_On_Off(RxBuffer[]-'');
}
else if(strcmp("cmd_spwr",(const char*)tmp)==)
{
Uart_Send_String("switch on or off lamp pwr!\r\n");
DataDel(RxBuffer,len);//del cmd to get data
vpwr=RxBuffer[]-'';
}
else if(strcmp("cmd_sbat",(const char*)tmp)==)
{
Uart_Send_String("start charging bat!\r\n");
lastChargeHour=normalTime[];//update charge hour
lastChargeDay=normalTime[];//update the day of last charging
}
VFD_DCRAM_Load();
//clr
for (i=;i<len;i++)
RxBuffer[i]=;
UART_RX_NUM=;//clr
} void Tim0_Init(void){
AUXR &= 0x7F; //?????12T??
TMOD &= 0xF0; //???????
TL0 = 0x30; //??????
TH0 = 0xF8; //??????
TR0 = ; //???0????
ET0=;
EA=;
} void Uart_Init(void) //115200bps@12.000MHz
{
SCON = 0x50; //8???,?????
AUXR |= 0x01; //??1?????2???????
AUXR |= 0x04; //???2???Fosc,?1T
T2L = 0xE6; //??????
T2H = 0xFF; //??????
AUXR |= 0x10; //?????2
ES=;
} void Uart_Send_Data(unsigned char dat)
{
SBUF = dat;
//while(!Uart_Snd_Flag);
//Uart_Snd_Flag = 0;
while(!TI);
TI=;
} void Uart_Send_String(unsigned char *str)
{
while(*str)
{
Uart_Send_Data(*str++);
}
}
//---------------------------------------------------------------------------------------//

主函数就是简单时钟读取和显示,电池充电控制逻辑。串口部分直接沿用以前代码,稍加修改就可以用了。

更多功能留给后续修改实现。电池待机时间有待测试,充电应该改为闹钟控制。

放图

未完待续。。。。

FUTABA 13-ST-84GINK + DS3231 时钟的更多相关文章

  1. [数据结构与算法-13]ST表

    ST表 主要用来快速查询静态数据区间最大值 思路 数组\(A[i][j]\)存储数列\(\{a_i\}\)中区间\(i \in [i, i+2^j)\)的最大值 查询时只需要查询\(max\{A[i] ...

  2. 玩转 RTC时钟库 DS3231

    1.前言     接着博主的上一篇 玩转 RTC时钟库 + DS1302,这一篇我们重点讲解DS3231时钟模块.没有看过上一篇的同学,麻烦先去阅读一下,因为很多理论基础已经在上一篇做了详细讲解,这里 ...

  3. Micropython TurnipBit 电子时钟 青少年编程入门

    电子时钟是一个很常用但是制作非常简单的小玩具了,对于Micropython初学者来说,制作一个电子时钟是非常简单又容易检验自己学习成果的实验了.TurnipBit相比于其他开发板,制作电子时钟就更加简 ...

  4. STM32单片机应用与全案例实践 /stm32自学笔记 第二版 pdf

    STM32单片机应用与全案例实践pdf https://pan.baidu.com/s/16WrivuLcHvLTwS__Zcwl6Q 4rj3 stm32自学笔记 第二版 pdf https://p ...

  5. STM32 SysTick定时器应用【worldsing笔记】

    SysTick是CM内核独立的定时器,时钟可以用内核内部的,也可以用芯片厂家(ST)的时钟,参考<Cortex-M3权威指南>的第13章: 另外也可以考<STM32F10xxx Co ...

  6. TS 数据流分析学习

    TS 流.包结构以及同步 1. TS 流: 可以将TS流理解为一种单一码流.混合码流. 单一码流:TS流的基本组成单位是长度为188字节的TS包. 混合码流:TS流有多种数据组成,一个TS包中的数据可 ...

  7. 如何制作一个Arduino温度数据记录仪

    在本项目中,我们将使用Arduino开发板制作一个温度数据记录仪,该设备从温度传感器LM35获取温度值,并从DS3231实时时钟模块获取时间.然后我们将使用mini SD卡模块将这些值存储在SD卡文件 ...

  8. R自动数据收集第二章HTML笔记1(主要关于handler处理器函数和帮助文档所有示例)

    本文知识点:     1潜在畸形页面使用htmlTreeParse函数 2startElement的用法 3闭包 4handler函数的命令和函数体主要写法 5节点的丢弃,取出,取出标签名称.属性.属 ...

  9. Web jquery表格组件 JQGrid 的使用 - 5.Pager翻页、搜索、格式化、自定义按钮

    系列索引 Web jquery表格组件 JQGrid 的使用 - 从入门到精通 开篇及索引 Web jquery表格组件 JQGrid 的使用 - 4.JQGrid参数.ColModel API.事件 ...

随机推荐

  1. iOS UIView 选择性倒角

    有些APP中会有卡券,卡券做成了选择性倒角,例如左上,右上倒角.非常美观.看一下iOS的实现: #import "Masonry.h" @interface WJWDaojiaoV ...

  2. [ipsec][crypto] IKEv2的协商交互分析

    一: 无论协商了什么样的加密算法.DH都交换一块长度为32byte的内存,作为key. IKE和esp的key,分别基于这块内存生成. 二: 当esp的算法协商没有指定dh group时,rekey将 ...

  3. 工作中对git使用的总结

    git与svn的区别,简单的说,       svn在checkout后,如果不提交,那么版本库没有记录,如果修改的文件比较多,中间想回退几个文件,非常麻烦.git 是clone下来代码和记录,不提交 ...

  4. sleep wait yield

    sleep 暂停当前线程,允许低优先级线程获得执行机会,但并不释放对象的锁,进入不可运行状态 yield 类似sleep,但只允许同优先级有获得执行机会,同样也不会释放锁,当前线程仍是可运行状态,因此 ...

  5. idea将maven项目打包成war包

    1.单击红色方框处 2.在IDEA右侧出现maven project选项 3.单击maven project选项,出现Spring MVC Basic Feature菜单,选择 其中的Lifecycl ...

  6. 讨论mui 的 mui.init 与 mui.plusReady

    先来看一段代码 (function(m, doc) { mui.plusReady(function(){ var self = plus.webview.currentWebview(); olti ...

  7. photoshop 修改pdf文件并保存为pdf

    1.CTRL + O   打开要编辑的pdf文件 按住shift 选中每一页,点击确定. pdf文档每一页以一个psd文件显示在工作区, 分别进行修改, 2.批量修改同一个元素(比如加个图标) 在一页 ...

  8. PL_SQL学习

    打印输出: dbms_output.put_line('AA'); 显示服务器输出信息  set serveroutput on; 打印出eid=1的员工姓名: declare v_name varc ...

  9. win10配置java环境变量,解决javac不是内部或外部命令等问题

    win10配置java环境变量,解决javac不是内部或外部命令等问题 https://www.cnblogs.com/qianji/p/6402690.html

  10. Java 基础 多线程进阶(锁,线程安全)

    一,前言 前面我们已经对线程和线程池有一定的了解,但是只要说到多线程,肯定需要考虑线程安全等问题.接下来我们就来好好聊聊这些问题. 二,线程安全 如果有多个线程在同时运行,而这些线程可能会同时运行这段 ...