源程序
- 格式:doc
- 大小:99.50 KB
- 文档页数:20
源程序#include<reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned int#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();_nop_();};uchar code table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; sbit exter=P3^3; //外部中断sbit key0=P1^0; //清零sbit key1=P1^1; //切换/+sbit key2=P1^2; //-sbit key3=P1^3; //功能键sbit p30=P3^0; //数码管各位控制sbit p31=P3^1;sbit p32=P3^2;sbit p34=P3^4;sbit p35=P3^5;sbit p36=P3^6;sbit p37=P3^7;sbit SDA=P2^3; //IIC引脚sbit SCL=P2^2;uint inter,aa,bb,temp,temp1;uint zongjine,licheng,dengdai;uint key3num,qiehuantemp,delaytemp;uchar danjia1,danjia2,danjia3,danjia,qibu;void delay(uint x) //延时时基为1ms {int i,j;for(i=x;i>0;i--)for(j=340;j>0;j--);}void start() //IIC开始位{SDA = 1;SCL = 1;delayNOP();SDA = 0;delayNOP();SCL = 0;}void stop() // IIC停止位{SDA = 0;delayNOP();SCL = 1;delayNOP();SDA = 1;}void respons() //IIC应答位{uchar i;SCL=1;delayNOP();while((SDA==1)&&(i<250))i++;SCL=0;delayNOP();}uchar read_byte() // 从EEPROM读到MCU {uchar i,j;for(i=0;i<8;i++){SCL=1;j<<=1;j|=SDA;SCL=0;}return(j);}void write_byte(uchar date) // 从MCU写到EEPROM {uchar i,temp;temp=date;for(i=0;i<8;i++){temp=temp<<1;SCL=0;delayNOP();SDA=CY;delayNOP();SCL=1;delayNOP();}SCL=0;delayNOP();SDA=1;delayNOP();}void write_data(uchar addr, uchar date) // 在指定地址addr处写入数据date {start();write_byte(0xa0);respons();write_byte(addr);respons();write_byte(date);respons();stop();}uchar read_data(uchar addr) // 在指定地址addr读取数据{uchar date;start();write_byte(0xa0);respons();write_byte(addr);respons();start();write_byte(0xa1);respons();date=read_byte();stop();return date;}void display(uint zongjine0,uint licheng0,uint danjia0) //数码管显示{uint jbai,jshi,jge,lshi,lge,dshi,dge;uint numwei,numshu;//数码管位置分配jbai=zongjine0/100;jshi=zongjine0%100/10;jge=zongjine0%100%10;lshi=licheng0/10;lge=licheng0%10;dshi=danjia0/10;dge=danjia0%10;//数码管动态显示if(aa){aa=0;numshu++;if(numshu==7)numshu=0;P3=0xff;switch(numwei){case 0:p30=0;P0=table[jbai];break;case 1:p31=0;P0=table[jshi]&0x7f;break;case 2:p32=0;P0=table[jge];break;case 3:p34=0;P0=table[lshi];break;case 4:p35=0;P0=table[lge];break;case 5:p36=0;P0=table[dshi]&0x7f;break;case 6:p37=0;P0=table[dge];break;}numwei++;if(numwei==7)numwei=0;}}void keyscan() //键盘扫描{if(key3==0) //功能键调节{delay(5);if(key3==0){key3num=1;while(!key3);delay(5);while(!key3);while(key3num){if(key3num==1) //调白天单价{if(key1==0){delay(5);if(key1==0){danjia1++;if(danjia1==100) danjia1=0;while(!key1);delay(5);while(!key1);}}if(key2==0){delay(5);if(key2==0){danjia1--;if(danjia1==-1) danjia1=99;while(!key2);delay(5);while(!key2);}}display(1,0,danjia1);}if(key3num==2) //调夜晚单价{write_data(1,danjia1);if(key1==0){delay(5);if(key1==0){danjia2++;if(danjia2==100) danjia2=0;while(!key1);delay(5);while(!key1);}}if(key2==0){delay(5);if(key2==0){danjia2--;if(danjia2==-1) danjia2=99;while(!key2);delay(5);while(!key2);}}display(2,0,danjia2);}if(key3num==3)//调等待单价{write_data(2,danjia2);if(key1==0){delay(5);if(key1==0){danjia3++;if(danjia3==100) danjia3=0;while(!key1);delay(5);while(!key1);}}if(key2==0){delay(5);if(key2==0){danjia3--;if(danjia3==-1) danjia3=99;while(!key2);delay(5);while(!key2);}}display(3,0,danjia3);}if(key3num==4) //调起步价{write_data(3,danjia3);if(key1==0){delay(5);if(key1==0){qibu++;if(qibu==100) qibu=0;while(!key1);delay(5);while(!key1);}}if(key2==0){delay(5);if(key2==0){qibu--;if(qibu==-1) qibu=99;while(!key2);delay(5);while(!key2);}}display(4,0,qibu);}if(key3num==5) //退出功能键{write_data(4,qibu);key3num=0;}if(key3==0){delay(5);if(key3==0){key3num++;while(!key3);delay(5);while(!key3);}}}}}}void init(){SDA=1;SCL=1;zongjine=0;licheng=0;dengdai=0;danjia1=read_data(1);danjia2=read_data(2);danjia3=read_data(3);qibu=read_data(4);aa=0; //数码管动态扫描的定时器时基个数bb=0; //判断是否等待的时基个数inter=0;EA=1; //开总中断EX1=1; //开外部中断1IT1=1; //触发方式下降沿TMOD=0x01;TH0=(65536-1000)/256;TL0=(65536-1000)%256;ET0=1; //开定时器T0中断TR0=1; //开定时器T0P3=0x08;P0=table[0];}void jisuan(){if(licheng>3)zongjine=qibu+(licheng-3)*danjia+dengdai*danjia3; //金额计算elsezongjine=qibu+dengdai*danjia3; //起步公里内金额计算}void qiehuan(){if(key1==0) //白天夜晚切换{delay(5); //键盘防抖if(key1==0)qiehuantemp=!qiehuantemp;while(!key1);delay(5);while(!key1);}if(qiehuantemp==0)danjia=danjia2;if(qiehuantemp==1)danjia=danjia1;}void main(){init();qiehuantemp=1;key3num=0;while(1){qiehuan(); //切换白天夜晚单价jisuan(); //计算总金额display(zongjine,licheng,danjia);keyscan();if(key0==0) //清零键init();}}void inter1() interrupt 2 //脉冲中断{delay(5); //if(exter==0) //{ //IT1=1;inter++;if(inter==5){inter=0;licheng++;}} //while(!exter); //delay(5); //while(!exter); //}void timer0() interrupt 1{TH0=(65536-1000)/256;TL0=(65536-1000)%256;aa++;bb++;temp1=licheng; //测试是否进入等待if(bb==10000) //10s无反应进入等待计费{bb=0;if(temp=temp&temp1)dengdai++;temp=licheng;}}。