⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 csd2x_1hl.asm

📁 带触摸按键的高端电磁炉设计 该方案采用CYPRESS的新器件CY8C22545,是一款专门针对中高端的家电触摸产品设计。除了集成触摸按键功能外
💻 ASM
📖 第 1 页 / 共 3 页
字号:
.ENDSECTION

IF CSD2X_1_SLIDERS_EXIST
.SECTION
;-----------------------------------------------------------------------------
;  FUNCTION NAME: CSD2X_1_wGetCentroidPos(BYTE bSnsGroup)
;
;  DESCRIPTION:
;      Checks the difference array for a centroid.  If one exists, the offset
;      (within the whole difference arrary) and length are placed in the
;      bCentroidLength and bCentroidStart variables.
;
;      Then the function finds and returns the position of the centroid in the
;      difference array.
;
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;       A => Sensor Group
;       Sensor Group = 0 for the independent sensors group
;       Sensor Group = 1 for the first slider group
;       Sensor Group = 2 for the second slider group
;
;  RETURNS:
;      iCtrdPos -> position of the centroid
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16
;    functions.
;
 CSD2X_1_wGetCentroidPos:
_CSD2X_1_wGetCentroidPos:
; Legacy function name labels below, do not use for new designs
 CSD2X_1_bGetCentroidPos:
_CSD2X_1_bGetCentroidPos:
 CSD2X_1_iGetCentroidPos:
_CSD2X_1_iGetCentroidPos:
; End legacy function names
   RAM_PROLOGUE RAM_USE_CLASS_3
   RAM_SETPAGE_CUR 0 ; direct access ram will always be in interrupt ram area

; First get the starting location and size of this sensor group
   asl A ; multiply by two to get diplex
   mov X, A
   index CSD2X_1_Diplex_Table ; get the diplex table MSB and LSB
   mov [CSD2X_1_bDiplexMSB], A
   mov A, X
   inc A
   index CSD2X_1_Diplex_Table
   mov [CSD2X_1_bDiplexLSB], A
   mov A, X
   mov [CSD2X_1_bStartIndex], A ; Use bStartIndex as a temp storage byte
   asl A
   add [CSD2X_1_bStartIndex], A
   mov A, [CSD2X_1_bStartIndex] ; A now has slider offset multiplied by six
   mov X, A
   index CSD2X_1_Group_Table ; get first sensor index
   mov [CSD2X_1_bEndOfArray], A
   mov [CSD2X_1_bCurPos], A
   mov [CSD2X_1_bStartIndex], A
   mov A, X
   inc A
   index CSD2X_1_Group_Table ; get size of group
   add [CSD2X_1_bEndOfArray], A ; Store for later
   mov A, X
   add A, 2
   index CSD2X_1_Group_Table ; get if diplexed or not and max size of centroid (data = 0 if not diplexed)
   mov [CSD2X_1_bDiplexInfo], A ; Store for later
   mov A, X
   add A, 3
   mov [CSD2X_1_bSnsMaskPtr], A ; Store starting position in an unused temp CSD2X_1_bSnsMaskPtr

; First find the starting location and size of the largest centroid
   mov [CSD2X_1_bBiggestCtrdStartPos], 0
   mov [CSD2X_1_bBiggestCtrdSize], 0
   mov [CSD2X_1_bCurCtrdStartPos], 0
   mov [CSD2X_1_bCurCtrdSize], 0

   mov A, [CSD2X_1_bStartIndex]
   asl A ; multiply by two because we are using ints
   mov X, A

.LocateCtrd:
   RAM_SETPAGE_IDX >CSD2X_1_waSnsDiff
   mov A, [X+CSD2X_1_waSnsDiff]
   jnz .DiffIsNotZero
   mov A, [X+CSD2X_1_waSnsDiff+1]
   jnz .DiffIsNotZero
; The difference is zero, we either just ended a centroid or are between centroids
; First check the Current Size, if zero, we are in the middle of zeros, else, we just ended
.DifferenceIsZero:
   mov A, [CSD2X_1_bCurCtrdSize]
   jz .LocateCtrdNextSensor
