;----------------------------------------------------------------------------- ; Copyright (C) 2004 by Takao. ; All rights reserved. ; ; FILE NAME : BL_ESC_05.ASM ; DATE : 22 AUG '04 ; TARGET MCU : C8051F330 ; DESCRIPTION : BL motor start run + Sampling comparator data drive + Zero Cross swithing drive. ; ; NOTES: improve BEMF pattern detector by noise check routine. ; Stepping start + BEMF run + Zero Cross swithing drive ; $include (c8051f330.inc) ; Include register definition file. ;----------------------------------------------------------------------------- ; EQUATES ;----------------------------------------------------------------------------- TEST_PIN equ P1.7 ; Scope Trigger Pin OUT_U equ P1.4 ; Motor 'U' lead drive port OUT_V equ P1.5 ; Motor 'V' lead drive port OUT_W equ P1.6 ; Motor 'W' lead drive port COMP_D equ R1 ; Comparator result result strage TEMP0 equ R2 ; Patially used in stepping start sequence. TEMP1 equ 011h ; General Purpose regsters in RAM address 0 - 019h area TEMP2 equ 012h TEMP3 equ R3 DUTY equ 014h ON_DUTY equ R5 ; ON duty control data strage TEMP5 equ 015h TEMP6 equ 016h TEMP7 equ 017h IO_MODE_M equ 018h ; IO_SETTING equ 019h ; TEMP20 equ 020h ; bit addresable RAM address area 020h -02Fh S_ON_DUTY equ 35 ; "on duty" at Stepping starting S_OFF_DUTY equ 170 ; "off duty" at Stepping starting S_S_FRAME equ 100 ; slow stepping start frame timing data S_R_FRAME equ 20 ; slow stepping running frame timing data ; SLOW_START equ 60 ; BEMF start runs fron stepping run with this low power duty(%) BEMF_T2_CNT equ 80 ; BEMF running T2 repeat count timer set(@24.5MHz sys. clock) STACK SEGMENT IDATA ; declare STACK segment RSEG STACK DS 80h ; reserve 128 bytes for stack ;----------------------------------------------------------------------------- ; RESET and INTERRUPT VECTORS ;----------------------------------------------------------------------------- ;Reset Vector cseg AT 0 ljmp Main ; Locate a jump to the start of code at the reset vector. ;----------------------------------------------------------------------------- ; CODE SEGMENT ;----------------------------------------------------------------------------- BL_ESC segment CODE rseg BL_ESC ; Switch to this code segment. using 0 ; Specify register bank for the following program code. Main: ; Disable the WDT. anl PCA0MD, #NOT(040h) ; clear Watchdog Enable bit orl OSCICN, #00000011b ; make 24.5MHz run ;orl OSCICN, #00000010b ; make 12MHz run orl P0MDIN, #10000000b ; make the out put pin's input mode digital or analog orl P1MDIN, #11110000b ; make the out put pin's input mode digital or analog orl P0MDOUT, #00000000b ; make the out put pin's mode. "0"= Open Drain, "1"= Push-Pull. orl P1MDOUT, #10000000b ; make the out put pin's mode. "0"= Open Drain, "1"= Push-Pull. orl P0SKIP, #00111111b ; skipped by the cross bar orl P1SKIP, #11110111b ; skipped by the cross bar ; Enable the Port I/O Crossbar ; orl XBR0, #00000000b ; mov XBR1, #11000000b ; no weak pull-ups, cross bar enabled on out put pins. ; All out puts are "L", just after RESET. ; orl CPT0CN, #10000000b ; bit7: Comp. Enable, bit6: Comp out, bit5,4: no interrupt, bit3-0: no hys. SET_START_FRAME: mov TEMP0, #S_S_FRAME ; slow starting frame timing data to avoid Ansync. stepping. STEPPING_START: acall STATE1 acall STEP_DRIVE_CNT acall STATE2 acall STEP_DRIVE_CNT acall STATE3 acall STEP_DRIVE_CNT acall STATE4 acall STEP_DRIVE_CNT acall STATE5 acall STEP_DRIVE_CNT acall STATE6 acall STEP_DRIVE_CNT dec TEMP0 cjne TEMP0, #S_R_FRAME-1, STEPPING_START ; Frame Timing Sweep starting control *********** jmp BEMF_START ; Stepping start with duty control as current limitter. STEP_DRIVE_CNT: mov TEMP5, TEMP0 STEP_FRAME_CNT: acall START_PWR_CNTROL djnz TEMP5, STEP_FRAME_CNT ret ;----------------------- BEMF_START: acall WAKE_UP_CP ; wait for comparator wake up. mov ON_DUTY, #SLOW_START ; BEMF Starting duty as slow start mov TEMP0, #0 ; times of T2 over flow counter SET_BEMF_TIMER: acall T2_SET ; Start T2 timer for slow BEMF control time GET_BEMF: mov P1MDOUT, #10000000b ; make the outputs are open drain as 3-Sate open, EXCEPT P1.7 test pin orl P1, #01110111b ; U, V, W=3ST acall GET_COMP_DATA ; Compare the motor generative voltage while drive 3-ST timing. COMP_STATE1: cjne COMP_D, #1, COMP_STATE2 acall STATE1 jmp BEFM_START COMP_STATE2: cjne COMP_D, #2, COMP_STATE3 acall STATE2 jmp BEFM_START COMP_STATE3: cjne COMP_D, #3, COMP_STATE4 acall STATE3 jmp BEFM_START COMP_STATE4: cjne COMP_D, #4, COMP_STATE5 acall STATE4 jmp BEFM_START COMP_STATE5: cjne COMP_D, #5, COMP_STATE6 acall STATE5 jmp BEFM_START COMP_STATE6: cjne COMP_D, #6, UNUSUAL_STATE mov a, TMR2CN ; BEMF end control timer for next control anl a, #10000000b ; checking T2 high byte over flow flag for starting ZERO cross timing control. jz DRIVE_STATE6 BEMF_RUN_TIMER_COUNT: inc TEMP0 cjne TEMP0, #BEMF_T2_CNT, T2_REPEAT jmp ZERO_CROSS_START_CHECK ; T2_REPEAT: clr TF2H DRIVE_STATE6: acall STATE6 jmp BEFM_START UNUSUAL_STATE: jmp GET_BEMF BEFM_START: acall ON_TIMER jmp GET_BEMF ; spin with BEMF control ;------------ ZERO_CROSS_START_CHECK: ;mov TEMP0, #0 ; TIMING TEST ONLY GET_STATE6_CHK: acall GET_COMP_DATA cjne COMP_D, #6, GET_STATE1_CHK jmp GET_STATE6_CHK GET_STATE1_CHK: acall STATE1 ;comp data check TEST ONLY clr TF2H mov TEMP0, #0 ; TIMING TEST ONLY jmp BEFM_START ;------------------------------- acall GET_COMP_DATA cjne COMP_D, #1, GET_STATE1_CHK ; Get start of state1 drive timing GET_1_CROSS: acall T2_SET ; start T2 for state frame timing measuring GET_STATE2_CHK: acall GET_COMP_DATA ; T2 over flow may occur at the end of state6 in off state cjne COMP_D, #2, GET_STATE2_CHK ; Get start of state2 drive timing GET_2_CROSS: acall T2_SET ; start T2 for state frame timing measuring GET_STATE3_CHK: acall GET_COMP_DATA cjne COMP_D, #3, GET_STATE3_CHK ; Get start of state3 drive timing GET_3_ZERO_CROSS: acall STATE3 ;U=3ST, V=1, W=0 ;jmp GET_03_CROSS clr TF2H jmp BEFM_START COMP_STATE01: cjne COMP_D, #1, COMP_STATE02 jmp ZERO_ ; U=1, V=0, W=3ST COMP_STATE02: cjne COMP_D, #2, COMP_STATE03 jmp ZERO_ ; U=1, V=3ST, W=0 COMP_STATE03: cjne COMP_D, #3, COMP_STATE04 jmp ZERO_ COMP_STATE04: cjne COMP_D, #4, COMP_STATE05 jmp ZERO_ COMP_STATE05: cjne COMP_D, #5, COMP_STATE06 jmp ZERO_ COMP_STATE06: ;acall STATE6 ZERO_: acall ON_TIMER jmp GET_BEMF ;INC_SPEED: clr TF2H ; Clear T2 high byte over flow flag ; inc ON_DUTY ;LIMIT_CHK: cjne ON_DUTY, #DUTY_LIMIT, PWR_UP ; mov ON_DUTY, #DUTY_LIMIT-1; max power duty limit at samplig BEMF mode ;------------ V_UH: V_VH: V_WH: V_UL: V_VL: V_WL: U_0_CROSS: V_0_CROSS: W_0_CROSS: ;------------ GET_COMP_DATA: acall COMP_MEASURE ;ret ; ************ no noise filter ************ mov TEMP6, COMP_D RE_MEASURE: acall COMP_MEASURE ; Re-check mov a, COMP_D ; cjne a, TEMP6, NOISE_DATA ; Same comp. result? jmp COMP_OK ; Yes NOISE_DATA: mov TEMP6, a ; No jmp RE_MEASURE COMP_OK: ret ;------------------------------------ ; Timer2 16bit counter with auto re-load, pre-scaled clock is 1/12=490nS. T2_SET: mov CKCON, #0 ; T2 clock source select mov TMR2CN, #00000100b ; Enable Timer2 with 1/12 sys. clock. jmp CLR_T2 T02_SET: mov CKCON, #01100000b ; T2 clock source select is system clock. mov TMR2CN, #00000100b ; Enable Timer2 with 1/12 sys. clock. CLR_T2: mov TMR2RLL, #0h ; low byte re-load data mov TMR2RLH, #0h ; High byte re-load data mov TMR2L, #0h ; mov TMR2H, #0h ; clr TF2H ret ;------------ ; BEMF run power duty control timer routine ON_TIMER: ; 33% ON duty for TEST RUN only mov DUTY, ON_DUTY L1: acall WAIT_1uS djnz DUTY, L1 FREE_RUN: mov P1MDOUT, #10000000b ; make the outputs are open drain as 3-Sate open, EXCEPT P1.7 test pin orl P1, #01110111b ; U, V, W=3ST mov a, #100 ; frame is 100 counts as % mov DUTY, ON_DUTY subb a, DUTY mov DUTY, a L2: acall WAIT_1uS djnz DUTY, L2 ret ;----------------- START_PWR_CNTROL: ON_TIM: mov TEMP3, #S_ON_DUTY sLoop10: nop nop nop nop nop nop nop nop nop nop nop djnz TEMP3, sLoop10 ALL_3ST: mov IO_MODE_M, P1MDOUT ; GPIO mode setting data storage mov IO_SETTING, P1 ; IO data storage mov P1MDOUT, #0 ; make the outputs are open drain as 3-Sate open to reduce the SW noise mov P1, #10000111b ; All "0" for stepping start with magnetic brake to get each step ***** OFF_TIM: mov TEMP3, #S_OFF_DUTY tLoop10: nop nop nop nop nop nop nop nop nop nop nop nop djnz TEMP3, tLoop10 ; mov P1, #11111111b ; All "1" for 3st open for free run for TEST MONITORING ONLY. RE_ON: mov P1, IO_SETTING ; IO data storage mov P1MDOUT, IO_MODE_M ; GPIO mode setting data storage ret ;------------------------------------ WAIT_1uS: mov TEMP1, #5 jmp W_10L WAKE_UP_CP: orl CPT0CN, #10000000b ; bit7: Comp. Enable, bit6: Comp out, bit5,4: no interrupt, bit3-0: no hys. WAIT_10uS: mov TEMP1, #95 ; 95 at 24.5MHz ;orl P1, #10000000b ;P1.7 is test pin for scope trigger. W_10L: nop ; 1 cycle clock = 40nS nop ; 1 cycle clock = 40nS djnz TEMP1, W_10L ; 2/3 cycle clock = 26nS ;anl P1, #01111111b ;P1.7 is test pin for scope trigger. ret ;----------------------------------------------------------------------------- COMP_MEASURE: ;P0.0 and P0.1, P0.2 and P0.3, P0.4 and P0.5 are connected togather by solder. mov CPT0MX, #00100001b ; CP in-: P0.5, CP in+: P0.2 nop ; wait for syncronizer response nop nop ;nop mov a, CPT0CN ; Get Comparator result anl a, #01000000b ; Get CPOUT bit jnz P02H_P03L P02L_P03H: mov CPT0MX, #00000001b ; CP in-: P0.1, CP in+: P0.2 nop ; wait for syncronizer response nop nop ;nop mov a, CPT0CN ; Get Comparator result anl a, #01000000b ; Get CPOUT bit jnz P03H_P02M_P01L_1X0 P02L_P01H: mov CPT0MX, #00100000b ; CP in-: P0.5, CP in+: P0.0 nop ; wait for syncronizer response nop nop ;nop mov a, CPT0CN ; Get Comparator result anl a, #01000000b ; Get CPOUT bit jnz P01H_P03M_P02L_X01 P03H_P01M_P02L_10X: mov COMP_D, #6 ret ;---- P02H_P03L: mov CPT0MX, #00000001b ; CP in-: P0.1, CP in+: P0.2 nop ; wait for syncronizer response nop nop ;nop mov a, CPT0CN ; Get Comparator result anl a, #01000000b ; Get CPOUT bit jnz P02H_P01L ; P01H_P02M_P03L_0X1: mov COMP_D, #2 ret ;---- P02H_P01L: mov CPT0MX, #00100000b ; CP in-: P0.4, CP in+: P0.1 as P0.0, nop ; wait for syncronizer response nop nop ;nop mov a, CPT0CN ; Get Comparator result anl a, #01000000b ; Get CPOUT bit jnz P02H_P01M_P03L_01X P02H_P03M_P01L_X10: mov COMP_D, #4 ret ;---- P02H_P01M_P03L_01X: mov COMP_D, #3 ret P03H_P02M_P01L_1X0: mov COMP_D, #5 ret P01H_P03M_P02L_X01: mov COMP_D, #1 ret ;-------------------------------------- ;Motor drive each states STATE1: mov P1MDOUT, #10110000b ; make the out UV pin output push-pull, W pin is 3ST mov P1, #11010111b ; U=1, V=0, W=3ST + TEST PIN=1 mov P1, #01010111b ; U=1, V=0, W=3ST + TEST PIN=0 ret STATE2: mov P1MDOUT, #00010000b ; make the out U pin output push-pull, V,W pin 3ST mov P1, #00110111b ; U=1, V=3ST, W=0 mov P1MDOUT, #01010000b ; make the out UW pin output push-pull, V pin is 3ST ret STATE3: mov P1MDOUT, #01100000b ; make the out V,W pin output push-pull, U pin is 3ST mov P1, #00110111b ; U=3ST, V=1, W=0 ret STATE4: mov P1MDOUT, #00100000b ; make the out V pin output push-pull, U,W pin 3ST mov P1, #01100111b ; U=0, V=1, W=3ST mov P1MDOUT, #00110000b ; make the out UV pin output push-pull, W pin is 3ST ret STATE5: mov P1MDOUT, #01010000b ; make the out UW pin output push-pull, V pin is 3ST mov P1, #01100111b ; U=0, V=3ST, W=1 ret STATE6: ;mov P1MDOUT, #0 ; make the outputs are open drain as 3-Sate open mov P1MDOUT, #01000000b ; make the out W pin output push-pull, U,V pin is 3ST mov P1, #01010111b ; U=3ST, V=0, W=1 mov P1MDOUT, #01100000b ; make the out VW pin output push-pull, U pin is 3ST ret ; End of file. END