; File: PCA_TxD2.A51 Date: 2/12/93 ; ; /* (c) Copyright BLUE EARTH RESEARCH, MANKATO, MN 1993 */ ; /* All rights reserved. */ $ ERRORPRINT PAGELENGTH (60) PAGEWIDTH (110) ; Assembler controls $ XREF TITLE (2nd Serial Port Transmit Only) $ DATE (2/25/93) NOGEN NOMOD51 ; ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ; º PCA 2ND SERIAL PORT "PRINT@" DRIVER ROUTINE º ; ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ; ----------------------------------------------------------------------------- ; Written by Tom Bachmann, Blue Earth Research, Mankato, MN 56001 ; Original 2/12/93, Updated 2/25/93 by Tom Bachmann ; ----------------------------------------------------------------------------- ; This program implements the transmit portion of the PCA serial port driver. ; The program assumes that the primary serial port is properly set up and that ; the secondary port is initialized similar to the BASIC program shown below. ; After this program is initialized from within BASIC by executing the ; "CALL 7F00H" Statement, characters are written to the second serial port ; by the "PRINT@" Statement. ; ------------------------- BASIC LANGUAGE PROGRAM ---------------------------- ; 1 REM Baud Rate Converter ; ; REM DEFINE THE SYSTEM'S SECOND SERIAL PORT BAUD RATE ; REM AND CALCULATE TIMING PARAMETERS ; 20 BPS=2400 : FULLBIT=1E+6/BPS ; 40 DBY(19H)=INT(FULLBIT/256) : DBY(18H)=FULLBIT.AND.255 ; 60 CALL 7F00H ; 100 PRINT@ "HELLO" ; NOTE: Slightly better accuracy can be obtained by setting the PCA to ; increment at 1/4 of the crystal frequency (instead of 1/12 F). This change ; would make the BASIC variable FULLBIT increase by a factor of three. In ; this case line 20 above would be " 20 BPS=2400 : FULLBIT=3E+6/BPS" ; Changing the PCA time base is done by setting the CPS0 bit in CMOD. $ EJECT ; ------------------------ ASSEMBLY LANGUAGE PROGRAM -------------------------- ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ SYMBOL DEFINITIONS ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ $ NOLIST ; DON'T SHOW IN LIST FILE $ INCLUDE(REGFX.INC) ; INCLUDE 83C51FB REGISTERS $ LIST ; SHOW THE REST IN THE LIST FILE ; ----------------------------- EQUATE TABLE ---------------------------------- PCAAddress EQU 4033H ; PCA Interrupt Vector SoftTimer EQU 049H CodeAddr EQU 7F00H ; Locate this program at top of ; write protectable memory space ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ INTERNAL DATA SEGMENT ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ DSEG AT 18H LoFullBitTime: DS 1 ; Hold the reload values for the HiFullBitTime: DS 1 ; PCA Serial Port Timing TxmCounter: DS 1 ; Counter for sending bits TxmTemp: DS 1 ; Software Transmit SBUF ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ INTERNAL BIT SEGMENT ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ BSEG AT 0 TxmStart: DBIT 1 ; Transmit Bits InProgress: DBIT 1 $ EJECT ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ EXTERNAL CODE SEGMENT ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ CSEG AT CodeAddr ; ---------------------- INITIALIZE PCA INTERRUPT ----------------------------- MOV DPTR,#PCAAddress ; Stuff "LJMP PCAINT" into MOV A,#2 ; mirrored PCA interrupt MOVX @DPTR,A ; vector at address 4033H. INC DPTR MOV A,#HIGH PCAINT ; Location of PCA MOVX @DPTR,A ; interrupt routine. INC DPTR MOV A,#LOW PCAINT MOVX @DPTR,A ; The following code places the jump vector in memory and sets the bit that ; tells BASIC where it should direct the PRINT@ output to. Start: MOV DPTR,#403CH ; POINT TO JUMP LOCATION MOV A,#2 ; LOAD LJMP Instruction MOVX @DPTR,A INC DPTR MOV A,#HIGH SendChar MOVX @DPTR,A INC DPTR MOV A,#LOW SendChar MOVX @DPTR,A SETB 39 ; PROTECTION BIT $ EJECT ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ INITIALIZE CPU FUNCTIONS ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ MOV CL,#0 ; CLEAR PCA TIMER REGISTERS MOV CH,#0 MOV CCAP4L,LoFullBitTime ; Initialize Transmit Mode. MOV CCAP4H,HiFullBitTime ; ÚÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄ¿ ; IE = ³ EA ³ EC ³ ET2 ³ ES ³ ET1 ³ EX1 ³ ET0 ³ EX0 ³ ; ÀÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÙ ; 1 1 0 0 0 0 0 0 MOV IE,#0C0H ; ÚÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄ¿ ; CCAPM = ³ -- ³ ECOM ³ CAPP ³ CAPN ³ MAT ³ TOG ³ PWM ³ ECCF ³ ; ÀÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÙ ; Module 4 -> 0 1 0 0 1 0 0 1 MOV CCAPM4,#SoftTimer ; ÚÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄ¿ ; CMOD = ³ CIDL ³ WDTE ³ -- ³ -- ³ -- ³ CPS1 ³ CPS0 ³ ECF ³ ; ÀÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÙ ; 0 0 0 0 0 0 0 0 MOV CMOD,#0 ; PCA Timebase = 1 microsecond ; NOTE: For better resolution, the PCA Timebase can be set at 1/3 ; microsecond by setting the CPS0 bit in CMOD. ; MOV CMOD,#2 ; PCA Timebase = 1/3 microsecond ; ÚÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄ¿ ; CCON = ³ CF ³ CR ³ -- ³ CCF4 ³ CCF3 ³ CCF2 ³ CCF1 ³ CCF0 ³ ; ÀÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÙ ; 0 1 0 0 0 0 0 0 MOV CCON,#00H ; No need to turn timer on yet. CLR InProgress ; No chars being transmitted now. RET ; Back to BASIC. $ EJECT ; ----------------------------- MAIN PROGRAM ---------------------------------- ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ SET UP TO TRANSMIT A CHARACTER ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ SendChar: JB InProgress,$ ; Make sure no previous chars yet CLR TxmStart ; Clear status flag MOV TxmTemp,A ; Load "SBUF" with data byte MOV TxmCounter,#9 ; 8 data bits + 1 stop bit SETB InProgress SETB CR ; Start the PCA timer RET ; Back to BASIC ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ PCA INTERRUPT ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ PCAINT: JNB CCF4,NoMore ; Check for receive Interrupt ; ---------------------------- TRANSMIT INTERRUPT ----------------------------- TransmitInt: CLR CCF4 PUSH ACC PUSH PSW JNB InProgress,TxmDone JB TxmStart,SendByte ; See if Start Bit was sent CLR P1.7 ; Otherwise transmit Start bit SETB TxmStart ; Set start bit flag SJMP TxmDone SendByte: DJNZ TxmCounter,TxmNext ; Transmit 8 data bits TxmStop: SETB P1.7 ; Transmit stop bit CLR InProgress ; Transmission Completed! CLR CR ; Turn the PCA off SJMP TxmDone TxmNext: MOV A,TxmTemp ; Transmit one bit at a time RRC A ; through the carry bit MOV P1.7,C MOV TxmTemp,A ; Save for next time $ EJECT TxmDone: MOV A,LoFullBitTime ; Setup for next PCA int. ADD A,CCAP4L MOV CCAP4L,A MOV A,HiFullBitTime ADDC A,CCAP4H MOV CCAP4H,A POP PSW POP ACC NoMore: RETI END ; Following is the HEX file derived from the assembled source ; file. This can be used for directly loading the program via ; MONITOR-51 and almost any terminal program. :107F00009040337402F0A3747FF0A37448F0904063 :107F10003C7402F0A3747FF0A37439F0D22775E9A2 :107F20000075F9008518EE8519FE75A8C075DE4943 :107F300075D90075D800C201222001FDC200F51BD1 :107F4000751A09D201D2DE2230DC34C2DCC0E0C0B6 :107F5000D030011B200006C297D2008012D51A082B :107F6000D297C201C2DE8007E51B139297F51BE58D :107F70001825EEF5EEE51935FEF5FED0D0D0E0324D :00000001FF