📄 picservo.lst
字号:
346F 346C 346C
3465 3472 340D
340A 3400
00330
00331 ;+-----------------------------------------------------------------------------
00332 ;| SUBROUTINE: GetResetMsg
00333 ;|
00334 ;| return the character at offset in the W register for the Power On Message
00335 ;| returns 0 if at the end of the string
00336 ;+-----------------------------------------------------------------------------
0027 00337 GetResetMsg
0027 0782 00338 ADDWF PCL, f
0028 3452 3465 3473 00339 DT "Reset\r\n", 0
3465 3474 340D
340A 3400
00340
00341 ;+-----------------------------------------------------------------------------
00342 ;| SUBROUTINE: GetAddressOfServoData
00343 ;|
00344 ;| Returns the acutal memory address of the first data byte for the given servo
00345 ;| This is the Mask value, it is then followed by the offset and position.
00346 ;|
00347 ;| Call with W between 0 and 3. This routine will ensure the value is
00348 ;| within that range.
00349 ;+-----------------------------------------------------------------------------
0030 00350 GetAddressOfServoData
0030 3907 00351 ANDLW 07h ; Ensure that there is a max of 7.
MPASM 4.02 Released PICSERVO.ASM 12-31-2006 11:50:00 PAGE 8
LOC OBJECT CODE LINE SOURCE TEXT
VALUE
0031 0782 00352 ADDWF PCL, f ; Jump into the commands below to return
00353 ; the correct value
0032 340C 340F 3412 00354 DT Servo0_Mask, Servo1_Mask, Servo2_Mask, Servo3_Mask, Servo4_Mask, Servo5_Mask, Se
rvo6_Mask, Servo7_Mask
3415 3418 341B
341E 3421
00355
00356
00357
00358 ;+-----------------------------------------------------------------------------
00359 ;| Interrupt Routine.
00360 ;+-----------------------------------------------------------------------------
003A 00361 Interrupt
00362 ; Save the state of the W and STATUS registers
00363 ; Note this is the only way to do it properly
003A 00A4 00364 MOVWF Int_W_Save
003B 0803 00365 MOVF STATUS, w
003C 00A5 00366 MOVWF Int_STATUS_Save
00367
00368 ; Process the interrupt. Note that the only interrupt generated is the
00369 ; timer overflow.
00370 ;
00371 ; when the timer expires from the 19ms delay, we have to disable the CTS line
00372 ; so that the computer will not send us any more data, however we have to
00373 ; continue listening for data for a little while so that we don't miss any if
00374 ; it starts to send just as we deactivate the CTS line.
00375 ;
00376 ; Therefore we will wait for a further 2 bit times (about 1ms) before we signal
00377 ; the main routine that it is safe to process the servo pulses.
00378
00379 ; Check if we have just expired the short 1ms delay
003D 1DA6 00380 BTFSS Flag_WaitingForCTS
003E 2844 00381 GOTO Int_LongDelayFinished
00382
00383 ; our short delay has just expired, we need to signal to the
00384 ; main loop that it is now safe to proceed with the servo pulses
00385 ; and disable any further timer interrupts (the main loop will
00386 ; set them up again when it is ready)
003F 11A6 00387 BCF Flag_WaitingForCTS
0040 1526 00388 BSF Flag_ServoPulseSafe
0041 110B 00389 BCF INTCON, T0IF
0042 128B 00390 BCF INTCON, T0IE ; mask the timer interrupt
0043 284A 00391 GOTO Int_Finish
00392
00393 ; Our long delay has just expired. Disable CTS and setup for the short delay
0044 00394 Int_LongDelayFinished
0044 1505 00395 BSF Serial_CTS
0045 15A6 00396 BSF Flag_WaitingForCTS
0046 30F7 00397 MOVLW RTCC_1msValue
0047 0081 00398 MOVWF TMR0
0048 110B 00399 BCF INTCON, T0IF
0049 168B 00400 BSF INTCON, T0IE ; unmask the timer interrupt
00401
MPASM 4.02 Released PICSERVO.ASM 12-31-2006 11:50:00 PAGE 9
LOC OBJECT CODE LINE SOURCE TEXT
VALUE
004A 00402 Int_Finish
00403 ; Restore the STATUS and W registers
00404 ; Note that this is the only way to do it properly
004A 0825 00405 MOVF Int_STATUS_Save, w
004B 0083 00406 MOVWF STATUS
004C 0EA4 00407 SWAPF Int_W_Save, f
004D 0E24 00408 SWAPF Int_W_Save, w
00409
004E 0009 00410 RETFIE ; return from interrupt and reset GIE
00411
00412
00413
00414 ;+-----------------------------------------------------------------------------
00415 ;| SUBROUTINE: DelayWByFour
00416 ;|
00417 ;| Wait the number of 4 instruction cycles given in the W register. Note that
00418 ;| a value of zero will actually result in a delay of 256*4 instructions
00419 ;| because the loop decrements W each iteration as the first instruction,
00420 ;| so the zero will rollover to 255 and the loop will continue until it hits
00421 ;| zero again.
00422 ;|
00423 ;| This version of the Delay add no extra cycles to the loop.
00424 ;|
00425 ;| The numbers in brackets indicate the number of instructions in a normal
00426 ;| loop execution. However there are fixed costs to calling this routine which
00427 ;| need to be accounted for if accurate timing is to be generated.
00428 ;|
00429 ;| Each time the instruction pointer is adjusted (by a GOTO, CALL, RETURN etc)
00430 ;| the CPU stalls for an extra cycle resulting in an instruction taking 2 cycles.
00431 ;| Note that when the bit test results in a skip, the GOTO is effectivly treated
00432 ;| as a NOP so the loop consists of only 3 instructions before the return so
00433 ;| we need to add an extra NOP to bring the total in the iteration up to 4
00434 ;|
00435 ;| Therefore the following are the extras that need to be accounted for:
00436 ;| Call Entering: 2
00437 ;| Call Return: 2
00438 ;| ---------------------
00439 ;| Total: 4
00440 ;|
00441 ;| Meaning that one less loop is actually required to get the correct timing.
00442 ;|
00443 ;| Some timing examples, the number of cycles that "CALL DelayWByFour" takes:
00444 ;| W cycles
00445 ;| --------------
00446 ;| 0 4+256*4 = 1028
00447 ;| 1 4+1*4 = 8
00448 ;| 2 4+2*4 = 12
00449 ;| 3 4+3*4 = 16
00450 ;| ...
00451 ;| 255 4+255*4 = 1024
00452 ;|
00453 ;+-----------------------------------------------------------------------------
004F 00454 DelayWByFour
MPASM 4.02 Released PICSERVO.ASM 12-31-2006 11:50:00 PAGE 10
LOC OBJECT CODE LINE SOURCE TEXT
VALUE
004F 3EFF 00455 ADDLW 0FFh ; (1) Subtract one from the W register.
0050 1D03 00456 BTFSS STATUS, Z ; (1) If we are at zero, then exit the loop
0051 284F 00457 GOTO DelayWByFour ; (2) loop
0052 0000 00458 NOP ; (1) adjust final loop to be 4
instructions
0053 0008 00459 RETURN
00460
00461
00462 ;+-----------------------------------------------------------------------------
00463 ;| SUBROUTINE: DoServoControlPulse
00464 ;|
00465 ;| Send a control pulse for a servo if it is active. This routine relies on the
00466 ;| caller setting the FSR (indirect addressing register) to the servo mask
00467 ;| for the correct server. It will then read the information it needs from it,
00468 ;| increment the FSR and access the servo's offset and position loop counts.
00469 ;|
00470 ;| Call with W between 0 and 3 indicating which servo to work with.
00471 ;+-----------------------------------------------------------------------------
0054 00472 DoServoControlPulse
00473 ; convert the servo number in W to an offset for the Mask byte data for
00474 ; the servo
0054 2030 00475 CALL GetAddressOfServoData
0055 0084 00476 MOVWF FSR
00477
00478 ; Get the Output Bit setting mask
0056 0800 00479 MOVF INDF, w ; get the mask byte
0057 00A9 00480 MOVWF CurrentServoMask
00481
00482 ; Modify the FSR to point to the next byte of data which is the
00483 ; offset loop counter, this is the number of 4 cycle
00484 ; loops to preform.
0058 0A84 00485 INCF FSR, f
00486
00487 ; Set the control bit high to begin the control pulse. Note that from
00488 ; now until it is set to low is part of the timimg pulse so instructions
00489 ; are critical. The number in brackets is the number of EXTRA cycles each
00490 ; instruction uses which are not directly related to the pulse time and
00491 ; need to be adjusted for This is easily done with the Offset value.
00492 ; Note that W still contains the output mask generated above.
0059 0486 00493 IORWF PORTB, f ; bit is set, any other are left unchanged
00494 ; pulse time starts at the end of this i
nstruction
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -