51单片机简易计算器程序

合集下载

51单片机外部脉冲计数程序

51单片机外部脉冲计数程序

51单片机外部脉冲计数程序51单片机外部脉冲计数程序是一种常见的嵌入式应用程序,它可以通过计数外部脉冲信号来实现各种功能,如测量速度、记录行程、控制电机等。

在本文中,我们将介绍如何编写一个简单的51单片机外部脉冲计数程序,供初学者参考。

一、程序框架```c#include <reg52.h>sbit PulsePin = P1^0; //定义脉冲信号输入引脚unsigned long cnt = 0; //计数器void ExternalInterrupt0() interrupt 0 //外部中断0的中断服务程序{cnt++; //计数器加一}```程序中定义了一个脉冲信号输入引脚PulsePin,一个计数器cnt,并在主程序中开启了全局中断和外部中断0,并设置外部中断0为下降沿触发。

在外部中断0的中断服务程序中,计数器cnt会加一。

二、程序解析1. 硬件连接将需要计数的脉冲信号输入引脚连接到单片机的P1.0引脚上,并连接好单片机的电源和地线。

2. 宏定义和全局变量首先定义了PulsePin引脚为输入模式,并定义了计数器cnt为无符号长整型变量。

3. 主程序在主程序中,首先开启了全局中断和外部中断0,然后设置外部中断0为下降沿触发。

最后加入一个无限循环,等待外部中断的触发。

4. 外部中断0的中断服务程序在外部中断0的中断服务程序中,计数器cnt会加一。

三、总结本文介绍了如何编写一个简单的51单片机外部脉冲计数程序。

通过外部中断0的中断服务程序,可以实现对外部脉冲信号的计数。

本程序只是一个简单的例子,读者可以根据自己的需求对其进行改进和优化。

51单片机计算器程序

51单片机计算器程序

