http://www.oocities.org/sstandfast/OBDII.htm

  1 // File: VPWM.jal
// Author: Shawn Standfast
// Version 1.00.2
// 11/1/2005
// Library for OBDII Variable Pulse Width Modulation on PIC16F877(A) @ 20MHz
//
// *Note - This library utilizes the CCPX Module, Timer 1, Timer 2 W/ Interrupts
// Also, be sure to be in Bank 0 before using any procedures in this
// library.
//
// This library is designed around the SAE J1850 VPWM standard. It is assumed
// that the bus is a CSMA/CR (Carrier Sense, Multiple Access, Collision Resolution)
// type bus. Ultimate bus control is determined by bit-by-bit arbitration. The
// general message format used is SOF + 1 or 3 Header Bytes + 10 or 8 Data Bytes
// + 1 CRC Byte + EOD + EOF. Max Frame Length = 12 Bytes
//
// Nominal Pulse widths are as follows:
// +-----------+--------------+
// | SYMBOL | Pulse Width |
// |-----------+--------------+
// | Active 1 | 64uS |
// | Passive 0 | 64uS |
// | |
// | Passive 1 | 128uS |
// | Active 0 | 128uS |
// | |
// | SOF | 200uS |
// | EOD | 200uS |
// | |
// | EOF | 280-300uS |
// +-----------+--------------+
// Functions: vpw_send(byte in data) return bit
// Procedures: vpw_receive()
// get_frame(byte in frame_num)
//
// I/O Pin Definitions and Directions
//
// pin_c2_direction = input
// pin_c1_direction = output
//
// vpwin is pin_c2
// vpwout is pin_c1 // Required Libraries:
include jpic // Set Bounds for Buffer Arrays
const array_check_indices = true const array0_start = 0xA0 // Output Array Start
const array0_end = 0xAC // Output Array End
const array1_start = 0xAD // Input Buffer Array 1 Start
const array1_end = 0xB9 // Input Buffer Array 1 End
const array2_start = 0xBA // Input Buffer Array 2 Start
const array2_end = 0xC6 // Input Buffer Array 2 End
const array3_start = 0xC7 // Input Buffer Array 3 Start
const array3_end = 0xD3 // Input Buffer Array 3 End
const array4_start = 0xD4 // Processing Buffer Array Start
const array4_end = 0xE0 // Processing Buffer Array End include bank_arrays // Other Constants
const rising = 0x05 // configure for capture on rising edge
const falling = 0x04 // configure for capture on falling edge
const per_short = 0x50 // number of cycles for 64uS for tmr1
const per_long = 0xA0 // number of cycles for 128uS for tmr1
const per_sof = 0xFA // number of cycles for 200uS for tmr1
const per_eof = 0xAF // #cycles 280uS, must use 1:8 prescaler for EOF detection
const comp_drive_low = 0x09 // for ccp2con to drive CCP2 pin low on compare
const comp_drive_high = 0x08 // for ccp2con to drive CCP2 pin high on compare
const comp_only = 0x0A // for ccp2con to flag only // I/O Pin Definitions and Directions
pin_c2_direction = input
pin_c1_direction = output
var bit vpwin is pin_c2
var bit vpwout is pin_c1
vpwout = false // Some Variables
// Byte Variables RESERVED FOR INTERRUPT ROUTINE
var byte tmr1_low_old = 0x00, tmr1_high_old = 0x00 // stores old tmr1 values
var byte tmr1_low_new = 0x00, tmr1_high_new = 0x00 // stores new tmr1 values
var byte delta_low = 0x00, delta_high = 0x00 // stores the difference between
// tmr1_old & tmr1_new
var bit pulse_rec = off // Configure ccpXmodule //--------------------------------------------------------
f877_ccp1con = 0x00
f877_ccp2con = 0x00 f877_ccpr2l = 0x00
f877_ccpr2h = 0x00 f877_ccpr1l = 0x00
f877_ccpr1h = 0x00 pir1_ccp1if = false // clear both CCP interrupt flags
pir2_ccp2if = false // Initialize Timer1------------------------------------------------------------
//
// max frame width = SOF + 11*(8 Data Bits) + 1 CRC Byte + EOF
// SOF = 200uS
// EOF = 300uS
// Max Byte Width (longest byte = 0b_1010_1010) = 128uS*8 = 1.024mS
// Max Data Width = 12*1024mS = 12.288mS
// max frame width = 12.788mS
// tmr1 overflows w/ a 1:4 prescaler @ 52.4288mS ample room for an entire frame
//
// //--------------------------------------------------------------------------- f877_t1con = 0x00 // 1:4 prescaler for timer1
t1ckps1 = on
tmr1if = false // clear interupt flag
f877_tmr1h = 0x00
f877_tmr1l = 0x00 // Initialize Timer 2 // --------------------------------------------------------
f877_t2con = 0x02 // 1:16 prescaler 1:1 postscaler for timer2
f877_tmr2 = 0x00 pir1_tmr2if = false // Initialize Periphial Interrupts // ------------------------------------------- asm BSF STATUS, // bank 1
tmr1ie = off // disable tmr1 interupt flag
pie1_ccp1ie = on // enable ccp1 interrupt flag
pie2_ccp2ie = off // disable ccp2 interrupt flag
pie1_tmr2ie = off // disable timer2 interrupts
f877_pr2 = 0x58
asm BCF STATUS, // bank 0 // disable interrupts //--------------------------------------------------------- intcon_gie = off
intcon_peie = off // vpw_idle_chk is for internal use to check for inactivity on the Com. Bus
procedure vpw_idle_chk is
tmr1on = false
vpwout = false // make sure only transmitting a low signal
pir2_ccp2if = false
t1ckps1 = on
t1ckps0 = on // set 1:8 prescaler for timer1 f877_tmr1l = 0x00 // reset timer one high and low bytes
f877_tmr1h = 0x00 f877_ccpr2l = per_eof // set period for compare to be ~280uS
f877_ccpr2h = 0x00 f877_ccp2con = comp_only // set CCP2 module to only flag when timer times out while vpwin loop end loop // loop until bus transisitions low tmr1on = on // start timer while ! pir2_ccp2if loop // wait while bus is low
if vpwin then // if activity detected on bus restart timer
f877_tmr1l = 0x00 // no need to reset high byte
end if
end loop pir2_ccp2if = false // clear interrupt flag tmr1on = false // stop timer 1 f877_tmr1l = 0x00 // reset timer 1
f877_tmr1h = 0x00 t1ckps0 = false // 1:4 prescaler for timer1
end procedure procedure crc_calc(byte in data, byte in out crc ) is // calculates the CRC byte
var byte bit_point = 0x80 // that is appended to the end of the OBD message Frame
var byte poly // NOTE* Procedure is to be called continuously for each
for loop // byte that is transmitted. However, once final byte is
if (bit_point & data) != then // passed through the CRC routine the final result in crc_reg
if (crc & 0x80) != then // must be complimented before appending to the message.
poly = 0x01 // For all messages, paramater CRC should be initialized to
else // 0xFF for the first itteration.
poly = 0x1C
end if
crc = ((crc << ) | ) ^ poly // original C Code for CRC posted on http:// obddiagnostics.com by B. Roadman
else // adapted to JAL by Shawn Standfast
poly = 0x00
if (crc & 0x80) != then
poly = 0x1D
end if
crc = (crc << ) ^ poly
end if
bit_point = bit_point >>
end loop
end procedure // Function vpw_send(byte in data) shifts out "data" one bit at a time
// MSB first. Arbritration is taken care of during transmission. If the
// transmission is successful then the function returns true else it returns
// false. Call procedure repeatedly to send multiple bytes. just be sure to
// only send one start of frame symbol per message frame. // Example Usage: *success is a var of type bit
// Send Single byte of data: success = vpw_send(data,true)
// tmr1on = false
// Send Multiple bytes in the same frame: success = vpw_send(data1,true)
// if success then
// success = vpw_send(data2,false)
// end if
// tmr1on = false
// Send "Array" of data:
// var bit send_sof = true
// var byte count = 0x00
// while ((success) & (count < arrayX_put_index)) loop
// temp = arrayX
// success = vpw_send(temp,send_sof)
// send_sof = false
// count = count + 1
// end loop
// tmr1on = false function vpw_send (byte in data, bit in send_sof) return bit is
asm bcf intcon_gie // disables interrupts while sending. otherwise we can get
asm bcf intcon_peie // into all sorts of trouble. :)
f877_ccp1con = 0x00
var bit error_flag = false
var volatile bit bit_out at data : // select bit to be transmitted
var bit dom_pass = false // keep track of active or passive symbol
var byte timer_low_byte, timer_high_byte, prtc_buf
var volatile byte next_bit = 0x00 // sets next pulse width for loop // shift data out one bit at a time; MSB first if bit_out then // if bit to be sent is a One
if dom_pass then // send "Active" One
next_bit = per_short
else // send "Passive" One
next_bit = per_long
end if
else // Bit to be sent is a Zero
if dom_pass then // send active zero
next_bit = per_long
else // send "Passive" zero
next_bit = per_short
end if
end if
// start of frame takes care of period adjustment for first bit. If current
// itteration is not sending a SOF, must adjust new period by adding pulse width
// to current ccp2H:ccp2L registers. if send_sof then // need to send a start of frame first?
// send start of frame plus first bit
vpw_idle_chk // verify bus is idle before beginning transmission f877_ccp2con = comp_drive_low // bus will be high for SOF. Drive bus low
// when pulse width is achieved. should also
// drive output pin high beginning transmission tmr1on = on // begin timing bus position f877_ccpr2l = per_sof // set period for compare to be ~200uS
f877_ccpr2h = 0x00 pir2_ccp2if = false error_flag = false // assume success unless failure occurs while ! pir2_ccp2if loop end loop // wait until timer2 times out. Once
// this loop is exited our SOF symbol
// will have finished and our output
// pin will be low.
// If the bus is still active then that means another node is still
// transmitting. The only other allowed active symbol that lasts for
// this duration is a BREAK symbol. So we poll the bus for the shortest
// allowed BREAK time. If this is passed then we will cease our attempt
// to transmit.
while vpwin loop // allows for nodes with slower clocks to finish their
assembler // SOF's.
local shorter
movf f877_tmr1h,w // The new starting point for the compare register
movwf f877_ccpr2h // is updated while the other nodes finish.
movf f877_tmr1l,w
movwf f877_ccpr2l
movf f877_tmr1h,w // ensures proper loading of CCP2 with the current
movwf f877_ccpr2h // timer value
bcf status_Z
movlw 0x01
subwf f877_ccpr2h,w // magnitude comparison of the current high byte
BTFSS status_Z // if the current timer value is greater than
GOTO shorter // 0x128 then the maximum allowed transmission
movlw 0x28 // length for a SOF has been reached. If it isnt
bsf status_C
subwf f877_ccpr2l,w // then we need to poll the bus again and repeat.
BTFSS status_C
GOTO shorter
bsf error_flag
shorter:
end assembler
if error_flag then
vpwout = false
tmr1on = false
f877_tmr1l = 0x00
f877_tmr1h = 0x00
f877_ccp2con = 0x00
return false
end if
end loop // SOF is always followed by data bytes. Prep for first bit to be sent
assembler // add next period to compare reference, 8-bit + 16-bit
bank MOVF next_bit,W
bank ADDWF f877_ccpr2l,f
BTFSC status_C
bank INCF f877_ccpr2h,f
end assembler asm clrf f877_ccp2con // first bit to be transmitted is always low
f877_ccp2con = comp_drive_high // set ccp2 to drive output high on match pir2_ccp2if = false // reset interrupt flag
send_sof = false // no more start of frame symbols to transmit
else // just send the remaining bits
assembler // add next period to compare reference. 8-bit + 16-bit
bank MOVF next_bit,W
bank ADDWF f877_ccpr2l,f
BTFSC status_C
bank INCF f877_ccpr2h,f
end assembler
end if while ! pir2_ccp2if loop // wait until end of period, when loop is
// exited bus transition should be done.
prtc_buf = port_c // Check for arbitration. If output does not
prtc_buf = prtc_buf & 0x06 // match input then arbitration may be lost.
if ((prtc_buf == 0x04) & (! pir2_ccp2if)) then
assembler
bcf tmr1on // Comparison between the bus transition time
// and the time remaining before bus expected
// transition is used to compensate for clock
// mismatch. Therefore false "lost arbritration"
// is avoided. This portion only checks for nodes
// that transition early. Nodes that transition
// later are dealt with after this portion.
bsf status_C
bcf status_Z local EXITE, EXIT
MOVF f877_tmr1l,W // determine delta between expected transition
SUBWF f877_ccpr2l,w // and actual transition time.
movwf timer_low_byte // timer_X_byte = ccpr2X - f877_tmr1X
MOVF f877_tmr1h,W
BTFSS status_C
INCF f877_tmr1h,W
SUBWF f877_ccpr2h,w
movwf timer_high_byte
btfss status, status_z // the difference between high bytes must be zero
goto EXITE
movlw 0x14 // to be within tolerance the difference must be less
bsf status_C // than 20 instructions. Setting the Carry/Borrow bit
subwf timer_low_byte,w // makes it available to borrow.
BTFSS status_C // If the low byte is >= 20 then a borrow
goto EXIT // will not have occured and status_c will still be set.
BTFSC status_Z // If the result is 0 then transition occured right on
goto EXIT // the boundary and is still valid.
EXITE: // check somewhere has not passed.
bsf error_flag
EXIT:
end assembler
if (error_flag) then // bus dominance lost.
vpwout = false // "Shut up and try again later"
tmr1on = false
f877_tmr1l = 0x00
f877_tmr1h = 0x00
f877_ccp2con = 0x00
return false
else // early transitioning node transitioned within specs. Change
f877_tmr1l = f877_ccpr2l // output and move on.
f877_tmr1h = f877_ccpr2h
tmr1on = on
end if
end if
if ((prtc_buf == 0x02) & (! pir2_ccp2if)) then // bus fault has been detected. Try again later.
vpwout = false
tmr1on = false
f877_tmr1l = 0x00
f877_tmr1h = 0x00
f877_ccp2con = 0x00
return false
end if
end loop pir2_ccp2if = false // reset ccp2 interrupt flag if dom_pass then // switch transition directions
// first must allow for nodes that are transmitting their active signals
// for just a little bit longer than we are. For the short pulse, the
// maximum allowed overshoot in time is 32uS and for the long pulse the
// maximum allowed overshoot in time is 34uS. Splitting the difference
// we will check for 33uS. However, I believe this to be incorrect and used 16uS.
if vpwin then // bus is still active
assembler
local loop1, done, exita
movlw comp_only
movwf f877_ccp2con
MOVlW 0x14
bank ADDWF f877_ccpr2l,f
BTFSC status_C
bank INCF f877_ccpr2h,f
loop1:
BTFSS vpwin // loops until either the input pin changes
goto done // or our "added" time expires.
BTFSS pir2_ccp2if
goto loop1
bcf tmr1on // if the program gets here then that means the input
bcf vpwout // is still set and our timer period has expired. If
clrf f877_tmr1l // we were sending a short pulse then it means arbitration
clrf f877_tmr1h // has been lost. If it is a long pulse then it could
clrf f877_ccp2con // mean a break symbol is being transmitted. Either way
bsf error_flag // we need to stop transmitting and exit.
bcf pir2_ccp2if
goto exita
done:
clrf f877_ccp2con // updates the compare registers with new
movf f877_tmr1h,w // starting values
movwf f877_ccpr2h
movf f877_tmr1l,w
movwf f877_ccpr2l
movf f877_tmr1h,w
movwf f877_ccpr2h
bcf pir2_ccp2if
exita:
end assembler
if error_flag then
return false
end if
end if
f877_ccp2con = comp_drive_high // if previously sending an active signal
dom_pass = false // next symbol will be passive. Ergo need
else // to drive bus high on next compare.
f877_ccp2con = comp_drive_low // Same logic here just opposite results
dom_pass = on // No need to check for devices with "longer"
end if // periods here because we have driven the
// bus high already.
data = data << // shift in next bit to be sent
end loop
return true
end function // procedure vpw_receive configures the ccp1 module to capture timer 1 and timer2
// to time inactivity. First ccp1 is configured to interrupt on the rising
// edge. On the first rising edge, timer 1 is started and the ccp1 module is
// reset for falling edge int. On the following edge interrupts, the two different
// captured timer 1 values are subtracted from each other to determine the
// pulse witdh. Then based upon which direction of the interrupting edge, the
// symbol is decoded. Once a SOF character has been decoded timer2 is enabled to start
// counting out 280uS to determine if IFS has been satisfied. Timer2 is reset
// on each valid pulse received. Therefore, timer2 clocks 280uS from the last bit received.
// Once a bit is received, it is placed in a bit buffer that is shifted left
// after each bit. When 8 bits have been received, that byte is placed into
// the first available frame buffer array. // ***NOTE*** In-Frame Response has NOT been implimented yet!! If you are using
// this library for a VPW system that requires IFR then you will need to add it.
// I will get around to adding it sometime in the near future but right now I do
// not need it (GM doesn't use IFR).
// //-------------------------------------------------------------------------- function vpw_receive return bit is var byte delta_low_old = 0x00, delta_high_old = 0x00 // buffers delta bytes
var volatile byte rec_buff = 0x00 // buffers the current received byte before
// loading into the buffer array
var byte bit_count = 0x00 // counts number of bits received
var volatile bit bit_rec = false // holds current received bit
var volatile bit data_rec = false // determines whether data has been received
var volatile bit bit_buff at rec_buff : // stores current received bit
var volatile bit long_short = false // flag indicating long or short pulse
var volatile bit brk_rec = false // flag indicating a BRK symbol has been received
var volatile byte ccpconfig = 0x00 // stores current ccp1 configuration
var volatile bit sof_rec = false f877_tmr1l = 0x00 // reset timer 1
f877_tmr1h = 0x00
tmr1_low_old = 0x00 // reset tmr1 storage variables
tmr1_high_old = 0x00
array4_put_index = 0x00 // reset processing buffer index to 0
pulse_rec = false
f877_ccp2con = 0x00 intcon_gie = on // enable interrupts
intcon_peie = on pir1_tmr2if = false vpw_idle_chk // wait until beginning of next frame before starting to receive asm clrf f877_ccp1con
f877_ccp1con = rising while ! pir1_tmr2if loop
while ! pulse_rec loop end loop
pulse_rec = false
delta_low_old = delta_low // buffer the delta values incase interrupt occurs
delta_high_old = delta_high // before we finish working with this pulse
ccpconfig = f877_ccp1con // buffer ccp1 configuration incase interrupt
// occurs before we finish working with this pulse if ((delta_high_old == 0x00) ) then
if delta_low_old >= 0xCC then
sof_rec = on
tmr2on = on
bit_count = 0x00
f877_tmr2 = 0x00
array4_put_index = 0x00
elsif ((delta_low_old <= 0xCB) & (delta_low_old >= 0x78)) then
long_short = on
data_rec = on
f877_tmr2 = 0x00
elsif ((delta_low_old <= 0x77) & (delta_low_old >= 0x2A)) then
long_short = off
data_rec = on
f877_tmr2 = 0x00
else
data_rec = false
end if
elsif ((delta_high_old == 0x01) ) then
if ((delta_low_old >= 0x2B) & (! pir1_tmr2if)) then
brk_rec = on
sof_rec = false
data_rec = false
long_short = false
tmr1on = false
tmr2on = false
f877_tmr1l = 0x00
f877_tmr1h = 0x00
f877_tmr2 = 0x00
array4_put_index = 0x00
tmr1_low_old = 0x00
tmr1_high_old = 0x00
delta_low_old = 0x00
delta_high_old = 0x00
asm clrf f877_ccp1con
f877_ccp1con = rising
elsif delta_low_old < 0x2B then
sof_rec = on
tmr2on = on
pir1_tmr2if = false
bit_count = 0x00
f877_tmr2 = 0x00
array4_put_index = 0x00
end if
end if
if data_rec & sof_rec then
if ccpconfig == rising then // if the next interrupt edge will be rising
if long_short then // then that means the previous pulse was active.
bit_rec = off // that means a long pulse = 0 and a short pulse = 1
else
bit_rec = on
end if
else // next interrupt edge will be falling, indicating the
if long_short then // previous pulse was passive. long_pulse = 1 & short_pulse = 0
bit_rec = on
else
bit_rec = off
end if
end if
rec_buff = rec_buff <<
bit_buff = bit_rec
data_rec = false
bit_count = bit_count +
end if
if bit_count == 0x08 then
array4 = rec_buff
bit_count = 0x00
end if
end loop
tmr1on = false
tmr2on = false
f877_ccp1con = 0x00
f877_tmr1l = 0x00
f877_tmr1h = 0x00
f877_tmr2 = 0x00
pir1_tmr2if = false
pir1_ccp1if = false intcon_gie = false
intcon_peie = false
return brk_rec
end function // Table for determining pulse widths from delta values:
// |long pulse| short pulse| SOF | break |
// | max | min | max | min | max | min | max | min |
// delta_high |0x00 | 0x00| 0x00 | 0x00| 0x01| 0x00| 0x01| 0x01|
// delta_low |0xCC | 0x78| 0x78 | 0x2A| 0x2B| 0xCC| 0x2B| 0x2B|
//
// Logic Flow: If delta_high > 0 then either SOF or BREAK
// if delta_low - 0x2B > 0 & delta_high > 0 then it is a break
// if delta_low - 0x2B <= 0 & delta_high > 0 then it is a SOF
// cases for delta_high == 0
// IF delta_low - 0xCC > 0 then it is a SOF
// If delta_low - 0x78 >= 0 & delta_low - 0xCC < 0 then it is a long pulse
// if delta_low - 0x2A >= 0 & delta_low - 0x78 < 0 then it is a short pulse
// if delta_low - 0x2A < 0 then it is too short procedure interrupt_handler is // edge has been detected on ccp1
pragma interrupt
tmr1_low_new = f877_ccpr1l
tmr1_high_new = f877_ccpr1h
// tmr1_new - tmr1_old = delta
assembler // 16-bit subtraction of old values from the new
btfss tmr1on
bsf tmr1on
bank MOVF tmr1_low_old,W
bank SUBWF tmr1_low_new,W
bank MOVWF delta_low
bank MOVF tmr1_high_old,W
BTFSS status_C
INCFSZ tmr1_high_old,W
bank SUBWF tmr1_high_new,W
bank MOVWF delta_high
end assembler
tmr1_low_old = tmr1_low_new // replace old values with new ones
tmr1_high_old = tmr1_high_new if ccp1m0 then // rising edge interrupt has been detected on ccp1
assembler
clrf f877_ccp1con // configure for falling edge
movlw falling
movwf f877_ccp1con
end assembler
else
// falling edge detected
assembler
clrf f877_ccp1con
movlw rising
movwf f877_ccp1con
end assembler
end if
pir1_ccp1if = false
pulse_rec = on
end procedure

