⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prog47i.asm

📁 主要是8051源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;  PROG47i - Working through the Electronic Breakout Box  
;
;
;  Start Taking User Input.
;
;  PROG47i - Poll on "Enter" Button while Showing the Output
;
;  PROG47H - Do Bidirectional Communication
;          - Redraw "Left" Communication When Neccesary
;  
;  PROG47G - Start Taking Serial Input/Displaying it on the LCD.  
;
;  PROG47F - Get and Set the Data Rate.  This is Just a Simulator exercise. 
;
;  PROG47E1 - Put in PROG47E Code, But Look for Problems - Found with the 
;              Mix-Up in Registers, the 5 msec delay wasn't executed with the 
;              change in the registers.  
;
;  PROG47D - Read (and Debounce) the Button
;
;  PROG47C - Output a Table and Save the Blank Positions in R5, R6 and R7 
;
;  Myke Predko
;  98.06.22
;
;  Hardware Notes:
;  DS87C520 is used as the Microcontroller
;   - Oscillator Speed is 11.052 MHz
;  P2.4-7 are the LCD Data Bits (NOTE: Bits Are Reversed)
;  P0.3 is Pulled up with a 4.7L K resistor and used for the LCD "RS" Bit
;  P0.4 is Pulled up with a 4.7K Resistor and used for the LCD "E" Bit
;  P2.0 is Used as the "Select" Button
;  P2.1 is Used as the "Enter" Button
;
;  P2.2 is Used as Left _DTE/DCE Control
;  P2.3 is Used as the Right _DTE/DCE Control

;  Constant Declarations
define RS=P0.3                  ;  Define the LCD "RS" Bit
define EStrobe=P0.4             ;  Define the LCD "E" Bit

define Select=P2.0              ;  Define the "Select" Button
define Enter=P2.1               ;  Define the "Enter" Button

define LeftDCE=P2.2             ;  Define the _DTE/DCE Bits
define RightDCE=P2.3

;  Variable Declarations
BufferHold   EQU 020h           ;  Register to Allow Data Updates to be Set

DelayCount   EQU 030h           ;  Button Delay Count
DelayCounthi EQU 031h

LeftLast     EQU 032h           ;  Last Position of the "Left" Buffer
RightLast    EQU 033h

LeftCount    EQU 034h           ;  Keep Track of the Number of Columns Used
RightCount   EQU 035h

LeftBuffer   EQU 040h           ;  Buffer for the Incoming "Left" Data
RightBuffer  EQU 060h           ;  Buffer for the Incoming "Right" Data


;  Macros


;  Mainline
 org 0                          ;  Execution Starts Here

  ajmp   Mainline               ;  Jump Over Interrupt Handlers

 org 023h                       ;  Serial Port 0 (Left Serial Port) Interrupt
Serial0:

  clr    SCON0.1                ;  Clear the TX Flag

  jnb    SCON0.0,Serial0_End    ;  Only Handle if it was an RX Interrupt

  clr    SCON0.0                ;  Acknowledge the Interrupt Happened

  mov    @R0,SBUF0              ;  Save the Value Read
  mov    SBUF1,@R0              ;  Send it Back Out the other side

  inc    R0
  mov    BufferHold,R0          ;  Make Sure the Value Stays in the 16 Byte Buffer
  clr    4                      ;   This is Bit 5
  mov    R0,BufferHold

Serial0_End:

  reti

 org 03Bh                       ;  Serial Port 1 (Right Serial Port) Interrupt
Serial1:

  clr    SCON1.1                ;  Clear the TX Interrupt
  
  jnb    SCON1.0,Serial1_End    ;  Only Handle Incoming Interrupts

  clr    SCON1.0                ;  Acknowledge the Interrupt Happened

  mov    @R1,SBUF1              ;  Save the Value Read
  mov    SBUF0,@R1              ;  Send it Back Out the other side

  inc    R1
  mov    BufferHold,R1          ;  Make Sure the Value Stays in the 16 Byte Buffer
  clr    4                      ;   This is Bit 5
  mov    R1,BufferHold

Serial1_End:

  reti

