计算器的设计和实现

要求:1、了解计算器的基本原理
              2、进一步掌握数字键盘和多位数码显示管的联合使用

              3、实现加、减、乘、除的运算(可显示负数),和清零、溢出报错的显示

计算器的设计和实现_第1张图片

#include 
#include 
#include 

#define ROW P1
#define COL P3

sbit DIN = P2^0;
sbit CS = P2^1;
sbit CLK = P2^2;

unsigned char key[] = {
    '7', '8', '9', '/',
    '4', '5', '6', '*',
    '1', '2', '3', '-',
    'c', '0', '=', '+'
};

unsigned char Seg[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15};
unsigned char error[] = {0x0f, 0x0f, 0x0f, 0x0f, 0x0b, 0x1f, 0x11, 0x00, 0x0b};

void delay(unsigned int a)
{
    unsigned int b;
    while(a--)
        for(b = 0; b < 150; ++b);
}

void write_7221(unsigned char addr, unsigned char dat)
{
    unsigned char i;
    CS = 0;
    for(i = 0; i < 8; ++i)
    {
        CLK = 0;
		addr <<= 1;
		DIN = CY;
        CLK = 1; _nop_(); _nop_();
        CLK = 0;
    }
    for(i = 0; i < 8; ++i)
    {
        CLK = 0;
		dat <<= 1;
		DIN = CY;
        CLK = 1; _nop_(); _nop_();
        CLK = 0;
    }
    CS = 1;
}

void init_7221()
{
    write_7221(0x09, 0xff);
    write_7221(0x0a, 0x07);
    write_7221(0x0b, 0x07);
    write_7221(0x0c, 0x01);
}

unsigned char scankey()
{
    unsigned char i, j, k1, k2;
    while(1)
    {
        ROW = 0xfe;
        for(i = 0; i < 4; ++i)
        {
            if(COL != 0xff)
            {
                j = ~ROW + ~COL;
                k1 = log(j%16)/log(2);
                k2 = log(j/16)/log(2);
                return key[k1*4 + k2];
            }
            ROW <<= 1;
            ROW += 1;
        }
    }
}

void diserror()
{
    unsigned char i = 1;
    for(; i <= 6; ++i)
        write_7221(i, error[i]);
}

void display(unsigned char *dat, unsigned char len)
{
    unsigned char i = len, j = 8, k;
    for(k = 1; k <= 8; ++k)
    {
        write_7221(k, 0x0f);
    }
    while(i != 0)
    {
        write_7221(j, dat[i - 1]);
        --i;
        --j;
    }
}

unsigned char kind(unsigned char k)
{
    if(k >= '0' && k <= '9')
        return 1;
    else
        return 0;
}

unsigned char itodat(unsigned char *dat, long i)
{
    unsigned char x = 0, y = 9, z = 0;
    if(i > 99999999 || i < -9999999)
        return 0;
	if(i == 0)
	{
	 	dat[0] = 0;
		return 1;
	}
    if(i < 0)
    {
        dat[0] = 10;
		i = -i;
        ++x;
    }
    while(i != 0)
    {
        dat[y] = i % 10;
        i /= 10;
        --y;
        ++z;
    }
    while(z != 0)
    {
        dat[x] = dat[y + 1];
        ++x;
        ++y;
        --z;
    }
    return x;
}

void main()
{
    long sum = 0, num1;
    unsigned char len = 0, i, k, isop, op, flag_n, result; 
    unsigned char dat[10];

	init_7221();
	for(k = 1; k <= 7; ++k)
    {
        write_7221(k, 0x0f);
    }
	write_7221(8, 0);

    while(1)
    {
        i = scankey();
        delay(120);
        if(kind(i))
        {
			if(flag_n)
			{
				num1 = 0;
				flag_n = 0;
			}
            num1 = num1 * 10 + i - 0x30;
            len = itodat(dat, num1);
			if(len == 0)
				goto err;
            display(dat, len);
        }
        else if(i == 'c')
        {
            sum = num1 = 0;
            for(k = 1; k <= 7; ++k)
                write_7221(k, 0x0f);
            write_7221(8, 0);
            isop = 0;
			result = 0;
        }
        else if(i == '=')
        {
            if(isop)
            {
                if(op == '+')
                    sum += num1;
                else if(op == '-')
                    sum -= num1;
                else if(op == '*')
                    sum *= num1;
                else if(op == '/')
                {
                    if(num1 == 0)
                        goto err;
                    sum /= num1;
                }
                len = itodat(dat, sum);
                if(len == 0)
                    goto err;
                display(dat, len);
                flag_n = 1;
				isop = 0;
				result = 1;
            }
            else
            {
				if(!result)
                	sum = num1;
                flag_n = 1;
				result = 0;
            }
        }
        else
        {
            if(isop)
            {
                if(op == '+')
                    sum += num1;
                if(op == '-')
                    sum -= num1;
                if(op == '*')
                    sum *= num1;
                if(op == '/')
                {
                    if(num1 == 0)
                        goto err;
                    sum /= num1;
                }
                len = itodat(dat, sum);
                if(len == 0)
                    goto err;
                display(dat, len);
				op = i;
				flag_n = 1;
				result = 1;
            }
            else
            {
				if(!result)
					sum = num1;
				flag_n = 1;
                op = i;
                isop = 1;
				result = 0;
            }
        }
		continue;
        err:
            diserror();
            sum = num1 = 0;
			len = 0;
			isop = 0;
			result = 0;
    }
}


你可能感兴趣的:(单片机89C51)