Main

Lab 3: Basic Calculator

Starts: Week 8 (Oct 11 - Oct 15)
Demo Due: Week 9 (Oct 18 - Oct 22)
Points: 50

Updates and Clarifications:

(if needed)

Datasheets and Manuals

Parts Needed for Lab (all parts are provided in your team's Parts Kit)

1 - 8x2 LCD Screen (1.50” x 1”)
1 - Keypad (4x4)
Male Headers
Optional: 4x4 Vector Prototype Board

Lab Overview:

In this lab, you will build a basic calculator capable or performing addition, subtraction, multiplication, and division of 2 digit decimal inputs. This lab assignment will interface to a 4x4 Keypad for user input, and will require implementing a keypad scanning functions along with configuring the keypad to utilize change notification interrupts. The LCD software driver developed in your previous lab assignment will be utilized to display results using the 8x2 LCD Display.

NOTE: As you will be incorporating additional components with your PIC microcontroller, those components can either be directly integrated in the prototyping area of the 16-bit 28-pin Starter Board or using a separate prototype board. Each team is provided with a prototype board within their Parts Kits. If your team decides to integrate the components in the prototype area of the Starter Board, of the team member must be willing to use his/her board for this purpose.

Provided Software Code:

Source Code for Lab 3: lab3.c, keypad.h, keypad.c

Lab 3 Procedure:

  1. Part 1: Keypad Interface and Keypad Scanning Driver
    1. Connect the 4x4 Keypad to the PIC24F. The keypad is organized as 4 rows and four columns. You will need to either configure the 4 columns as inputs, and the 4 rows as output, or configure the 4 columns as outputs and the 4 rows and inputs. In either case, you should use open drain collectors for the outputs, and pull-up resistors for the inputs. The four inputs must also be connected a input pin that has a change notification (labeled CNx) assigned to it. You may either use internal or external pull-up resistor for the inputs. Most of the details for connecting the keypad to the PIC24F can be found within the 4x4 Keypad Datasheet.

      Note 1: The datasheet and keypad do not provide any indication of which pin in pin 1. You will need to experiment with the keypad to determine the correct order of the pins. You should be able to use the continuity setting on your multimeter to determine this.

      Note 2: The datasheet for the keypad uses row and columns labels of 1-4, instead of 0-3.

    2. Using the provided C code (lab3.c, keypad.h, keypad.c) complete the keypad initialization, keypad scanning, and change notification interrupt code required to interface with the 4x4 keypad and display the pressed key using the LCD Display. To complete this functionality, you will need to complete the following:
      1. Develop a KeypadInitialize() function that will configure IOs and Change Notificaiton interrupt for keypad scanning. This configuration should ensure that if any key is pressed, a change notification interrupt will be generated.
      2. Develop a KeypadScan() function implementing the keypad scanning procedure to detect if exactly one button of the keypad is pressed. The function should immediately return the current state of the keypad as:
        • 0 : Return 0 if no keys are pressed.
        • '0' - '9' : Return the ASCII character '0' to '9' if one of the numeric (0 - 9) keys are pressed.
        • '+' : Return the ASCII character '+' if the A key is pressed.
        • '-' : Return the ASCII character '-' if the B key is pressed.
        • '*' : Return the ASCII character '*' if the C key is pressed.
        • '/' : Return the ASCII character '/' if the D key is pressed.
        • -1 : Return -1 if the * or # keys are pressed, or if more than one key is pressed simultaneously.
      3. NOTE: In implementing the KeypadScan(), a for/while/do..while loop with bit masking and shifting operations should be utilized in the scanning process for either the rows of the columns of the scanning process. Full credit will not be awarded if both individual rows and columns are set and checked.
      4. Implement the initialize program functionality for displaying any single key press using the LCD Display. This functionality must utilize a change notification interrupt to detect if *any* key of the keypad is *pressed*, and update a scanKeypad variable to indicate keypad scanning process must be executed. The keypad scanning procedure itself should be called from within the main execution loop of the main() function.
  2. Part 2: Implement Basic Calculator Functionality
    1. Add functionality for simple calculator that detects two distinct digit ('0' - '9') presses for the first input, a distinct operation press for '+', '-', '*', or '/', and two distinct digit ('0' - '9') presses for the second input:
      1. This input should be displayed on the first line of the LCD display as the user enters the operations, e.g. "01+09 =".
      2. Only valid inputs should be allowed by the user such that all invalid inputs are ignored until a valid input is detected.
      3. The user must release all keys of the keypad before the following key press is processed. This is prevent invalid keypress from being processed if the users presses multiple keys simultaneously.
      4. As soon as the user correctly enters the second number, the result of the calculation should be displayed on second line of the LCD display. The basic calculator functionality should simply use integer division for all operations.
  3. Extra Credit (2 points): Precise Division Calculation
    1. For the division operation, implement a more precise division calculation that will report the resulting quotient using 4 fractional digits (i.e. four digits to the right of the decimal points). To receive this extra credit you must adhere to the following requirements:
      1. No floating point division is allow. All calculation must use integer operations.
      2. You may not use any library functions such as sprintf().
      3. Trailing zeros in the fractional part of the quotient should not be displayed. For example, the result of 4/5 should be printed as "0.8" not "0.8000".