Author Topic: C Programming.  (Read 1394 times)

I've got to program a PIC chip with a 4x4 keypad.  I have to make a reverse polish calculator.  I wouldn't normally ask this, I don't even know if anyone here knows this stuff, but nobody in today's lab finished.  It's a crazy hard lab and our teacher doesn't really teach the stuff well.

I don't expect anybody to write the code for me, I don't even really expect help.  Any assistance would be much appreciated.

The assignment: http://www.eece.maine.edu/~eason/ece177/lab07.pdf

The starter code:

Quote
#include <pic.h>      // Always include this
#include "lcd.h"
#include "delay.h"
#include "printf.h"

__CONFIG(INTIO&WDTDIS&PWRTDIS&MCLREN&UNPROTECT&DUNPROTECT&BORDIS&IESODIS&FCMDIS&LVPDIS&DEBUGDIS);

signed char getkey(void);         // forward declarations
unsigned char mapkey(signed char);
signed int getnum(void);

// Global variables, #defines, and enums here
char operator;         // operator returned from "getnum()"
enum {enter=10, backspace, plus, minus, times, divide};


void main(void) {      // main program here

signed char getkey(void) {
// This routine will get a key on the keypad and will return the
// key number, or -1 if no key is pressed. Keys are numbered top to
// bottom and left to right and the keypad is mapped as follows

//             Output   Key
//             Bits     Number
//              0 |  0  1  2  3
//              1 |  4  5  6  7
//              2 |  8  9 10 11
//              3 | 12 13 14 15
//                 ------------
//                   4  5  6  7
//                   Input Bits


unsigned char mapkey(signed char key) {
//   Return the mapping of the given key according to the following

//    Key Number        Mapping
// |  0  1  2  3      0 |  1  2  3  +
// |  4  5  6  7      1 |  4  5  6  -
// |  8  9 10 11      2 |  7  8  9  *
// | 12 13 14 15      3 | BS  0 EN  /      (BS = Backspace)
//  ------------         ------------      (EN = ENTER)


signed int getnum(void) {
// Wait for user to enter a number followed by an operator. The
// function return value is the number. The operator is returned
// in the global variable "operator".


Ephi might know, if he doesn't answer shot him a PM.

I don't understand how “12 ENTER 3 + 4 /” is equal to (12 + 3) / 4

Yeah I'm going to message him on MSN in the morning if I don't get anything useful.  Otis should also know this stuff.

Give me a sec to look at the project, I'll see if I can piece it together.

I don't understand how “12 ENTER 3 + 4 /” is equal to (12 + 3) / 4

Move every operator behind the number.

We say plus four, they say four plus. We say Divided by four, they say division of four.

Your best bet would be to use a stack approach.
Something like this:
  • Program starts, empty stack
  • Number 12 entered, stack is [12]
  • Number 3 entered, stack is [12, 3]
  • Operator + entered, pop the last two numbers off the stack, add them up, push them on stack, stack is [15]
  • Number 4 entered, stack is [15, 4]
  • Operator / entered, pop the last 2 numbers off the stack, divide them, push them on the stack, stack is [3.75]
  • You get the result of your operations when the stack size is 1, pop the last value off the stack to get the result

You could use something like this for your stack implementation.

Edit:
I wrote a small implementation in Python, translating it to PIC-C is up to you...
Code: [Select]
def ReversePolish(line):
stack = []
tokens = line.split(" ")

for token in tokens:
try:
#maybe the token is a number, try to convert it from string to number
a = float(token)
stack.append(a)
except ValueError:
#looks like it's not a number, maybe it's an operator
if token in "+-*/":
#check if stack is big enough, 2 elements required!
if len(stack) < 2:
raise SyntaxError

if token == "+":
stack.append(stack.pop() + stack.pop())
elif token == "-":
stack.append(-stack.pop() + stack.pop())
elif token == "*":
stack.append(stack.pop() * stack.pop())
elif token == "/":
stack.append(stack.pop() / stack.pop())
else:
raise SyntaxError
#all tokens have been parsed, check stack size and return the result
if len(stack) == 1:
return stack.pop()
else:
raise SyntaxError

if __name__ == "__main__":
line = input("Enter reverse polish: ")
try:
print(ReversePolish(line))
except SyntaxError:
print("Syntax Error!")
« Last Edit: March 24, 2009, 05:22:16 AM by TheGeek »

Wow, Geek that is awesome.  I may just give one of those a try after using the switch/case method I discussed with Skele.  We haven't discussed stacks in class so I don't know if the professor will go for it.

I found a small bug in my script, "8 4 /" calculated 4/8 instead of 8/4, so here's the updated version:
Code: [Select]
def ReversePolish(line):
stack = []
tokens = line.split(" ")

for token in tokens:
try:
#maybe the token is a number, try to convert it from string to number
a = float(token)
stack.append(a)
except ValueError:
#looks like it's not a number, maybe it's an operator
if token in "+-*/":
#check if stack is big enough, 2 elements required!
if len(stack) < 2:
raise SyntaxError

#stack is [blah, blah, blah, a, b], so b has to be popped first
b = stack.pop()
a = stack.pop()
if token == "+":
stack.append(a + b)
elif token == "-":
stack.append(a - b)
elif token == "*":
stack.append(a * b)
elif token == "/":
stack.append(a / b)
else:
raise SyntaxError
#all tokens have been parsed, check stack size and return the result
if len(stack) == 1:
return stack.pop()
else:
raise SyntaxError

if __name__ == "__main__":
line = input("Enter reverse polish: ")
try:
print(ReversePolish(line))
except SyntaxError:
print("Syntax Error!")

I managed to do most of the code in switch/case with Skele.  I'll show you guys how it ended up once I finish the math section tomorrow.

Geek:  Your script is going to be amazingly helpful when we start trying something similar with arrays.  Thanks.
« Last Edit: March 24, 2009, 07:19:57 PM by UnDiViDeD »