;encoder讀值and計算馬達輸出pulse; $MOD51 RESET EQU 0000H STACK EQU 60H COUNT EQU 25D ;馬達輸入pulse數量暫存器 SEL EQU P2.7 ;定義SEL腳位 OE EQU P2.6 ;定義OE腳位 DD EQU P2.5 ;定義U/D腳位 ORG RESET MOV SP,#STACK MOV R3,#00H ;encoder舊值暫存器 MOV P0,#00H ;清空p0 SETB SEL SETB OE ;===============判斷是否讀取新值================; START: CLR SEL ;設定讀取encoder高byte CLR OE ;開始讀取 MOV DPH,P0 ;高btye的值放入dph SETB SEL ;設定讀取encoder低byte MOV DPL,P0 ;低btye的值放入dpl SETB OE ;停止讀值 MOV A,DPL ; {{ SUBB A,R3 ; 與舊值相減~判斷是否有讀取新值 CJNE A,#00H,STA_GET_DATA ; 有的話則跳至STA_GET_DATA MOV A,R3 ; }} JMP START ;若無讀取新值則跳回START重新讀取 ;===============重新讀值========================; STA_GET_DATA: CLR SEL CLR OE MOV DPH,P0 SETB SEL MOV DPL,P0 SETB OE MOV R3,DPL CLR A MOV R0,DPH ;讀取進位次數 ;===============判斷encoder正轉或反轉===========; DETE_RI_OR_REV: JB DD,CAL_REV_PULSE ;若反轉則跳躍 ;===============計算正轉pulse===================; CAL_RI_PULSE: ADD A,#13D ;256/20=12.8,四捨五入=>13 DJNZ R0,CAL_RI_PULSE ;計算高btye的pulse MOV R4,A ;計算完的值放入pulse計數器 MOV A,DPL ; {{ MOV B,#20D ; 計算低btye的pulse(1.8/0.09=20) DIV AB ; }} ADD A,R4 ;高btye+低byte=總pulse數 MOV R4,A ;放入pulse計數器 MOV A,#11101110B ;設定馬達輸出起始值 ;===============正轉程式========================; TURN_RI: RL A ;往左移(A => B => A- => B-) MOV P1,A ;p1輸出至馬達 CALL DELAY ;呼叫pulse速度副程式 DJNZ R4,TURN_RI SJMP START ;===============計算反轉pulse===================; CAL_REV_PULSE: MOV A,#0FFH ; {{ SUBB A,DPH ; MOV DPH,A ; MOV A,#0FFH ; 將反轉數值轉為正轉數值 SUBB A,DPL ; MOV DPL,A ; }} MOV R0,DPH ;讀取進位次數 CLR A CAL: ADD A,#13D DJNZ R0,CAL MOV R4,A MOV A,DPL MOV B,#20D DIV AB ADD A,R4 MOV R4,A MOV A,#11101110B ;===============反轉程式=======================; TURN_REV: RR A MOV P1,A CALL DELAY DJNZ R4,TURN_REV SJMP START DELAY1: MOV R0,#250D DEL1: MOV R1,#250D DE1: MOV R2,#5D DJNZ R2,$ DJNZ R1,DE1 DJNZ R0,DEL1 RET ;===============馬達速度副程式=================; DELAY: MOV R0,#10D DEL: MOV R1,#3D DE: MOV R2,#100D DJNZ R2,$ DJNZ R1,DE DJNZ R0,DEL RET END