51单片机实现4位数以内的加减法
扫描二维码
随时随地手机看文章
中南民族大学,电子信息工程学院,开设了一门课程,叫《嵌入式电路设计》,由舒老师带头,旨在引导低年级的学生入门嵌入式,其内容比较多,包括模电、数电、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
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<
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 //======================