51单片机实现4位数以内的加减法
生活随笔
收集整理的這篇文章主要介紹了
51单片机实现4位数以内的加减法
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
中南民族大學(xué),電子信息工程學(xué)院,開(kāi)設(shè)了一門課程,叫《嵌入式電路設(shè)計(jì)》,由舒老師帶頭,旨在引導(dǎo)低年級(jí)的學(xué)生入門嵌入式,其內(nèi)容比較多,包括模電、數(shù)電、C語(yǔ)言、單片機(jī)、EDA技術(shù)等。最近有位師弟找到我,希望我能幫他指導(dǎo)一下,利用AT89C52單片機(jī)設(shè)計(jì)一個(gè)最小系統(tǒng),其中包括矩陣鍵盤、數(shù)碼管顯示、中斷、2位數(shù)加減法、定時(shí)計(jì)數(shù)與暫停等功能。我也粗略的設(shè)計(jì)了一個(gè),在此分享出來(lái),希望能對(duì)初學(xué)者有所幫助,使更多的人加入到嵌入式的行業(yè)來(lái)。
開(kāi)發(fā)工具: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 // 數(shù)碼管顯示譯碼,共陰極 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 // 定時(shí)器0初始化函數(shù),定時(shí)50毫秒 14 // 用鍵盤上的“START”鍵啟動(dòng)計(jì)數(shù) 15 // 用鍵盤上的“SUS”鍵暫停計(jì)數(shù) 16 //======================================================== 17 void Init_Timer0() 18 { 19 TMOD |= 0x01; 20 TH0 = 0x3C; 21 TL0 = 0xB0; 22 TR0 = 0; 23 ET0 = 1; 24 } 25 //========================================================= 26 // 定時(shí)器1初始化函數(shù) 27 // 定時(shí)23毫秒,用于顯示 28 // 初始化后計(jì)時(shí)啟動(dòng) 29 //========================================================= 30 void Init_Timer1() 31 { 32 TMOD |= 0x10; 33 TH1 = 0xA6; 34 TL1 = 0x28; 35 TR1 = 1; 36 ET1 = 1; 37 } 38 //========================================================= 39 // 延時(shí)函數(shù) 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 // 四位數(shù)碼管顯示函數(shù) 50 // 能自動(dòng)滅零,自動(dòng)識(shí)別正負(fù)號(hào) 51 // 數(shù)值超出顯示范圍時(shí)顯示錯(cuò)誤"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 // 鍵盤掃描函數(shù) 119 // 返回按鍵情況,掃描結(jié)果 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); //去抖動(dòng) 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 '+'; //加號(hào) 143 144 case 0xed: return '4'; 145 case 0xdd: return '5'; 146 case 0xbd: return '6'; 147 case 0x7d: return '-'; //減號(hào) 148 149 case 0xeb: return '7'; 150 case 0xdb: return '8'; 151 case 0xbb: return '9'; 152 case 0x7b: return 'r'; //復(fù)位 153 154 case 0xe7: return '0'; 155 case 0xd7: return 's'; //啟動(dòng) 156 case 0xb7: return 't'; //暫停 157 case 0x77: return '='; //等于 158 default: ; 159 } 160 } 161 } 162 } 163 return '0'; 164 } 165 //========================================================= 166 // 鍵盤解析函數(shù) 167 // 對(duì)掃描得到的鍵值進(jìn)行解析 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; //啟動(dòng)計(jì)數(shù) 204 StartFlag = 1; 205 break; 206 case 't': sign = 't'; 207 if(StartFlag) 208 TR0 ^= 1;//暫停/啟動(dòng)計(jì)數(shù) 209 break; 210 case 'r': sign = 'r'; 211 opr1 = 0; 212 opr2 = 0; 213 SysValue = 0; 214 keyCounter = 0; 215 TR0 = 0; //停止計(jì)數(shù)器 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 // 主函數(shù)main 233 // 全局采用中斷方式,有利于降低功耗 234 //========================================================= 235 void main() 236 { 237 EX0 = 1; //允許外部0中斷 238 IT0 = 1; //外部0中斷方式為 “下降沿” 239 Init_Timer0(); /*初始化定時(shí)器0,在鍵盤上點(diǎn)擊“START”后 240 開(kāi)始計(jì)數(shù),定時(shí)時(shí)間為1秒*/ 241 Init_Timer1(); /*初始化定時(shí)器1,用于定時(shí)顯示,定時(shí)時(shí)間 242 為23毫秒,即每隔23毫秒調(diào)用一次顯示函數(shù)*/ 243 EA = 1; //總中斷開(kāi) 244 P1 = 0xF0; //初始鍵盤接口 245 while(1) ; 246 } 247 //========================================================= 248 // 按鍵中斷服務(wù)函數(shù),采用外部中斷0 249 // 按鍵中斷,在中斷里面檢測(cè)按鍵并解析按鍵 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 // 定時(shí)器0中斷服務(wù)函數(shù) 261 // 用于,定時(shí)1秒計(jì)數(shù),計(jì)數(shù)到8888后返回重新新計(jì)數(shù) 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) //計(jì)數(shù)20次 20*50 = 1000毫秒,即1秒 271 { 272 cnt50ms = 0; 273 SysValue=(SysValue>8887)?0:SysValue+1; 274 } 275 } 276 //========================================================= 277 // 定時(shí)器1中斷服務(wù)函數(shù) 278 // 方式1,定時(shí)時(shí)間為23毫秒 279 // 用于數(shù)碼管顯示 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 }?
轉(zhuǎn)載于:https://www.cnblogs.com/phelonYang/archive/2012/12/18/2823550.html
總結(jié)
以上是生活随笔為你收集整理的51单片机实现4位数以内的加减法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 许可证( License License
- 下一篇: 读jQuery之二十(Deferred对