本次出租车计价器设计以AT89C52单片机为中心,采用AMPIRE28*64液晶屏显示出租车计价单价、里程数和金额;采用时钟芯片DS1302来显示时间和在系统需要时进行计时。其中有三个按键代表“开始/暂停”、“清零”和设置“白天/黑夜”。
实验要求 基本功能 1)显示: 可以显示 单价、里程、总金额 2)停车计费功能:中途因故停车超过5分钟后每分钟按当时单价的50%收费 3)自动分时计费功能:白天和夜间应能自动更换单价 4)性能 里程误差小于2% 扩展功能 1)可增加时钟功能 2)可增加数据掉电保护功能 已完成显示、分时计费、时钟三个功能,另外增添了暂停和清零功能。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载) AMPIRE128*64液晶显示屏 按键电路的设计
话不多说,直接上单片机代码 - #include<reg52.h>
- #include<intrins.h>
- #include"lcd12864.c"
- #include"code.h"
- #include"ds1302.c"
- #include"display.c"
- sbit P34=P3^4; //按钮
- sbit P33=P3^3; //按钮
- sbit P12=P1^2; //灯
- float p,price,distance_km,money; //路程,金额
- unsigned int b,n;
- bit flag=1;
- voidmain(void) //主函数
- {
- init_lcd(); //液晶显示屏
- clearscreen(0); //清屏
- setline(0); //起始行
- TMOD=0x01; //方式1 定时功能
- TH0=0x3c; //00111100
- TL0=0xaf; //10101111 50ms计数一次
- IE=0x87;
- IT0=1;
- IP=0x01;
- distance_km=0; //路程=0
- Init_DS1302(); //时钟芯片
- while(1)
- {
- if(flag)
- {
- TR0=0;
- P12=1;
- price=p;
- display(price);
- display1(distance_km); //显示路程
- display2(money); //显示金额
- }
- else
- {
- TR0=1; //T0中断
- P12=0; //灯亮
- price=p;
- display(price);
- display1(distance_km); //显示路程
- display2(money); //显示金额
- }
- displayc(1,0,0*16,dan); //显示“单”
- displayc(1,0,1*16,jia); //显示“价”
- displaye(1,0,4*8,num,15); //显示“:”
- displayc(1,3,0*16,li); //显示“里”
- displayc(1,3,1*16,chen); //显示“程”
- displayc(1,3,2*16,shu); //显示“数”
- displaye(1,3,6*8,num,15); //显示“:”
- displayc(1,6,0*16,jin); //显示“金”
- displayc(1,6,1*16,e); //显示“额”
- displaye(1,6,4*8,num,15); //显示“:”
- }
- }
- void timer1(void)interrupt 1 //定时器0中断
- {
- TH0=0x3c; //00111100
- TL0=0xaf; //10101111 50ms计数一次
- b++;
- if(b==10)
- {
- if(P34==1)
- {
- p=1.5;
- distance_km+=0.1; //路程+0.1
- if(distance_km<=3)money=5; //小于3km,计价5元
- elsemoney=4.9+(distance_km-3)*p; //大于3km部分1.5元每km
- b=0;
- }
- else
- {
- p=2;
- distance_km+=0.1; //路程+0.1
- if(distance_km<=3)money=6; //小于3km,计价6元
- elsemoney=5.9+(distance_km-3)*p; //大于3km部分2元每km
- b=0;
- }
- }
- }
- void timer0(void)interrupt 0 //外部中断0 按键1
- {
- flag=~flag;
- }
- void timer2(void)interrupt 2 //外部中断1 按键2
- {
- distance_km=0; //路程=0
- money=0;
- price=p;
- }
- LCD12864.C
- #include<reg52.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit cs1=P2^0;
- sbit cs2=P2^1;
- sbit EN=P2^2;
- sbit RW=P2^3;
- sbit RS=P2^4;
- void delay(uchar i)
- {
- while(i--); //延时
- }
- void readbusy() //忙碌
- {
- P0=0x00; //00000000
- RS=0;
- RW=1; //读出忙标志(BF)及地址记数器(AC)的状态
- EN=1; //读写使能,下降沿锁定数据
- while(P0&0x80); //当BF=0,while(0),当BF=1,while(1)
- EN=0; //EN=1-0,配合RW写数据或指令
- }
- void lcd_wcmd(uchar cmd)
- {
- readbusy(); //判断忙碌
- RS=0;
- RW=0; //MPU写指令到指令暂存器
- P0=cmd;
- EN=1; //配合RS进行读数据或指令
- _nop_(); //延时2个指令周期
- _nop_();
- EN=0; //EN=1-0,配合RW写数据或指令
- }
- void lcd_wdat(uchar dat)
- {
- readbusy(); //判断忙碌
- RS=1;
- RW=0; //MPU写数据到数据暂存器
- P0=dat;
- EN=1; //配合RS进行读数据或指令
- _nop_(); //延时2个指令周期
- _nop_();
- EN=0; //EN=1-0,配合RW写数据或指令
- }
- void setpage(uchar page)
- {
- page=0xb8|page; //起始页 10111000
- lcd_wcmd(page); //写指令
- }
- void setline(uchar line)
- {
-
- line=line&0x3f; //最终行 00000111
- line=line|0xc0; //起始行 11000000
- lcd_wcmd(line); //写指令
- }
- void setcolumn(uchar column)
- {
- column=column&0x3f; //最终列 00111111
- column=column|0x40; //起始列 01000000
- lcd_wcmd(column); //写指令
- }
- void setonoff(uchar onoff)
- {
- onoff=0x3e|onoff; //00111110
- lcd_wcmd(onoff); //写指令
- }
- void selectscreen(uchar screen) //选择屏幕
- {
- switch(screen)
- {
- case0:cs1=0;delay(2);cs2=0;delay(2);break; //全屏
- case1:cs1=0;delay(2);cs2=1;delay(2);break; //左屏
- case2:cs1=1;delay(2);cs2=0;delay(2);break; //右屏
- default:break;
- }
- }
- void clearscreen(uchar screen) //清屏
- {
- uchari,j;
- selectscreen(screen); //选屏
- for(i=0;i<8;i++)
- {
- setpage(i); //0-7页
- setcolumn(0); //起始行
- for(j=0;j<64;j++)
- {
- lcd_wdat(0x00); //写数据 0-63
- }
- }
- }
- void init_lcd()
- {
- readbusy();
- selectscreen(0); //全屏
- setonoff(0); //关
- selectscreen(0); //全屏
- setonoff(1); //开
- selectscreen(0); //全屏
- clearscreen(0); //清屏
- setline(0); //起始行
- }
- Code.h
- unsigned char code dan[]={0x00,0x00,0x00,0xf8,0x4b,0x4e,0x4c,0xf8,0x4c,0x4e,0x4b,0xf8,0x00,0x00,0x00,0x00,
- 0x00,0x08,0x08,0x0b,0x0a,0x0a,0x0a,0xff,0x0a,0x0a,0x0a,0x0b,0x08,0x08,0x00,0x00};
- unsigned char code jia []={0x00,0x20,0x30,0x18,0xfc,0x07,0x20,0x30,0xf8,0x0c,0x07,0x0c,0xf8,0x30,0x20,0x00,
- 0x00,0x00,0x00,0x00,0xff,0x00,0xf0,0x1c,0x07,0x00,0x00,0x00,0xff,0x00,0x00,0x00};
- unsigned char code li []={0x00,0x00,0xFE,0x92,0x92,0x92,0x92,0xFE,0x92,0x92,0x92,0x92,0xFE,0x00,0x00,0x00,
- 0x40,0x40,0x44,0x44,0x44,0x44,0x44,0x7F,0x44,0x44,0x44,0x44,0x44,0x40,0x40,0x00};
- unsigned char code chen []={0x24,0x24,0xA4,0xFE,0x23,0x22,0x00,0x3E,0x22,0x22,0x22,0x22,0x22,0x3E,0x00,0x00,
- 0x08,0x06,0x01,0xFF,0x01,0x06,0x40,0x49,0x49,0x49,0x7F,0x49,0x49,0x49,0x41,0x00};
- unsigned char code shu []={0x90,0x52,0x34,0x10,0xFF,0x10,0x34,0x52,0x80,0x70,0x8F,0x08,0x08,0xF8,0x08,0x00,
- 0x82,0x9A,0x56,0x63,0x22,0x52,0x8E,0x00,0x80,0x40,0x33,0x0C,0x33,0x40,0x80,0x00};
- unsigned char code jin []={0x00,0x80,0x80,0x40,0x20,0x50,0x48,0x44,0xC3,0x44,0x48,0x50,0x20,0x40,0x80,0x80,
- 0x00,0x40,0x40,0x42,0x4A,0x72,0x42,0x42,0x7F,0x42,0x42,0x62,0x5A,0x42,0x40,0x40};
- unsigned char code e []={0x00,0x00,0x8C,0x44,0xB5,0x26,0xA4,0x64,0x0C,0x02,0xF2,0x1A,0xD6,0x12,0xF2,0x02,
- 0x00,0x10,0x08,0xFC,0x4A,0x49,0x4A,0xFC,0x08,0x80,0x4F,0x30,0x0F,0x10,0x2F,0xC0};
- unsigned char code gong []={0x00,0x00,0x80,0x40,0x20,0x18,0x06,0x80,0x00,0x07,0x18,0x20,0x40,0x80,0x00,0x00,
- 0x00,0x01,0x00,0x20,0x70,0x28,0x26,0x21,0x20,0x20,0x24,0x38,0x60,0x00,0x01,0x01};
- unsigned char code yuan []={0x00,0x20,0x20,0x22,0x22,0x22,0xE2,0x22,0x22,0x22,0xE2,0x22,0x22,0x22,0x20,0x20,
- 0x00,0x80,0x40,0x20,0x10,0x0C,0x03,0x00,0x00,0x00,0x3F,0x40,0x40,0x40,0x40,0x78};
- unsigned int code num[16][16]=
- {
- {0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00}, //0
- {0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00}, //1
- {0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00}, //2
- {0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00}, //3
- {0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00}, //4
- {0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00}, //5
- {0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00}, //6
- {0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00}, //7
- {0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00}, //8
- {0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00}, //9
- {0x00,0x10,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x7F,0x48,0x0C,0x53,0x61,0x41}, //k
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x7F,0x41,0x01,0x7F,0x41,0x01,0x7E}, //m
- {0x00,0x00,0x00,0x80,0xe0,0x38,0x0f,0x00,0x00,0xf0,0x1c,0x07,0x00,0x00,0x00,0x00}, // /
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, // -
- {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00}, // .
- {0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x61,0x00,0x00,0x00}}; // :
- Display.c
- void displayc(unsigned char screen,unsignedchar page,unsigned char column,unsigned char table[]) //写汉字
- //选择屏幕,页,列,数组
- {
- unsignedchar i;
- selectscreen(screen); //选择屏幕
- setpage(page); //选择页
- setcolumn(column); //选择列
- for(i=0;i<16;i++)//上半部分
- {
- lcd_wdat(table);_nop_(); //写数据 0-15
- }
- setpage(page+1); //页+1
- setcolumn(column); //选择列
- for(i=0;i<16;i++)//下半部分
- {
- lcd_wdat(table[i+16]);_nop_(); //写数据 16-31
- }
- }
- void displaye(unsigned char screen,unsignedchar page,unsigned char column,unsigned int table[][16],unsigned char n) //写数字
- //选择左右屏幕,页,列,数组,数字/汉字
- {
- unsignedchar i;
- selectscreen(screen); //选择屏幕
- setpage(page); //选择页
- setcolumn(column); //选择列
- for(i=0;i<8;i++) //上半部分
- {
- lcd_wdat(table[n]);_nop_(); //选择第n行,i 0-7循环显示一个数字
- }
- setpage(page+1); //页+1
- setcolumn(column); //选择列
- for(i=0;i<8;i++) //下半部分
- {
- lcd_wdat(table[n][i+8]);_nop_(); //选择第n行,i 8-15循环显示一个数字
- }
- }
- void display(float price) //单价
- {
- unsignedchar x,y,n;
- n=(int)(price);
- x=n;
- y=(price-n)*10;
- displaye(1,0,6*8,num,x);
- displaye(1,0,7*8,num,14);
- displaye(2,0,0*8,num,y);
- displayc(2,0,1*8,yuan);
- displaye(2,0,3*8,num,12);
- displayc(2,0,2*16,gong);
- displayc(2,0,3*16,li);
- }
- void display1(float distance_km) //显示路程
- {
- unsignedchar counta,countb,countc,countd,n;
- n=(int)(distance_km); //强行转换成整型
- counta=n/100;
- countb=n%100/10;
- countc=n%10;
- countd=(distance_km-n)*10;
- displaye(1,3,7*8,num,counta);
- displaye(2,3,0*8,num,countb);
- displaye(2,3,1*8,num,countc);
- displaye(2,3,2*8,num,14);
- displaye(2,3,3*8,num,countd);
- displayc(2,3,2*16,gong);
- displayc(2,3,3*16,li);
- }
- void display2(float money) //金额
- {
- unsignedchar a,b,c,d,n;
- n=(int)(money);
- a=n/100;
- b=n%100/10;
- c=n%10;
- d=(money-n)*10;
- displaye(2,6,1*8,num,a);
- displaye(2,6,2*8,num,b);
- displaye(2,6,3*8,num,c);
- displaye(2,6,4*8,num,14);
- displaye(2,6,5*8,num,d);
- displayc(2,6,3*16,yuan);
- }
复制代码
单片机综合实验51hei.docx
(554.39 KB, 下载次数: 101)
protect和keil源文件.rar
(91.61 KB, 下载次数: 186)
|