📄 data.asm
字号:
;;; amt.asminclude "8051fa.h"include "kernel.lib" ;;; This MUST be the first module included.include "math.lib"include "stdio.lib";;; TimingCTIME equ 08h ;;; 2 bytesTIME equ 0ah ;;; 2 bytesSetCEX: mov CMOD, #ECF mov CCAPM0, #(CAPN + ECCF) mov CCAPM1, #(CAPN + ECCF) mov CCAPM2, #(CAPN + ECCF) mov CCAPM3, #(CAPN + ECCF) mov CCAPM4, #(CAPN + ECCF) ;;; Set CEX inputs for falling edge mode. setb CEX0 setb CEX1 setb CEX2 setb CEX3 setb CEX4 ;;; Latch CEX inputs for input. clr PPC ;;; Set interrupt for low priority.retSetT2EX: setb T2EX setb CP_RL2 setb EXEN2 ;;; Enable captures in T2EX. clr C_T2 ;;; Set TIMER2 as a timer. clr PT2 ;;; And set its interrupt priority low.retSetTF0: mov A, TMOD anl A, #11110000b add A, #01h ;;; Timer 0: 16-bit internal timer. mov TMOD, A clr PT0 ;;; Set for low priority.retSetCClock: mov CL, #0 mov CH, #0 mov CTIME, #0 mov (CTIME + 1), #0 ;;; CTIME = 0; clr CF setb EC setb CR ;;; CLOCK ON;CTimeLoop: ;;; while (1) {ret ;;; "pause on CF";CTick: inc CTIME mov A, CTIME jnz CBreakInc inc (CTIME + 1) CBreakInc: ;;; CTIME++;sjmp CTimeLoop ;;; }SetClock: mov TL2, #0 mov TH2, #0 mov TIME, #0 mov (TIME + 1), #0 ;;; TIME = 0; clr TF2 setb ET2 setb TR2 ;;; CLOCK ON;TimeLoop: ;;; while (1) {retTick: ;;; "pause on TF2"; inc TIME mov A, TIME jnz BreakInc inc (TIME + 1) BreakInc: ;;; TIME++;sjmp TimeLoop ;;; }Capture: ;;; "capture the time of the last sensor"; mov (TIME0 + 0), TL2 mov (TIME0 + 1), TH2 mov (TIME0 + 2), (TIME + 0) mov (TIME0 + 3), (TIME + 1) mov (TIME1 + 0), CL mov (TIME1 + 1), CH mov (TIME1 + 2), (CTIME + 0) mov (TIME1 + 3), (CTIME + 1) mov (TIME2 + 0), CL mov (TIME2 + 1), CH mov (TIME2 + 2), (CTIME + 0) mov (TIME2 + 3), (CTIME + 1) mov (TIME3 + 0), CL mov (TIME3 + 1), CH mov (TIME3 + 2), (CTIME + 0) mov (TIME3 + 3), (CTIME + 1) mov (TIME4 + 0), CL mov (TIME4 + 1), CH mov (TIME4 + 2), (CTIME + 0) mov (TIME4 + 3), (CTIME + 1) mov (TIME5 + 0), CL mov (TIME5 + 1), CH mov (TIME5 + 2), (CTIME + 0) mov (TIME5 + 3), (CTIME + 1)retARR_BASE: dw 0080h, 15c0h, 2b00h, 3f40h, 5580h, 6ac0hGetBase: mov A, Counter rl A mov B, A mov DPTR, #ARR_BASE movc A, @A + DPTR xch A, B ;;; B = ARR_BASE[2*Counter] inc A movc A, @A + DPTR ;;; A = ARR_BASE[2*Counter + 1]; mov Bot, A mov (Bot + 1), B ;;; Bot = ((word *)ARR_BASE)[Counter];retGetSize: mov A, Counter rl A add A, #Cycles mov R0, A mov A, @R0 mov B, R2 mul AB mov Size, A mov (Size + 1), B inc R0 mov A, @R0 mov B, R2 mul AB add A, (Size + 1) xch A, (Size + 1) ;;; Size = R2 * ((word *)Cycles)[Counter];retStore: mov A, Bot add A, Size mov DPL, A mov A, (Bot + 1) addc A, (Size + 1) mov DPH, A ;;; for (DPTR = Bot + Size; R2 > 0; R2--) { StoreLoop: mov A, @R0 inc R0 movx @DPTR, A inc DPTR ;;; *DPTR++ = R0++; djnz R2, StoreLoop ;;; }ret;;; All the statistical variables for the 6 inputs are replicated 6 times.SECTORS equ 20Sector0 equ 24h ;;; 1 byteSector1 equ 25h ;;; 1 byteSector2 equ 26h ;;; 1 byteSector3 equ 27h ;;; 1 byteSector4 equ 28h ;;; 1 byteSector5 equ 29h ;;; 1 byteStatSeg equ 2ah ;;; STAT_SIZE bytesSTAT_SIZE equ (22*6)TIME0 equ 2ah ;;; 4 bytesTIME1 equ 2eh ;;; 4 bytesTIME2 equ 32h ;;; 4 bytesTIME3 equ 36h ;;; 4 bytesTIME4 equ 3ah ;;; 4 bytesTIME5 equ 3eh ;;; 4 bytesCycles equ 42h ;;; 2*6 bytesFirst equ 4eh ;;; 4*6 bytesLast equ 66h ;;; 4*6 bytesSquare equ 7eh ;;; 8*6 bytesWidth equ 0ch ;;; 4 bytesBot equ 10h ;;; 2 bytesSize equ 12h ;;; 2 bytesSetStats: mov R0, #Sector0 mov R2, #6 SetSector: mov @R0, #1 inc R0 djnz R2, SetSector ;;; Set all sector counts to 0; mov State, #00111111b ;;; Set all FXn to 1, and clear the abort flag FXX. mov R0, #StatSeg mov R2, #STAT_SIZE acall ClearX ;;; Clear all statistical registers;retPartial: ;;; "pause on PULSE"; mov A, Counter rl A rl A add A, #First mov R0, A add A, #(TIME0 - First) mov R1, A mov R2, #4 acall CopyX ;;; First = TIME;StatsLoop: ;;; while (1) { mov A, Counter rl A rl A add A, #Last mov R0, A add A, #(TIME0 - Last) mov R1, A mov R2, #4 acall CopyX ;;; Last = TIME;retNutation: ;;; "pause on PULSE"; mov R0, #Width mov A, Counter rl A rl A add A, #TIME0 mov R1, A mov R2, #4 acall CopyX ;;; Width = TIME; mov R0, #Width mov A, Counter rl A rl A add A, #Last mov R1, A mov R2, #4 acall SubtractX ;;; Width -= Last; acall GetBase ;;; Bot = ARR_BASE; mov R2, #4 acall GetSize ;;; Size = 4*Cycles; mov R0, #Width mov R2, #4 acall Store ;;; Bot[Size] = Width; mov A, Counter rl A add A, #Cycles mov R0, A mov R2, #2 acall IncX ;;; Cycles++; mov ArgX, #Width mov SizeX, #4 mov ArgY, #Width mov SizeY, #4 mov A, Counter rl A rl A rl A add A, #Square mov ArgZ, A acall MultiplyX ;;; Square += Width*Width;sjmp StatsLoop ;;; }SetIE0: setb INT0 ;;; Latch INT0 for input. setb IT0 clr PX0 ;;; And set its interrupt priority low (should be high).retClearFlags: clr EXF2 clr CCF0 clr CCF1 clr CCF2 clr CCF3 clr CCF4 mov TSTATUS, #0 mov CSTATUS, #0retSetTest: acall SetIE0 ;;; Enable IE0; acall SetT2EX ;;; Enable TF2, EXF2; acall SetCEX ;;; Enable CF, CCFn; acall SetTF0 ;;; Enable process scheduler. mov State, #01000000b ;;; Set abort flag, clear all others.retTestCycle: acall SetStats clr IE0 setb EX0 ;;; "turn on IE0"; mov R0, #SP_IE0 acall Pause ;;; "pause on IE0, first sensor"; acall SetClock acall SetCClock acall ClearFlags acall Scheduler clr IE0 mov R0, #SP_IE0 acall Pause ;;; "pause on IE0, second sensor"; clr EX0 ;;; "turn off IE0"; clr TR0 clr ET0 clr TR2 clr ET2 ;;; "turn off TF2, EXF2"; clr CR clr EC ;;; "turn off CF, CCF0, CCF1, CCF2, CCF3, CCF4"; acall Capture ;;; "save the time of the last sensor";ret;;; Data transfer;;; # SIZE <Data> Sum <-- PacketSendDBY: ;;; R0: Base, R2: Size mov A, #'#' acall putchar ;;; putchar('#'); mov A, #23 acall putchar ;;; putchar(23); mov A, State acall putchar ;;; putchar(State); mov R3, State mov A, Counter rl A mov R7, A add A, #Cycles mov Bot, A mov R2, #2 acall DBYLoop ;;; Send(Cycles[Counter]); mov R0, #Width mov A, R7 rl A mov R7, A add A, #TIME0 mov Bot, A mov R2, #4 acall DBYLoop ;;; Send(TIME[Counter]); mov A, R7 add A, #First mov Bot, A mov R2, #4 acall DBYLoop ;;; Send(First[Counter]); mov A, R7 add A, #Last mov Bot, A mov R2, #4 acall DBYLoop ;;; Send(Last[Counter]); mov A, R7 rl A add A, #Square mov Bot, A mov R2, #8 acall DBYLoop ;;; Send(Square[Counter]); mov A, R3 acall putchar ;;; Send(CheckSum);retDBYLoop: mov R0, Bot inc Bot mov A, @R0 xch A, R3 add A, R3 xch A, R3 acall putchardjnz R2, DBYLoopret;;; : SIZE <Data> Sum <-- Packet SIZE == 0 means a full packet: 100h bytes.;;; . <-- End of transmissionRETRIES equ 3SendXBY: mov R4, #RETRIES ;;; Retry = RETRIES; mov A, Size orl A, (Size + 1)jnz SendPacket ;;; if (Size == 0) { mov A, #'.' acall putchar ;;; putchar('.'); return;ret ;;; }SendPacket: mov A, #':' acall putchar ;;; putchar(':'); mov A, Size acall putchar ;;; putchar(Size); mov R3, #0 ;;; CheckSum = 0; mov DPL, Bot mov DPH, (Bot + 1) mov R2, Size XBYLoop: ;;; for (DPTR = Bot, R2 = Size; R2 > 0; R2--) { movx A, @DPTR inc DPTR xch A, R3 add A, R3 xch A, R3 acall putchar ;;; putchar(A = *DPTR++), CheckSum += A; djnz R2, XBYLoop ;;; } mov A, R3 acall putchar ;;; putchar(CheckSum); acall getchar ;;; switch (getchar()) {Z0: cjne A, #1bh, Z1 ;;; case NAK: djnz R4, ZZ ;;; if (--Retry == 0) { ret ;;; return; ZZ: ;;; }ajmp SendPacket ;;; resend the packet;Z1: cjne A, #1ch, Z2 ;;; case ACK: mov A, Size jz WW ;;; if (Size%0x100 != 0) { mov Size, #0 ;;; Size -= Size%0x100; sjmp XX ;;; } WW: ;;; else { dec (Size + 1) ;;; Size -= 0x100; XX: ;;; } mov Bot, DPL mov (Bot + 1), DPH ;;; Bot = DPTR;ajmp SendXBY ;;; send the next packet;Z2: ret ;;; default: abort;;;; Command Interpreter:;;; Data format (in octal):;;; 000 + m -- Stats m;;; 010 + m -- Dump m;;; 020 -- Status;;; 030 -- Test;;; 037 -- AbortInterpreter: ;;; Interpreter() { acall SetPort ;;; open the serial port at 9600,N,9,1;CommandLoop: ;;; while (1) { acall getchar ;;; A = getchar(); mov Counter, A anl A, #00111000b xch A, Counter anl A, #00000111b xch A, Counter ;;; Counter = A&7, switch (A&0370) {X0: cjne A, #00h, X1 ;;; case 000:jb EX0, CommandLoop ;;; if (in test) break; mov A, Counter cjne A, #6, $ + 3jnc CommandLoop ;;; if (Counter >= 6) break; acall SendDBY ;;; SendDBY(Counter);sjmp CommandLoop ;;; break;X1: cjne A, #08h, X2 ;;; case 010:jb EX0, CommandLoop ;;; if (in test) break; mov A, Counter cjne A, #6, $ + 3jnc CommandLoop ;;; if (Counter >= 6) break; acall GetBase ;;; Bot = ARR_BASE[Counter]; mov R2, #4 acall GetSize ;;; Size = 4*Cycles[Counter]; acall SendXBY ;;; SendXBY(Bot, Size);sjmp CommandLoop ;;; break;X2: cjne A, #10h, X3 ;;; case 020: mov A, Countercjne A, #0, CommandLoop ;;; if (Counter != 0) break; jnb ET2, YY0 ;;; if (in test && counting) { mov A, #'2' ;;; putchar('2'); sjmp YY ;;; } YY0: ;;; else jnb EX0, YY1 ;;; if (in test) { mov A, #'1' ;;; putchar('1`); sjmp YY ;;; } YY1: ;;; else { mov A, #'0' ;;; putchar('0'); YY: ;;; } acall putcharsjmp CommandLoop ;;; break;X3: cjne A, #18h, X4 ;;; case 030: mov A, Counter ;;; switch (Counter) { Y0: cjne A, #00h, Y1 ;;; case 0: jb EX0, CommandLoop ;;; if (in test) break; mov R0, #0e0h mov DPTR, #TestCycle acall Spawn ;;; Spawn(0xe0, TestCycle); sjmp CommandLoop ;;; break; Y1: cjne A, #07h, Y2 ;;; case 7: jnb EX0, CommandLoop ;;; if (!in test) break; clr EX0 ;;; "turn off sensor"; clr TR0 ;;; "turn off the scheduler"; clr ET0 clr TR2 clr ET2 ;;; "turn off timer 2"; clr CR clr EC ;;; "turn off the capture timer"; acall Capture ;;; "save the time of the abort"; setb FXX ;;; flag the abort; Y2: ajmp CommandLoop ;;; break;X4: ajmp CommandLoop ;;; }main: ;;; main() { acall SetTest ;;; SetTest(); mov R0, #0c8h mov DPTR, #Interpreter acall Spawn ;;; Spawn(0xc8, Interpreter); setb EA ;;; "turn on multi-tasker";ret ;;; }end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -