电子词典系统设计实验报告
12121583 曹连强 周四6-8
一、项目要求:
1、在实验板上设计实现一个无操作系统的简易电子词典
2、设计友好的人机交互界面
3、 :字符输入、功能选择、英汉翻译。
二、电子词典系统实现具体功能:
1.能够通过键盘输入英文。键盘作为本系统中最主要的输入设备,需要完成26个英文字母的输入,并且需要上翻页,下翻页,上一行,下一行,翻译,退格等功能。要求键盘至少要有16个按键,每个按键都可以被处理器及时,准确地读入。
2.提供友好的人机界面,将输入的内容和翻译的结果显示在LCD的相应区域内。
3. 对输入的单词即时翻译。
4.可以记忆3个已经查询过的的单词。
在无操作系统的电子词典系统中,由于是单任务环境,因此此时系统的各个功能模块均按照顺序执行。初始化后,即进入翻译待机状态,等待用户的输入操作。当用户输入操作发生后,系统调用键盘或触摸屏中断进行键值读取,将键值传给主函数中的系统功能实现模块,该模块按不同的输入键值进行相应的功能选择,最后将此次操作的结果输出到LCD上。
三、程序设计
可将电子词典的软件设计分为如下几个主要模块:键值处理、翻译、词库设计和LCD显示。
1、键值处理
电子词典的输入设备为键盘和触摸屏,要完成的功能为:
(1)键盘:10个英文字母和6个功能键输入
(2)触摸屏:6各功能键的输入
2、翻译:
3、词库设计
翻译功能中通过将输入单词和词库中相应的单词进行比较得到要显示的翻译结果,因此,词库可采用结构体实现,此结构中包括4项:英文单词、词性、汉语释意、英文例句。
4、LCD显示功能
翻页、选行及翻页结果的输出都可以归到LCD显示功能中,这些功能都可以通过调用LCD实验中的相关函数完成。
四.设计程序
////////////////////////////////////////////////////////////
#include "Ts_sep.h"
#include <string.h>
///////////////////////////////////////////////////////////
#include "def.h"
#include "2410lib.h"
#include "option.h"
#include "2410addr.h"
#include "interrupt.h"
#include "lcdlib.h"
//#define STN_LCD
#define TFT_8_0
/////////////////8888888////////////////////////////
#define LOOP 1
#define ADCPRS 39
#define TS_JUSTIFY_LEFTTOP 1
#define TS_JUSTIFY_RIGHTBOT 2
#define TS_START 3
///////////////////8888888888888888//////////////////////
void Lcd_Disp_Char(void);
void Lcd_Disp_Grap(void);
void Frame(void);//设置背景框架
void Clearscreen(void);//清屏
//void Key_init(void);//初始化键盘
void Cursor(int flag);
void CursorCl(int flag);
void delay( int count );
void disp();
void translate(int num);
static int x=0,y=0,letter=0,flag=0,wei=0,prev[5],i,j;//函数里有调用我换成全局变量
int which[20];//此时满足罗列单词
int word,w;
int m,n;
////////////////////////////////////////////////
int ts_status = TS_JUSTIFY_LEFTTOP;
int ts_lefttop_x, ts_lefttop_y, ts_rightbot_x, ts_rightbot_y;
int ts_lcd_x, ts_lcd_y;
///////////////////////////////////////////////
typedef struct{
int w; //单词对应的值
int o;
int r;
int d;
int s;
char c[20]; //英文单词
char e[20]; //翻译
}str_word;
str_word dictionary[20]={
{1,3,5,0,0,"ACE","王牌"},
{2,5,5,0,0,"BEE","蜜蜂"},
{1,4,4,0,0,"ADD","增加,计算"},
{2,1,4,0,0,"BAD","坏的"},
{4,5,3,1,4,"DECAD","十;十数"}
};
////////////////////////////////////////////////////////
void Adc_or_TsSep() __attribute__ ((interrupt("IRQ")));
void Adc_or_TsSep(void)
{
int i;
U32 Ptx[6], Pty[6];
rINTSUBMSK |= (BIT_SUB_ADC|BIT_SUB_TC); // Mask sub interrupt (ADC and TC)
// TC(Touch screen Control) Interrupt
if(rADCTSC & 0x100)
{
PRINTF("\nStylus Up!!\n");
rADCTSC &= 0xff; // Set stylus down interrupt
}
else
{
PRINTF("\nStylus Down!!\n");
// <X-Position Read>
rADCTSC=(0<<8)|(0<<7)|(1<<6)|(1<<5)|(0<<4)|(1<<3)|(0<<2)|(1); // Down,Hi-Z,AIN5,GND,Ext vlt,Pullup Dis,Normal,X-position
for(i=0;i<LOOP;i++); //delay to set up the next channel for(i=0;i<5;i++)
{
rADCCON|=0x1; // Start X-position conversion while(rADCCON & 0x1); // Check if Enable_start is low while(!(0x8000&rADCCON)); // Check ECFLG
Ptx[i]=(0x3ff&rADCDAT0);
}
Ptx[5]=(Ptx[0]+Ptx[1]+Ptx[2]+Ptx[3]+Ptx[4])/5;
// <Y-Position Read>
rADCTSC=(0<<8)|(0<<7)|(1<<6)|(1<<5)|(0<<4)|(1<<3)|(0<<2)|(2);
// Down,GND,Ext vlt,Hi-Z,AIN7,Pullup Dis,Normal,Y-position
for(i=0;i<LOOP;i++); //delay to set up the next channel for(i=0;i<5;i++)
{
rADCCON|=0x1; // Start X-position conversion while(rADCCON & 0x1); // Check if Enable_start is low while(!(0x8000&rADCCON)); // Check ECFLG
Pty[i]=(0x3ff&rADCDAT1);
}
Pty[5]=(Pty[0]+Pty[1]+Pty[2]+Pty[3]+Pty[4])/5;
rADCTSC=(1<<8)|(1<<7)|(1<<6)|(0<<5)|(1<<4)|(0<<3)|(0<<2)|(3);
// Up,GND,AIN,Hi-z,AIN,Pullup En,Normal,Waiting mode
PRINTF("TOUCH Position = (%04d, %04d) ", Ptx[5], Pty[5]); m=Ptx[5];
n=Pty[5];
if(ts_status == TS_JUSTIFY_LEFTTOP)
{
ts_lefttop_x = Ptx[5];
ts_lefttop_y = Pty[5];
ts_status = TS_JUSTIFY_RIGHTBOT;
PRINTF("\nLeft top (0, 0) -> (%04d, %04d)\n", ts_lefttop_x, ts_lefttop_y);
PRINTF(" 请触摸屏幕右下角位置\n");
}else if(ts_status == TS_JUSTIFY_RIGHTBOT)
{
ts_rightbot_x = Ptx[5];
ts_rightbot_y = Pty[5];
ts_status = TS_START;
PRINTF("\nRight bottom (319, 239) -> (%04d, %04d)\n", ts_rightbot_x, ts_rightbot_y);
PRINTF("[2] 请点击触摸屏\n");
}else
{
/* ts_lcd_x = 320 - (Ptx[5] - ts_rightbot_x) * 1.0 / (ts_lefttop_x - ts_rightbot_x) * 320.0 ;
ts_lcd_y = (Pty[5] - ts_lefttop_y) * 1.0 / (ts_rightbot_y - ts_lefttop_y) * 240.0 ;
if(ts_lcd_x > 319) ts_lcd_x = 319;
if(ts_lcd_x < 0) ts_lcd_x = 0;
if(ts_lcd_y > 239) ts_lcd_x = 239;
if(ts_lcd_y < 0) ts_lcd_x = 0;
PRINTF("LCD Position = (%04d, %04d)\n", ts_lcd_x, ts_lcd_y);*/
}
}
rSUBSRCPND |= BIT_SUB_TC;
rINTSUBMSK =~ (BIT_SUB_TC); // Unmask sub interrupt (TC) ClearPending(BIT_ADC);
}
void Ts_Sep(void)
{
PRINTF("------触摸屏测试------\n");
PRINTF("[1] 触摸屏校准\n 请触摸屏幕左上角位置\n");
ts_status = TS_JUSTIFY_LEFTTOP;
rADCDLY = (50000); // ADC Start or Interval Delay
rADCCON = (1<<14)|(ADCPRS<<6)|(0<<3)|(0<<2)|(0<<1)|(0);
// Enable Prescaler,Prescaler,AIN7/5 fix,Normal,Disable read start,No operation
rADCTSC = (0<<8)|(1<<7)|(1<<6)|(0<<5)|(1<<4)|(0<<3)|(0<<2)|(3);
// Down,YM:GND,YP:AIN5,XM:Hi-z,XP:AIN7,XP pullup En,Normal,Waiting for interrupt mode
pISR_ADC = (unsigned)Adc_or_TsSep;
rINTMSK &=~(BIT_ADC);
rINTSUBMSK =~(BIT_SUB_TC);
// while(1);
delay(200);
// rINTSUBMSK |= BIT_SUB_TC;
//rINTMSK |= BIT_ADC;
// PRINTF("----触摸屏测试结束----\n");
}
//////////////////////////////////////////////////////
void Main(void)
{
unsigned char ch='1';
/* 配置系统时钟 */
ChangeClockDivider(1,1); // 1:2:4
ChangeMPllValue(0xa1,0x3,0x1); // FCLK=202.8MHz
/* 初始化端口 */
Port_Init();
/* 初始化串口 */
Uart_Init(0,115200);
Uart_Select(0);
/* 打印提示信息 */
PRINTF("\n---LCD测试程序---\n");
PRINTF("\n请将UART0与PC串口进行连接,然后启动超级终端程序(115200, 8, N,
1)\n");
/* LCD初始化 */
Lcd_Port_Init();
#ifdef STN_LCD
Lcd_Init(MODE_CSTN_8BIT);
Glib_Init(MODE_CSTN_8BIT);
Lcd_CstnOnOff(1);
Glib_ClearScr(0xff, MODE_CSTN_8BIT);
#else
#ifdef TFT_8_0
rGPCCON &= ~(3<<8);
rGPCCON |= (2<<8);
Lcd_Init(MODE_TFT_16BIT_640480);
Glib_Init(MODE_TFT_16BIT_640480);
Glib_ClearScr(0xffff, MODE_TFT_16BIT_640480);
Lcd_PowerEnable(0, 1);
Lcd_EnvidOnOff(1);
#else
Lcd_Init(MODE_TFT_16BIT_240320);
Glib_Init(MODE_TFT_16BIT_240320);
Glib_ClearScr(0xffff, MODE_TFT_16BIT_240320);
Lcd_PowerEnable(0, 1);
Lcd_EnvidOnOff(1);
#endif
#endif
#define LCD_DISP_CHAR
#ifdef LCD_DISP_CHAR
#else
Lcd_Disp_Grap();
#endif
//布局
Glib_FilledRectangle(0,0,640,240,0xffff); //白底
// Glib_Rectangle(60,80,620,110,0x0000);//首字母框
Glib_Rectangle(60,80,620,440,0x0000);//主框
Glib_Line(290,110,290,410,0x0000);//分割线1
Glib_Line(60,110,620,110,0x0000);//分割线2
Glib_Line(60,410,620,410,0x0000);//分割线3
Glib_Line(172,410,172,440,0x0000);//分割线4
Glib_Line(284,410,284,440,0x0000);//分割线5
Glib_Line(396,410,396,440,0x0000);//分割线6
Glib_Line(508,410,508,440,0x0000);//分割线7
// Glib_Rectangle(520,80,620,120,0x0000);//up
Glib_disp_hzk16(110,420,"上", 0x0000);
// Glib_Rectangle(520,140,620,180,0x0000);//down
Glib_disp_hzk16(222,420,"下", 0x0000);
// Glib_Rectangle(520,200,620,240,0x0000);//Del
Glib_disp_hzk16(334,420,"清屏", 0x0000);
// Glib_Rectangle(520,260,620,300,0x0000);//Enter
Glib_disp_hzk16(446,420,"查询", 0x0000);
// Glib_Rectangle(520,320,620,360,0x0000);//Cancel
Glib_disp_hzk16(558,420,"返回", 0x0000);
Ts_Sep();
while(1)//大循环等键按下
{
Cursor(flag);
ch = Key_GetKeyPoll();
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if((m>=145&&m<237)&&(n>395&&n<540))ch='E';//qingpin
if((m>=145&&m<237)&&(n>678&&n<830))ch='C';//Shang
if((m>=145&&m<237)&&(n>540&&n<678))ch='D';//Xia
if((m>=145&&m<237)&&(n>57&&n<219))ch='B';///shanchu
if((m>=145&&m<237)&&(n>219&&n<395))ch='F';//queding
m=n=0;
////////////////////////////////////////////////////////////////////////////////////////////////////////////
switch(ch){
case '1'://a
Glib_FilledRectangle(65,120,280,400,0xffff);//先清罗列单词区
letter=1;//1表示输入字母为1
Glib_disp_hzk16(90+wei*20,90,"A", 0x0000);//显示界面显示a
prev[wei]=1;//存放
disp();//显示单词区的单词
wei++;//下一个放字母位置
if(wei>=5){Glib_disp_hzk16(340,90,"已满", 0x0000);//单词字母小于等于四个
delay(1000);
Glib_disp_hzk16(340,90,"已满", 0xffff);//清掉"已经满了"
};//超出错误,只能查四位
break;
case '2'://b
Glib_FilledRectangle(65,120,280,400,0xffff);//先清罗列单词区
letter=2;//1表示输入字母为1
Glib_disp_hzk16(90+wei*20,90,"B", 0x0000);//显示界面显示a
prev[wei]=2;//存放
disp();//显示单词区的单词
wei++;//下一个放字母位置
if(wei>=5){Glib_disp_hzk16(340,90,"已满", 0x0000);//单词字母小于等于四个
delay(1000);
Glib_disp_hzk16(340,90,"已满", 0xffff);//清掉"已经满了"
};//超出错误,只能查四位
break;
case '3'://c
Glib_FilledRectangle(65,120,280,400,0xffff);//先清罗列单词区
letter=3;//1表示输入字母为1
Glib_disp_hzk16(90+wei*20,90,"B", 0x0000);//显示界面显示a
prev[wei]=3;//存放
disp();//显示单词区的单词
wei++;//下一个放字母位置
if(wei>=5){Glib_disp_hzk16(340,90,"已满", 0x0000);//单词字母小于等于四个
delay(1000);
Glib_disp_hzk16(340,90,"已满", 0xffff);//清掉"已经满了"
};//超出错误,只能查四位
break;
case '4'://d
Glib_FilledRectangle(65,120,280,400,0xffff);//先清罗列单词区
letter=4;//1表示输入字母为1
Glib_disp_hzk16(90+wei*20,90,"D", 0x0000);//显示界面显示a
prev[wei]=4;//存放
disp();//显示单词区的单词
wei++;//下一个放字母位置
if(wei>=5){Glib_disp_hzk16(340,90,"已满", 0x0000);//单词字母小于等于四个
delay(1000);
Glib_disp_hzk16(340,90,"已满", 0xffff);//清掉"已经满了"
};//超出错误,只能查四位
break;
case '5'://e
Glib_FilledRectangle(65,120,280,400,0xffff);//先清罗列单词区
letter=5;//1表示输入字母为1
Glib_disp_hzk16(80+wei*20,90,"E", 0x0000);//显示界面显示a
prev[wei]=5;//存放
disp();//显示单词区的单词
wei++;//下一个放字母位置
if(wei>=5){Glib_disp_hzk16(340,90,"已满", 0x0000);//单词字母小于等于四个
delay(1000);
Glib_disp_hzk16(340,90,"已满", 0xffff);//清掉"已经满了"
};//超出错误,只能查四位
break;
case '6'://f
break;
case '7'://g
break;
case '8'://h
break;
case '9'://i
break;
case '0'://j
break;
case 'A'://k
letter=11;
break;
case 'C'://上
flag--;
if(flag>=0&&flag<=3){
Cursor(flag);//单词列表选中变色
CursorCl(flag+1);}//再上恢复刚才那条的背景色
else flag=0;
break;
case 'D'://下
flag++;
if(flag>=0&&flag<=3){
Cursor(flag);
CursorCl(flag-1);}
else flag=3;
break;
case 'E'://cancel清屏
Glib_FilledRectangle(70,90,339,109,0xffff);//先清单词区
Glib_FilledRectangle(65,120,280,400,0xffff);//先清罗列单词区 Glib_FilledRectangle(300,120,610,400,0xffff);//清翻译区 for(j=0;j<=10;j++){
which[j]=0;
};
letter=0;
wei=0;
for(j=0;j<=5;j++){
prev[j]=0;
};
break;
case 'F'://enter确定
Glib_FilledRectangle(300,120,610,400,0xffff);//主翻译区
if(flag>=0&&flag<=3)
translate(which[flag]);//显示结果
break;
case 'B'://del删除
Glib_FilledRectangle(70,120,280,400,0xffff);//先清罗列单词区
letter=0;
wei--;
prev[wei]=0;//上一位变0
Glib_FilledRectangle(70+wei*30,90,70+wei*30+20,109,0xffff);//消掉一个字母
wei--;
disp();
wei++;
break;
default:
Glib_disp_hzk16(500,90,"←请输入单词", 0x0000);
break;
}
}
}
void disp(){
y=0;//初始单词显示位置
for(i=0;i<=20;i++){
if((dictionary[i].w==prev[0])&&(wei==0)){//第一个字母正
which[y]=i;//存放哪几个单词显示了
Glib_disp_hzk16(80,120+32*y,dictionary[i].c, 0x0000);//显示单词 y++;//位置改变
}
if((dictionary[i].w==prev[0])&&(dictionary[i].o==prev[1])&&(wei==1)){//前两个字母正确
which[y]=i;//存放哪几个单词显示了
Glib_disp_hzk16(80,120+32*y,dictionary[i].c, 0x0000);//显示单词 y++;//位置改变
}
if((dictionary[i].w==prev[0])&&(dictionary[i].o==prev[1])&&(dictionary[i].r==prev[2])&&(wei==2)){//前3个字母正确
which[y]=i;//存放哪几个单词显示了
Glib_disp_hzk16(80,120+32*y,dictionary[i].c, 0x0000);//显示单词 y++;//位置改变
}
if((dictionary[i].w==prev[0])&&(dictionary[i].o==prev[1])&&(dictionary[i].r==prev[2])&&(dictionary[i].d==prev[3])&&(wei==3)){//前4个字母正确
which[y]=i;//存放哪几个单词显示了
Glib_disp_hzk16(80,120+32*y,dictionary[i].c, 0x0000);//显示单词 y++;//位置改变
}
}
}
void translate(int num){//显示单词选项3个
Glib_disp_hzk16(300,120,dictionary[num].e, 0x0000);
}
//void Clearscreen(void) //清屏
//{
// Glib_FilledRectangle(65,81,499,99,0xffff);
// Glib_FilledRectangle(65,121,499,439,0xffff);
// Glib_Line(240,120,240,440,0x0000);
//}
void Cursor(int flag)
{
Glib_FilledRectangle(65,121+flag*32,75,153+flag*32,0x55);
}
void CursorCl(int flag)
{
Glib_FilledRectangle(65,121+flag*32,75,153+flag*32,0xffff);
}
void Lcd_Disp_Grap(void)
{
int i,j;
for(j=0;j<240;j++)
for(i=0;i<320;i++) //RRRGGGBB
PutPixel(i,j,((i/40)<<5)+((j/30)<<2)+(((j/15)%2)<<1)+((i/20)%2)); }
void delay( int count )
{
int cnt;
for( count = count; count>0; count--)
for( cnt = 0; cnt < 100; cnt++);
}