条形码检测装置

上传人:仙*** 文档编号:34894441 上传时间:2021-10-24 格式:DOC 页数:27 大小:122.50KB
返回 下载 相关 举报
条形码检测装置_第1页
第1页 / 共27页
条形码检测装置_第2页
第2页 / 共27页
条形码检测装置_第3页
第3页 / 共27页
点击查看更多>>
资源描述
电子设计大赛报告书题目B:条形码检测装置 目录一、 设计要求3二、 方案选择与原理3三、 作品简介4四、 模块化设计41. 硬件部分42. 软件部分5(1) 信号处理5(2) 查表程序6(3) 显示和数据库程序8(4) 整体程序14五、 心得体会26六、 参考资料26一、设计要求制作一个黑白条码检测装置,能够扫描、识别黑白条形图案,显示相应的信息。不得采用现成的条码识别设备和模块。基本考核点:1、 自制10个不同的条形图形,定义为0# - 9#,标注在图形的背面,使用自制扫描装置,应能正确的区分和显示其号码(能扫描国际标准条码者,可免测该项);2、 采用手移动或条码图形移动方式均可,考察是否易于操作,出错情况;3、 有声光的提示功能(如当前扫描位置和成功扫描后的蜂鸣声,可增加声调的变化)。扩展考察点:1、 扫描方式为自动方式,即不是用人手或条码的移动,而是靠机械的运动完成扫描;2、 能扫描一种类型的国际标准条形码(如UPC码、EAN码等),正确获得相应信息,并显示出来;3、 可以扫描多种系列的条码;4、 增加扫描装置与被扫条码间的距离,仍可以正确识别,按距离远近评价;5、 具有一定的抗破损能力,如人为遮挡条码的一部分或改变条码的清晰度等;6、 具有结合条码应用的配套的显示界面、数据库等;7、 其他实用和创新的功能。二、方案选择与原理黑白两种颜色对光线的反射强度是不同的,光线照射到黑颜色时反射的光弱而照到白颜色的反射光强。利用这个特点我们用激光头和接收管搭建电路。当激光头发出的光线照射到白条上由于反射的光线强,接收管的输出为低电平。当激光头发出的光线照射到黑条上时接收管的输出为高电平。基于这个原理,当我们在扫一个黑白相间的条码的时候接收管就会输出占空比不同的带有高低电平的方波,把这些方波经过I/O口传送到单片机中经过计算后可以在显示器上显示条码相应的信息。在软件设计方面,为了测量高电平方波的宽度,我们第一个想到的是定时器在上升沿的时候定时器开始计时,下降沿的时候引发中断定时器停止计时。这是定时器记下的时间就是方波的宽度,从而达到测量方波的目的。但我们发现这个方法无论是从操作还是软件编程方面都比较复杂。所以我们改为用第二种方法:在高电平的时候变量count1自加,这个方法程序比较简单,也为后来的扩展提供了更好的基础。这个方法在下面软件部分会详细介绍。三、作品简介 该作品操作简单,由于采用的是对采样信号进行比值的计算的方法,所以用户在使用的时候不用刻意规定自己的手速,或快或慢只要保证匀速即可,这就使操作得到了很大的方便。该作品还具有较强的功能,上电后显示器会提示用户选择条形码的类型。例如:扫ISBN码请按键盘1,扫二进制码请按键盘2。用户可根据自己的需要选择条码的类型。在扫码成功后,显示器会提提示用户按键盘3可以调用数据库以便显示该产品的详细信息,在商品的数据库里有产品的名称价格等详细信息,这些都可以通过液晶显示器显示出来。在显示成功后用户按复位键即可立即对下一个条码进行扫描。另外,该作品还有纠错功能,在用户操作错误的情况下显示器会提示“扫描错误,请重新扫描”,这样,就大大提高了扫描的准确性!四、模块化设计1、硬件部分该作品的硬件电路有激光头的发射电路和接收管的接受电路组成电路图如下:发射电路如电路图,调制管下拉电阻,输出180khz的频率,经过三极管8050放大之后驱动发射管,使发射管以180KHZ的频率,20%-30%的占空比发射出650nm的光线,经过反射后,接收管接收到反射回来的黑白信号,输出高低电平,由单片机识别,从而达到识别的功能。 接下来接收管的电路,接收管为什么要上拉4.7k左右的电阻呢,这是因为如果不接这个上拉电阻就会引起逻辑混乱,如果不接这个上拉电阻,很多情况会“黑白不分”,也就是无论照到黑的还是白的,接收管接收到的都是一个电平;上拉电阻旁边的指示灯,只是一个指示作用,让我们比较直观的看到接收管接收回来的信号明显的变化。2、软件部分 在接受管收到方波之后,这些方波要经过单片机的计算处理来显示条码相关的信息。在这里我简述一下我们对软件设计的思想和算法:程序分为四大部分:信号处理、查表、送显、数据库。(1)信号处理: 我们定义了一个变量count1,当外界信号为高电平的时候(即扫到黑条)count1自加,当外界信号变成低电平的时候(即扫到白条)count1停止自加同时把累加得到的数值赋给另外一个变量divisor,在下个高电平来的时候count1仍然自加,然后将这时的自加值除以上次的division,得到的比值送到数组lounth7里。信号处理程序如下:while(1) while(ch452_key=0x68)if (WAV) count1+; delay(1); /延时1毫秒 if (WAV=0&count1) ratio=(count1/divisor); divisor=count1; count1=0; if(ratio0&ratio0&lounthm0.7&lounthm1.6&lounthm2.3时lounthm=2。依次类推,这样就大大提高了条码的可读性,解决了这个问题后,下面就可以根据数组里存的值显示相关的数据了,查表程序如下所示:void registration()int m;for(m=0;m0&lounthm0.7&lounthm1.6&lounthm0;n-)/for循环配合空语句实现软件延时x=ch452_key;if(x) break; void LCD_Send()LCD_locate(1); /调用显示定位函数在第2个显示位开始存放switch(j)case 0: LCD_Ddata_Send(0x30);break;/显示0 case 1: LCD_Ddata_Send(0x31);break;/显示1 case 2: LCD_Ddata_Send(0x32);break;/显示2 case 3: LCD_Ddata_Send(0x33);break;/显示3case 4: LCD_Ddata_Send(0x34);break;/显示4 case 5: LCD_Ddata_Send(0x35);break;/显示5 case 6: LCD_Ddata_Send(0x36);break;/显示6 case 7: LCD_Ddata_Send(0x37);break;/显示7 case 8: LCD_Ddata_Send(0x38);break;/显示8case 9: LCD_Ddata_Send(0x39);break;/显示9case 10:LCD_Ddata_Send(0xb1,0xb1);break;void custom()void scanf();LCD_locate(0);LCD_Ddata_Send(0xb2,0xfa);LCD_Ddata_Send(0xc6,0xb7);LCD_Ddata_Send(0xc3,0xfb);LCD_Ddata_Send(0xb3,0xc6);LCD_Ddata_Send(0x3a);switch(j)case 0: LCD_Ddata_Send(0xb6,0xfa);/耳 LCD_Ddata_Send(0xbb,0xfa); /机 break; case 1: LCD_Ddata_Send(0xc3,0xab); / 毛LCD_Ddata_Send(0xbd,0xed); /巾break; case 2: LCD_Ddata_Send(0xd1,0xc0); /牙 LCD_Ddata_Send(0xb8,0xe0); /膏 break; case 3:LCD_Ddata_Send(0xca,0xd6); /手LCD_Ddata_Send(0xb1,0xed); /表break;case 4: LCD_Ddata_Send(0xb1,0xfd); /饼 LCD_Ddata_Send(0xb8,0xc9); /干 break; case 5:LCD_Ddata_Send(0xc4,0xcc); /奶LCD_Ddata_Send(0xb2,0xe8); /茶break; case 6: LCD_Ddata_Send(0xbf,0xc9); /可LCD_Ddata_Send(0xc0,0xd6); /乐 break; case 7: LCD_Ddata_Send(0xc2,0xcc); /绿 LCD_Ddata_Send(0xb2,0xe8); /茶 break; case 8: LCD_Ddata_Send(0xcb,0xe1); /酸 LCD_Ddata_Send(0xb2,0xe8); /奶 break;case 9: LCD_Ddata_Send(0xcf,0xe3); /香 LCD_Ddata_Send(0xcb,0xae); /水 break;case 10:LCD_Ddata_Send(0xb1,0xb1);break;LCD_locate(8);LCD_Ddata_Send(0xb2,0xfa);LCD_Ddata_Send(0xc6,0xb7);LCD_Ddata_Send(0xbc,0xdb);LCD_Ddata_Send(0xb8,0xf1);LCD_Ddata_Send(0x3a);switch(j)case 0: LCD_Ddata_Send(0x37); LCD_Ddata_Send(0x35);/价格break; case 1: LCD_Ddata_Send(0x36);break;/显示1 case 2: LCD_Ddata_Send(0x38);break;/显示2 case 3: LCD_Ddata_Send(0x36); LCD_Ddata_Send(0x30);break;/显示3case 4: LCD_Ddata_Send(0x35);break;/显示4 case 5: LCD_Ddata_Send(0x31); LCD_Ddata_Send(0x30); break;/显示5 case 6: LCD_Ddata_Send(0x33);break;/显示6 case 7: LCD_Ddata_Send(0x32);break;/显示7 case 8: LCD_Ddata_Send(0x35);break;/显示8case 9: LCD_Ddata_Send(0x39); LCD_Ddata_Send(0x30);break;/显示9case 10:LCD_Ddata_Send(0xb1,0xb1);break; LCD_Ddata_Send(0xd4,0xaa);while(1) if (ch452_key=0x69) LCD_com_Send(0x01);delay(500); scanf(); 整体程序如下#include C8051F020.h/包含C8051F020硬件信息的头文件#include absacc.h/包含绝对地址访问信息的头文件/数据定义头文件#include data_define.c/YLF12232操作函数#include YLF12232.c/CH452操作函数#include ch452x.c/设备初始化函数,在主程序中调用Init_Device()#include Init_Device.c/用P0口的P3.0sbit WAV = P30; sbit bee = P31; float count1=0,divisor=1,ratio=0,lounth7;int i=0,j,k;void delay(int z) int x,y; for(x=500;x1;x-) for(y=z;y1;y-);void error()void scanf();LCD_locate(0);LCD_Ddata_Send(0xcc,0xf5);LCD_Ddata_Send(0xc2,0xeb);LCD_Ddata_Send(0xd3,0xd0);LCD_Ddata_Send(0xce,0xf3);LCD_Ddata_Send(0x2c);LCD_locate(8);LCD_Ddata_Send(0xc7,0xeb);LCD_Ddata_Send(0xd6,0xd8);LCD_Ddata_Send(0xd0,0xc2);LCD_Ddata_Send(0xc9,0xa8);LCD_Ddata_Send(0xc3,0xe8);delay(1000); scanf();/查表函数void registration()int m;for(m=0;m0&lounthm0.7&lounthm1.6&lounthm0;n-)/for循环配合空语句实现软件延时x=ch452_key;if(x) break; void LCD_Send()LCD_locate(1); /调用显示定位函数在第2个显示位开始存放switch(j)case 0: LCD_Ddata_Send(0x30);break;/显示0 case 1: LCD_Ddata_Send(0x31);break;/显示1 case 2: LCD_Ddata_Send(0x32);break;/显示2 case 3: LCD_Ddata_Send(0x33);break;/显示3case 4: LCD_Ddata_Send(0x34);break;/显示4 case 5: LCD_Ddata_Send(0x35);break;/显示5 case 6: LCD_Ddata_Send(0x36);break;/显示6 case 7: LCD_Ddata_Send(0x37);break;/显示7 case 8: LCD_Ddata_Send(0x38);break;/显示8case 9: LCD_Ddata_Send(0x39);break;/显示9case 10:LCD_Ddata_Send(0xb1,0xb1);break; void custom()void scanf();LCD_locate(0);LCD_Ddata_Send(0xb2,0xfa);LCD_Ddata_Send(0xc6,0xb7);LCD_Ddata_Send(0xc3,0xfb);LCD_Ddata_Send(0xb3,0xc6);LCD_Ddata_Send(0x3a);switch(j)case 0: LCD_Ddata_Send(0xb6,0xfa);/耳 LCD_Ddata_Send(0xbb,0xfa); /机 break; case 1: LCD_Ddata_Send(0xc3,0xab); / 毛LCD_Ddata_Send(0xbd,0xed); /巾break; case 2: LCD_Ddata_Send(0xd1,0xc0); /牙 LCD_Ddata_Send(0xb8,0xe0); /膏 break; case 3:LCD_Ddata_Send(0xca,0xd6); /手LCD_Ddata_Send(0xb1,0xed); /表break;case 4: LCD_Ddata_Send(0xb1,0xfd); /饼 LCD_Ddata_Send(0xb8,0xc9); /干 break; case 5:LCD_Ddata_Send(0xc4,0xcc); /奶LCD_Ddata_Send(0xb2,0xe8); /茶break; case 6: LCD_Ddata_Send(0xbf,0xc9); /可LCD_Ddata_Send(0xc0,0xd6); /乐 break; case 7: LCD_Ddata_Send(0xc2,0xcc); /绿 LCD_Ddata_Send(0xb2,0xe8); /茶 break; case 8: LCD_Ddata_Send(0xcb,0xe1); /酸 LCD_Ddata_Send(0xb2,0xe8); /奶 break;case 9: LCD_Ddata_Send(0xcf,0xe3); /香 LCD_Ddata_Send(0xcb,0xae); /水 break;case 10:LCD_Ddata_Send(0xb1,0xb1);break;LCD_locate(8);LCD_Ddata_Send(0xb2,0xfa);LCD_Ddata_Send(0xc6,0xb7);LCD_Ddata_Send(0xbc,0xdb);LCD_Ddata_Send(0xb8,0xf1);LCD_Ddata_Send(0x3a);switch(j)case 0: LCD_Ddata_Send(0x37); LCD_Ddata_Send(0x35);/价格break; case 1: LCD_Ddata_Send(0x36);break;/显示1 case 2: LCD_Ddata_Send(0x38);break;/显示2 case 3: LCD_Ddata_Send(0x36); LCD_Ddata_Send(0x30);break;/显示3case 4: LCD_Ddata_Send(0x35);break;/显示4 case 5: LCD_Ddata_Send(0x31); LCD_Ddata_Send(0x30); break;/显示5 case 6: LCD_Ddata_Send(0x33);break;/显示6 case 7: LCD_Ddata_Send(0x32);break;/显示7 case 8: LCD_Ddata_Send(0x35);break;/显示8case 9: LCD_Ddata_Send(0x39); LCD_Ddata_Send(0x30);break;/显示9case 10:LCD_Ddata_Send(0xb1,0xb1);break;LCD_Ddata_Send(0xd4,0xaa); while(1) if (ch452_key=0x69) LCD_com_Send(0x01);delay(500); scanf(); /扫描函数void scanf()LCD_locate(0);LCD_Ddata_Send(0xb0,0xb4);LCD_Ddata_Send(0x61);LCD_Ddata_Send(0xbf,0xaa);LCD_Ddata_Send(0xca,0xbc);LCD_Ddata_Send(0xcc,0xf5);LCD_Ddata_Send(0xc2,0xeb);delay(1000);LCD_com_Send(0x01);ch452_key=0x00; while(1) while(ch452_key=0x68)if (WAV) count1+; delay(1); /延时1毫秒 if (WAV=0&count1) ratio=(count1/divisor); divisor=count1; count1=0; if(ratio0&ratio2.3) lounthi=ratio; i+; if (lounth7=ratio) registration(); LCD_Send(); divisor=1; i=0; LED1=0; delay(500); LED1=1;LCD_locate(8);LCD_Ddata_Send(0xb0,0xb4);LCD_Ddata_Send(0x33);LCD_Ddata_Send(0xbc,0xfc);LCD_Ddata_Send(0xb2,0xe9);LCD_Ddata_Send(0xd1,0xaf);LCD_Ddata_Send(0xcf,0xea);LCD_Ddata_Send(0xc7,0xe9); if (ch452_key=0x69) LCD_com_Send(0x01); RSTSRC=0x02; if(ch452_key=0x50) custom();/主函数void main() Init_Device(); /调用设备初始化函数完成功能选择、端口配置等操作LCD_com_Send(0x0c);/传送不显示光标命令 vertical();LCD_locate(1); /调用显示定位函数在第2个显示位开始存放 LCD_com_Send(0x01); delay(100); scanf();五、心得体会通过这次大赛,我们对单片机有了更深一步的认知,同时使我们的编程的能力有了很大的提高。虽然我们学习过了单片机原理和C语言程序设计,但以前学习的都是纯理论知识,我们根本不知道怎样应用这些理论知识去实现单片机的具体功能。这次大赛给了我们一个很好的平台让我们得以把理论和实践相结合。通过实践,让我们切实感受到了书本上学习不到的知识,也解决了我们原来学习理论知识存在的困惑和疑问。真可谓是一举多得。这次大赛也让我们真正实现了学以致用。六、参考资料何钦铭 C语言程序设计 高等教育出版社李金哲 条形码技术应用 辽宁科学技术出版社陈连坤 单片机原理及接口技术(C语言版) 清华大学出版社
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 压缩资料 > 基础医学


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!