中南民族大学,电子信息工程学院,开设了一门课程,叫《嵌入式电路设计》,由舒老师带头,旨在引导低年级的学生入门嵌入式,其内容比较多,包括模电、数电、C语言、单片机、EDA技术等。最近有位师弟找到我,希望我能帮他指导一下,利用AT89C52单片机设计一个最小系统,其中包括矩阵键盘、数码管显示、中断、2位数加减法、定时计数与暂停等功能。我也粗略的设计了一个,在此分享出来,希望能对初学者有所帮助,使更多的人加入到嵌入式的行业来。

  开发工具:keil

  仿真工具:proteus

电路图

代码如下:

头文件:inc_all.h

 1 #ifndef INC_ALL_H_
 2 #define INC_ALL_H_
 3
 4 volatile unsigned char keyValue;
 5 volatile unsigned char sign;
 6 volatile long int opr1;
 7 volatile long int opr2;
 8 volatile long int SysValue=0;
 9 volatile int keyCounter;
10 volatile int cnt50ms=0;
11 volatile bit StartFlag;
12
13 void Init_Timer0();
14 void Init_Timer1();
15 void delayms(int t);
16 unsigned char KeyScan(void);
17 void showNumber(long int num);
18 void keyAnalyzing(unsigned char keyval);
19
20 #endif