OBDII Interface Project Source Code的更多相关文章

  1. Using command-line Subversion to access project source files

    Help index About source code version control with Software Configuration Management (Subversion) Usi ...

  2. Tips for newbie to read source code

    This post is first posted on my WeChat public account: GeekArtT Reading source code is always one bi ...

  3. Spring 4 MVC example with Maven - [Source Code Download]

    In this tutorial, we show you a Spring 4 MVC example, using Maven build tool. Technologies used : Sp ...

  4. source code analyzer 功能强大的C/C++源代码分析软件 Celerity CRACK 破解版

    特色 迅捷是一个功能强大的C/C++源代码分析软件.可以处理数百万行的源程序代码.支持标准及K&R风格的C/C++.对每一个打开的源代码工程,通过建立一个包含丰富交叉引用关系的数据库,显示其所 ...

  5. Indenting source code

    Artistic Style 1.15.3 A Free , Fast and Small Automatic Formatterfor C , C++ , C# , Java Source Code ...

  6. How to build the Robotics Library from source code on Windows

    The Robotics Library is an open source C++ library for robot kinematics, motion planning and control ...

  7. How to build windows azure PowerShell Source Code

    Download any version source code of Windows Azure Powershell from https://github.com/Azure/azure-sdk ...

  8. 3 Ways of JDK Source Code Attachment in Eclipse---reference

    You wanna look at a JVM class while you are coding and you cannot. Here is the solution. First of al ...

  9. Android Branch and master source code merge(patch)

    Environment : Android 4.4.2 merge with Android 4.4.3(with other vendors source code) 1.确定你要merge 到 其 ...

