⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 计算器.c

📁 使用MSP430的键盘、LCD模块等完成一个简单的计算器的功能
💻 C
字号:
#include <msp430x44x.h>

int key_val = 0xFF;									//全局变量,按键的值
int is_a_new = 0;									//是否为一个新的按键
int key_val_last = 0xff;							//最后一按键的键值
int op = 0;											//操作符
int trans = 0;										//状态变量
int key_map[12] = {1,2,3,10,4,5,6,0,7,8,9,11};		//设置键盘逻辑键值与程序计算键值的映射
int digit_led[10] = {0XD7,0X14,0XCD,0X5D,0X1E,0X5B,0XDB,0X15,0XDF,0X5F};			//led的字型编码
int digit_lcd[10] = {0x7B,0x12,0x4F,0x1F,0x36,0x3D,0x7D,0x13,0x7F,0x3F};			//lcd的字型编码
int lcd[7] = {0,0,0,0,0,0,0};

void init_lcd()			//初始化lcd
{
	int i;
	LCDCTL = LCDON + LCD4MUX + LCDP2;			// 4Mux, S0-S17
	BTCTL = BTFRFQ1;							// 基本定时器输出
	P5SEL = 0xFF;								// 公共极和Rxx选择
	for(i = 9;i >= 0;i--)
		LCDMEM[i] = 0x00;
}

void init_led()
{
	P4DIR |= 0X03;
	P3DIR = 0XFF;
	P3OUT = 0XFE;
	P4OUT = 0X02;
	P4OUT = 0X00;
	P3OUT = digit_led[op];
	P4OUT = 0X01;
}

void init_Keyboard()
{     
	P1DIR = 0x0F;			//设置P1.4~P1.8 设置为输入模式,P1.0~P1.3 设置为输出模式
	P1OUT = 0x0E;			//P1.1~P1.3 输出值清零
}

void check_key()
{
	unsigned char row ,col,tmp1,tmp2;
	// tmp1用来设置P1OUT的值,使P1.1~P1.3中有一个为0
	tmp1 = 0x08;
	for(row=0;row<3;row++)
	{
		P1OUT |= 0x0E;                          // p1.1~P1.3=1
		P1OUT -= tmp1;                          // P1.1~p1.3中有一个为0
		tmp1 = tmp1/2;                          // tmp1 右移一位      
		if ((P1IN & 0xf0) < 0xf0)
		{              			// 是否P1IN的P1.4~P1.7中有一位为0         
			tmp2 = 0x80;
			for(col =0;col<4;col++)
			{         			// 列检测
				if((P1IN & tmp2)==0x00)
				{          			// 是否是该列
					key_val =key_map[ row*4 +col] ; // 获取键值
					if(key_val != key_val_last)
					{
						is_a_new = 1;
						key_val_last = key_val;
						return;// 退出循环
					}
					else
					{
						is_a_new = 0;
						
						return;
					}                        
				}
				tmp2 /= 2;                      // tmp2右移 
			}
		}
	}  
	key_val_last=0xff;   
}

void display_lcd(long x)
{
	int i;
	for(i=0;i<7;i++)
	{
		LCDMEM[i] = x % 10;
		x /= 10;
	}		
}

long calcul(long num1,long num2,int op)
{
	int re=0;
	int i;
	switch(op)
	{
	case 1:
		re = num1 + num2;
		break;
	case 2:
		re = num1 - num2;
		break;
	case 3:
		re = num1 * num2;
		break;
	case 4:
		re = num1 / num2;
		break;
	case 5:
		re = num1 % num2;
		break;
	case 6://x的y次方
		re = 1;
		for(i = num2;i < 0;i--)
			re = re * num1;
		break;
	case 7://排列
		re = 1;
		for(i = num2;i < 0;i--)
			re = re * (num1 - i + 1);
		break;
	case 8://组合
		re = 1;
		for(i = num2;i < 0;i--)
			re = re * (num1 - i + 1) / i;
		break;
	case 9://x2
		re = num1 * num1;
	default :
		break;
	}
	display_lcd(re);
	return re;
}

void display()
{
	P3OUT = digit_led[op];	
}

void main()
{
	long num1 = 0;
	long num2 = 0;
	int s_eq = 1;
	long result = 0;
	int n1 = 0;
	int key = 0XFF;
	WDTCTL = WDTPW + WDTHOLD;	
	init_led();
	init_lcd();
	init_Keyboard();			
	WDTCTL = WDT_ADLY_250;  		//开看门狗中断
	IE1 |= WDTIE;					//看门狗中断允许
	_EINT();						//开系统中断
	while(1)
	{
		while(is_a_new)
		{
			is_a_new = 0;
			key = key_val;
			switch(trans)
			{
			case 0:
				{
					s_eq = 1;
					switch(key)
					{
					case 10:
						if(n1 == 0) num1 = result;
						n1 = 0;
						op = 0;
						trans = 1;
						is_a_new = 1;
						break;
					case 11:
						{
							if(op != 0)
							{
								switch(s_eq)
								{
								case 1:
									result = calcul(result,num2,op);
									break;
								case 2:
									result = calcul(num1,num1,op);
									break;
								case 3:
									result = calcul(num1,num2,op);
								default:
									break;
								}
							}								
						}
						break;
					default:
						if(n1 == 0)
						{
							n1 = 1;
							num1 = 0;
						}
						num1 = num1 * 10 + key;
						display_lcd(num1);
						break;
					}
				}
				break;
			case 1:
				{
					s_eq = 2;
					switch(key)
					{
					case 10:
						if(++op == 10) op = 1;
						display();
						break;
					case 11:
						trans = 0;
						is_a_new = 1;
						break;
					default:
						if(op != 9)
						{
							trans = 2;
							num2 = 0;
							is_a_new = 1;
						}
						break;
					}
				}
				break;				
			case 2:
				{
					s_eq = 3;
					switch(key)
					{
					case 10:
						op = 0;
						trans = 1;
						is_a_new = 1;						
						break;
					case 11:
						trans = 0;
						is_a_new = 1;
						break;
					default:
						num2 = num2 * 10 + key;
						display_lcd(num2);
						break;
					}
				}
				break;
			default:
				break;
			}
		}		
	}
}

#pragma vector = WDT_VECTOR
__interrupt void watchdog_timer()
{
	check_key();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -