实验名称: 密码锁实验 院 系: 物理与机电工程学院 专业班级: 09电子信息工程 姓 名: 李兴富 学 号:2009041616 指导教师: 罗锦彬 完成时间: 报告成绩:
评阅意见:
评阅教师 日期
密码锁实验
一、实验目的
1. 掌握液晶的使用方法;
2. 掌握液晶信号之间时序的正确识别和引入 3. 掌握键盘信号的输入,DSP I/O口的使用; 4. 掌握键盘信号之间时序的正确识别和引入。 5. 熟悉对TMS320F2812的编程调试。
二、实验设备
1. 一台装有CCS2000软件的计算机; 2. 插上2812主控板的DSP实验箱; 3. DSP硬件仿真器。
三、实验原理
1.128液晶显示器:
本实验箱采用的液晶接口在DSP的数据总线上,由于DSP是十六位总线,液晶是八位总线,所以DSP的高八位总线悬空。液晶的结构框图如下,
2.4*4矩阵按键:
实验箱上提供一个4x4的行列式键盘。2812的8个I/O口与之相连,这里按键的识别方法是扫描法。
键被按下时,与此键相连的行线电平将由与此键相连的列线电平决定,而行线的电平在无按键按下时处于高电平状态。让所有的列线处于低电平,按键所在的行电平将被拉成低电平。根据此行电平的变化,便能判断此行一定有按键被按下,但还不能确定是哪个键被按下。那么,按下键的那列电平就会拉成低电平,判断出哪列为低电平就可以判断出按键号码。
四、实验步骤
1.把2812模块小板插到大板上;打开液晶模块的电源开关; 2.更改源程序,通过仿真器把执行代码下载到DSP芯片,不断调试; 3.运行程序,通过128液晶显示和矩阵按键实现密码锁功能。
五、总结和体会
通过本次实验,实现了密码锁基本功能。具有重新输入功能,能够通过按键修改密码,且最大的密码位数可通过改变程序中mimaweishu变量快速修改,初始值为50位。通过128显示输入提示,人机界面友好。程序实现在解密后自动弹出 “欢迎使用 DSP 2812”的数据信息。 虽然是基本功能,但真要实现起来还是感觉有些难度的,程序中应用大量标志来执行不同的功能,使尽量减少程序漏洞。并通过本次实验提高了标志应用能力。 实验过程中遇到了很多问题,最终解决问题错误并成功实现密码锁功能。整个实验过程,
是不断学习、不断进步的过程。通过实验掌握了液晶和矩阵按键的控制使用。程序的编写能力也得到了提高。 由于要占用大量的存储空间来存放显示的汉字,开始时遇到了容量不足的问题。于是去加深学习了2812的存储器映射和CMD文件编写相关的知识,但是资料的例子都没用到L0和L1存储空间,而是用H0空间既做程序又做数据空间。通过更改Length值还是没有解决问题。后来想到了利用LO和L1的连续8K空间和H0的8K连续空间分别作为程序空间和数据空间,解决了容量不足的问题。 由于矩阵按键程序为循环扫描方式,因此源程序运行时按一下按键,按键将被扫描了几百次,这样肯定不能实现密码锁按键要单次触发的要求。通过更改按键程序实现了单次触发的条件,很好地为后续程序服务。 通过实验,提高了2812程序调试能力。学会了观察变量变化在线调试的分析方法。
实验程序:
#include \"include/DSP281x_Device.h\" // DSP281x Headerfile Include File #include \"include/DSP281x_Examples.h\" // DSP281x Examples Include File
unsigned short mimaweishu=50; unsigned short chongshuflag=0,enBflag=0,enjinflag=0,initflag=0,anAdengdai=1,shuruflag=0,chongshemima=0,rightflag=0,jiemiflag=0,chongsheflag=0,errorflag=0,anjianjishu=0,shurufinish=0; unsigned short key,keyvalue,an0=0,an1=0,an2=0,an3=0,an4=0,an5=0,an6=0,an7=0,an8=0,an9=0,anA=0,anB=0,anC=0,anD=0,anjin=0,anxin=0;
unsigned short a[51],b[51]={'a','1','2','3','4','5','6','7','8','9','*','0','D','C'}; unsigned short table[]={'0','1','2','3','4','5','6','7','8','9'};
void xianshi(unsigned short); void anjianqingling() {
anA=anB=anC=anD=anxin=anjin=an1=an2=an3=an4=an5=an6=an7=an8=an9=an0=0; } // ASCII码表
unsigned char nAsciiDot[] = // ASCII { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // - -
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x38,0xFC,0xFC,0x38,0x00,0x00, // -!- 0x00,0x00,0x00,0x0D,0x0D,0x00,0x00,0x00, …… };
typedef struct typFNT_GB16 // 汉字字模数据结构 {
signed char Index[2]; // 汉字内码索引 char Msk[32]; // 点阵码数据 }aa;
// 汉字数据表
struct typFNT_GB16 GB_16[] = {
\"欢0\ 0x0F,0xE8,0x08,0x08,0x28,0x18,0x00,0x00, 0x10,0x08,0x06,0x01,0x82,0x8C,0x40,0x30, 0x0C,0x03,0x0C,0x10,0x60,0xC0,0x40,0x00, \"迎1\使2\用3\"
/*-- 文字: 输4 --*//*-- 文字: 入5 --*//*-- 文字: 密6 --*//*-- 文字: 码7 --*//*-- 文字: 查8 --*//*-- 文字: 看9 --*//*-- 文字: 数10 --*//*-- 文字: 据11 --*//*-- 文字: 按12 --*//*-- 文字: 键13 --*//*-- 文字: 开14 --*//*-- 文字: 始15 --*//*-- 文字: 确16 --*//*-- 文字: 认17 --*//*-- 文字: 正18 --*//*-- 文字: 为19 --*//*-- 文字: 错20 --*//*-- 文字: 误21 --*//*-- 文字: 请22 --*//*-- 文字: 重23 --*//*-- 文字: 试 24 --*//*-- 文字: 新25 --*//*-- 文字: 设26 --*//*-- 文字: 稍27 --*//*-- 文字: 后28 --*//*-- 文字: …29 --*//*-- 文字: 初30 --*//*-- 文字: 始31 --*//*-- 文字: 成32 --*//*-- 文字: 功33 --*/ };
void Gpio_select(void); void delay(int time) {
int i,j;
for(i=0;ivoid wcom(unsigned char com) {Reg08=com; }
void wdata(unsigned char dat) { Reg07=dat; }
void lcdinit(void) { wcom(0xa4); wcom(0xad); wcom(0x03); wcom(0xac); wcom(0xe2); //initialize interal function delay(10); wcom(0xa2); //set nomal display wcom(0xa0); //ADC select SEG1 to SEG132 wcom(0xc8); //set SHL COM1 to COM start page setup wcom(0x2c); //power control(VB,VR,VF=1,1,1) wcom(0x2e); //power control(VB,VR,VF=1,1,1) wcom(0x2f); //power control(VB,VR,VF=1,1,1) wcom(0x25); // wcom(0x81); //set reference voltage mode wcom(0x20); //set reference voltage wcom(0x40); //Initial Display Line was first line wcom(0xa6); //set nomal display wcom(0xa4); //set nomal display wcom(0xaf); //display on }
void clear(void) { unsigned char page; unsigned char seg;
for(page=0xb0;page<0xb9;page++) //写页地址共8页 0xb0----0xb8 {
wcom(page); wcom(0x10); wcom(0x00);
for(seg=0;seg<128;seg++) {
wdata(0x00); } } }
void lcdwritechar(char codenum ,char y ,char x ) { unsigned char seg; unsigned int coden; codenum-=0x20; coden=codenum<<4;
wcom(0xb0|(y&0x0f));// wcom(0x10|((x>>1)&0x0f)); wcom(0x00|((x<<3)&0x0f)); for(seg=0;seg<8;seg++) wdata(nAsciiDot[coden++]); wcom(0xb0|((y+1)&0x0f)); wcom(0x10|((x>>1)&0x0f)); wcom(0x00|((x<<3)&0x0f)); for(seg=0;seg<8;seg++) wdata(nAsciiDot[coden++]); }
void lcdwritehz(char hznum ,char y ,char x ) { unsigned char seg,hz; unsigned char coden=0; hz=hznum; wcom(0xb0|(y&0x0f)); wcom(0x10|((x>>1)&0x0f)); wcom(0x00|((x<<3)&0x0f)); for(seg=0;seg<16;seg++)wdata(GB_16[hz].Msk[coden++]); wcom(0xb0|((y+1)&0x0f)); wcom(0x10|((x>>1)&0x0f)); wcom(0x00|((x<<3)&0x0f)); for(seg=0;seg<16;seg++)wdata(GB_16[hz].Msk[coden++]); }
main() {
short i,j; InitSysCtrl(); DINT;
InitPieCtrl(); IER = 0x0000; IFR = 0x0000; InitPieVectTable(); lcdinit(); clear();
for(i=14;ib[i]='a'; } while(1) {keyvalue=0;//注意的地方!!使程序执行一周后keyvalue变为初始值0
GpioDataRegs.GPADAT.all =0xefff; Reg05=0x00;
key=GpioDataRegs.GPADAT.all; if(key!=0xefff) {
if(key==0xe7ff && 0==anD) { anjianqingling(); anD=1; anjianjishu++; keyvalue='D'; } if(key==0xebff && 0==anjin) { anjianqingling(); anjin=1; //anjianjishu++;确认键,不需计数。计数只为了输密码或设密码 keyvalue='#'; }
if(key==0xef7f && 0==an0) { anjianqingling(); an0=1; anjianjishu++; keyvalue='0'; }
if(key==0xefbf && 0==anxin) { anjianqingling(); anxin=1; anjianjishu++; keyvalue='*'; } }
Reg05=0x00;
GpioDataRegs.GPADAT.all =0xdfff; Reg05=0x00;
key=GpioDataRegs.GPADAT.all; if(key!=0xdfff) {
if(key==0xd7ff && 0==anA) {
anjianqingling(); anA=1; // anjianjishu++;计数只为了输密码或设密码 keyvalue='A'; }
if(key==0xdbff && 0==an3) { anjianqingling(); an3=1;
anjianjishu++; keyvalue='3'; }
if(key==0xdf7f && 0==an2) { anjianqingling(); an2=1; anjianjishu++; keyvalue='2'; }
if(key==0xdfbf && 0==an1) { anjianqingling(); an1=1; anjianjishu++; keyvalue='1'; } }
Reg05=0x00;
GpioDataRegs.GPADAT.all =0xbfff; Reg05=0x00;
key=GpioDataRegs.GPADAT.all; if(key!=0xbfff) {
if(key==0xb7ff && 0==anB) { anjianqingling(); anB=1; // anjianjishu++; keyvalue='B'; }
if(key==0xbbff && 0==an6) {
anjianqingling(); an6=1;
anjianjishu++; keyvalue='6'; }
if(key==0xbf7f && 0==an5) {
anjianqingling(); an5=1;
anjianjishu++; keyvalue='5'; }
if(key==0xbfbf && 0==an4) {
anjianqingling(); an4=1;
anjianjishu++; keyvalue='4'; } }
Reg05=0x00;
GpioDataRegs.GPADAT.all =0x7fff; Reg05=0x00;
key=GpioDataRegs.GPADAT.all; if(key!=0x7fff) {
if(key==0x77ff && 0==anC) {
anjianqingling(); anC=1;
anjianjishu++; keyvalue='C'; }
if(key==0x7bff && 0==an9) {
anjianqingling(); an9=1;
anjianjishu++; keyvalue='9'; }
if(key==0x7f7f && 0==an8) {
anjianqingling(); an8=1;
anjianjishu++; keyvalue='8';
}
if(key==0x7fbf && 0==an7) {
anjianqingling(); an7=1;
anjianjishu++; keyvalue='7'; } }
Reg05=0x00;
if(0==keyvalue && 0==initflag)//请按A键输入密码查看数据 { initflag=1; xianshi(0); }
if('A'==keyvalue && 0==chongshemima && 0==chongsheflag) {
chongshu: keyvalue=0;//使用goto没有经过开始处keyvalue=0;将导致按键所以一直循环. anjianjishu=0; shuruflag=1; anAdengdai=0; enBflag=enjinflag=1;
//注意要重新赋值!!否则再次输密码时只要前面对了就行。 for(i=0;iif('B'==keyvalue && 1==enBflag && 0==anAdengdai) {if(1==chongshemima)goto shuxin; enBflag=0;
chongshe:
keyvalue=0; chongsheflag=1; shuruflag=1; anjianjishu=0;
//请输入初始密码: //按B键重新输入 //按#键确认输入
xianshi(2); }
if(1==shuruflag && 0!=keyvalue && 0!=anjianjishu &&'#'!=keyvalue && 0==chongshemima) { if('B'==keyvalue && 0==anAdengdai)goto chongshe; a[anjianjishu]=keyvalue; if(1==chongsheflag) { lcdwritechar('*',2,anjianjishu-1); if(anjianjishu>=17 && anjianjishu<33) { if(17==anjianjishu) { for(i=0;i<16;i++)lcdwritechar(' ',2,i); } lcdwritechar('*',2,anjianjishu-17); } else if(anjianjishu<49) { if(33==anjianjishu) { for(i=0;i<16;i++)lcdwritechar(' ',2,i); } lcdwritechar('*',2,anjianjishu-33); } else if(anjianjishu<65) { if(49==anjianjishu) { for(i=0;i<16;i++)lcdwritechar(' ',2,i); } lcdwritechar('*',2,anjianjishu-49); }
} else {
lcdwritechar('*',0,10+anjianjishu); if(anjianjishu>=6 && anjianjishu<22) { if(6==anjianjishu) { for(i=0;i<16;i++)lcdwritechar(' ',0,i); } lcdwritechar('*',0,anjianjishu-6); } else if(anjianjishu<38) { if(22==anjianjishu) { for(i=0;i<16;i++)lcdwritechar(' ',0,i); } lcdwritechar('*',0,anjianjishu-22); } else if(anjianjishu<54) { if(38==anjianjishu) { for(i=0;i<16;i++)lcdwritechar(' ',0,i); } lcdwritechar('*',0,anjianjishu-38); } } }
if('#'==keyvalue && 1==enjinflag && 0==anAdengdai) {
keyvalue=0;
for(i=1;iif(a[i]!=b[i]) { errorflag=1; } } if(0==errorflag)rightflag=1; }if(1==errorflag)
{
errorflag=0;
//密码错误!请重新输入 xianshi(3);
for(i=0;i<32767;i++) for(j=0;j<40;j++);
if(1==chongsheflag) {
goto chongshe; }
else goto chongshu; }
if(1==rightflag) { jiemiflag=1; rightflag=0; enjinflag=0;//防止#键进入确认功能
//密码正确!请稍后。。。 xianshi(4);
//一段延时模拟等待 for(i=0;i<32767;i++)
for(j=0;j<50;j++); }
if(1==jiemiflag && 1==chongsheflag) {
shuxin:
jiemiflag=0; chongsheflag=0; chongshemima=1; anjianjishu=0; enBflag=1; //请输入新密码: //按B键重新输入 //按#键确认输入
xianshi(5); }
else if(1==jiemiflag)
{
jiemiflag=0; anAdengdai=1; //欢迎使用 //DSP 2812! xianshi(6); }
if(1== anAdengdai && 0!=keyvalue && '#'!=keyvalue) {
clear();
keyvalue=0;
chongshuflag=enBflag=enjinflag=initflag=shuruflag=chongshemima=rightflag=jiemiflag=chongsheflag=errorflag=anjianjishu=shurufinish=0; anAdengdai=1; }
if(1==chongshemima && 0!=keyvalue && '#'!=keyvalue && 0!=anjianjishu) { //anjianjishu++;//按键程序本身带有自加。 b[anjianjishu]=keyvalue; lcdwritechar('*',2,anjianjishu-1); if(anjianjishu>=17 && anjianjishu<33) { if(17==anjianjishu) { for(i=0;i<16;i++)lcdwritechar(' ',2,i); } lcdwritechar('*',2,anjianjishu-17); } else if(anjianjishu<49) { if(33==anjianjishu) { for(i=0;i<16;i++)lcdwritechar(' ',2,i); } lcdwritechar('*',2,anjianjishu-33); } else if(anjianjishu<65) { if(49==anjianjishu) { for(i=0;i<16;i++)lcdwritechar(' ',2,i); }
lcdwritechar('*',2,anjianjishu-49); } }
if('#'==keyvalue && 1==chongshemima && 0!=anjianjishu) { chongshemima=0; if(anjianjishu//一段延时模拟等待 for(i=0;i<32767;i++) for(j=0;j<50;j++);goto chongshu; }
Reg05=0x00; }//while(); }//main
void Gpio_select(void) {
Uint16 var1; Uint16 var2; Uint16 var3; var1= 0x0000; // sets GPIO Muxs as I/Os var2= 0xf000; // sets GPIO DIR as outputs var3= 0x0000; // sets the Input qualifier values EALLOW; GpioMuxRegs.GPAMUX.all=var1; GpioMuxRegs.GPADIR.all=var2; // GPIO PORTs as output GpioMuxRegs.GPAQUAL.all=var3; // Set GPIO input qualifier values EDIS;
}
void xianshi(unsigned short changenum) {
switch(changenum) {
case 0: lcdwritehz(22,2,2); lcdwritehz(12,2,4); lcdwritechar('A',2,6); lcdwritehz(13,2,7); lcdwritehz(4,2,9); lcdwritehz(5,2,11); lcdwritehz(6,4,2); lcdwritehz(7,4,4); lcdwritehz(8,4,6); lcdwritehz(9,4,8); lcdwritehz(10,4,10); lcdwritehz(11,4,12); break; case 1: clear(); lcdwritehz(22,0,0); lcdwritehz(4,0,2); lcdwritehz(5,0,4); lcdwritehz(6,0,6); lcdwritehz(7,0,8); lcdwritechar(':',0,10); lcdwritehz(12,2,0); lcdwritechar('B',2,2); lcdwritehz(13,2,4); lcdwritehz(23,2,6); lcdwritehz(26,2,8); lcdwritehz(6,2,10); lcdwritehz(7,2,12); lcdwritehz(12,4,0); lcdwritechar('A',4,2); lcdwritehz(13,4,4); lcdwritehz(23,4,6); lcdwritehz(25,4,8);
lcdwritehz(4,4,10); lcdwritehz(5,4,12); lcdwritehz(12,6,0); lcdwritechar('#',6,2); lcdwritehz(13,6,4); lcdwritehz(16,6,6); lcdwritehz(17,6,8); lcdwritehz(4,6,10); lcdwritehz(5,6,12); break; case 2: clear(); lcdwritehz(22,0,0); lcdwritehz(4,0,2); lcdwritehz(5,0,4); lcdwritehz(30,0,6); lcdwritehz(31,0,8); lcdwritehz(6,0,10); lcdwritehz(7,0,12); lcdwritechar(':',0,14); lcdwritehz(12,4,0); lcdwritechar('B',4,2); lcdwritehz(13,4,4); lcdwritehz(23,4,6); lcdwritehz(25,4,8); lcdwritehz(4,4,10); lcdwritehz(5,4,12); lcdwritehz(12,6,0); lcdwritechar('#',6,2); lcdwritehz(13,6,4); lcdwritehz(16,6,6); lcdwritehz(17,6,8); lcdwritehz(4,6,10); lcdwritehz(5,6,12); break; case 3: clear();
lcdwritehz(6,2,4); lcdwritehz(7,2,6); lcdwritehz(20,2,8); lcdwritehz(21,2,10);
lcdwritechar('!',2,12);
lcdwritehz(22,4,2); lcdwritehz(23,4,4); lcdwritehz(25,4,6); lcdwritehz(4,4,8); lcdwritehz(5,4,10); break; case 4: clear(); lcdwritehz(6,2,4); lcdwritehz(7,2,6); lcdwritehz(18,2,8); lcdwritehz(16,2,10); lcdwritechar('!',2,12); lcdwritehz(22,6,4); lcdwritehz(27,6,6); lcdwritehz(28,6,8); lcdwritehz(29,6,10); lcdwritehz(29,6,12); break; case 5: clear(); lcdwritehz(22,0,0); lcdwritehz(4,0,2); lcdwritehz(5,0,4); lcdwritehz(25,0,6); lcdwritehz(6,0,8); lcdwritehz(7,0,10); lcdwritechar(':',0,12); lcdwritehz(12,4,0); lcdwritechar('B',4,2); lcdwritehz(13,4,4); lcdwritehz(23,4,6); lcdwritehz(25,4,8); lcdwritehz(4,4,10); lcdwritehz(5,4,12); lcdwritehz(12,6,0); lcdwritechar('#',6,2); lcdwritehz(13,6,4); lcdwritehz(16,6,6); lcdwritehz(17,6,8);
lcdwritehz(4,6,10); lcdwritehz(5,6,12); break; case 6: clear(); lcdwritehz(0,2,4); lcdwritehz(1,2,6); lcdwritehz(2,2,8); lcdwritehz(3,2,10); lcdwritechar('D',4,4); lcdwritechar('S',4,5); lcdwritechar('P',4,6); lcdwritechar(' ',4,7); lcdwritechar('2',4,8); lcdwritechar('8',4,9); lcdwritechar('1',4,10); lcdwritechar('2',4,11); lcdwritechar('!',4,12); break; case 7: clear(); lcdwritehz(23,2,0); lcdwritehz(26,2,2); lcdwritehz(6,2,4); lcdwritehz(7,2,6); lcdwritehz(32,2,8); lcdwritehz(33,2,10); lcdwritechar('!',2,12); lcdwritehz(22,6,4); lcdwritehz(27,6,6); lcdwritehz(28,6,8); lcdwritehz(29,6,10); lcdwritehz(29,6,12); break; } }
//=========================================================================== // No more.
//===========================================================================