随机推荐

  1. 关于LookUp的切换实例

    在关注了很久后发现还是有太多的东西没有记住,需要自己一步一步地去学习!不用太关注太多的杂乱的事,只用关注自己一点一滴,我相信所有的一切都会有一个很好的结局.

  2. Codeforces 354B dp Game with Strings dp

    Game with Strings 题意并不是在图上走,看了好久才看出来.. dp[ i ][ mask ]表示从 i 层开始走,起点有mask个, a的个数-b的个数的  最大值或者最小值. #in ...

  3. Codeforces 965E Short Code 启发式合并 (看题解)

    Short Code 我的想法是建出字典树, 然后让后面节点最多的点优先向上移到不能移为止, 然后gg. 正确做法是对于当前的节点如果没有被占, 那么从它的子树中选出一个深度最大的点换到当前位置. 用 ...

  4. HDU1814 Peaceful Commission 2-sat

    原文链接http://www.cnblogs.com/zhouzhendong/p/8099115.html 题目传送门 - HDU1814 题面 Description 根据宪法,Byteland民 ...

  5. 001_JavaScript学习

    1,面向对象,事件驱动 2,动态,交互性 3,解释性语言,非强(弱)类型变量:不用声明,解释时检查类型 4,区分大小写,嵌入html,句尾加分号,可以独立保存为一个外部文件,但其中不能包含<sc ...

  6. systemd创建自定义服务(Ubuntu)

    /lib/systemd/system下创建test.service文件 vim /lib/systemd/system/test.service [Unit] Description=test [S ...

  7. 041 Spring Boot中排除功能的处理

    这个问题,原本是没有注意,主要是理解的不够深刻. 1.先看我的配置文件 package com.springBoot.ioc.config; import com.springBoot.ioc.con ...

  8. day38 mycql 初识概念,库(增删改查),表(增删改)以及表字段(增删改查),插入更新操作

    在Navicat中把已经生成的表逆向成模型 数据库上,右键-逆向数据库到模型 ego笔记: 增删改查 文件夹(库) 增 create database day43 charset utf8; 改 al ...

  9. HDFS常用API(2)

    一.读取HDFS文件数据.将本地文件写入HDFS中文件.使用IOUtils读写数据 ** * @author: PrincessHug * @date: 2019/3/18, 17:24 * @Blo ...

  10. Vue 中 computed、watch对比

    computed:就像调用VUE的DATA一样 watch的对比 :监听事件