16键计算器用c51实现

发布者:静心悠然最新更新时间:2012-08-04 来源: 61ic关键字:16键计算器  c51  中断程序 手机看文章 扫描二维码
随时随地手机看文章

1、定时显示

  开辟一显示缓冲区,显示中断程序定时读取缓冲区显示各灯位,每灯位显示2.5ms,显示4只灯需要10ms,也就是显示的刷新频率是100Hz,亮度为25%。这样既保证亮度又不闪烁,同时CPU还有足够时间做其他事情。

2、键盘中断扫描

  利用键盘中断扫描程序,读出按键的键码,存入键盘缓冲区,供主程序读区。

3、计算器的主程序读取键盘缓冲区的键码,驱动计算器的运行,计算器的运行过程要清晰明了;

4、计算中需要十进制与十六进制(或二进制)转化。


点击浏览下一页

 

#define LED_seg      XBYTE[0x6000]     //段码地址

#define LED_light    XBYTE[0x8000]      //灯位地址

#include "reg51.h"

#include "absacc.h"

unsigned char read_key(unsigned char);

unsigned char display(unsigned char,unsigned char);

void delay(unsigned int);

unsigned char light[4]={0xfe,0xfd,0xfb,0xf7};   //扫描值 灯位码

unsigned char seg[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //段码

unsigned char disp_buffer[5]={1,0,0,0,0};            //当前灯位、 显示区

unsigned char key_buffer[2]={0,0xff};           //缓冲区满标志、键码

void main()

{

 Unsigned char temp[5];

 unsigned char i;

 unsigned char operator=0;

 unsigned int tempa,tempb;

 bit first=1;

 TMOD=0x01;       //置T0为方式1

 TL0=0x0;          //延时2.5mS的定时器初始值

 TH0=0xf7;          //赋初值

 PT0=1;             //定时中断0优先设置

TR0=1;           //启动定时

 ET0=1;           //允许定时

 IT1=0;        //电平触发低电平有效

 EX1=1;       //允许外中断

 PX1=1;       // 外部中断1优先级设定

 EA=1;        //中断总允许

 while(1)

      {

       P1=0xf0;                           //扫描

       if (key_buffer[0])

                {

                    switch(key_buffer[1])              //缓冲区满

                      {

                          case 0:

                          case 1:

                          case 2:

                          case 3:

                          case 4:

                          case 5:

                          case 6:

                          case 7:

                          case 8:

                          case 9: if (first)  for(i=1;i<=4;i++)   //保存数据,等待另一个数据输入

                                             {

                                                                temp[i]=disp_buffer[i];

                                                                disp_buffer[i]=0;                                           

                                                                }

                   first=0;

                                      for(i=1;i<=3;i++)  disp_buffer[i]=disp_buffer[i+1];

                                      disp_buffer[4]=key_buffer[1];

                                break;

                          case 10:

                          case 11:

                          case 12:

                          case 13:

                          case 14: first=1;

tempa=1000*disp_buffer[1]+100*disp_buffer[2]+10*disp_buffer[3]+disp_buffer[4];

                     tempb=1000*temp[1]+100*temp[2]+10*temp[3]+temp[4];

                     switch(operator)

                          {

                           case 10:tempa+=tempb;

                                   break;

                           case 11:tempa=tempb-tempa;

                                   break;

                           case 12:tempa*=tempb;

                                   break;

                           case 13:tempa=tempb/tempa;

                           }

                     tempa%=10000;

                     disp_buffer[1]=tempa/1000;

                     tempa%=1000;

                     disp_buffer[2]=tempa/100;

                     tempa%=100;

                     disp_buffer[3]=tempa/10;

                     disp_buffer[4]=tempa%10;

                                  operator=key_buffer[1];

                                        break;

                          case 15: for(i=1;i<=4;i++)  disp_buffer[i]=temp[i]=0;

                           first=1;

                                          operator=0;

                          }

                    key_buffer[0]=0;                     //缓冲区空

                    }          

       }

 }

void disp_LED() interrupt 1

{

 TL0=0x0;         //延时2.5mS的定时器初始值

 TH0=0xf7;

 if (disp_buffer[0]==5)  disp_buffer[0]=1;

 display(disp_buffer[disp_buffer[0]],disp_buffer[0]);

 disp_buffer[0]++;

 }

void get_keypad_code() interrupt 2

{

 unsigned char i,key;

 EA=0;

 for (i=0;i<=3;i++)

      {

       key=read_key(light[i]);    //读键码

       if (key!=0xff) delay(10);                //延时5-10ms,去抖动

       if (read_key(light[i])!=key) key=0xff;    //读键码比较

       if (key!=0xff)

                {

                    key_buffer[0]=1;                //缓冲区满

                    key_buffer[1]=key;      //键码

                    }                     

       }

 EA=1;

 }

unsigned char read_key(unsigned char scan)

{

 P1=scan;       //扫描

 switch(P1)     //返回扫描码->键码

    {

     case 0x77:return(0x7);

     case 0xb7:return(0x8);

     case 0xd7:return(0x9);

     case 0xe7:return(0xd);

     case 0x7b:return(0x4);

     case 0xbb:return(0x5);

     case 0xdb:return(0x6);

     case 0xeb:return(0xc);

     case 0x7d:return(0x1);

     case 0xbd:return(0x2);

     case 0xdd:return(0x3);

     case 0xed:return(0xb);

     case 0x7e:return(0xf);

     case 0xbe:return(0x0);

     case 0xde:return(0xe);

     case 0xee:return(0xa);

     default:  return(0xff);

     }

 }

unsigned char display(unsigned char disp_key,unsigned char n) //disp_key 显示字符,n 灯位

{

 if ((n<=4)&&(n>=1)) LED_light=light[n-1];

 else  LED_light=0xff;

 if ((disp_key>=0)&&(disp_key<=16)) LED_seg=seg[disp_key];

 else  LED_seg=0x00;

 return light[n-1];

 }

void delay(unsigned int k)     //延时k*1ms

{

unsigned int i,j;

 for (j=0;j<=k;j++)

    for(i=0;i<=1085;i++);

}
关键字:16键计算器  c51  中断程序 引用地址:16键计算器用c51实现

上一篇:自制51单片机超大数码管时钟
下一篇:STC自动下载器

推荐阅读最新更新时间:2024-03-16 13:04

C51单片机串口通信
1、在使用串口之前,应对其进行初始化,步骤如下: (1)定时器1工作模式,设置TMOD寄存器 (2)装载TH1,TL1,决定波特率的值 (3)启动定时器1 (4)串口工作模式设置,SCON (5)如需中断,开总中断,开串行中断 2、如需奇偶校验: 偶校验:就是发送的8个数据位的1的个数为偶数时,TB8=0;为奇数时,TB8=1; 奇校验:与偶校验相反的TB8。 用软件产生奇偶校验位是根据51系列单片机的状态寄存器PSW的定义:当累加器ACC中为1的个数为奇数时,P=1,否则P=0。 3、程序(采用偶校验) #include reg52.h #define uchar unsigned char #define ui
[单片机]
C51/C52的串口原理及参考代码
一、什么是串口(RS232 9针串口) 串口是我们的大多数微控制单元(MCU)都具有的基本的外部接口,一般串口最基本的功能就是调试,又能做数据通信的接口(数据量要小一些)。 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 二、串口通信原理 一条信息的各位数据按位依次顺序的通信方式称为串行通信,传信通信可以是串口也可以是
[单片机]
<font color='red'>C51</font>/C52的串口原理及参考代码
C51系统上实现YAFFS文件系统
随着NAND Flash存储器作为大容量数据存储介质的普及,基于NAND闪存的文件系统YAFFS(Yet Another Flash File System)正逐渐被应用到各种嵌入式系统中。本文将详细阐述YAFFS文件系统在C51系统上的实现过程。 1 NAND Flash的特点 非易失性闪速存储器Flash具有速度快、成本低、密度大的特点,被广泛应用于嵌入式系统中。Flash存储器主要有NOR和NAND两种类型。NOR型比较适合存储程序代码;NAND型则可用作大容量数据存储。NAND闪存的存储单元为块和页。本文使用的Samsung公司的K9F5608包括2 048块,每一块又包括32页,一页大小为528字节,依次分为2个256
[应用]
矩阵键盘加电子时钟(c51
//矩阵键盘扫描和可调的电子时钟 //采用翻转识别法(相对代码少一些)处理矩阵键盘, //在按下15号键的时候处理电子时钟,然后可以启动12号键 //用来调节时间 #include reg52.h #define uchar unsigned char //类型重定义 #define uint unsigned int uchar key=0; uchar count=0; int second=40,minute=59,hour=23; int second_shi=0,second_ge=0,minute_shi=0,minute_ge=0,hour_shi=0,hour_ge=0; uchar
[单片机]
矩阵键盘加电子时钟(<font color='red'>c51</font>)
C51单片机中常用的头文件
通常有reg51.h,reg52.h,math.h, ctype.h, stdio.h, stdlib.h, absacc.h, intrins.h 。 但常用的却只有reg51.h或reg52.h,math.h 。 reg51.h和reg52.h是定义51单片机或52单片机特殊功能寄存器和位寄存器的,着两个头文件中大部分内容是一样的,52单片机比51单片机多一个定时器T2,因此,reg52.h中也就比reg51.h中多几行定义T2寄存器的内容。 math.h是定义常用数学运算的,比如求绝对值、求方根、求正弦和余弦等,该头文件中包含有各种数学运算函数,当我们需要使用时可以直接调用它的内部函数。 学习单片机应该掌握的主要内
[单片机]
Keil C51开发系统基本知识3
2. 第二节 几类重要库函数 1. 1. 专用寄存器include文件 例如8031、8051均为REG51.h其中包括了所有8051的SFR及其位ㄒ澹话阆低扯急匦氚ū疚募?br 2. 2. 绝对地址include文件absacc.h 该文件中实际只定义了几个宏,以确定各存储空间的绝对地址。 3. 3. 动态内存分配函数,位于stdlib.h中 4. 4. 缓冲区处理函数位于 string.h 中 其中包括拷贝比较移动等函数如: memccpy memchr memcmp memcpy memmove memset 这样很方便地对缓冲区进行处理。 5. 5. 输入输出流函数,位于 stdio.h 中 流函数通8051的串口或
[单片机]
P10点阵屏C51单片机程序
P10点阵屏C51程序 1/4扫描,四扫下行,1路16行,数据低OE高(04-P16-08) 适用于HUB12接口单色P10 串口模式0,普通左移,亮度速度可调,6个IO口,用的STC8F1K08,最多231个字 制作出来的实物图如下: 单片机源程序如下: #include STC8.H #include intrins.h #include string.h #define DATA P30 // #define CLOCK P31 //↑ ↓ #define ADDR_A P32 //↑ #de
[单片机]
P10点阵屏<font color='red'>C51</font>单片机<font color='red'>程序</font>
模拟I2C总线软件包(C51)
/****************************************************************************** I2C.H 标准80C51模拟I2C总线程序头文件 ******************************************************************************/ #ifndef I2C_H #define I2C_H //定义I2C操作模式 #define I2C_RECV 0 /* 接收模式 */ #define I2C_SEND 1 /* 发送模式 */ #define I2C_SrRECV 2
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
  • ARM裸机篇--按键中断
    先看看GPOI的输入实验:按键电路图:GPF1管教的功能:EINT1要使用GPF1作为EINT1的功能时,只要将GPFCON的3:2位配置成10就可以了!GPF1先配 ...
  • 网上下的--ARM入门笔记
    简单的介绍打今天起菜鸟的ARM笔记算是开张了,也算给我的这些笔记找个存的地方。为什么要发布出来?也许是大家感兴趣的,其实这些笔记之所 ...
  • 学习ARM开发(23)
    三个任务准备与运行结果下来看看创建任务和任运的栈空间怎么样的,以及运行输出。Made in china by UCSDN(caijunsheng)Lichee 1 0 0 ...
  • 学习ARM开发(22)
    关闭中断与打开中断中断是一种高效的对话机制,但有时并不想程序运行的过程中中断运行,比如正在打印东西,但程序突然中断了,又让另外一个 ...
  • 学习ARM开发(21)
    先要声明任务指针,因为后面需要使用。 任务指针 volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • 学习ARM开发(20)
  • 学习ARM开发(19)
  • 学习ARM开发(14)
  • 学习ARM开发(15)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved