微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 把下面德源程序生成.hex文件 谢谢大神

把下面德源程序生成.hex文件 谢谢大神

时间:10-02 整理:3721RD 点击:

NAME    KEYPAD

?PR?input?KEYPAD               SEGMENT CODE

        PUBLIC        input

?DT?input?KEYPAD               SEGMENT DATA

RSEG  ?DT?input?KEYPAD                        

KEY_ROW1        equ        0EFh

KEY_ROW2        equ        0DFh

KEY_ROW3        equ        0BFh

KEY_ROW4        equ        07Fh

keyflags:        ds        16

RSEG  ?PR?input?KEYPAD                          

input:

keyscan:        push DPH

                push DPL

                mov R0,#keyflags                

                mov R1,#KEY_ROW1               

                mov R2,#4                       

ksrow:        mov P2,R1                       

                nop

                mov A,P1                       

                mov R3,#4               

                anl A,#3Fh

ks0:        rrc A                       

                mov R4,A                       

                jc ks1                               

                mov A,@R0               

                mov @R0,#1                       

                jz ksnew               

                jmp ks2

ks1:        mov @R0,#0                       

ks2:        inc R0                               

                mov A,R4

                djnz R3,ks0

                mov A,R1                       

                rl A

                mov R1,A

                djnz R2,ksrow

                clr A                               

                mov R7,A                       

                jmp ksend                               

ksnew:        mov DPTR,#keycodes               

                mov A,R0                       

                clr C

                subb A,#keyflags

                movc A,@A+DPTR

                mov R7,A                       

ksend: mov P2,#0FFh

                pop DPL

                pop DPH

                ret

keycodes:        db         '7','8','9', '/'

                db        '4','5','6', '*'

                db        '1','2','3', '-'

                db        'C','0','=', '+'

                END

加减乘除运算程序:

    #include <intrins.h>

#include <reg51.h>

#include "calc.h"

static  data LONG lvalue;

static  data LONG rvalue;

static  data CHAR currtoken;

static  data CHAR lasttoken;

static  data CHAR lastpress;

static  xdata CHAR outputbuffer[MAX_DISPLAY_CHAR];

VOID main (VOID)

{ lvalue    = 0;

   rvalue    = 0;

   currtoken = '=';

   lasttoken = '0';

   initialise();

   calc_output(OK);

   calc_evaluate();

}   

VOID calc_evaluate()

{ CHAR data key;

   INT  data i;

   CHAR xdata number[MAX_DISPLAY_CHAR];

   CHAR xdata *bufferptr;

   for (i = 0; i <= MAX_DISPLAY_CHAR; i++)

      { number = ' ';

          }

   bufferptr = number;  

   for (;;)

     { key = calc_getkey();

           if (calc_testkey(key))

          { if (bufferptr != &number[MAX_DISPLAY_CHAR - 2])

               { *bufferptr = key;

                 calc_display(number);

                 bufferptr++;

               }

          }

       else

          {

                    

            if (lasttoken == '0')

               { lvalue = calc_asciidec (number);}

            else

               { rvalue = calc_asciidec (number);}

            bufferptr = number;

            for (i = 0;i <= MAX_DISPLAY_CHAR; i++)

               { number = ' '; }

                 

            

            currtoken = key;

                        if (currtoken == 'C')

                           { calc_opfunctions(currtoken); }

                         else

                           { calc_opfunctions(lasttoken); }

               

            for (i = 0;i <= MAX_DISPLAY_CHAR;i++)

               { outputbuffer = ' ';}

                   bufferptr = number;

                        if (currtoken != 0x3D) lasttoken = currtoken;

            

                     }

       lastpress = key;

     }

}

VOID calc_opfunctions (CHAR token)

{ CHAR data result;

   switch(token)

        // Add.

     {  case '+' : if ((currtoken == '=' ) || ((lastpress >= 0x30) && (lastpress <=0x39)))

                                    { lvalue += rvalue;

                                    result = calc_chkerror(lvalue);

                                          }

                                      else

                                        { result =  SLEEP; }                break;

        // Subtract.

                case '-' : if ((currtoken == '=' ) || ((lastpress >= 0x30) && (lastpress <=0x39)))

                      { lvalue -= rvalue;

                        result = calc_chkerror(lvalue);               

                                          }

                   else

                      { result = SLEEP;}                break;

        // Multiply.

                case '*' : if ((currtoken == '=' ) || ((lastpress >= 0x30) && (lastpress <=0x39)))

                      { lvalue *= rvalue;

                        result =  calc_chkerror(lvalue);

                      }

                   else

                      { result =  SLEEP;}                break;

                // Divide.                          

                case '/' : if ((currtoken == '=' ) || ((lastpress >= 0x30) && (lastpress <=0x39)))

                      { if (rvalue)

                           { lvalue /= rvalue;

                             result = calc_chkerror(lvalue);

                           }

                        else

                           { result = ERROR;}                                 

                      }

                   else

                      { result = SLEEP;}                break;

                // Cancel.

                case 'C' : lvalue = 0;

                   rvalue = 0;

                   currtoken = '0';

                   lasttoken = '0';

                   result = OK;                                          break;

       

                default :  result = SLEEP;  

      }

   calc_output(result);

}

INT calc_chkerror (LONG num)

// Check upper and lower bounds for the display.

// i.e. 99999999 and -99999999.

{ if ((num >= -9999999) && (num <= 9999999))

      return OK;

   else

      return ERROR;

}

VOID calc_output (INT status)

// Output according to the status of the operation.

// *Sleep* is used for the first op press after a full cancel

// or on startup.  

{ switch (status)

      { case OK      : calc_display(calc_decascii(lvalue));    break;

        case SLEEP   :                                         break;

                case ERROR   : calc_display("Exception ");                           break;       

        default      : calc_display("Exception ");                       break;

      }

}

LONG calc_asciidec (CHAR *buffer)

// Convert the ASCII string into the floating point number.

{ LONG data value;

   LONG data digit;

   value = 0;

   while (*buffer != ' ')

      { digit = *buffer - 48;

            value = value*10 + digit;

        buffer++;

          }

   return value;

}

CHAR *calc_decascii (LONG num)

// A rather messy function to convert a floating

// point number into an ASCII string.

{ LONG data temp = num;

   CHAR xdata *arrayptr = &outputbuffer[MAX_DISPLAY_CHAR];

   LONG data divisor = 10;

   LONG data result;

   CHAR data remainder,asciival;

   INT  data i;

   

   // If the result of the calculation is zero

   // insert a zero in the buffer and finish.

   if (!temp)

      { *arrayptr = 48;

            goto done;

          }

   // Handle Negative Numbers.

   if (temp < 0)

      { outputbuffer[0] = '-';

            temp -= 2*temp;

          }

   for (i=0 ; i < sizeof(outputbuffer) ; i++)

      { remainder = temp % divisor;   

        result = temp / divisor;

            

                // If we run off the end of the number insert a space into

            // the buffer.

            if ((!remainder) && (!result))

               { *arrayptr = ' ';}

          

            // We're in business - store the digit offsetting

            // by 48 decimal to account for the ascii value.

            else

               { asciival = remainder + 48;

                     *arrayptr = asciival;

                   }

          

                temp /= 10;

            // Save a place for a negative sign.

            if (arrayptr != &outputbuffer[1]) arrayptr--;

           }

   done: return outputbuffer;

}

CHAR calc_testkey (CHAR key)

// Test whether the key is a digit or an operator. Return 1 for digit, 0 for op.

{ if ((key >= 0x30) && (key <= 0x39))

      { return 1;}

   else

      { return 0;}

}

CHAR calc_getkey (VOID)

// Use the input routine from the *Keypad_Read* assembly file to

// Scan for a key and return ASCII value of the Key pressed.

{ CHAR data mykey;

  do mykey = input();

     while (mykey == 0);

  return mykey;

}

VOID calc_display (CHAR buf[MAX_DISPLAY_CHAR])

// Use the Output and Clearscreen routines from the

// *LCD_Write* assembly file to output ASCII values to the LCD.

{ INT data  i = 0;

   clearscreen();

   for (i ; i <= MAX_DISPLAY_CHAR ; i++)

      { if (buf != ' ')

             { output(buf); }

          }       

}

LCD显示程序:

NAME    LCD

LCD              SEGMENT CODE

RSEG             LCD

                 PUBLIC  _output

                 PUBLIC  initialise

                 PUBLIC  clearscreen

;LCD Register Addresses.液晶寄存器地址

LCD_CMD_WR        equ         00h

LCD_DATA_WR        equ        01h

LCD_BUSY_RD        equ        02h

LCD_DATA_RD        equ        03h

LCD_PAGE        equ        80h

;LCD Commands液晶指令

LCD_CLS                equ        1

LCD_HOME        equ        2

LCD_SETMODE        equ        4

LCD_SETVISIBLE        equ        8

LCD_SHIFT        equ        16

LCD_SETFUNCTION        equ        32

LCD_SETCGADDR        equ        64

LCD_SETDDADDR        equ        128

; Initialisation Routine for the LCD display.初始化例程的LCD显示。

initialise:         mov A,#030h                        ;1 line, 8 bits

                call wrcmd

                mov A,#LCD_SETVISIBLE + 4

                call wrcmd

                mov A,#LCD_SETDDADDR+15               

                call wrcmd

                mov A,#LCD_SETMODE + 3                 

                call wrcmd

                ret

_output:        mov A,R7       

                call wrdata

                ret

clearscreen:        mov A,#LCD_CLS

                call wrcmd

                mov A,#LCD_SETDDADDR + 15

                call wrcmd

                ret

               

wrcmd:                mov P2,#LCD_PAGE

                mov R0,#LCD_CMD_WR

                movx @R0,A

                jmp wtbusy

wrdata:                MOV P2,#LCD_PAGE                               

                MOV R0,#LCD_DATA_WR

                MOV A,R7

                MOVX @R0,A

wtbusy:                MOV R1,#LCD_BUSY_RD

                MOVX A,@R1

                JB ACC.7,wtbusy

                ret

                END


Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top