51单片机实现4位数以内的加减法
生活随笔
收集整理的這篇文章主要介紹了
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 <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位数以内的加减法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 许可证( License License
- 下一篇: Python: logging日志模块简