; A centroid just ended.  Is it the largest centroid?
   cmp A, [CSD2X_1_bBiggestCtrdSize]
   jc .ClearCurCtrdSize
; It is the biggest so far, store as biggest
   mov [CSD2X_1_bBiggestCtrdSize], [CSD2X_1_bCurCtrdSize]
   mov [CSD2X_1_bBiggestCtrdStartPos], [CSD2X_1_bCurCtrdStartPos]
.ClearCurCtrdSize:
   mov [CSD2X_1_bCurCtrdSize], 0
   jmp .LocateCtrdNextSensor

;The difference is not zero, we either just started, or are in the middle of a centroid
.DiffIsNotZero:
   mov A, [CSD2X_1_bCurCtrdSize]
   jnz .IncCtrdSize
; Centroid just began, store the start pos
   mov A, [CSD2X_1_bCurPos]
   mov [CSD2X_1_bCurCtrdStartPos], A
.IncCtrdSize:
   inc [CSD2X_1_bCurCtrdSize]
; Find out the next position
.LocateCtrdNextSensor:
   inc X
   inc X
   inc [CSD2X_1_bCurPos]
   mov A, [CSD2X_1_bCurPos]
   cmp A, [CSD2X_1_bEndOfArray] ; Check for the end of the array
   jc .LocateCtrd
; Either at end of array, or diplexed
   tst [CSD2X_1_bDiplexInfo], 0xff ; check if diplexed
   jz .EndOfLocateCtrd
; Diplexed, so now find out if at end
   sub A, [CSD2X_1_bEndOfArray] ; subtract the size of the array
   add A, [CSD2X_1_bStartIndex] ; for comparison
   cmp A, [CSD2X_1_bEndOfArray] ; Check for the end of the array
   jnc .EndOfLocateCtrd
; Not the end of the diplexed array, find out offset of next position
   mov A, [CSD2X_1_bCurPos]
   sub A, [CSD2X_1_bStartIndex]
   add A, [CSD2X_1_bDiplexLSB]
   mov X, A
   mov A, [CSD2X_1_bDiplexMSB]
   adc A, 0 ; check if carry
   romx ; get the offset from the start
   add A, [CSD2X_1_bStartIndex]
   asl A ; because using ints
   mov X, A
   jmp .LocateCtrd
.EndOfLocateCtrd:
; Need to check if the current centroid is biggest
   mov A, [CSD2X_1_bCurCtrdSize]
   jz .CalculateCtrd
; There was a centroid at the end, is it biggest?
   cmp A, [CSD2X_1_bBiggestCtrdSize]
   jc .CalculateCtrd ; if two are the same size, last one wins
; It is the biggest so far, store as biggest
   mov [CSD2X_1_bBiggestCtrdSize], [CSD2X_1_bCurCtrdSize]
   mov [CSD2X_1_bBiggestCtrdStartPos], [CSD2X_1_bCurCtrdStartPos]

.CalculateCtrd:
   mov A, [CSD2X_1_bBiggestCtrdSize]
   jz .COM_Error
   mov A, [CSD2X_1_bDiplexInfo] ; check if diplexed
   jz .COM_Init
   cmp [CSD2X_1_bBiggestCtrdSize], 2
   jc .COM_Error ; for diplexing, one or less is too small
   cmp A, [CSD2X_1_bBiggestCtrdSize]
   jc .COM_Error ; for diplexing, check if centroid is too large

.COM_Init:
   mov A, [CSD2X_1_bBiggestCtrdStartPos] ; Use for current position, may be diplexed
   mov [CSD2X_1_bCurPos], A
   mov [CSD2X_1_wDenom+MSB], 0 ; Clear the numerator and denominator
   mov [CSD2X_1_wDenom+LSB], 0
   mov [CSD2X_1_dNumer+MMSB], 0
   mov [CSD2X_1_dNumer+MLSB], 0
   mov [CSD2X_1_dNumer+LMSB], 0
   mov [CSD2X_1_dNumer+LLSB], 0

