[size=12.0000pt]一、系统方案 系统设计将软件设计内容分为了五大模块,分别是进入、驶出传感器检测、液晶显示、LED模块、蜂鸣器报警电路、按键模块,系统将其进行分别设计,接通电源之后,单片机分别向LCD1602液晶显示器和按键发出初始化指令,初始化结束后,进行按键扫描,若检测到按键信号,处理按键对应操作,无论是否有按键信号,都会继续进行下一步,然后进入、驶出传感器检测车辆数量,如果车辆数大于16,蜂鸣器报警,否则停止报警,并在LCD1602液晶显示器上进入、驶出数量,之后返回到LCD1602液晶显示器、和按键初始化,继续这个流程,直到断开电源结束。 二、硬件设计 原理图如下: 三、单片机软件设计 1、首先是系统初始化: beep = 1; init_1602(); write_string(1,0,"IN : OUT:"); write_string(2,0,"Car: P:"); write_sfm2(1,4,num_jin); write_sfm2(1,12,num_chu); write_sfm2(2,4,num_car); write_sfm2(2,12,16-num_car); write_74hc595(0); 2、液晶显示程序 /******************************************************************** * 名称 : delay_uint() * 功能 : 小延时。 * 输入 : 无 * 输出 : 无 ***********************************************************************/ void delay_uint(uint q) { while(q--); } /******************************************************************** * 名称 : write_com(uchar com) * 功能 : 1602命令函数 * 输入 : 输入的命令值 * 输出 : 无 ***********************************************************************/ void write_com(uchar com) { e=0; rs=0; rw=0; P0=com; delay_uint(3); e=1; delay_uint(25); e=0; } /******************************************************************** * 名称 : write_data(uchar dat) * 功能 : 1602写数据函数 * 输入 : 需要写入1602的数据 * 输出 : 无 ***********************************************************************/ void write_data(uchar dat) { e=0; rs=1; rw=0; P0=dat; delay_uint(3); e=1; delay_uint(25); e=0; } /******************************************************************** * 名称 : write_sfm2(uchar hang,uchar add,uchar date) * 功能 : 显示2位十进制数,如果要让第一行,第五个字符开始显示"23" ,调用该函数如下 write_sfm1(1,5,23) * 输入 : 行,列,需要输入1602的数据 * 输出 : 无 ***********************************************************************/ void write_sfm2(uchar hang,uchar add,uint date) { if(hang==1) write_com(0x80+add); else write_com(0x80+0x40+add); if(date >= 100) { write_data(0x30+date/100%10); write_data(0x30+date/10%10); } else { write_data(' '); write_data(0x30+date/10%10); } write_data(0x30+date%10); } /******************************************************************** * 名称 : write_string(uchar hang,uchar add,uchar *p) * 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下 write_string(1,5,"ab cd ef;") * 输入 : 行,列,需要输入1602的数据 * 输出 : 无 ***********************************************************************/ void write_string(uchar hang,uchar add,uchar *p) { if(hang==1) write_com(0x80+add); else write_com(0x80+0x40+add); while(1) { if(*p == '\0') break; write_data(*p); p++; } } /******************************************************************** * 名称 : clear_1602() * 功能 : 清除1602显示 * 输入 : 无 * 输出 : 无 ***********************************************************************/ void clear_1602() { write_string(1,0," "); write_string(2,0," "); } /***********************lcd1602上显示特定的字符************************/ void write_zifu(uchar hang,uchar add,uchar date) { if(hang==1) write_com(0x80+add); else write_com(0x80+0x40+add); write_data(date); } /******************************************************************** * 名称 : init_1602() * 功能 : 初始化1602液晶 * 输入 : 无 * 输出 : 无 ***********************************************************************/ void init_1602() { write_com(0x38); write_com(0x0c); write_com(0x06); // write_string(1,0," Alcohol: 00mg/L"); // write_string(2,0," BaoJing: 80mg/L"); // write_sfm2(2,9,s_dengji); //显示酒精等级 } 3、按键检测程序 void key() //独立按键程序 { if(num_car==16) { beep=0;// { beep=0; delay_1ms(200); beep=1;} }else{ beep = 1; } if(!K1) // 汽车进入 { delay_1ms(20); if(!K1) { while(!K1) ; if(num_car<16) { num_car++; if(num_jin<=255) { num_jin++;} } write_sfm2(1,4,num_jin); write_sfm2(1,12,num_chu); write_sfm2(2,4,num_car); write_sfm2(2,12,16-num_car); write_74hc595(num_2_led(num_car)); } } if(!K2) // // 汽车驶出 { delay_1ms(20); if(!K2) { while(!K2); if(num_car>=1) { num_car--; if(num_chu<=255) { num_chu++;} } write_sfm2(1,4,num_jin); write_sfm2(1,12,num_chu); write_sfm2(2,4,num_car); write_sfm2(2,12,16-num_car); write_74hc595(num_2_led(num_car)); } } } 4、核心算法程序 void write_74hc595(unsigned int num) { int i; ST = 0; for(i=0; i<16; i++) { SH = 0; if (num & 0x0001) { DS = 1; } else { DS = 0; } SH = 1; num >>= 1; } ST = 1; } unsigned int num_2_led(unsigned int num) { int i; unsigned int ret=0; if (num > 16) return 0xFFFF; for(i=0;i<num;i++) { ret |= 1<<i; } return ret; } [size=12.0000pt]四、proteus仿真设计 Proteus软件是一款应用比较广泛的工具,它可以在没有硬件平台的基础上通过自身的软件仿真出硬件平台的运行情况,这样就可以通过软件仿真来验证我们设计的方案有没有问题,如果有问题,可以重新选择器件,连接器件,直到达到我们设定的目的,避免我们搭建实物的时候,如果当初选择的方案有问题,我们器件都已经焊接好了,再去卸载下去,再去焊接新的方案的器件,测试,这样会浪费人力和物力,也给开发者带来一定困惑,Proteus仿真软件就很好的解决这个问题,我们在设计之初,就使用该软件进行模拟仿真,测试,选择满足我们设计的最优方案。最后根据测试没问题的仿真图纸,焊接实物,调试,最终完成本设计的作品。
|