源文件如下:main.c

  1 #include <reg52.h>
  2 #include "inc_all.h"
  3 //=======================================================
  4 //  数码管显示译码,共阴极
  5 //  0,1,2,3,4,5,6,7,8,9,灭,‘E’,'-'
  6 //=======================================================
  7 unsigned char code table[]={0x3F,0x06,0x5b,0x4F,0x66,
  8                             0x6d,0x7d,0x07,0x7F,0x6F,
  9                             0x00/* trun off */,
 10                             0x79/* Error */,
 11                             0x40/* - */};
 12 //========================================================
 13 //  定时器0初始化函数,定时50毫秒
 14 //  用键盘上的“START”键启动计数
 15 //  用键盘上的“SUS”键暂停计数
 16 //========================================================
 17 void Init_Timer0()
 18 {
 19     TMOD |= 0x01;
 20     TH0  = 0x3C;
 21     TL0  = 0xB0;
 22     TR0  = 0;
 23     ET0  = 1;
 24 }
 25 //=========================================================
 26 //  定时器1初始化函数
 27 //  定时23毫秒,用于显示
 28 //  初始化后计时启动
 29 //=========================================================
 30 void Init_Timer1()
 31 {
 32     TMOD |= 0x10;
 33     TH1  = 0xA6;
 34     TL1  = 0x28;
 35     TR1  = 1;
 36     ET1  = 1;
 37 }
 38 //=========================================================
 39 //  延时函数
 40 //=========================================================
 41 void delayms(int t)
 42 {
 43     int i,j;
 44     for(i=t;i>0;i--)
 45         for(j=25;j>0;j--)
 46             ;
 47 }
 48 //=========================================================
 49 //  四位数码管显示函数
 50 //  能自动灭零,自动识别正负号
 51 //  数值超出显示范围时显示错误"E---"
 52 //=========================================================
 53 void showNumber(long int num)
 54 {
 55     unsigned char q,s,b,g;
 56     if(num>=0)
 57     {
 58         q = num/1000;
 59         b = num/100%10;
 60         s = num/10%10;
 61         g = num%10;
 62         if(num<10)
 63         {
 64             q = 10;
 65             b = 10;
 66             s = 10;
 67         }
 68         else if(num<100)
 69         {
 70             q = 10;
 71             b = 10;
 72         }
 73         else if(num<1000)
 74             q = 10;
 75         else if(num>9999)
 76         {
 77             q = 11;     //show error
 78             b = 12;
 79             s = 12;
 80             g = 12;
 81         }
 82     }
 83     else
 84     {
 85         if(num>-1000)
 86         {
 87             q = 12;
 88             b = (0-num)/100;
 89             s = (0-num)/10%10;
 90             g = (0-num)%10;
 91         }
 92         else
 93         {
 94             q = 11;     //show error
 95             b = 12;
 96             s = 12;
 97             g = 12;
 98         }
 99     }
100     P0 = 0x00;
101     P0 = table[q];
102     P2 = 0xFE;
103     delayms(10);
104     P0 = 0x00;
105     P0 = table[b];
106     P2 = 0xFD;
107     delayms(10);
108     P0 = 0x00;
109     P0 = table[s];
110     P2 = 0xFB;
111     delayms(10);
112     P0 = 0x00;
113     P0 = table[g];
114     P2 = 0xF7;
115     delayms(10);
116 }
117 //=========================================================
118 //  键盘扫描函数
119 //  返回按键情况,扫描结果
120 //=========================================================
121 unsigned char KeyScan(void)
122 {
123     unsigned char temp=0xF0;
124     P1 = temp;
125     temp = P1;
126     if(temp!=0xF0)
127     {
128         delayms(5);     //去抖动
129         temp = P1;
130         if(temp!=0xF0)
131         {
132             int t=0x01,i;
133             for(i=0;i<4;i++)
134             {
135                 P1 = ~(t<<i);
136                 temp = P1;
137                 switch(temp)                //按行扫描
138                 {
139                     case 0xee:  return '1';
140                     case 0xde:  return '2';
141                     case 0xbe:  return '3';
142                     case 0x7e:  return '+'; //加号
143
144                     case 0xed:  return '4';
145                     case 0xdd:  return '5';
146                     case 0xbd:  return '6';
147                     case 0x7d:  return '-'; //减号
148
149                     case 0xeb:  return '7';
150                     case 0xdb:  return '8';
151                     case 0xbb:  return '9';
152                     case 0x7b:  return 'r'; //复位
153
154                     case 0xe7:  return '0';
155                     case 0xd7:  return 's'; //启动
156                     case 0xb7:  return 't'; //暂停
157                     case 0x77:  return '='; //等于
158                     default:    ;
159                 }
160             }
161         }
162     }
163     return '0';
164 }
165 //=========================================================
166 //  键盘解析函数
167 //  对扫描得到的键值进行解析
168 //=========================================================
169 void keyAnalyzing(unsigned char keyval)
170 {
171     if(keyval>='0' && keyval<='9')
172     {
173         switch(keyCounter)
174         {
175             case 0: SysValue = (int)keyval-0x30;
176                     keyCounter++;
177                     break;
178             case 1: ;
179             case 2: ;
180             case 3: SysValue =SysValue*10+(int)keyval-0x30;
181                     keyCounter++;
182                     break;
183             case 4: SysValue =SysValue*10+(int)keyval-0x30;
184                     keyCounter=0;
185                     break;
186         }
187     }
188     else
189     {
190         switch(keyval)
191         {
192             case '+':   sign = '+';
193                         opr1 = SysValue;
194                         SysValue = 0;
195                         keyCounter = 0;
196                         break;
197             case '-':   opr1 = SysValue;
198                         SysValue = 0;
199                         keyCounter = 0;
200                         sign = '-';
201                         break;
202             case 's':   sign = 's';
203                         TR0 = 1;     //启动计数
204                         StartFlag = 1;
205                         break;
206             case 't':   sign = 't';
207                         if(StartFlag)
208                             TR0 ^= 1;//暂停/启动计数
209                         break;
210             case 'r':   sign = 'r';
211                         opr1 = 0;
212                         opr2 = 0;
213                         SysValue = 0;
214                         keyCounter = 0;
215                         TR0 = 0;    //停止计数器
216                         StartFlag = 0;
217                         break;
218             case '=':   opr2 = SysValue;
219                         if(sign=='+')
220                             SysValue = opr1+opr2;
221                         else if(sign=='-')
222                             SysValue = opr1 - opr2;
223                         opr1 = 0;
224                         opr2 = 0;
225                         keyCounter = 0;
226                         sign = '=';
227                         break;
228         }
229     }
230 }
231 //=========================================================
232 //  主函数main
233 //  全局采用中断方式,有利于降低功耗
234 //=========================================================
235 void main()
236 {
237     EX0 = 1;        //允许外部0中断
238     IT0 = 1;        //外部0中断方式为 “下降沿”
239     Init_Timer0();  /*初始化定时器0,在键盘上点击“START”后
240                     开始计数,定时时间为1秒*/
241     Init_Timer1();  /*初始化定时器1,用于定时显示,定时时间
242                     为23毫秒,即每隔23毫秒调用一次显示函数*/
243     EA  = 1;        //总中断开
244     P1 = 0xF0;      //初始键盘接口
245     while(1) ;
246 }
247 //=========================================================
248 //  按键中断服务函数,采用外部中断0
249 //  按键中断,在中断里面检测按键并解析按键
250 //=========================================================
251 void key_isr(void) interrupt 0
252 {
253     EA = 0;
254     keyValue = KeyScan();
255     keyAnalyzing(keyValue);
256     P1 = 0xF0;
257     EA = 1;
258 }
259 //=========================================================
260 //  定时器0中断服务函数
261 //  用于,定时1秒计数,计数到8888后返回重新新计数
262 //=========================================================
263 void timer0_isr(void) interrupt 1
264 {
265     TR0  = 0;
266     TH0  = 0x3C;
267     TL0  = 0xB0;
268     TR0  = 1;
269     cnt50ms++;
270     if(cnt50ms==19)     //计数20次  20*50 = 1000毫秒,即1秒
271     {
272         cnt50ms = 0;
273         SysValue=(SysValue>8887)?0:SysValue+1;
274     }
275 }
276 //=========================================================
277 //  定时器1中断服务函数
278 //  方式1,定时时间为23毫秒
279 //  用于数码管显示
280 //=========================================================
281 void timer1_isr(void) interrupt 3
282 {
283     TR1  = 0;
284     TH1  = 0xA6;
285     TL1  = 0x28;
286     showNumber(SysValue);
287     TR1  = 1;
288 }