.COM_NextPosition:
   mov A, [CSD2X_1_bCurPos]
   cmp A, [CSD2X_1_bEndOfArray]
   jnc .COM_CheckDiplex
   asl A
   mov X, A
   jmp .COM_AddElement
; Must be diplexed, check for safe measure
.COM_CheckDiplex:
   tst [CSD2X_1_bDiplexInfo], 0xff ; check if diplexed
   jz .COM_Compute
; Find out offset of next position
   mov A, [CSD2X_1_bCurPos]
   sub A, [CSD2X_1_bStartIndex]
   add A, [CSD2X_1_bDiplexLSB]
   mov X, A
   mov A, [CSD2X_1_bDiplexMSB]
   adc A, 0 ; check if carry
   romx ; get the offset from the start
   add A, [CSD2X_1_bStartIndex]
   asl A ; because using ints
   mov X, A
.COM_AddElement:
; Subtract the noise from the difference, this will yield a more accurate result
   RAM_SETPAGE_IDX >CSD2X_1_waSnsDiff
   mov A, [CSD2X_1_bNoiseThreshold]
   sub [X+CSD2X_1_waSnsDiff+LSB], A
   sbb [X+CSD2X_1_waSnsDiff+MSB], 0
; Store a copy of the sensor difference in CSD2X_1_dMultTempX
   mov A, [X+CSD2X_1_waSnsDiff+LSB]
   mov [CSD2X_1_dMultTempX+LLSB], A
; Add LSB to denominator
   add [CSD2X_1_wDenom+LSB], A
   mov A, [X+CSD2X_1_waSnsDiff]
   mov [CSD2X_1_dMultTempX+LMSB], A
   mov [CSD2X_1_dMultTempX+MLSB], 0
   mov [CSD2X_1_dMultTempX+MMSB], 0
; Add MSB to denominator
   adc [CSD2X_1_wDenom], A
   mov A, [CSD2X_1_bCurPos]
   sub A, [CSD2X_1_bStartIndex] ; we need offset from beginning of group
   mov [CSD2X_1_wDivBtwSns+MSB], 0
   mov [CSD2X_1_wDivBtwSns+LSB], A

   call .MultiplyNumeratorWhole

   inc [CSD2X_1_bCurPos]
   dec [CSD2X_1_bBiggestCtrdSize]
   jz .COM_Compute
   jmp .COM_NextPosition

.COM_Compute:
   mov A, [CSD2X_1_dNumer+LLSB] ; Move numerator to temp
   mov [CSD2X_1_dMultTempX+LLSB], A
   mov [CSD2X_1_dMultTempY+LLSB], A
   mov A, [CSD2X_1_dNumer+LMSB]
   mov [CSD2X_1_dMultTempX+LMSB], A
   mov [CSD2X_1_dMultTempY+LMSB], A
   mov A, [CSD2X_1_dNumer+MLSB]
   mov [CSD2X_1_dMultTempX+MLSB], A
   mov [CSD2X_1_dMultTempY+MLSB], A
   mov A, [CSD2X_1_dNumer+MMSB]
   mov [CSD2X_1_dMultTempX+MMSB], A
   mov [CSD2X_1_dMultTempY+MMSB], A

   mov [CSD2X_1_dNumer+MMSB], 0 ; Clear numerator
   mov [CSD2X_1_dNumer+MLSB], 0
   mov [CSD2X_1_dNumer+LMSB], 0
   mov [CSD2X_1_dNumer+LLSB], 0

   mov A, [CSD2X_1_bSnsMaskPtr] ; Retrieve starting position in index of the DivBtwSns
   push A
   index CSD2X_1_Group_Table ; get MSB of whole multiplier
   mov [CSD2X_1_wDivBtwSns+MSB], A
   pop A
   inc A
   push A
   index CSD2X_1_Group_Table ; get LSB of whole multiplier
   mov [CSD2X_1_wDivBtwSns+LSB], A
   call .MultiplyNumeratorWhole ; Multiplies by whole part
   pop A
   inc A
   index CSD2X_1_Group_Table ; get byte of fractional multiplier
   mov [CSD2X_1_wDivBtwSns+LSB], A
   call .MultiplyNumeratorFraction ; Multiplies by fractional part

