通信设计应用


#define OWIN M0[09h].6 ; PI1.6 #define OWOUT M0[01h].6 ; PO1.6 #define OWDIR M0[11h].6 ; PD1.6 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Function : Reset1Wire ;; Description : Sends a standard speed 1-Wire reset pulse on P1.6 ;; and checks for a presence pulse reply. ;; Inputs : None ;; Outputs : C - Cleared on success; set on error (no presence ;; pulse detected) ;; Destroys : PSF, LC[0] ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Reset1Wire: move OWDIR, #1 ; Output mode move OWOUT, #0 ; Drive low move LC[0], #RESET_LOW djnz LC[0], $ move OWOUT, #1 ; Snap high move LC[0], #SNAP djnz LC[0], $ move OWDIR, #0 ; Change to weak pullup input move LC[0], #RESET_PRESAMPLE djnz LC[0], $ move C, OWIN ; Check for presence detect move LC[0], #RESET_POSTSAMPLE djnz LC[0], $ ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Function : Write1Wire ;; Description : Writes a standard speed 1-Wire output byte on P1.6. ;; Inputs : GRL - Byte to write to 1-Wire. ;; Outputs : None. ;; Destroys : PSF, AP, APC, A[0], LC[0], LC[1] ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Write1Wire: move APC, #080h ; Standard mode, select A[0] as Acc move Acc, GRL move OWDIR, #1 ; Output drive mode move LC[1], #8 ; 8 bits to write Write1Wire_slot: move OWOUT, #0 ; Drive low for start of write slot move LC[0], #WRITE_PREBIT djnz LC[0], $ rrc ; Get the next bit jump C, Write1Wire_one Write1Wire_zer move OWOUT, #0 ; Keep the line low (zero bit) jump Write1Wire_next Write1Wire_one: move OWOUT, #1 Write1Wire_next: move LC[0], #WRITE_POSTBIT djnz LC[0], $ ; Finish the time slot move OWOUT, #1 ; Drive back high (end of slot) move LC[0], #WRITE_RECOVERY djnz LC[0], $ ; Recovery time period djnz LC[1], Write1Wire_slot ret实现读时隙的功能与之类似。注意,在1-Wire总线上所有数据均为低有效位(LSB)先发。
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Function : ConvertAndReadTemp ;; Description : Sends commands to measure temperature and read ;; scratchpad from the DS1822. ;; Inputs : None. ;; Outputs : GRL - 8-bit signed temperature value, in degrees C. ;; Destroys : PSF, AP, APC, A[0], A[1], A[2], LC[0], LC[1] ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ConvertAndReadTemp: call Reset1Wire ; Reset the DS1822 move GRL, #OW_SKIP_ROM ; Select the DS1822 call Write1Wire move GRL, #OW_CONVERT ; Send temp convert command call Write1Wire move OWDIR, #1 ; Turn on strong pullup for draw current move OWOUT, #1 move LC[0], #55 ; About a second delay: move LC[1], #0 djnz LC[1], $ djnz LC[0], delay call Reset1Wire ; Conversion completed; reset again move GRL, #OW_SKIP_ROM ; Select again call Write1Wire move GRL, #OW_RD_SCRATCH ; Read the scratchpad values call Write1Wire call Read1Wire move A[1], GRL ; Temp LSB 3210xxxx call Read1Wire move A[2], GRL ; Temp MSB sssss654 move Acc, A[1] ; 3210xxxx and #0F0h ; 3210---- xchn ; ----3210 move A[1], Acc move Acc, A[2] ; sssss654 and #00Fh ; ----s654 xchn ; s654---- or A[1] ; s6543210 move GRL, Acc ret
;; Two out of three majority vote, or failing that, the measurement
;; in the middle of the three.
move Acc, A[4]
cmp A[5]
jump E, recordTempA ; If (A==B), use that value
cmp A[6]
jump E, recordTempA ; If (A==C), use that value
move Acc, A[5]
cmp A[6]
jump E, recordTempB ; If (B==C), use that value
move Acc, A[4]
sub A[5]
jump S, B_greaterThan_A ; Sign is set if (A-B) is negative
;; If (A > B) {
;; If (C > A) record A (C > A > B)
;; If (B > C) record B, (A > B > C)
;; else record C (A > C > B)
A_greaterThan_B:
move Acc, A[4]
sub A[6] ; A-C
jump S, recordTempA ; Sign is set if (A-C) is negative
move Acc, A[5]
sub A[6] ; B-C
jump S, recordTempC ; Sign is set if (B-C) is negative
jump recordTempB
;; If (B > A) {
;; If (C > B) record B (C > B > A)
;; If (A > C) record B, (A > B > C)
;; else record C (B > C > A)
B_greaterThan_A:
move Acc, A[5]
sub A[6] ; B-C
jump S, recordTempB ; Sign is set if (B-C) is negative
move Acc, A[4]
sub A[6] ; A-C
jump S, recordTempC ; Sign is set if (A-C) is negative
jump recordTempB
recordTempA:
move GRL, A[4]
jump recordTemp
recordTempB:
move GRL, A[5]
jump recordTemp
recordTempC:
move GRL, A[6]
jump recordTemp
recordTemp:
move A[15], GRL
move GRL, #'@'
call TxCharBB
move GR, DP[0]
move GRL, GRH
call TxHexByteBB
move GRL, DP[0]
call TxHexByteBB
move GRL, #' '
call TxCharBB
move GRL, #'W'
call TxCharBB
move GRL, A[15]
call TxHexByteBB
move GRL, A[15] ; Low byte contains temp data
move GRH, #055h ; High byte marks nonzero entry
lcall UROM_loadData ; Write entry to data EEPROM
call IncDP0_EE ; Move to the next entry position
move GR, #0000h ; Erase any data that exists
lcall UROM_loadData ; Erase the oldest entry
记录采用循环方式,从数据EEPROM地址020h开始到05Fh结束,然后再回到开始处。之后每写入一个新记录,将擦除一个最旧的记录。当通过串行接口向外发送数据时,应用程序通过查找前面是否又有空记录的方式定位最旧的记录数据。
;; Start the wakeup timer for 60 seconds. move CKCN.6, #1 ; Select ring oscillator mode waitRing: move C, CKCN.5 jump NC, waitRing ; Wait for RGMD=1 (running from ring) move WUT, #30000 ; 1/8kHz * 30000 * 16 = 60 seconds move WUTC, #0101b ; Start the wakeup timer (running from ring) move IV, #wakeUpInt ; Set interrupt handler for wakeup interrupt move IMR.0, #1 ; Enable interrupts from module 0 move IC.0, #1 ; Globally enable interrupts move PD0.7, #0 ; Turn off output mode for LED pin move PO0.7, #1 ; Return to default state (weak pullup) move CKCN.4, #1 ; Go into Stop mode, wait for wakeup int nop jump mainLoop ; Back for another round ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; wakeUpInt: move PD0.7, #1 ; Turn on output mode for LED port pin move PO0.7, #0 ; Light the LED move CKCN.6, #1 ; Select ring oscillator mode wakeUp_ring: move C, CKCN.5 jump NC, wakeUp_ring ; Wait for RGMD=1 (running from ring) move LC[0], #4000 djnz LC[0], $ move PO0.7, #1 ; LED off move LC[0], #4000 djnz LC[0], $ move WUTC, #0 ; Clear wakeup timer flag move CKCN.6, #0 ; Select crystal mode wakeUp_xtal: move C, CKCN.5 jump C, wakeUp_xtal ; Wait for RGMD=0 (running from crystal) move GRL, #'W' call TxCharBB move GRL, #'U' call TxCharBB move GRL, #0Dh call TxCharBB move GRL, #0Ah call TxCharBB reti
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Function : TxCharBB ;; Description : Transmits a 10-bit serial character (bit-banged) ;; over P0.0. ;; Inputs : GRL - Character to send ;; Outputs : None ;; Destroys : PSF, AP, APC, A[0], LC[0], LC[1] ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; TxCharBB: move APC, #080h ; Standard mode, select A[0] as Acc move Acc, GRL move PO0.0, #0 ; START bit low move LC[0], #BITLOOP djnz LC[0], $ move LC[1], #8 ; 8 bits TxCharBB_bitLoop: rrc ; Get the next bit jump C, TxCharBB_one TxCharBB_zer move PO0.0, #0 sjump TxCharBB_next TxCharBB_one: move PO0.0, #1 TxCharBB_next: move LC[0], #BITLOOP djnz LC[0], $ djnz LC[1], TxCharBB_bitLoop move PO0.0, #1 ; STOP bit high move LC[0], #BITLOOP djnz LC[0], $ move LC[0], #BITLOOP djnz LC[0], $ ret要把温度数据从带符号的2进制、8位摄氏度数值转换成容易识别的ASCII码、华氏度数值,还需要增加较多代码,但这些代码简单易懂。使用BCD (二进制编码的十进制)运算规则执行二进制到十进制的转换,同时完成摄氏度到华氏度的转换。
move GR, @DP[0] ; Get the current entry move Acc, GRH ; Check the high byte jump Z, endOutput ; If it's zero we're done move A[15], GRL ; Save the low byte (temp value) move A[7], #0 ; Hundreds = 0 move A[6], #0 ; Tens = 0 move A[5], #0 ; Ones = 0 move A[4], #0 ; Tenths = 0 move A[3], #0 ; Add 01.8 per degree C move A[2], #1 move A[1], #8 move Acc, A[15] ; s6543210 jump S, tempNegC tempPosC: move GRL, #'+' jump Z, tempPrint move LC[0], Acc tempPosC_loop: call AddBCD djnz LC[0], tempPosC_loop move A[3], #3 move A[2], #2 move A[1], #0 ; Add 32.0 call AddBCD jump tempPrint tempNegC: move GRL, #'-' neg jump Z, tempPrint ; Negative zero jump S, tempPrint ; -128 is outside the sensor range anyhow move LC[0], Acc tempNegC_loop: call AddBCD djnz LC[0], tempNegC_loop move A[3], #3 move A[2], #2 move A[1], #0 ; Subtract 32.0 call SubBCD jump NC, tempPrint move GRL, #'+' ; Back to positive again jump tempPrint tempPrint: call TxCharBB ; Print plus/minus sign call TxTempBB ; Print temperature value + newline call IncDP0_EE ; Move to the next entry由于MAXQ3210的端口输出采用5V电平,在与PC的COM串口连接之前必须使用外部器件(如MAX233ACWP)对输出进行电平转换。完成这一转换后,可以使用任何标准终端仿真程序接收应用输出的数据。
RST DS1822 Detected : 22A9CC15000000E5 + 57.2 + 57.2 + 57.2 + 57.2 + 57.2 + 57.2 + 57.2 + 57.2 + 57.2 + 59.0 + 62.6 + 69.8 + 59.0 + 55.4 + 55.4 + 55.4 + 55.4 + 55.4 + 55.4 + 55.4 + 57.2 + 55.4 + 55.4 + 57.2 + 57.2 + 57.2 + 57.2 + 57.2 + 57.2
全部0条评论
快来发表一下你的评论吧 !