#include <reg51.h>#include <intrins.h>unsigned char data digit;unsigned char data index;unsigned char data buf[16];unsigned char code table[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};unsigned int temp_dat;unsigned long int temp1,temp2,temp;unsigned int flag,flag1,key_times,key_flag,key_temp;unsigned char key_scan();void delay(void);void key_proc();void sys_init();void dis_result();void dis_init();void result_proc();void start_proc();void dat_proc(unsigned int key_dat);void char_proc(unsigned char i);void delayms(unsigned char ms);void main(){sys_init();while(1){key_proc();dis_result();}}void sys_init(){P0=0xff;P2=0x00;TMOD=0x01;TH0=0xfc;TL0=0x17;digit=0x00;index=0;temp=0;temp1=0;temp2=0;flag=0;key_times=0;temp_dat=0;key_flag=0;key_temp=0;dis_init();IE=0x82;TR0=1;}void dis_init(){buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[10];buf[7]=table[10];buf[8]=table[10];buf[9]=table[10];buf[10]=table[10];buf[11]=table[10];buf[12]=table[10];buf[13]=table[10];buf[14]=table[10];buf[15]=table[10];}void dis_result(){if((temp<=4294967295)&&(temp>999999999)) {buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[temp/1000000000];buf[7]=table[(temp%1000000000)/100000000];buf[8]=table[((temp%1000000000)%100000000)/10000000];buf[9]=table[(((temp%1000000000)%100000000)%10000000)/1000000];buf[10]=table[((((temp%1000000000)%100000000)%10000000)%1000000)/100000];buf[11]=table[(((((temp%1000000000)%100000000)%10000000)%1000000)%100000)/10000];buf[12]=table[((((((temp%1000000000)%100000000)%10000000)%1000000)%100000)%10000) /1000];buf[13]=table[(((((((temp%1000000000)%100000000)%10000000)%1000000)%100000)%10000 )%1000)/100];buf[14]=table[((((((((temp%1000000000)%100000000)%10000000)%1000000)%100000)%1000 0)%1000)%100)/10];buf[15]=table[((((((((temp%1000000000)%100000000)%10000000)%1000000)%100000)%1000 0)%1000)%100)%10];}if((temp<=999999999)&&(temp>99999999)){buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[10];buf[7]=table[temp/100000000];buf[8]=table[(temp%100000000)/10000000];buf[9]=table[((temp%100000000)%10000000)/1000000];buf[10]=table[(((temp%100000000)%10000000)%1000000)/100000];buf[11]=table[((((temp%100000000)%10000000)%1000000)%100000)/10000];buf[12]=table[(((((temp%100000000)%10000000)%1000000)%100000)%10000)/1000]; buf[13]=table[((((((temp%100000000)%10000000)%1000000)%100000)%10000)%1000)/100];buf[14]=table[(((((((temp%100000000)%10000000)%1000000)%100000)%10000)%1000)%100) /10];buf[15]=table[(((((((temp%100000000)%10000000)%1000000)%100000)%10000)%1000)%100) %10];}if((temp<=99999999)&&(temp>9999999)){buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[10];buf[7]=table[10];buf[8]=table[temp/10000000];buf[9]=table[(temp%10000000)/1000000];buf[10]=table[((temp%10000000)%1000000)/100000];buf[11]=table[(((temp%10000000)%1000000)%100000)/10000];buf[12]=table[((((temp%10000000)%1000000)%100000)%10000)/1000];buf[13]=table[(((((temp%10000000)%1000000)%100000)%10000)%1000)/100];buf[14]=table[((((((temp%10000000)%1000000)%100000)%10000)%1000)%100)/10];buf[15]=table[((((((temp%10000000)%1000000)%100000)%10000)%1000)%100)%10];}if((temp<=9999999)&&(temp>999999)){buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[10];buf[7]=table[10];buf[8]=table[10];buf[9]=table[temp/1000000];buf[10]=table[(temp%1000000)/100000];buf[11]=table[((temp%1000000)%100000)/10000];buf[12]=table[(((temp%1000000)%100000)%10000)/1000];buf[13]=table[((((temp%1000000)%100000)%10000)%1000)/100];buf[14]=table[(((((temp%1000000)%100000)%10000)%1000)%100)/10];buf[15]=table[(((((temp%1000000)%100000)%10000)%1000)%100)%10];}if((temp<=999999)&&(temp>99999)){buf[0]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[10];buf[7]=table[10];buf[8]=table[10];buf[9]=table[10];buf[10]=table[temp/100000];buf[11]=table[(temp%100000)/10000];buf[12]=table[((temp%100000)%10000)/1000];buf[13]=table[(((temp%100000)%10000)%1000)/100];buf[14]=table[((((temp%100000)%10000)%1000)%100)/10];buf[15]=table[((((temp%100000)%10000)%1000)%100)%10]; }if((temp<=99999)&&(temp>9999)){buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[10];buf[7]=table[10];buf[8]=table[10];buf[9]=table[10];buf[10]=table[10];buf[11]=table[temp/10000];buf[12]=table[(temp%10000)/1000];buf[13]=table[((temp%10000)%1000)/100];buf[14]=table[(((temp%10000)%1000)%100)/10];buf[15]=table[(((temp%10000)%1000)%100)%10];}else if((temp<=9999)&&(temp>999)){buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[7]=table[10];buf[8]=table[10];buf[9]=table[10];buf[10]=table[10];buf[11]=table[10];buf[12]=table[temp/1000];buf[13]=table[(temp%1000)/100];buf[14]=table[((temp%1000)%100)/10];buf[15]=table[((temp%1000)%100)%10]; }else if((temp<=999)&&(temp>99)){buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[10];buf[7]=table[10];buf[8]=table[10];buf[9]=table[10];buf[10]=table[10];buf[11]=table[10];buf[12]=table[10];buf[13]=table[temp/100];buf[14]=table[(temp%100)/10];buf[15]=table[(temp%100)%10];}else if((temp<=99)&&(temp>9)){buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[10];buf[7]=table[10];buf[8]=table[10];buf[9]=table[10];buf[10]=table[10];buf[11]=table[10];buf[13]=table[10];buf[14]=table[temp/10];buf[15]=table[temp%10];}else if(temp<=9){buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[10];buf[7]=table[10];buf[8]=table[10];buf[9]=table[10];buf[10]=table[10];buf[11]=table[10];buf[12]=table[10];buf[13]=table[10];buf[14]=table[10];buf[15]=table[temp];}}unsigned char key_scan(){unsigned char code_h,code_l;P1=0xf0;if((P1&0xf0)!=0xf0){delayms(2);if((P1&0xf0)!=0xf0) //两次判断,确认有键按下{code_h=0xfe; //低四位为行地址,对每一行进行扫描,即将每一行依次赋值0while((code_h&0x10)!=0x00){P1=code_h;if((P1&0xf0)!=0xf0){code_l=(P1&0xf0|0x0f);return((~code_h)+(~code_l)); //取反之后,高四位与低四位都只有一个1,相加不会进位}elsecode_h=((code_h<<1)|0x01); //依次进行扫描}}}return(0);}void key_proc(){unsigned char key_value;key_value=key_scan();switch(key_value){case 0x18: dat_proc(7);break; //7case 0x28: dat_proc(4);break; //4case 0x48: dat_proc(1);break; //1case 0x14: dat_proc(8);break; //8case 0x24: dat_proc(5);break; //5case 0x44: dat_proc(2);break; //2case 0x84: dat_proc(0);break; //0case 0x12: dat_proc(9);break; //9case 0x22: dat_proc(6);break; //6case 0x42: dat_proc(3);break; //3case 0x82: result_proc();break; //=case 0x11: char_proc(4);break; ///case 0x21: char_proc(3);break; //*case 0x41: char_proc(2);break; //-case 0x81: char_proc(1);break; //+case 0x88: start_proc();break; //ondefault :break;}}void dat_proc(unsigned int key_dat){if(key_times==0)temp=key_dat;else{if(flag==0)temp=(temp1*10+key_dat);else if(flag==1)temp=(temp2*10+key_dat);}if(flag==0)temp1=temp;else if(flag==1)temp2=temp;delayms(200);key_times++;}void char_proc(unsigned char i){key_times=0;key_flag=i;if(temp==0)flag=0;else{flag=1;}}void result_proc(){unsigned char flag_value;flag_value=key_flag;switch(flag_value){case 1: temp=(temp1+temp2);break;case 2: temp=(temp1-temp2);break;case 3: temp=(temp1*temp2);break;case 4: temp=(temp1/temp2);break;}key_times=0;flag=0;}void start_proc(){temp=0;temp1=0;temp2=0;flag=0;key_times=0;temp_dat=0;key_flag=0;}void time0() interrupt 1 using 2 {TH0=0xfc;TL0=0x17;P2=0x00;P0=buf[index];P2=digit;digit=digit++;index++;index&=0x0f;}void delayms(unsigned char ms) {unsigned char i;while(ms--){for(i = 0; i < 120; i++);}}D0D1D2D3D4D5D6D7P3.1Q1CSDAQ2INT1Q3LCDENQ4WRQ6RDQ7Q0Q5Q4Q7Q5Q6Q 3Q 0Q 1Q 2D 0D 7D 6D 5D 4D 3D 2D 1W 0W 1W 2W 3W 4W 5W 6W 7D 0D 1D 2D 3D 4D 5D 6D 7W 8W 10W 11W 12W 13W 14W 15W 9W0W1W2W3W4W5W6W7W8W9W10W11W12W13W14W15XTAL218XTAL119ALE 30EA31PSEN 29RST9P0.0/AD039P0.1/AD138P0.2/AD237P0.3/AD336P0.4/AD435P0.5/AD534P0.6/AD633P0.7/AD732P1.0/T21P1.1/T2EX 2P1.23P1.34P1.45P1.56P1.67P1.78P3.0/RXD 10P3.1/TXD 11P3.2/INT012P3.3/INT113P3.4/T014P3.7/RD17P3.6/WR 16P3.5/T115P2.7/A1528P2.0/A821P2.1/A922P2.2/A1023P2.3/A1124P2.4/A1225P2.5/A1326P2.6/A1427U3AT89C52234567891RP1RESPACK-812365489=7+CONABCD1243A 1B 2C3E16E24E35Y015Y114Y213Y312Y411Y510Y69Y77U174HC138A 1B 2C3E16E24E35Y015Y114Y213Y312Y411Y510Y69Y77U274HC138U4NOTU5NOTU6NOTU7NOTU8NOTU9NOTU10NOTU11NOTU12NOTU13NOTU14NOTU15NOTU16NOTU17NOTU19NOTU20NOTU22NOT。

51单片机实现计算器程序

51单片机实现计算器程序

#include <reg52.h>#include <intrins.h>#include <math.h>#define uchar unsigned char#define uint unsigned intsbit LCD_RS=P2^2;//数据和命令端sbit LCD_EN=P2^0;//使能端sbit LCD_RW=P2^1;sbit CS1=P2^4;sbit CS2=P2^3;uint keytime,keyno[10];uint result,date1,date2,w_date1,w_date2;uint KeyNO1,opercha;uint date10n;uint date10n_d[16];uchar code hz[]={/*-- 文字: 数--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x10,0x92,0x54,0x38,0xFF,0x38,0x54,0x52,0x80,0xF0,0x1F,0x12,0x10,0xF0,0x10,0x00,0x42,0x42,0x2A,0x2E,0x13,0x1A,0x26,0x02,0x40,0x20,0x13,0x0C,0x33,0x60,0x20,0x00,/*-- 文字: 据--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x08,0x08,0x08,0xFF,0x88,0x40,0xFE,0x92,0x92,0x92,0xF2,0x92,0x92,0x9E,0x80,0x00,0x02,0x42,0x81,0x7F,0x40,0x30,0x0F,0xFC,0x44,0x44,0x47,0x44,0x44,0xFC,0x00,0x00,/*-- 文字: 结--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x20,0x30,0xAC,0x63,0x10,0x00,0x08,0x48,0x48,0x48,0x7F,0x48,0x48,0x48,0x08,0x00,0x22,0x23,0x22,0x12,0x12,0x00,0x00,0x7E,0x22,0x22,0x22,0x22,0x22,0x7E,0x00,0x00,/*-- 文字: 果--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0x00,0x00,0x3E,0x2A,0x2A,0x2A,0xFE,0x2A,0x2A,0x2A,0x3E,0x00,0x00,0x00,0x00,0x21,0x21,0x11,0x11,0x09,0x05,0x03,0xFF,0x03,0x05,0x09,0x09,0x11,0x31,0x11,0x00};uchar code sz[]={0x00,0x00,0xF0,0xF8,0x08,0x68,0xF8,0xF0,0x00,0x00,0x07,0x0F,0x0B,0x08,0x0F,0x07, //0 0x00,0x20,0x20,0x30,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00, //1 0x00,0x30,0x38,0x08,0x88,0xF8,0x70,0x00,0x00,0x0C,0x0E,0x0B,0x09,0x08,0x08,0x00, //2 0x00,0x30,0x38,0x88,0x88,0xF8,0x70,0x00,0x00,0x06,0x0E,0x08,0x08,0x0F,0x07,0x00, //3 0x00,0x00,0xF8,0xF8,0x00,0xE0,0xE0,0x00,0x00,0x03,0x03,0x02,0x02,0x0F,0x0F,0x02, //4 0x00,0xF8,0xF8,0x88,0x88,0x88,0x08,0x00,0x00,0x08,0x08,0x08,0x0C,0x07,0x03,0x00, //5 0x00,0xC0,0xE0,0x78,0x58,0xC8,0x80,0x00,0x00,0x07,0x0F,0x08,0x08,0x0F,0x07,0x00, //6 0x00,0x08,0x08,0x88,0xE8,0x78,0x18,0x00,0x00,0x00,0x0E,0x0F,0x01,0x00,0x00,0x00, //7 0x00,0x70,0xF8,0xC8,0x88,0xF8,0x70,0x00,0x00,0x07,0x0F,0x08,0x09,0x0F,0x07,0x00, //8 0x00,0xF0,0xF8,0x08,0x08,0xF8,0xF0,0x00,0x00,0x00,0x09,0x0D,0x0F,0x03,0x01,0x00, //90x00,0x00,0x00,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x0C,0x00,0x00, //: 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x0C,0x00,0x00//.};/*******************************名称:delay()输入:延时数输出: 无功能:延时********************************/void delay(uint x){int y,z;for(y=x;y>0;y--)for (z=120;z>0;z--);}void write_c(uchar c) //写指令端{LCD_RW=0;LCD_RS=0;LCD_EN=1;P0=c;LCD_EN=0;delay(1);LCD_EN=1;}void write_d(uchar d)//写数据{LCD_RW=0;LCD_RS=1;LCD_EN=1;P0=d;LCD_EN=0;delay(1);LCD_EN=1;}void pianxuan(screen) //片选{switch(screen){case 0:CS1=0;CS2=0;break;case 1:CS1=1;CS2=0;break;case 2:CS1=0;CS2=1;break;case 3:CS1=1;CS2=1;break;}}void qinping(screen)//清屏,从第一行第一列开始{uint x,y; //页的设置位pianxuan(screen);//选择哪个清屏for(x=0xb8;x<0xc0;x++){write_c(x);//页初始值为0XB8到0xc0共八页write_c(0x40);//列的初始地址为0x40,共64列for(y=0;y<64;y++){write_d(0x00);//选择全部清屏}}}/*LCD显示汉字字库函数*/void lcd_display_hanzi(uchar screen,uchar page,uchar lie,uint mun) //screen:选择屏幕参数,page:选择页参数0-3,lie列参数0-3,mun:显示第几个汉字的参数{int i; //page页其实就是行,是行计数器页指针共九位计数器,高三位为X,低六位为Ymun=mun*32;pianxuan(screen) ; //片选看哪个段write_c(0x40+(lie*16)); //一个汉字占用两个字节write_c(0xb8+(page*2)); //一个字节显示for ( i=0;i<16;i++){write_d(hz[mun++]);}write_c(0x40+(lie*16));write_c(0xb8+(page*2)+1);for (i=0;i<16;i++){write_d(hz[mun++]);}}void lcd_display_shuzi(uchar screen,uchar page,uchar lie,uint mun) //screen:选择屏幕参数,page:选择页参数0-3,lie列参数0-3,mun:显示第几个汉字的参数{int i; //page页其实就是行,是行计数器页指针共九位计数器,高三位为X,低六位为Ymun=mun*16;pianxuan(screen) ; //片选看哪个段write_c(0x40+(lie*8)); //一个汉字占用两个字节write_c(0xb8+(page*2)); //一个字节显示for ( i=0;i<8;i++){write_d(sz[mun++]);}write_c(0x40+(lie*8));write_c(0xb8+(page*2)+1);for (i=0;i<8;i++){write_d(sz[mun++]);}}void LCD_init(){write_c(0x3f);// 显示开启write_c(0xc0); //显示起始行,从第一位开始,从0到63 write_c(0xb8);// 设置页得地址从0到7write_c(0x40); //设置列的地址,从第一位开始,从0到63 }/*******************************名称:GET_key()输入:无输出: 按键的相应数目功能:扫描按键********************************/uchar GET_key(){uchar Tmp,KeyNO;P1 = 0xf0;delay(1);Tmp = P1;switch(Tmp){case 0xe0: KeyNO = 3; break;case 0xd0: KeyNO = 2; break;case 0xb0: KeyNO = 1; break;case 0x70: KeyNO = 0;}P1 = 0x0f;delay(1);Tmp = P1;switch(Tmp){case 0x0e: KeyNO+= 12; break;case 0x0d: KeyNO+= 8; break;case 0x0b: KeyNO+= 4; break;case 0x07: KeyNO+= 0; break;default: break;}return(KeyNO);}void write_key(){uchar i,j,m,n;m = 7;n = 7;KeyNO1 = GET_key();if (KeyNO1>=0 && KeyNO1<=9){keytime++;}if (KeyNO1>=10 && KeyNO1<=13){/* keytime= keytime-1;for (j=keytime; j>=0;j--){if ((keytime-j) == 0)w_date1=keyno[keytime];else{for (k=0; k<keytime-j; k++){w_date1=keyno[keytime--]*10;}}date1=date1+w_date1;}*/keytime = 0;opercha = KeyNO1;}if (!(opercha>=10 && opercha<=13)){date1=0;if ((keytime-1) < 10 ){keyno[keytime-1] = KeyNO1;if (keytime-1>=0 && keytime-1 <= 7){for (i=keytime; i>0; i--){lcd_display_shuzi(1,0,m,keyno[i-1]);m--;if ((keytime-i) == 0){w_date1=keyno[i-1];}else{for (j=0; j<keytime-i; j++){w_date1=keyno[i-1]*10;}}date1=date1+w_date1;}}else{for (i=keytime-8; i>0; i--){lcd_display_shuzi(2,0,n,keyno[i-1]);n--;for (j=0; j<keytime-i; j++){w_date1=keyno[i-1]*10;}date1=date1+w_date1;}m=7;for (i=keytime; i>keytime-8; i--){lcd_display_shuzi(1,0,m,keyno[i-1]);m--;if ((keytime-i) == 0)w_date1=keyno[i-1];else{for (j=0; j<keytime-i; j++){w_date1=keyno[i-1]*10;}}date1=date1+w_date1;}}}}if ( (opercha>=10 && opercha<=13) && (KeyNO1 != 14) ) {date2=0;if ((keytime-1)<10 && (keytime-1)>=0){keyno[keytime-1] = KeyNO1;if (keytime-1 <= 7){for (i=keytime; i>0; i--){lcd_display_shuzi(1,1,m,keyno[i-1]);m--;if ((keytime-i) == 0)w_date2=keyno[i-1];else{for (j=0; j<keytime-i; j++){w_date2=keyno[i-1]*10;}}date2=date2+w_date2;}}else{for (i=keytime-8; i>0; i--){lcd_display_shuzi(2,1,n,keyno[i-1]);n--;for (j=0; j<keytime-i; j++){w_date1=keyno[i-1]*10;}date2=date2+w_date2;}m=7;for (i=keytime; i>keytime-8; i--){lcd_display_shuzi(1,1,m,keyno[i-1]);m--;if ((keytime-i) == 0)w_date2=keyno[i-1];else{for (j=0; j<keytime-i; j++){w_date2=keyno[i-1]*10;}}date2=date2+w_date2;}}}}/*if (KeyNO1 == 15){keytime= keytime-1;for (j=keytime; j>=0;j--){if ((keytime-j) == 0)w_date2=keyno[keytime];else{for (i=0; i<keytime-j; i++){w_date2=keyno[keytime--]*10;}}date2=date2+w_date2;}} */if (opercha>=10 && opercha<=13){m=7;if (KeyNO1 == 14){switch(opercha){case 10:result=date1+date2;break;case 11:result=date1-date2;break;case 12:result=date1*date2;break;case 13:result=date1/date2;break;default:break;}for (i=1; ;i++){date10n=1;for (j=0; j<i-1; j++){date10n=date10n*10;}date10n_d[i-1]=(result / date10n) % 10;if (date10n*10>result){j=i;break;}}P3=result / date10n;for (i=0;i<j;i++){lcd_display_shuzi(1,2,m,date10n_d[i]);m--;}/* lcd_display_shuzi(1,2,7,result);P3 =opercha; */}}}void main(){keytime=0;date1=0;date2=0;w_date1=0;w_date2=0;result=0;opercha=0;KeyNO1=16;date10n=1;LCD_init();qinping(0);lcd_display_hanzi(2,0,0,0); //LCD显示汉字"数" //screen:选择屏幕参数,page:选择页参数0-3,lie列参数0-3,mun:显示第几个汉字的参数lcd_display_hanzi(2,0,1,1); //LCD显示汉字"据"lcd_display_shuzi(2,0,4,1); //LCD显示数字"1"lcd_display_shuzi(2,0,5,10);//LCD显示符号":"lcd_display_hanzi(2,1,0,0); //LCD显示汉字"数"lcd_display_hanzi(2,1,1,1); //LCD显示汉字"据"lcd_display_shuzi(2,1,4,2); //LCD显示数字"2"lcd_display_shuzi(2,1,5,10);//LCD显示符号":"lcd_display_hanzi(2,2,0,2); //LCD显示汉字"结"lcd_display_hanzi(2,2,1,3); //LCD显示汉字"果"lcd_display_shuzi(2,2,4,10);//LCD显示符号":"while(1){P1 = 0x0f;if (P1 != 0x0f){delay(1);if (P1 != 0x0f){write_key();while (P1 != 0x0f);}}}}。