转载于:https://www.cnblogs.com/phelonYang/archive/2012/12/18/2823550.html

51单片机实现4位数以内的加减法相关推荐

  1. 51单片机4位数乘法C语言,51单片机实现4位数以内的加减法

    中南民族大学,电子信息工程学院,开设了一门课程,叫<嵌入式电路设计>,由舒老师带头,旨在引导低年级的学生入门嵌入式,其内容比较多,包括模电.数电.C语言.单片机.EDA技术等.最近有位师弟 ...

  2. 51单片机2位数简易计算器C语言实现

    今天是51单片机模块! 事实上,也是离不开C语言编程啦 适合手头上有51单片机且对硬件有兴趣的小伙伴们 这里推荐初学者(我自己就是哈哈哈)购买天祥电子51单片机开发板(TX-1C) 话不多说,上代码: ...

  3. 单片机 | 51单片机原理

    [金善愚] 单片机应用原理篇 笔记整理 课程视频 :https://space.bilibili.com/483942191/channel/collectiondetail?sid=51090 文章 ...

  4. 《uCOS51移植心得》---七年前之《快快乐乐跟我学51单片机操作系统和IP栈》

    http://www.amobbs.com/forum.php?mod=viewthread&tid=3396563 <uCOS51移植心得>---七年前之<快快乐乐跟我学5 ...

  5. 单片机原理与实践学习记录之51单片机硬件基础

    单片机原理与实践学习记录 第三课(更新时间:2021.9.6) 51单片机硬件基础 MCS-51是Intel公司生产的一个单片机系列的总称.在功能上,该系列单片机有基本型和增强型两大类,通常以芯片型号 ...

  6. 51单片机 | DAC数模转换实验

    文章目录 一.DAC介绍 2.DAC 工作原理 二.PWM介绍 三.硬件设计 四.软件设计 1.PWM实现函数 2. 主函数 五.实验现象   这一节来介绍下如何使用 51 单片机输出模拟信号,要让 ...

  7. codeblocks 51单片机学习(四)简易计算器

    基于51单片机的数码管和矩阵按键实现的简易计算器,其实可以加入的东西有很多,就像我这个负数运算还没有加进去,以及我的除法运算只能算655(65535/100)以内的数,不过就先做到这里,这个作品至少已 ...

  8. 基于51单片机LCD1602的简易矩阵键盘密码锁

    写在前面 初次开始写博客,表达方面也许会有很多不足,希望自己能通过这种方式巩固自己的学习和锻炼表达能力,同时也是对于自己学习的记录. 一.功能介绍 四位密码锁,密码可更改,输入仅四次以内有效 矩阵键盘 ...

  9. 51单片机常用寄存器速查

    51单片机常用寄存器速查表 一 : 定时器 / 计数器方式选择 : TMOD 地址 (89H) 不可位寻址 D7 D6 D5 D4 D3 D2 D1 D0 GATE C/T M1 M0 GATE C/ ...

最新文章

  1. MarkDown入门及技巧
  2. 几个常用有力的特征的分析LBP、HOG、FAST、SIFT/SURF、MSER、BRISK
  3. python最长回文子串leetcode_Python版LeetCode5. 最长回文子串
  4. KMP算法求解next数组值(模式串从下标0开始或从下标1开始)以及求值后与主串的匹配过程
  5. 窗体的Alpha通道透明色支持
  6. CentOS7 安装 Nginx PHP
  7. 要想挣大钱,就要懂一个基本
  8. pandas数据处理实践三(DataFrame.apply、merge、rename,数据预处理、DataFrame.drop_duplicates去重)
  9. 全网首发:编译jna:dispatch.h:30:34: fatal error: com_sun_jna_Function.h: 没有那个文件或目录
  10. 163Editor 编辑器概览
  11. Qt 环境下MAPX组件的编程
  12. WPS使用VB批量将多个sheet单独存储为xls文件
  13. 典型相关分析(SPSS)
  14. java -jar xxx.jar
  15. Python学习之——列表、字典、实验低配版非诚勿扰
  16. android 壁纸存储位置,手机图片去了哪?教你理清照片存放路径(全文)
  17. 今日头条Go建千亿级微服务的实践
  18. sqlite数据库使用
  19. 03 朴素贝叶斯方法
  20. C#WinForm文本框记忆上次输入文本内容

热门文章

  1. 架构之美阅读笔记之一
  2. java第一季2.2
  3. 《算法竞赛入门经典》第三章 3.4
  4. Linux Command Line 解析
  5. jquery中的ajax方法(备忘)
  6. Selenium-基础操作
  7. # 2019-2020.3 《java程序设计》第一周学习总结
  8. 关于IE 对 $.get 缓存的记录
  9. 生信入门-爱课程上的华中农业大学
  10. BZOJ3172: [Tjoi2013]单词