MainLine:                       ;  Mainline of the Program

  mov    CKCON,#%00000000       ;  Use Internal /12 Clock for Timer1 (Serial Port Clocks)
  mov    TMOD,#%00100000        ;  Timer1 - Uses Internal Clock
                                ;         - Run in Mode 2
  mov    TL1,#253               ;  Start Timer1 at 9600 bps
  mov    TH1,#253
  mov    TCON,#%01000000        ;  Start Timer1 running

  mov    SCON,#%01010000        ;  Run Serial Port 0 in 8 Bit Mode
  mov    SCON1,#%01010000       ;  Run Serial Port 1 in 8 Bit Mode


  acall   LCDInit               ;  Initialize the LCD

Loop:                           ;  Loop Here for Each One

  acall   GetSpeed              ;  Get the Data Speed

  acall   DTECheck

;  #### - Put in the Different Breakout Box Operations

  clr     RS                    ;  Clear the LCD
  mov     A,#1
  acall   CharSend

  mov     A,#2                  ;  Put in the "Breakout Box" Message
  acall   MsgSend

  clr     RS                    ;  Put in the Lower Line
  mov     A,#0C0h
  acall   CharSend
  mov     A,#3                  ;  Display The "Run Configure" Message
  acall   MsgSend               ;  Output the Message

  acall   MenuRead              ;  Get the "Speed -" Information

  mov     A,R0                  ;  Do we have 300 bps?
  xrl     A,R5
  jnz     Loop                  ;  Configure the Serial Data

  clr     RS                    ;  Now, Reset the Screen for Displaying
  mov     A,#080h
  acall   CharSend
  mov     A,#14                 ;  Put on the Output Display
  acall   MsgSend
  clr     RS                    
  mov     A,#0C0h
  acall   CharSend
  mov     A,#15                 
  acall   MsgSend

  clr     SCON0.0               ;  Make Sure we don't Start with Any Interrupts
  clr     SCON0.1
  clr     SCON1.0               
  clr     SCON1.1

  mov     R0,#LeftBuffer        ;  Setup the Left Buffer
  mov     R1,#RightBuffer

  mov     LeftLast,#LeftBuffer  ;  Setup Buffer Check Values
  mov     RightLast,#RightBuffer

  mov     LeftCount,#0          ;  Set the Column Counters
  mov     RightCount,#0

  mov     IE,#%11010000         ;  Enable Serial Port0 and Serial Port1 Interrupts

EC_End:                         ;  Wait for the Switch to be released for 20 msecs
  mov     DelayCount,#0         ;  Load With a 20 Msec Wait
  mov     DelayCounthi,#29
EC_ELoop:                       ;  Wait for the "Enter" Button to be Down 20 msec
  jnb     Enter,EC_End          ;  If Button is Pressed (Down), Wait Again
  djnz    DelayCount,EC_ELoop   ;  4
  djnz    DelayCounthi,EC_ELoop ;  4  

DataLoop:                       ;  Loop Here for Each Character

  mov     A,LeftLast            ;  Get the Last Postion
  xrl     A,R0                  ;   Has Anything Changed?  
  jz      RightCheck            ;  Do we have something coming in from the Right?

  mov     A,LeftCount
  xrl     A,#14
  jnz     DisplayLeft

  clr     RS                    ;  Redraw the Top Line
  mov     A,#080h
  acall   CharSend

  clr     IE.7                  ;  Disable Interrupts for the Message
  push    0                     ;  Save R0 and R1 which Are used in "MsgSend
  push    1
  mov     A,#14
  acall   MsgSend
  pop     1
  pop     0
  setb    IE.7                  ;  Enable Interrupts After Message Displayed

  mov     LeftCount,#0          ;  Reset the Counter

DisplayLeft:                    ;  Display the Character on the Left

  clr     RS                    ;  Make Sure the Cursor is in the Correct Spot
  mov     A,#082h
  add     A,LeftCount
  acall   CharSend

  clr     IE.7                  ;  Display the Character
  mov     A,LeftLast            ;  Use "LeftLast" as the Character to Display
  xch     A,R0

  mov     B,@R0                 ;  Save the Character

  xch     A,R0                  ;  Restore the Registers
  mov     LeftLast,A
  setb    IE.7                  ;  Turn Interrupts Back on

  mov     A,B                   ;  Display the Character
  setb    RS
  acall   CharSend              

  inc     LeftLast
  mov     A,LeftLast
  clr     ACC.4
  mov     LeftLast,A

  inc     LeftCount             ;  Increment the Column Counter for Initial Check

  ajmp    DataLoop

