【普中开发板】基于51单片机简易计算器数码管显示设计

【普中开发板】基于51单片机简易计算器数码管显示设计( proteus仿真+程序+实物演示+讲解视频)

Proteus 仿真:Proteus 8.16(有低版本)

程序编译器:keil 4/keil 5

编程语言:C语言

设计编号:P04

1. 主要功能:

普中开发板实验设计

本设计旨在设计一个基于51单片机的简易计算器仿真设计。

功能要求:实现加减乘除四则简单运算数码管显示

1、能通过矩阵键盘输入正确键值;

2、能进行简单的四则运算;

3、能以数码管正确显示数值;

4、最大支持运算结果9 9999,超出将蜂鸣器报警;

(目前仅完全适配普中开发板A234,其他普中开发板型号可能需要做代码修改或接线)

需注意本设计仿真中51单片机芯片是兼容的,AT89C51,AT89C52是51单片机的具体型号,内核是一样的。相同的原理图里,无论stc还是at都一样,引脚功能都是一样的,程序是兼容的,芯片可以替换为STC89C52/STC89C51/AT89C52/AT89C51等51单片机芯片。

以下为本设计资料展示图:

2. 讲解视频:

讲解视频包含仿真运行讲解、实物运行讲解和代码讲解

3. 设计说明书(报告)

img

本次课程设计的主要目标是以51单片机为基础,结合Proteus仿真软件,设计一款简易计算器。这个计算器需要实现加减乘除四则运算功能,并且能够将运算结果通过数码管进行显示。这个任务不仅要求我们掌握单片机的编程技术,还需要我们深入理解数码管显示的工作原理,同时还需要通过Proteus软件进行系统的仿真和调试。

在设计过程中,我们将从硬件电路设计和软件编程两个方面进行。硬件电路设计包括单片机最小系统、输入按键、输出数码管等部分。其中,单片机最小系统是整个系统的核心,它包括了单片机、时钟电路、复位电路等基本部分。输入按键将用于用户输入数字和运算符号,而输出数码管则将用于显示运算结果。

软件编程方面,我们将使用C语言进行编程。首先,我们需要根据设计需求,编写出相应的程序。程序应该能够读取用户的输入,进行四则运算,并根据运算结果驱动数码管进行显示。然后,我们将在Proteus中进行仿真和调试,检查程序的正确性和系统的稳定性。

通过这个课程设计,我们不仅能够更加深入地理解单片机的原理和应用,还能够掌握基本的电路设计和软件编程技能。同时,通过Proteus的仿真和调试功能,我们还可以更好地理解系统的运行过程,提高我们的调试和解决问题的能力。我们期待通过这个课程设计,能够更好地掌握单片机的应用,为未来的学习和工作打下坚实的基础。

img

4. 仿真

打开仿真工程,双击proteus中的单片机,选择hex文件路径,然后开始仿真。

img

img

img

img

img

5. 实物烧录和现象

img

计算结果如下图:

img

软件准备:

第一次使用务必先安装CH340驱动。

双击打开 STC-ISP.exe。

下载步骤:

0.板子先上电,接电源线到电脑USB口,先不上电,板子无灯光。

1.选择选择单片机型号

2.选择下载器的串口

3.打开编译生成的 HEX 文件

4.点击下载,单片机板子电源键按下接通电源,等待下载完成提示

6. 程序代码

使用keil4或者keil5编译,代码有注释。

img

核心代码:

#include<reg52.h> //头文件
#include<intrins.h>//头文件
#include<math.h>
#define uint unsigned int //宏定义
#define uchar unsigned char//宏定义
long x=0,y=0,num=0;
uint operators,input,iny=0;
uchar key,k,ff=16;
sbit a0=P2^2;					//138锁存器
sbit a1=P2^3;
sbit a2=P2^4;
sbit beep=P2^5;
sbit led=P3^0;


 uchar code table[]={					 //数码管段选
 0x3f,0x06,0x5b,0x4f,
 0x66,0x6d,0x7d,0x07,
 0x7f,0x6f,0x77,0x7c,
 0x39,0x5e,0x79,0x71,
 0x00,0x40
 };

 //uchar code table1[]={0xfe,0xfd};	   //数码管位选


void delay(uint xms)  //延时
{
	uint xx,yy;
	for (xx=xms;xx>0;xx--)
		for(yy=110;yy>0;yy--);
}

void display() //显示函数,数码管动态扫描
{
    uchar wan,qian,bai,shi,ge;	
	wan=num/10000;
	qian=num%10000/1000;
	bai=num%1000/100;
	shi=num%100/10;							//num求摸  数码管显示十位
	ge=num%10;							//num求余  数码管显示个位

    P0=0x00;					//数码管全关
	P0=table[ff];			  //端选给P0
	a0=0;						   //位选
	a1=0; 
	a2=0;
	delay(3);				  //延时
	
	P0=0x00;				
	P0=table[ge];//段选显示个位数
	a0=0;
	a1=0;
	a2=0;		//选中第一位
	delay(3);

	P0=0x00;				
	P0=table[shi];//段选显示十位数
	a0=1;
	a1=0;
	a2=0;		//选中第二位
	delay(3);
	
	P0=0x00;
	P0=table[bai];
	a0=0;
	a1=1;
	a2=0;		//选中第三位
	delay(3);
	
	P0=0x00;
	P0=table[qian];//段选显示千位数
	a0=1;
	a1=1;
	a2=0;		//选中第四位
	delay(3);
	
	P0=0x00;
	P0=table[wan];//段选显示万位数
	a0=0;
	a1=0;
	a2=1;		//选中第五位
	delay(3);
	
 							 
}

  
 /**********算术运算函数*************/
void arithmetic()
{
	if (iny){
		switch(operators)
		{
			case 1:							//加法运算
			x=x+y;
			num=x;

			if(num<100000&&num>-100000)			 //正常范围
			{
			  TR0=0;
			}
			else							   //超出范围,报警
			TR0=1;

			break;

			case 2:						   //减法运算
			x=x-y;
			num=x;
			if(num<0)
			{
			  num=num*(-1);
			  ff=17;
			}
			else
			ff=16;
			if(num<100000&&num>-100000)
			{
			  TR0=0;
			}
			else
			TR0=1;

			break;

			case 3:
			x=x*y;						  //乘法运算
			num=x;

			if(num<100000&&num>-100000)
			{
			  TR0=0;
			}
			else
			TR0=1;
			break;

			case 4:						  //除法运算
			x=x/y;
			num=x;
			if(y!=0)					 //除数不为0
			{
			  //TR0=0;
			  led=1;
			}
			else					  //除数为0	报警
			//TR0=1;
			  led=0;
			}
		}
}

 /***********符号处理函数*************/

void fuhao() 
{
	if(key<=9&&key>=0)      //判断按下的键是否为数值
	{
	num=num*10+(key-0);
	if (operators>0)
		{
		y=num;
		iny=1;
		}
	else
		{
		x=num;
		if(num<100000&&num>-100000)
		{
		  TR0=0;
		}
		else
		TR0=1;



		}
	}
else
	{
	switch(key)						  //按键判断
		{
		case 'c':
					//x=0;
					//y=0;
					//num=0;
					if(operators==0)
					{
					  x=x/10;	 			 //一位一位删除
					  num=x;			  
					  iny=0;
					}
					if(operators>0)
					{
					  y=y/10;		//一位一位删除
					  num=y;		
					}			  
					//iny=0;
					//operators=0;
					//display();
					break;
		case '=':
					arithmetic();
					iny=0;
					operators=0;
					//num=0;
					break;
		case '+':
				    if (operators)
					arithmetic();
					operators=1;
					num=0;
					break;
		case '-':
				    if (operators)
					arithmetic();
					operators=2;
					num=0;
					break;
		case '*':
				    if (operators)
					arithmetic();
					operators=3;
					num=0;
					break;
		case '/':
					if (operators)
					arithmetic();
					operators=4;
					num=0;
					break;
		}
	}
}

7. 设计资料内容清单&&下载链接

资料设计资料包括仿真,程序代码、讲解视频、功能要求、设计报告、软硬件设计框图等。

0、常见使用问题及解决方法–必读!!!!

1、仿真图

2、程序源码

3、功能要求

4、讲解视频

5、烧录工具

6、开题报告

7、设计报告

8、软硬件流程框图

Altium Designer 安装破解

KEIL+proteus 单片机仿真设计教程

KEIL安装破解

Proteus元器件查找

Proteus安装

Proteus简易使用教程

单片机学习资料

普中-2&普中-3&普中-4开发板原理图.pdf

相关数据手册

答辩技巧

设计报告常用描述

鼠标双击打开查找嘉盛单片机51 STM32单片机课程毕业设计.url

img

P04 网盘链接
链接:https://pan.baidu.com/s/1gOCfxzo6YCBVVTFlX0BJdQ?pwd=m3yt
提取码:m3yt

<think>嗯,用户需要的是普中C51单片机驱动数码管计算器代码示例。我之前看到过类似的资料,比如参考引用[1]里的内容,里面提到了基于51单片机计算器设计,包含仿真、程序和实物演示。不过用户现在具体需要的是代码部分,所以我要先回忆一下51单片机驱动数码管的常用方法。 首先,数码管显示通常分为静态显示和动态扫描两种。动态扫描更节省IO口,适合多位数码管的情况。计算器一般需要4位或更多数码管,所以动态扫描应该是必要的。然后,计算器的按键输入通常通过矩阵键盘来实现,需要行扫描和列检测来确定按下的键值。 接下来,代码结构方面,主程序可能包括初始化、键盘扫描、数值处理、显示驱动等模块。需要注意延时消抖,防止按键误触。数码管的段选和位选需要正确配置,比如P0口控制段选,P2口控制位选,但具体端口可能因硬件设计而异,需要参考原理图。 用户提到的是普中开发板,可能使用的是共阴数码管,所以段选码应该是高电平有效。例如,数字0的段码是0x3F,1是0x06等。同时,按键处理部分需要将按键值转换为对应的数字或运算符,并处理连续输入和运算逻辑,比如加减乘除。 另外,代码中可能需要用到定时器中断来实现动态扫描,避免主循环阻塞。处理数值输入时要考虑多位数组合,比如按下1再按2,变成12。运算结果需要转换为数码管显示的各位数字,可能涉及除法和取余操作。 需要提醒用户根据实际硬件调整端口定义和延时参数,可能还需要添加错误处理,比如除以零的情况。最后,示例代码可能需要简化,只展示核心逻辑,而实际项目会更复杂,包含更多功能和处理。</think>根据普中C51单片机数码管计算器的典型实现,以下为代码框架及说明[^1]: ```c #include <reg52.h> // 定义数码管段选(P0)和位选(P2) #define SEG_PORT P0 #define DIG_PORT P2 // 共阴数码管段码表 unsigned char code seg_table[] = { 0x3F, 0x06, 0x5B, 0x4F, 0x66, // 0-4 0x6D, 0x7D, 0x07, 0x7F, 0x6F // 5-9 }; // 按键扫描函数 unsigned char key_scan(){ unsigned char key_val = 0; // 矩阵键盘扫描逻辑 // ... return key_val; // 返回键值0-15 } // 数码管显示函数 void display(unsigned int num){ unsigned char digits[4]; // 分离各位数字 digits[0] = num / 1000; digits[1] = num % 1000 / 100; digits[2] = num % 100 / 10; digits[3] = num % 10; // 动态扫描显示 for(int i=0; i<4; i++){ SEG_PORT = seg_table[digits[i]]; DIG_PORT = ~(0x08 >> i); delay_ms(2); // 延时保持视觉暂留 } } void main(){ unsigned int num1=0, num2=0, result=0; unsigned char operator=0; while(1){ unsigned char key = key_scan(); if(key <= 9){ // 数字输入 if(operator == 0){ num1 = num1*10 + key; }else{ num2 = num2*10 + key; } }else if(key >= 10 && key <=13){ // 运算符 operator = key; }else if(key == 14){ // 等于 switch(operator){ case 10: result = num1 + num2; break; case 11: result = num1 - num2; break; case 12: result = num1 * num2; break; case 13: result = num1 / num2; break; } } display(result); // 显示结果 } } ``` 关键实现要点: 1. **数码管驱动**:采用动态扫描方式,通过$74HC245$芯片驱动4位数码管[^1] 2. **键盘扫描**:使用$4×4$矩阵键盘,通过行列扫描检测按键 3. **运算逻辑**:支持连续数值输入和四则运算 4. **显示处理**:最大支持显示$9999$,通过分离各位数字实现动态显示 注意事项: - 需根据实际硬件修改IO口定义 - 需要添加延时消抖函数(约$10ms$) - 需处理除法运算的除零错误 - 实际应用需增加清零、退格等功能
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值