; Now do the division of the numerator and denominator

; Round up the temp by half of the denominator (0.5 gets 1)
   mov A, [CSD2X_1_wDenom+MSB]
   mov [CSD2X_1_dMultTempX+MSB], A
   mov A, [CSD2X_1_wDenom+LSB]
   mov [CSD2X_1_dMultTempX+LSB], A
   and F, ~0x04 ; Clear carry bit if set
   rrc [CSD2X_1_dMultTempX+MSB] ; divide denominator by 2
   rrc [CSD2X_1_dMultTempX+LSB]
   mov A, [CSD2X_1_dMultTempX+LSB]
   add [CSD2X_1_dNumer+LLSB], A ; add 1/2 denominator
   mov A, [CSD2X_1_dMultTempX+MSB]
   adc [CSD2X_1_dNumer+LMSB], A
   adc [CSD2X_1_dNumer+MLSB], 0
   adc [CSD2X_1_dNumer+MMSB], 0

; Compute the division of numerator divided by denominator
   asl [CSD2X_1_dNumer+LLSB]
   rlc [CSD2X_1_dNumer+LMSB]
   rlc [CSD2X_1_dNumer+MLSB]
   rlc [CSD2X_1_dNumer+MMSB]
   mov X, 16
.DivideLoop:
; Subtract the divisor or denominator from the MMSB MLSB dividend or numerator
   mov A, [CSD2X_1_wDenom+LSB]
   sub [CSD2X_1_dNumer+MLSB], A
   mov A, [CSD2X_1_wDenom+MSB]
   sbb [CSD2X_1_dNumer+MMSB], A
; Check if less than zero
   jnc .SetLSbToOneAndShift
.AddBackSetLSbToZeroAndShift:
; Less than zero so add back to dividend and shift a zero into the dividend
   mov A, [CSD2X_1_wDenom+LSB]
   add [CSD2X_1_dNumer+MLSB], A
   mov A, [CSD2X_1_wDenom+MSB]
   adc [CSD2X_1_dNumer+MMSB], A
   asl [CSD2X_1_dNumer+LLSB]
   rlc [CSD2X_1_dNumer+LMSB]
   rlc [CSD2X_1_dNumer+MLSB]
   rlc [CSD2X_1_dNumer+MMSB]
   dec X
   jnz .DivideLoop
   jmp .EndOfDivide
.SetLSbToOneAndShift:
   asl [CSD2X_1_dNumer+LLSB]
   or [CSD2X_1_dNumer+LLSB], 0x01
   rlc [CSD2X_1_dNumer+LMSB]
   rlc [CSD2X_1_dNumer+MLSB]
   rlc [CSD2X_1_dNumer+MMSB]
   dec X
   jnz .DivideLoop
.EndOfDivide:
; MMSB and MLSB have carry after shifted right once
   rrc [CSD2X_1_dNumer+MMSB]
   rrc [CSD2X_1_dNumer+MLSB]
; Load return value
   mov X, [CSD2X_1_wCtrdPos+MSB]
   mov A, [CSD2X_1_wCtrdPos+LSB]
   jmp .EndGetCtrdPos
.COM_Error:
; Load error return value
   mov A, 0xff
   mov X, 0xff
.EndGetCtrdPos:
; Algorithm is finished, position is in [CSD2X_1_wCtrdPos]
   RAM_EPILOGUE RAM_USE_CLASS_3
   ret

; Multiplication algorithm (for whole numbers)
.MultiplyNumeratorWhole:
   mov A, 0x01
.CheckToAddNext2xLSB:
   push A
   and A, [CSD2X_1_wDivBtwSns+LSB] ; See if current 2^x needs added
   jz .SkipAddAndShiftLeftLSB
   mov A, [CSD2X_1_dMultTempX+LLSB]
   add [CSD2X_1_dNumer+LLSB], A
   mov A, [CSD2X_1_dMultTempX+LMSB]
   adc [CSD2X_1_dNumer+LMSB], A
   mov A, [CSD2X_1_dMultTempX+MLSB]
   adc [CSD2X_1_dNumer+MLSB], A
   mov A, [CSD2X_1_dMultTempX+MMSB]
   adc [CSD2X_1_dNumer+MMSB], A
.SkipAddAndShiftLeftLSB:
   asl [CSD2X_1_dMultTempX+LLSB]
   rlc [CSD2X_1_dMultTempX+LMSB]
   rlc [CSD2X_1_dMultTempX+MLSB]
   rlc [CSD2X_1_dMultTempX+MMSB]
   pop A
   asl A
   jnc .CheckToAddNext2xLSB
   mov A, [CSD2X_1_wDivBtwSns+MSB]
   jz .EndMultiplyNumeratorWhole ; only multiply by MSB if needed
   mov A, 0x01
.CheckToAddNext2xMSB:
   push A
   and A, [CSD2X_1_wDivBtwSns+MSB] ; See if current 2^x needs added
   jz .SkipAddAndShiftLeftMSB
   mov A, [CSD2X_1_dMultTempX+LLSB]
   add [CSD2X_1_dNumer+LLSB], A
   mov A, [CSD2X_1_dMultTempX+LMSB]
   adc [CSD2X_1_dNumer+LMSB], A
   mov A, [CSD2X_1_dMultTempX+MLSB]
   adc [CSD2X_1_dNumer+MLSB], A
   mov A, [CSD2X_1_dMultTempX+MMSB]
   adc [CSD2X_1_dNumer+MMSB], A
.SkipAddAndShiftLeftMSB:
   asl [CSD2X_1_dMultTempX+LLSB]
   rlc [CSD2X_1_dMultTempX+LMSB]
   rlc [CSD2X_1_dMultTempX+MLSB]
   rlc [CSD2X_1_dMultTempX+MMSB]
   pop A
   asl A
   jnc .CheckToAddNext2xMSB
.EndMultiplyNumeratorWhole:
   ret

; Multiplication algorithm (for fractional numbers)
.MultiplyNumeratorFraction:
   and F, ~0x04 ; clear carry bit if set
   rrc [CSD2X_1_dMultTempY+MMSB]
   rrc [CSD2X_1_dMultTempY+MLSB]
   rrc [CSD2X_1_dMultTempY+LMSB]
   rrc [CSD2X_1_dMultTempY+LLSB]
   mov A, 0x80
.CheckToAddNextHalf:
   push A
   and A, [CSD2X_1_wDivBtwSns+LSB]
   jz .SkipAddAndShiftRight
   mov A, [CSD2X_1_dMultTempY+LLSB]
   add [CSD2X_1_dNumer+LLSB], A
   mov A, [CSD2X_1_dMultTempY+LMSB]
   adc [CSD2X_1_dNumer+LMSB], A
   mov A, [CSD2X_1_dMultTempY+MLSB]
   adc [CSD2X_1_dNumer+MLSB], A
   mov A, [CSD2X_1_dMultTempY+MMSB]
   adc [CSD2X_1_dNumer+MMSB], A
.SkipAddAndShiftRight:
   asr [CSD2X_1_dMultTempY+MMSB]
   rrc [CSD2X_1_dMultTempY+MLSB]
   rrc [CSD2X_1_dMultTempY+LMSB]
   rrc [CSD2X_1_dMultTempY+LLSB]
   pop A
   and F, ~0x04 ; clear carry bit if set
   rrc A
   jnc .CheckToAddNextHalf
   ret

.ENDSECTION
ENDIF

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -