msp430 realization of serial calculator

Project download link:

In this experiment, a Serial UART with baud rate of 115200 is registered, which will interrupt when receiving full cache and sending empty cache. Call oneCharProcess(revChar_temp) in receiving interrupt; accept character and send the string to be sent in the interrupt.

The service interruption procedure is as follows:

/* ======== USCI A0/B0 TX Interrupt Handler Generation ======== */
#pragma vector = USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(void){
    switch(__even_in_range(UCA1IV,4)){//user guide: 36.4.14 UCAxIV Register
        case 0:break;
        case 2://Accept data
            revChar_temp = UCA1RXBUF;
            oneCharProcess(revChar_temp);
            break;                   //vector 2 : RXIFG
        case 4://send data
            if(sendstr[str_index] != '\0'){
                UCA1TXBUF = sendstr[str_index++];
            }else{
                str_index = 0;
            }
            break;                    //vector 4 : TXIFG
        default: break;
    }
}

Here we will use the following variables as the intermediate variable cache for expression calculation, which is related to the calculation algorithm, and uses two stacks, one for storing operands and one for storing operators:

int num[20] = {0};//Arithmetic stack
int num_index = -1;//Operand stack top pointer
u8 sp[20] = {0};//Operator stack
int sp_index = -1;//Operator stack top pointer

In this program, we encapsulate the following functions:

//Function declaration used

//Operator priority: the lower the number, the higher the priority
u8 getPriority(u8 oneChar);

//Interrupt processing function, processing one character at a time
void oneCharProcess(u8 oneChar);

/*
 * Character parsing function
 * Note: if you enter characters 0-9, the number 0-9 will be returned, and - 1 will be returned for others
 * Return value:
 *       0~9: Number character to number
 *       -1: Four operators and parentheses and=
 *       -2: Other
 */
int analysis_char(u8 oneChar0);

/*
 * Send final results
 * Parameter: num final result number
 */
void sendResult(int num);

//b char0 a = ?
int calculate(char char0, int a, int b);

Before we look at the interrupt handling function, we will briefly explain the algorithm as follows:

In addition to brackets and equal signs, the four operators are essentially binary operators, in other words, the number of operands is fixed, and the order is fixed. So we use two stacks, one to store operands and one to store operators. Then an operator must represent two operands, so the number of elements in the operator stack represents the reading and writing times of the operands. Because the stack comes first and then comes out, the order of binary operands is ensured.

Now the algorithm is described as follows:

First, set the operator priority as follows:
( > * > / > - > + > ) > =
When calculating,
1 scan the expression from left to right,
  • If the SP stack is empty, the operator will be pushed when it is encountered. If the NUM stack is empty at this time, the zero will be filled in the NUM stack;
  • If (, (in SP stack; in NUM stack if numbers are encountered;
  • If the priority of the current operator is higher than that of the SP stack top operator, the operator is put into the SP stack;
  • If the priority of the current operator is lower than or equal to the SP stack top operator, and the SP stack top operator is not (. Then one SP stack top element will pop up in turn, and two NUM stack elements will pop up for binary operation, and the result will be put into NUM stack again. Repeat this process until the priority of the operator is higher than that of the SP stack top operator;
  • If encountered), one SP stack top element will pop up in turn, and two NUM stack elements will pop up for binary operation, and the result will be put into NUM stack again. Repeat this process until (. Then pop (, discard it.
2. After scanning, if =, a SP stack top element will pop up in turn, and two NUM stack elements will pop up for binary operation, and the result will be put into NUM stack again. Repeat this process until the SP stack is empty, and the pop-up of the NUM stack top element is the final result.

The specific code is as follows:

//Interrupt processing function, processing one character at a time
void oneCharProcess(u8 oneChar){
    int analysisChar = analysis_char(oneChar);//When an operand is encountered, it is pressed into num
    if(analysisChar != -1 && analysisChar != -2){
        num_push(analysisChar);
    }else if(analysisChar == -1){
        if(oneChar=='='){//All SP S are out of the stack, and the final calculation results are in the num stack
            char temp1 = sp_pop();
            while(temp1 != 0){
                num_push(calculate(temp1, num_pop(), num_pop()));
                temp1 = sp_pop();
            }
            sendResult(num_pop());
        }else if((sp_index==-1) && (num_index==-1) && (oneChar == '-')){//If the first operand is negative
            sp_push(oneChar);
            num_push(0);
        }else if((sp_index==-1) || (oneChar=='(') || (getPriority(oneChar)<getPriority(sp[sp_index]))){//In three cases, if SP is empty, if SP is empty, then if operator is' (') ③, the priority of operator is higher than that of operator at the top of SP stack;
            sp_push(oneChar);
        }else if(oneChar==')'){//If the closing bracket is ")", the operator at the top of SP stack will pop up in turn, and press num until the opening bracket is encountered, and then the pair of brackets will be discarded;
            char temp1 = sp_pop();
            while(temp1!='('){
                num_push(calculate(temp1, num_pop(), num_pop()));
                temp1 = sp_pop();//Last discarded(
            }
        }else if((getPriority(oneChar)>=getPriority(sp[sp_index])) && (sp[sp_index]!='(')){//If the priority of the operator is less than or equal to the priority of the SP stack top operator, and the stack top operator is not (, then pop up the SP stack top element in turn until the priority of the operator is greater than the priority of the SP stack top operator;
            while((getPriority(oneChar)>=getPriority(sp[sp_index])) && (sp[sp_index]!='(')){
                num_push(calculate(sp[sp_index], num_pop(), num_pop()));
                sp_pop();//Move out of used operators
            }
            sp_push(oneChar);
        }else{
            sp_push(oneChar);
        }
    }
}
Published 48 original articles, won praise 9, visited 2782
Private letter follow

Tags: less

Posted on Mon, 13 Jan 2020 02:25:49 -0800 by bimmer528