基于51单片机的计算器(附Proteus仿真图且程序有详细注释)

基于51单片机的计算器(附Proteus仿真图且程序有详细注释)
case 0x7b: key=11;flag1=1;display(7,0);break;
}
while(temp!=0xf0)
{
temp=P1;temp=temp&0xf0;
}
}
P1=0xf7;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
temp=P1;
x--;
delay(3);
}
}
}
else if ((flag1==1)&&(flag2==1))
{
for(i=7;i>=px3;i--)
{
display(i,RESUIT[i]);
delay(3);
}
}
}
{
P1=0xfe;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
temp=P1;
switch(temp)
{
case 0xee: key=0;flag=1;break;
case 0xde: key=1;flag=1;break;
case 0xbe: key=2;flag=1;break;
{
k=k*10;
}
x1=x1+k;
}
x1=x1+DATA1[px1-1];
for(i=0;i<(px2-1);i++) //把第二个数组中的数处理成十进制数
{
k=DATA2[i];
for(j=0;j<(px2-i-1);j++)

单片机课程设计——基于C51简易计算器

单片机课程设计——基于C51简易计算器

单片机双字节十六进制减法实验设计摘要本设计是基于51系列的单片机进行的双字节十六进制减法设计,可以完成计算器的键盘输入,进行加、减、3位无符号数字的简单运算,并在LED上相应的显示结果。

设计过程在硬件与软件方面进行同步设计。

硬件方面从功能考虑,首先选择内部存储资源丰富的AT89C51单片机,输入采用5个键盘。

显示采用3位7段共阴极LED动态显示。

软件方面从分析计算器功能、流程图设计,再到程序的编写进行系统设计。

编程语言方面从程序总体设计以及高效性和功能性对C语言和汇编语言进行比较分析,针对计算器四则运算算法特别是乘法和除法运算的实现,最终选用KEIL公司的μVision3软件,采用汇编语言进行编程,并用proteus 仿真。

引言十六进制减法计算器的原理与设计是单片机课程设计课题中的一个。

在完成理论学习和必要的实验后,我们掌握了单片机的基本原理以及编程和各种基本功能的应用,但对单片机的硬件实际应用设计和单片机完整的用户程序设计还不清楚,实际动手能力不够,因此对该课程进行一次课程设计是有必要的。

单片机课程设计既要让学生巩固课本学到的理论,还要让学生学习单片机硬件电路设计和用户程序设计,使所学的知识更深一层的理解,十进制加法计算器原理与硬软件的课程设计主要是通过学生独立设计方案并自己动手用计算机电路设计软件,编写和调试,最后仿真用户程序,来加深对单片机的认识,充分发挥学生的个人创新能力,并提高学生对单片机的兴趣,同时学习查阅资料、参考资料的方法。

关键词:单片机、计算器、AT89C51芯片、汇编语言、数码管、加减目录摘要 (01)引言 (01)一、设计任务和要求.............................1、1 设计要求1、2 性能指标1、3 设计方案的确定二、单片机简要原理.............................2、1 AT89C51的介绍2、2 单片机最小系统2、3 七段共阴极数码管三、硬件设计...................................3、1 键盘电路的设计3、2 显示电路的设计四、软件设计...................................4、1 系统设计4、2 显示电路的设计五、调试与仿真.................................5、1 Keil C51单片机软件开发系统5、2 proteus的操作六、心得体会....................................参考文献......................................... 附录1 系统硬件电路图............................ 附录2 程序清单..................................一、设计任务和要求1.1 设计要求本次课程设计,我选择的课题是单片机十进制加法计算器软硬件设计,设计任务为:设计一键盘显示装置,键盘上除需定义16个十六进制数字键外还要相应的功能键,其它键不定义无响应。

51单片机简易计算器设计-51单片机简易计算器课程设计

51单片机简易计算器设计-51单片机简易计算器课程设计

51单⽚机简易计算器设计-51单⽚机简易计算器课程设计⽬录⼀、设计任务和要求 (2)1、设计要求 (2)2、设计⽅案的确定 (2)⼆、硬件设计 (2)1、单⽚机最⼩系统 (2)2、键盘电路的设计 (3)3、显⽰电路的设计 (3)4、系统硬件电路图 (4)三、软件设计 (5)1 系统设计 (5)2 显⽰电路的设计 (6)3、程序清单 (8)四、调试与仿真 (14)五、试验箱实物图 (14)六、⼼得体会 (15)⼀、设计任务和要求1、设计要求利⽤单⽚机设计并制作简易计算器。

具体要求如下:1、4*4按键⽤于0~9的数字输⼊、加减乘除、等于、清零功能;2、能实现简单的加减乘除运算;3、输⼊数字及计算结果通过LED或LCD显⽰器显⽰。

2、设计⽅案的确定按照设计要求,本课题需要使⽤数码管显⽰和扩展4*4键盘,由于AT89C51芯⽚的I⼝不够多,⽽且为了硬件电路设计的简单化,故选择串⾏动态显⽰和⽤P1⼝扩展4*4键盘,扩展的4*4键盘定义⼗个数字键,六个功能键,使⽤串⾏动态显⽰显⽰运算结果。

主程序进⾏初始化,采⽤⾏列扫描进⾏查表得出键值,每次按键后调⽤显⽰⼦程序。

⼆、硬件设计简易数字计算器系统硬件设计主要包括:键盘电路,显⽰电路以及其他辅助电路。

下⾯分别进⾏设计。

1.单⽚机最⼩系统单⽚机最⼩系统就是⽀持主芯⽚正常⼯作的最⼩部分,包括主控芯⽚、复位电路和晶振电路。

(1)、复位电路复位电路本设计采⽤上电与⼿动复位电路,电阻分别选取100和10K,电容选取10uF,系统⼀上电,芯⽚就复位,或者中途按按键也可以进⾏复位。

(2)、晶振电路图三晶振电路晶振电路是单⽚机的⼼脏,它⽤于产⽣单⽚机⼯作所需要的时钟信号。

单⽚机的晶振选取11.0592MHz,晶振旁电容选取30pF。

2.键盘电路的设计键盘可分为两类:编码键盘和⾮编码键盘。

编码键盘是较多按键(20个以上)和专⽤驱动芯⽚的组合,当按下某个按键时,它能够处理按键抖动、连击等问题,直接输出按键的编码,⽆需系统软件⼲预。

51计算器代码

51计算器代码

51单片机做的简易计算器//by 河南大学电子信息06级金玉川//使用时应保证本计算器的输入数值与输出数值均不大于65536 数码管驱动芯片用的MAX7219,运算和键盘扫描用AT89S51 #include<at89x51.h>unsigned char key,temp;#define DIN P1_0 //串行数据输入引脚#define CLK P1_2 //同步时钟#define LOAD P1_1 //数据输入使能//--------10ms延时子程序-------------void delay10ms(unsigned char time){unsigned char a,b,c;for(a=0;a<time;a++)for(b=0;b<10;b++)for(c=0;c<120;c++);}//--------按键扫描子程序-------------//“1--9”号键的key值分别为1--9; “ +、-、*、/ ” 的key 值分别为13、14、15、16 //“ = ”的key 值为10//“on/c”的key值为11void KeyScan(void){P2=0xFF;P2_0=0;temp=P2;temp&=0xF0;if(temp !=0xF0){delay10ms(1);temp=P2;temp&=0xF0;if(temp !=0xF0){switch(temp){case 0xE0:key=7;break;case 0xd0:key=8;break;case 0xb0:key=9;break;case 0x70:key=16;break; //“除号”}}}P2=0xFF;P2_1=0;temp=P2;temp&=0xF0;if(temp !=0xF0)delay10ms(1);temp=P2;temp&=0xF0;if(temp !=0xF0){switch(temp){case 0xE0:key=4;break;case 0xd0:key=5;break;case 0xb0:key=6;break;case 0x70:key=15;break;//“乘号”}}}P2=0xFF;P2_2=0;temp=P2;temp&=0xF0;if(temp !=0xF0){delay10ms(1);temp=P2;temp&=0xF0;if(temp !=0xF0){switch(temp){case 0xE0:key=1;break;case 0xd0:key=2;break;case 0xb0:key=3;break;case 0x70:key=14;break;//减号}}P2=0xFF;P2_3=0;temp=P2;temp&=0xF0;if(temp !=0xF0){delay10ms(1);temp=P2;temp&=0xF0;if(temp !=0xF0){switch(temp){case 0xE0:key=11;break;//复位ON/Ccase 0xd0:key=10;break;//0case 0xb0:key=12;break;//等号case 0x70:key=13;break;//加号}}}}//-------数据发送子程序----------------void send(unsigned char addr,unsigned char dat) {unsigned char ADS,i,j;LOAD=0;i=0;while(i<16){if(i<8) ADS=addr;elseADS=dat;for(j=8;j>=1;j--){DIN=ADS&0x80;ADS<<=1;CLK=1;CLK=0;}i+=8;}LOAD=1;}//--------数据显示子程序--------------------void display(unsigned int n){unsigned char n2;unsigned char n3;unsigned char n4;unsigned char n5;if(n/10000==0&&(n%10000)/1000==0&&((n%10000)%1000)/100==0&&(((n%10000)%1000)%100)/10==0) //灭掉不必要的“0”{n2=0x0f;n3=0x0f;n4=0x0f;n5=0x0f;}else if(n/10000==0&&(n%10000)/1000==0&&((n%10000)%1000)/100==0&&(((n%10000)%1000)%100)/10!=0){n2=0x0f;n3=0x0f;n4=0x0f;n5=(((n%10000)%1000)%100)/10;}else if(n/10000==0&&(n%10000)/1000==0&&((n%10000)%1000)/100!=0){n2=0x0f;n3=0x0f;n4=((n%10000)%1000)/100;n5=(((n%10000)%1000)%100)/10;}else if(n/10000==0&&(n%10000)/1000!=0){n2=0x0f;n3=(n%10000)/1000;n4=((n%10000)%1000)/100;n5=(((n%10000)%1000)%100)/10;}else{n2=n/10000;n3=(n%10000)/1000;n4=((n%10000)%1000)/100;n5=(((n%10000)%1000)%100)/10;}send(0x0c,0x01); //掉电控制寄存器设置为正常操作send(0x0b,0x05); //扫描边界,显示前6位send(0x0a,0xf5); //亮度控制send(0x09,0xff); //译码方式send(0x01,0x0f); //最大显示结果65535;最高位不显示,灭零;send(0x02,n2);send(0x03,n3);send(0x04,n4);send(0x05,n5);send(0x06,n%10);}//-----------主函数-----------void main(void){unsigned int first;unsigned int second;unsigned int result;//最终运算结果unsigned char op;//用来存储+、-、*、/操作符键的值unsigned char flag;LOOP:first=0;second=0;result=0;op=0;flag=1;display(0);while(1){KeyScan();if(key<11&&key>0&&flag==1){first=first*10+key;key=0;display(first);}delay10ms(20);KeyScan();if(key>12&&key<=16){op=key;key=0;flag=2;}KeyScan();if(key<11&&key>0&&flag==2){second=second*10+key;key=0;display(second);}delay10ms(20);KeyScan();if(key==12){switch(op){case 13:result=first+second;break; case 14:result=first-second;break; case 15:result=first*second;break; case 16:result=first/second;break;}display(result);key=0;flag=1;}KeyScan();if(key==11)goto LOOP;}}。

基于51单片机的计算器设计程序代码(汇编)

基于51单片机的计算器设计程序代码(汇编)

DBUF EQU 30HTEMP EQU 40HYJ EQU 50H ;结果存放YJ1 EQU 51H ;中间结果存放GONG EQU 52H ;功能键存放ORG 00HSTART:MOV R3,#0 ;初始化显示为空MOV GONG,#0MOV 30H,#10HMOV 31H,#10HMOV 32H,#10HMOV 33H,#10HMOV 34H,#10HMLOOP:CALL DISP ;PAN调显示子程序WAIT:CALL TESTKEY ;判断有无按键JZ WAITCALL GETKEY ;读键INC R3 ;按键个数CJNE A,#0,NEXT1 ;判断是否数字键LJMP E1 ;转数字键处理NEXT1:CJNE A,#1,NEXT2LJMP E1NEXT2:CJNE A,#2,NEXT3LJMP E1NEXT3:CJNE A,#3,NEXT4LJMP E1NEXT4:CJNE A,#4,NEXT5LJMP E1NEXT5:CJNE A,#5,NEXT6LJMP E1NEXT6:CJNE A,#6,NEXT7LJMP E1NEXT7:CJNE A,#7,NEXT8LJMP E1NEXT8:CJNE A,#8,NEXT9LJMP E1NEXT9: CJNE A,#9,NEXT10LJMP E1NEXT10: CJNE A,#10,NEXT11 ;判断是否功能键LJMP E2 ;转功能键处理NEXT11:CJNE A,#11,NEXT12LJMP E2NEXT12:CJNE A,#12,NEXT13LJMP E2NEXT13:CJNE A,#13,NEXT14LJMP E2NEXT14:CJNE A,#14,NEXT15LJMP E2NEXT15: LJMP E3 ;判断是否清除键E1: CJNE R3,#1,N1 ;判断第几次按键LJMP E11 ;为第一个数字N1:CJNE R3,#2,N2LJMP E12 ;为第二个数字N2:CJNE R3,#3,N3LJMP E13 ;为第三个数字N3: LJMP E3 ;第四个数字转溢出E11:MOV R4,A ;输入值暂存R4 MOV 34H,A ;输入值送显示缓存MOV 33H,#10HMOV 32H,#10HLJMP MLOOP ;等待再次输入E12:MOV R7,A ;个位数暂存R7 MOV B,#10MOV A,R4MUL AB ;十位数ADD A,R7MOV R4,A ;输入值存R4MOV 32H,#10H ;输入值送显示缓存MOV 33H,34HMOV 34H,R7LJMP MLOOPE13:MOV R7,AMOV B,#10MOV A,R4MUL ABJB OV,E3 ;输入溢出ADD A,R7JB CY,E3 ;输入溢出MOV R4,AMOV 32H,33H ;输入值送显示缓存MOV 33H,34HMOV 34H,R7LJMP MLOOPE3: MOV R3,#0 ;按键次数清零MOV R4,#0 ;输入值清零MOV YJ,#0 ;计算结果清零MOV GONG,#0 ;功能键设为零MOV 30H,#10H ;显示清空MOV 31H,#10HMOV 32H,#10HMOV 33H,#10HMOV 34H,#10HLJMP MLOOPE2: MOV 34H,#10HMOV 33H,#10HMOV 32H,#10HMOV R0,GONG ;与上次功能键交换MOV GONG,AMOV A,R0CJNE A,#10,N21 ;判断功能键LJMP JIA ;”+"N21: CJNE A,#11,N22LJMP JIAN ;"-"N22:CJNE A,#12,N23LJMP CHENG ;"*”N23:CJNE A,#13,N24LJMP CHU ;”/”N24:CJNE A,#0,N25LJMP FIRST ;首次按功能键N25:LJMP DEN ;”=”N4:LJMP E3FIRST: MOV YJ,R4 ;输入值送结果MOV R3,#0 ;按键次数清零LJMP DISP1 ;结果处理JIA:MOV A,YJ ;上次结果送累加器ADD A,R4 ;上次结果加输入值JB CY,N4 ;溢出MOV YJ,A ;存本次结果MOV R3,#0 ;按键次数清零LJMP DISP1JIAN:MOV A,YJSUBB A,R4 ;上次结果减输入值JB CY,N4 ;负数溢出MOV YJ,AMOV R3,#0LJMP DISP1CHENG:M OV A,YJMOV B,AMOV A,R4MUL AB ;上次结果乘输入值JB OV,N4 ;溢出MOV YJ,ALJMP DISP1CHU:MOV A,R4MOV B,AMOV A,YJDIV AB ;上次结果除输入值MOV YJ,AMOV R3,#0LJMP DISP1DEN:MOV R3,#0LJMP DISP1DISP1:MOV B,#10MOV A,YJ ;结果送累加器DIV AB ;结果除10MOV YJ1,A ;暂存”商”MOV A,B ;取个位数MOV 34H,A ;个位数送显示缓存MOV A,YJ1JZ DISP11 ;结果是否为一位数MOV B,#10MOV A,YJ1DIV ABMOV YJ1,AMOV A,BMOV 33H,A ;十位送显示缓存MOV A,YJ1JZ DISP11 ;结果是否为二位数MOV 32H,A ;百位数送显示缓存DISP11: LJMP MLOOPDISP:MOV R0,#DBUF ;显示子程序MOV R1,#TEMP+4MOV R2,#5DP10:MOV DPTR,#SEGTABMOV A,@R0MOVC A,@A+DPTRMOV @R1,AINC R0DEC R1DJNZ R2,DP10MOV R0,#TEMPDP12:MOV A,@R0MOV P0,Aclr P2。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档