RightCheck:                     ;  Loop Here for Each Character

  mov     A,RightLast           ;  Get the Last Postion
  xrl     A,R1                  ;   Has Anything Changed?  
  jz      DisplayEnterCheck

  mov     A,RightCount
  xrl     A,#14
  jnz     DisplayRight

  clr     RS                    ;  Redraw the Top Line
  mov     A,#0C0h
  acall   CharSend

  clr     IE.7                  ;  Disable Interrupts for the Message
  push    0                     ;  Save R0 and R1 which Are used in "MsgSend
  push    1
  mov     A,#15
  acall   MsgSend
  pop     1
  pop     0
  setb    IE.7                  ;  Enable Interrupts After Message Displayed

  mov     RightCount,#0         ;  Reset the Counter

DisplayRight:                   ;  Display the Character on the Right

  clr     RS                    ;  Make Sure the Cursor is in the Correct Spot
  mov     A,#0C0h
  add     A,RightCount
  acall   CharSend

  clr     IE.7                  ;  Display the Character
  mov     A,RightLast           ;  Use "RightLast" as the Character to Display
  xch     A,R1

  mov     B,@R1                 ;  Save the Character

  xch     A,R1                  ;  Restore the Registers
  mov     RightLast,A
  setb    IE.7                  ;  Turn Interrupts Back on

  mov     A,B                   ;  Display the Character
  setb    RS
  acall   CharSend              

  inc     RightLast
  mov     A,RightLast
  clr     ACC.4
  mov     RightLast,A

  inc     RightCount            ;  Increment the Column Counter for Redisplay Check

  ajmp    DataLoop

DisplayEnterCheck:

  jnb     Enter,EC_Start        ;  If the "Enter" Button is Pressed, Stop Looping
   ajmp   DataLoop

EC_Start:
  mov     DelayCount,#0         ;  Load With a 20 Msec Wait
  mov     DelayCounthi,#29
EC_Loop:                        ;  Wait for the "Enter" Button to be Down 20 msec
  jb      Enter,EC_Start        ;  If Button is Pressed (Down), Wait Again
  djnz    DelayCount,EC_Loop    ;  4
  djnz    DelayCounthi,EC_Loop  ;  4  

  ajmp    Loop



;  Subroutines
GetSpeed:                       ;  Get and Set the Speed

  clr     RS                    ;  Clear the LCD
  mov     A,#1
  acall   CharSend

  mov     A,#4                  ;  Put in the "Speed -"" Message
  acall   MsgSend

  clr     RS                    ;  Put in the Lower Line
  mov     A,#0C0h
  acall   CharSend
  mov     A,#5                  ;  Display The "300/1200/Cont" Message
  acall   MsgSend               ;  Output the Message

  acall   MenuRead              ;  Get the "Speed -" Information

  mov     A,R0                  ;  Do we have 300 bps?
  xrl     A,R5
  jnz     Check1200             ;  No, Check 1200 bps

  mov     TL1,#160              ;  Load the 300 bps Delay
  mov     TH1,#160

  ajmp    GetSpeed_End

Check1200:                      ;  Do we have 1200 bps Selected?
  mov     A,R0
  xrl     A,R6
  jnz     GetSpeed_2nd          ;  No, Do the Next Menu

  mov     TL1,#232              ;  Load the 1200 bps Delay
  mov     TH1,#232

  ajmp    GetSpeed_End

GEtSpeed_2nd:                   ;  Check the Other Display

  clr     RS                    ;  Clear the LCD
  mov     A,#1
  acall   CharSend

  mov     A,#6                  ;  Put in the "Speed |"" Message
  acall   MsgSend

  clr     RS                    ;  Put in the Lower Line
  mov     A,#0C0h
  acall   CharSend
  mov     A,#7                  ;  Display The "2400/9600/Cont" Message
  acall   MsgSend               ;  Output the Message

  acall   MenuRead              ;  Get the "Speed -" Information

  mov     A,R0                  ;  Do we have 2400 bps?
  xrl     A,R5
  jnz     Check9600             ;  No, Check 9600 bps

  mov     TL1,#244              ;  Load the 2400 bps Delay
  mov     TH1,#244

  ajmp    GetSpeed_End

Check9600:                      ;  Do we have 9600 bps Selected?

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -