├── .gitattributes ├── Food.h ├── MyLib.h ├── README.md ├── client.h ├── draw.h ├── font.h ├── food.txt ├── keyboard.h ├── libfont.a ├── listFresh.h ├── order.c ├── orderKey.h ├── picture ├── 10.bmp ├── 11.bmp ├── 12.bmp ├── 13.bmp ├── 14.bmp ├── 15.bmp ├── 16.bmp ├── 17.bmp ├── 18.bmp ├── 19.bmp ├── 20.bmp ├── 21.bmp ├── 22.bmp ├── 23.bmp ├── 24.bmp ├── background.bmp ├── eraser.bmp ├── error.bmp ├── error.jpg ├── finger.bmp ├── index.bmp ├── logePicture.jpg ├── login.bmp ├── login.jpg ├── longzhu.bmp ├── menu.bmp ├── menu.jpg ├── num1.bmp ├── numBack.bmp ├── number.jfif ├── nvdi.bmp ├── onePiecePicture.bmp ├── photo1.bmp ├── photo1.jpeg ├── photo2.bmp ├── photo2.jpeg ├── photo3.bmp ├── photo3.jpeg ├── photo4.bmp ├── photo4.jpeg ├── photo5.bmp ├── photo5.jpeg ├── picture.bmp ├── register.bmp ├── register.jpg ├── success.bmp ├── success.jpg ├── wait.bmp ├── wait.jpg ├── 健脑益智-日式香煎三文鱼.jpg ├── 健脑益智-果仁菠菜.jpg ├── 健脑益智-糟溜鱼片.jpg ├── 健脑益智-红焖带鱼.jpg ├── 健脑益智-腐竹鱼头煲.jpg ├── 养颜抗衰老-冰糖阿胶燕窝.jpg ├── 养颜抗衰老-木瓜炖奶.jpg ├── 养颜抗衰老-花胶牛奶冻.jpg ├── 养颜抗衰老-银耳雪蛤羹.jpg ├── 橡皮擦.png ├── 热门-孜然排骨.jpg ├── 热门-红烧排骨.jpg ├── 热门-草莓牛奶布丁.jpg ├── 热门-麻辣香锅.jpg ├── 防辐射-血橙胡萝卜汁.jpg └── 防辐射-西红柿天鹅.jpg ├── showPicture.h ├── task.h ├── touchScreen.h ├── user.h ├── user.txt └── 点单记录.txt /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /Food.h: -------------------------------------------------------------------------------- 1 | #ifndef __FOOD__ 2 | #define __FOOD__ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | /** 9 | * attribute = 1:热门 10 | * attribute = 2:健脑益智 11 | * attribute = 3:养颜 12 | * attribute = 4:防辐射 13 | * 14 | * 10:西红柿天鹅 attribute = 4 15 | * 11:血橙胡萝卜汁 attribute = 4 16 | * 12:冰糖阿胶燕窝 attribute = 3 17 | * 13:花胶牛奶冻 attribute = 3 18 | * 14:木瓜炖奶 attribute = 3 19 | * 15:银耳雪蛤羹 attribute = 3 20 | * 16:糟溜鱼片 attribute = 2 21 | * 17:日式香煎三文鱼 attribute = 2 22 | * 18:红焖带鱼 attribute = 2 23 | * 19:果仁菠菜 attribute = 2 24 | * 20:腐竹鱼头煲 attribute =2*/ 25 | 26 | #define FoodFile "food.txt" 27 | 28 | struct Food{ 29 | int foodIdentify; 30 | int attribute; 31 | int pageRowPosition; 32 | int pageColumePosition; 33 | int orderNum; 34 | int money; 35 | struct Food* next; 36 | }; 37 | 38 | struct Food* initFoodLink(){ 39 | struct Food* head = (struct Food*)malloc(sizeof(struct Food)); //创建头结点 40 | struct Food* node = NULL,* end = head; 41 | FILE* filePoint; 42 | filePoint = fopen(FoodFile,"r"); 43 | int foodIdentify,attribute,pageRowPosition,pageColumePosition,money; 44 | 45 | /*打开文件操作*/ 46 | if(filePoint == NULL){ 47 | printf("fail to open the food file\n"); 48 | return NULL; 49 | }else{ 50 | printf("open the food file\n"); 51 | } 52 | while( fscanf(filePoint,"%d %d %d %d %d",&foodIdentify,&money,&attribute,&pageRowPosition,&pageColumePosition) != EOF ) { //按行读取菜单文件 53 | node = (struct Food*)malloc(sizeof(struct Food)); 54 | node->foodIdentify = foodIdentify; 55 | node->money = money; 56 | node->attribute = attribute; 57 | node->pageRowPosition = pageRowPosition; 58 | node->pageColumePosition = pageColumePosition; 59 | node->orderNum = 0; 60 | end->next = node; 61 | end = node; 62 | } 63 | end->next = NULL; //结束创建 64 | 65 | fclose(filePoint); //关闭文件 66 | return head; 67 | } 68 | /* 69 | int main(void){ 70 | struct Food* head = NULL; 71 | head = initFoodLink(); 72 | while (head->next != NULL) 73 | { 74 | head = head -> next; 75 | printf("id:%d;attribute:%d\n",head->foodIdentify,head->attribute); 76 | } 77 | 78 | return 0; 79 | } 80 | */ 81 | 82 | #endif 83 | 84 | -------------------------------------------------------------------------------- /MyLib.h: -------------------------------------------------------------------------------- 1 | #ifndef __MYLIB__ 2 | #define __MYLIB__ 3 | 4 | #include "Food.h" 5 | #include "user.h" 6 | 7 | // touch.h 8 | #define touchFile "/dev/input/event0" 9 | #define LCD "/dev/fb0" 10 | #define backgroundBmp "picture/background.bmp" 11 | #define LCDSize 800*480 12 | #define LCDLength 800 13 | #define LCDWidth 480 14 | #define LCDSizeof 800*480*4 15 | 16 | #define registerLeft 100 17 | #define registerRight 330 18 | #define loginLeft 470 19 | #define loginRight 680 20 | #define loginAbove 320 21 | #define loginBelow 400 22 | 23 | int red = 0x00FF0000; 24 | int green = 0x0000ff00; 25 | int white = 0x00ffffff; 26 | int black = 0x00000000; 27 | int skyBlue = 0x0087CEEB; 28 | int RoyalBlue = 0x0A4169E1; // 皇家蓝 29 | int Azure = 0x0AF0FFFF; //蔚蓝色 30 | int DarkVoilet = 0x009400D3; // 深紫罗兰色 31 | 32 | int touchFilePoint; //触摸屏文件描述符 33 | struct input_event touchEvent; 34 | 35 | int x = 0; 36 | int y = 0; 37 | int pressTime = 0; //按下后开始自加1,无限循环,直到松开清零 38 | int pressFlag = 0; //按下置1;抬起置0 39 | int pressX = 0,pressY = 0,releaseX = 0,releaseY = 0; 40 | int isPress = 0; //0:松开; 1:按下 41 | int isTouched = 0; //0:触摸事件未发生 1:触摸事件发生 42 | 43 | int mode = 0; //默认模式 0->主页面; 1->注册; 2->登录; 3->点餐; 4->提交订单 44 | int menuPage = 1; // 1->热门; 2->健脑; 3->养颜; 4->防辐射; 45 | int firstInMenuPage = 1; //菜单切换后第一次进入新page的标志位,进入后置零,再次更新mode后置一 46 | int firstInModeFlag = 1; //模式切换后第一次进入新mode的标志位,进入后置零,再次更新mode后置一 47 | int lastMode = 0; 48 | 49 | int orderRefreshFlag = 0; 50 | 51 | struct Food* head = NULL, * foodLink = NULL; 52 | struct User* userHead = NULL, * userLink = NULL; 53 | 54 | int submitFlag = 0; 55 | int sendFlag = 0; 56 | 57 | 58 | 59 | int photoNum = 1; 60 | int lastPhotoNum = 1; 61 | 62 | #endif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # self-service-ordering-system-based-on-ARM-A53 2 | 嵌入式自助点餐平板电脑是以餐饮业为平台,利用先进的计算机技术、嵌入式Linux技术、网络通信技术作为本项目的支撑。通过本项目,可以接触到当下主流的商用嵌入式开发平台ARM-Cortex A53架构的开发板,并能体验其开发的流程与工作原理。本项目中涉及到的网络传输相关的功能,可以在实践操作中,更加深入地学习TCP/UDP网络协议的理论及实现。 3 | 4 | 通过ARM-Cortex A53架构开发板,开发板中烧录32位Ubuntu系统,上位机通过Ubuntu16.04系统去编译c语言文件。 5 | 6 | ### 本应用实现了用户注册功能,用户登录功能,用户点单功能,账单上传服务器功能。 7 | 8 | #### 整体思路通过任务调度架构,循环地去访问各个模式的标志位,执行相应的代码段。 9 | 10 | #### 用户注册功能以及用户登录功能应用了链表技术,创建用户链表,动态的增加或删除用户信息,并写入文件。 11 | 12 | #### 用户点单功能实现了菜品动态添加的功能,通过将菜品信息以及菜品图片名称写入food.txt文件,应用菜品链表,实现菜单的动态更新。同时实现了菜单左右滑动翻页,单击菜品加一,长按菜品加一,左侧动态显示用户当前点单记录的功能。 13 | 14 | #### 账单上传服务器功能使用TCP通信协议,将账单上传至局域网的服务器地址中。 15 | 16 | #### ps:Ubuntu16.04 编译命令:arm-linux-gcc order.c -o order -lpthread -I ./ 17 | #### 项目演示视频地址: 18 | https://b23.tv/pgQoSzp 19 | -------------------------------------------------------------------------------- /client.h: -------------------------------------------------------------------------------- 1 | #ifndef __CLIENT__ 2 | #define __CLIENT__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "MyLib.h" 12 | #include /* See NOTES */ 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "user.h" 18 | #include "food.h" 19 | 20 | int sock; 21 | 22 | void *startSendDitect(void *arg) 23 | { 24 | while(1){ 25 | if(submitFlag){ 26 | 27 | char msg[60]; 28 | userLink = userHead; 29 | while (userLink->next != NULL){ 30 | userLink = userLink->next; 31 | if(userLink->isSelected){ 32 | userLink->isSelected = 0; //清除用户选择 33 | sprintf(msg,"===================================\n"); 34 | write(sock,msg,strlen(msg)); 35 | sprintf(msg,"===================================\n"); 36 | write(sock,msg,strlen(msg)); 37 | sprintf(msg,"用户 -- %d --已下单\n\n",userLink->userName); 38 | write(sock,msg,strlen(msg)); 39 | } 40 | } 41 | foodLink = head; 42 | int sumMoney = 0; 43 | while (foodLink->next != NULL){ 44 | foodLink = foodLink->next; 45 | if(foodLink->orderNum>0){ 46 | int foodNum = foodLink->orderNum; 47 | int money = foodLink->money; 48 | sumMoney = sumMoney + money * foodNum; 49 | switch (foodLink->foodIdentify){ 50 | case 10: 51 | sprintf(msg,"西红柿天鹅 %2d %d\n",foodNum,money); 52 | break; 53 | case 11: 54 | sprintf(msg,"血橙胡萝卜汁 %2d %d\n",foodNum,money); 55 | break; 56 | case 12: 57 | sprintf(msg,"冰糖阿胶燕窝 %2d %d\n",foodNum,money); 58 | break; 59 | case 13: 60 | sprintf(msg,"花胶牛奶冻 %2d %d\n",foodNum,money); 61 | break; 62 | case 14: 63 | sprintf(msg,"木瓜炖奶 %2d %d\n",foodNum,money); 64 | break; 65 | case 15: 66 | sprintf(msg,"银耳雪蛤羹 %2d %d\n",foodNum,money); 67 | break; 68 | case 16: 69 | sprintf(msg,"糟溜鱼片 %2d %d\n",foodNum,money); 70 | break; 71 | case 17: 72 | sprintf(msg,"日式香煎三文鱼 %2d %d\n",foodNum,money); 73 | break; 74 | case 18: 75 | sprintf(msg,"红焖带鱼 %2d %d\n",foodNum,money); 76 | break; 77 | case 19: 78 | sprintf(msg,"果仁菠菜 %2d %d\n",foodNum,money); 79 | break; 80 | case 20: 81 | sprintf(msg,"腐竹鱼头煲 %2d %d\n",foodNum,money); 82 | break; 83 | case 21: 84 | sprintf(msg,"红烧排骨 %2d %d\n",foodNum,money); 85 | break; 86 | case 22: 87 | sprintf(msg,"草莓牛奶布丁 %2d %d\n",foodNum,money); 88 | break; 89 | case 23: 90 | sprintf(msg,"孜然排骨 %2d %d\n",foodNum,money); 91 | break; 92 | case 24: 93 | sprintf(msg,"麻辣香锅 %2d %d\n",foodNum,money); 94 | break; 95 | default: 96 | break; 97 | } 98 | write(sock,msg,strlen(msg)); 99 | foodLink->orderNum = 0; 100 | } 101 | } 102 | sprintf(msg,"\n总价格 --------------- %d 元\n",sumMoney); 103 | write(sock,msg,strlen(msg)); 104 | sendFlag = 1; 105 | submitFlag = 0; 106 | } 107 | } 108 | 109 | } 110 | 111 | int startClient(void){ 112 | 113 | pthread_t tid; //定义线程号 114 | sock = socket(AF_INET,SOCK_STREAM,0); 115 | if(sock == -1){ 116 | perror("socket"); 117 | } 118 | struct sockaddr_in sockAddr; 119 | bzero(&sockAddr,sizeof(sockAddr)); 120 | sockAddr.sin_family = AF_INET; //IPV4 121 | sockAddr.sin_port = htons(50000); //PORT 122 | inet_pton(AF_INET,"192.168.1.1",&sockAddr.sin_addr); 123 | 124 | //connect server 125 | if(connect(sock, (struct sockaddr*)&sockAddr, sizeof(sockAddr))){ 126 | perror("connect success"); 127 | }else{ 128 | perror("connect failed"); 129 | } 130 | printf("connect success\n"); 131 | 132 | pthread_create(&tid, NULL, startSendDitect, NULL); //创建一个线程 133 | 134 | return 1; 135 | } 136 | 137 | #endif 138 | 139 | -------------------------------------------------------------------------------- /draw.h: -------------------------------------------------------------------------------- 1 | #ifndef __DRAW__ 2 | #define __DRAW__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "MyLib.h" 13 | 14 | #define logInBmp "picture/logInPicture.bmp" 15 | 16 | 17 | //x坐标起始点; y坐标起始点; 图片名称 18 | int displayBmpPicture( unsigned int x, unsigned int y, const char pictureName[]){ 19 | int bmpPoint, bmpReadRet, bmpBit; 20 | unsigned int bmpReadLength, bmpReadWidth,bmpLine; 21 | int lcdFilePoint,i,j; //lcd文件变量 22 | unsigned char bmpBuf[LCDSizeof] = {0}, ch = 0x00; 23 | int *mapPoint; //内存映射指针 24 | 25 | lcdFilePoint = open( LCD, O_RDWR ); //读lcd 26 | bmpPoint = open(pictureName,O_RDONLY); //读BMP文件 27 | if( lcdFilePoint == -1 || bmpPoint == -1 ){ 28 | printf("open file failed; lcd:%d; bmp:%d; %s",lcdFilePoint,bmpPoint,pictureName); 29 | return -1; 30 | } 31 | 32 | bmpReadRet = read(bmpPoint,bmpBuf,LCDSizeof); 33 | if(bmpReadRet > LCDSizeof){ 34 | perror("bmp oversize lcd screen"); 35 | return -2; 36 | }else if(bmpReadRet == -1){ 37 | perror("read bmp file failed"); 38 | return -3; 39 | } 40 | bmpReadWidth = bmpBuf[22] | bmpBuf[23]<<8 | bmpBuf[24]<<16 | bmpBuf[25]<<24; 41 | bmpReadLength = bmpBuf[18] | bmpBuf[19]<<8 | bmpBuf[20]<<16 | bmpBuf[21]<<24;; 42 | printf("picture: %s len = %d; width = %d\n",pictureName,bmpReadLength,bmpReadWidth); 43 | close(bmpPoint); 44 | 45 | //显存映射 46 | mapPoint = mmap( NULL, LCDSizeof, PROT_READ | PROT_WRITE, MAP_SHARED, lcdFilePoint, 0 ); 47 | if( mapPoint == NULL ){ //判断映射是否成功 48 | perror("mmap lcd failed"); 49 | return -4; 50 | } 51 | 52 | bmpPoint = open( pictureName, O_RDONLY ); //读bmp 53 | bzero(bmpBuf,sizeof(bmpBuf)); //清空数组 54 | lseek(bmpPoint, 54, SEEK_SET); 55 | bmpReadRet = read(bmpPoint,bmpBuf,LCDSizeof); 56 | printf("bmpReadRet = %d\n",bmpReadRet); 57 | if(bmpReadRet == -1){ 58 | perror("read file failed\n"); 59 | return -3; 60 | } 61 | 62 | bmpLine = bmpReadWidth-1; 63 | for(i = y; i < y+bmpReadWidth; i++,bmpLine--){ 64 | for(j = x; j < x+bmpReadLength; j++){ 65 | if(i 2 | #include 3 | #include 4 | #include "draw.h" 5 | #include "touchScreen.h" 6 | #include "task.h" 7 | #include "Food.h" 8 | #include "orderKey.h" 9 | #include "font.h" 10 | #include "client.h" 11 | 12 | int main(void) 13 | { 14 | Init_Font(); 15 | startTouchScreen(); 16 | startClient(); 17 | head = initFoodLink(); //读取菜单文件 18 | userHead = initUserFile(); //读取用户文件 19 | foodLink = head; 20 | while (1){ 21 | taskSchedule(); 22 | //getOrderInput(); 23 | } 24 | UnInit_Font(); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /orderKey.h: -------------------------------------------------------------------------------- 1 | #ifndef __ORDERKEY__ 2 | #define __ORDERKEY__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "MyLib.h" 13 | 14 | #define submitButton -1 15 | #define UnsubmitButton -2 16 | #define wrongInput -3 17 | #define leftSlip -4 18 | #define rightSlip -5 19 | #define position1 1 20 | #define position2 2 21 | #define position3 3 22 | #define position4 4 23 | #define position5 5 24 | #define position6 6 25 | #define longPosition1 7 26 | #define longPosition2 8 27 | #define longPosition3 9 28 | #define longPosition4 10 29 | #define longPosition5 11 30 | #define longPosition6 12 31 | 32 | 33 | 34 | #define position1Above 65 35 | #define position1Below 225 36 | #define position1Left 200 37 | #define position1Right 360 38 | #define position2Left 400 39 | #define position2Right 560 40 | #define position3Left 600 41 | #define position3Right 760 42 | 43 | #define position4Above 265 44 | #define position4Below 425 45 | #define position4Left 200 46 | #define position4Right 360 47 | #define position5Left 400 48 | #define position5Right 560 49 | #define position6Left 600 50 | #define position6Right 760 51 | 52 | #define submitAbove 430 53 | #define submitBelow 480 54 | #define submitLeft 0 55 | #define submitRight 90 56 | #define unSubmitLeft 100 57 | #define unSubmitRight 180 58 | 59 | int getOrderInput(void){ 60 | if(pressFlag == 1) pressTime++; 61 | if(touchEvent.type == EV_ABS) { //绝对事件(触摸屏) 62 | if(touchEvent.code == ABS_X) {//x轴事件 63 | x = touchEvent.value; 64 | }else if(touchEvent.code == ABS_Y){ 65 | y = touchEvent.value; 66 | }else if(touchEvent.code == ABS_PRESSURE){ 67 | if(touchEvent.value == 0){ 68 | pressFlag = 0; 69 | printf("松开\n"); 70 | printf("presstime: %d \n",pressTime); 71 | if(pressTime<12000000){ // 短按 || 滑动 72 | pressTime = 0; 73 | releaseX = x; 74 | releaseY = y; 75 | if(releaseX>pressX && (releaseX - pressX)>100){ //右划 76 | releaseX = 0; 77 | releaseY = 0; 78 | pressX = 0; 79 | pressY = 0; 80 | return rightSlip; 81 | }else if(pressX>releaseX && (pressX - releaseX)>100){ //左滑 82 | releaseX = 0; 83 | releaseY = 0; 84 | pressX = 0; 85 | pressY = 0; 86 | return leftSlip; 87 | } 88 | if(position1Above 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | 22 | //默认模式 0->主页; 1->注册; 2->登录; 23 | int modeIndex(){ 24 | if(firstInModeFlag){ 25 | firstInModeFlag = 0; 26 | displayBmpPicture(0,0,"picture/index.bmp"); 27 | } 28 | if(touchEvent.type == EV_ABS) { //绝对事件(触摸屏) 29 | if(touchEvent.code == ABS_X) {//x轴事件 30 | x = touchEvent.value; 31 | }else if(touchEvent.code == ABS_Y){ 32 | y = touchEvent.value; 33 | }else if(touchEvent.code == ABS_PRESSURE){ 34 | if(touchEvent.value == 0){ 35 | if(loginAbove主页; 1->注册; 2->登录; 38 | mode = 1; 39 | }else if(loginLeft 9999 || userPasswordInput > 9999){ 88 | displayBmpPicture(0,0,"picture/error.bmp"); 89 | printf("error!!\n"); 90 | sleep(1); 91 | mode = 0; 92 | }else{ 93 | writeUserInFile(userNameInput,userPasswordInput); 94 | userHead = initUserFile(); 95 | printf("success register\nname = %d;password = %d\n",userNameInput,userPasswordInput); 96 | displayBmpPicture(0,0,"picture/success.bmp"); 97 | mode = 0; 98 | } 99 | 100 | } 101 | if(NameInputFlag && 0<=keyBoardInput && keyBoardInput<=9){ //输入用户名 102 | loginPageFreshFlag = 1; 103 | userNameInput = keyBoardInput + userNameInput*10; 104 | printf("userName = %5d; keyboardInput = %d\n",userNameInput,keyBoardInput); 105 | } 106 | if(PasswordInputFlag && 0<=keyBoardInput && keyBoardInput<=9){ //输入密码 107 | loginPageFreshFlag = 1; 108 | userPasswordInput = keyBoardInput + userPasswordInput*10; 109 | printf("password = %5d\n",userPasswordInput); 110 | } 111 | if(PasswordInputFlag && keyBoardInput == backOffButton){ 112 | loginPageFreshFlag = 1; 113 | userPasswordInput = userPasswordInput/10; 114 | printf("password = %5d\n",userPasswordInput); 115 | } 116 | if(NameInputFlag && keyBoardInput == backOffButton){ 117 | loginPageFreshFlag = 1; 118 | userNameInput = userNameInput/10; 119 | printf("user name = %5d\n",userNameInput); 120 | } 121 | if(loginPageFreshFlag){ 122 | loginPageFreshFlag = 0; 123 | char buf[30]; 124 | int userDigit = 0, passwordDigit = 0, userTemp = userNameInput, passwordTemp = userPasswordInput; 125 | while(userTemp%10) { 126 | userDigit++; 127 | userTemp = userTemp/10; 128 | } 129 | while(passwordTemp%10){ 130 | passwordDigit++; 131 | passwordTemp = passwordTemp/10; 132 | } 133 | switch (userDigit) 134 | { 135 | case 0: 136 | displayColorBlock(390,40,780,96,white); 137 | Display_characterX(390,35,"****",black,5); 138 | break; 139 | case 1: 140 | displayColorBlock(390,40,780,96,white); 141 | sprintf(buf,"%1d***",userNameInput); 142 | Display_characterX(390,35,buf,black,5); 143 | break; 144 | case 2: 145 | displayColorBlock(390,40,780,96,white); 146 | sprintf(buf,"%2d**",userNameInput); 147 | Display_characterX(390,35,buf,black,5); 148 | break; 149 | case 3: 150 | displayColorBlock(390,40,780,96,white); 151 | sprintf(buf,"%3d*",userNameInput); 152 | Display_characterX(390,35,buf,black,5); 153 | break; 154 | case 4: 155 | displayColorBlock(390,40,780,96,white); 156 | sprintf(buf,"%4d",userNameInput); 157 | Display_characterX(390,35,buf,black,5); 158 | break; 159 | default: 160 | break; 161 | } 162 | switch (passwordDigit) 163 | { 164 | case 0: 165 | displayColorBlock(390,120,780,185,white); 166 | Display_characterX(390,120,"****",black,5); 167 | break; 168 | case 1: 169 | displayColorBlock(390,120,780,185,white); 170 | sprintf(buf,"%1d***",userPasswordInput); 171 | Display_characterX(390,120,buf,black,5); 172 | break; 173 | case 2: 174 | displayColorBlock(390,120,780,185,white); 175 | sprintf(buf,"%2d**",userPasswordInput); 176 | Display_characterX(390,120,buf,black,5); 177 | break; 178 | case 3: 179 | displayColorBlock(390,120,780,185,white); 180 | sprintf(buf,"%3d*",userPasswordInput); 181 | Display_characterX(390,120,buf,black,5); 182 | break; 183 | case 4: 184 | displayColorBlock(390,120,780,185,white); 185 | sprintf(buf,"%4d",userPasswordInput); 186 | Display_characterX(390,120,buf,black,5); 187 | break; 188 | default: 189 | break; 190 | } 191 | } 192 | } 193 | 194 | int modeLogin(){ 195 | int keyBoardInput = noInput,passFlag = 0; 196 | if(firstInModeFlag){ //第一次进入,刷新背景 197 | passFlag = 0; 198 | userNameInput = 0; 199 | userPasswordInput = 0; 200 | loginPageFreshFlag = 1; 201 | firstInModeFlag = 0; 202 | displayBmpPicture(0,0,"picture/login.bmp"); 203 | NameInputFlag = 0; 204 | PasswordInputFlag = 0; 205 | } 206 | keyBoardInput = getNumKeyInput(); 207 | if(keyBoardInput == returnButton){ 208 | printf("return button\n"); 209 | mode = 0; 210 | NameInputFlag = 0; 211 | PasswordInputFlag = 0; 212 | } 213 | if(keyBoardInput == confirmButton){ 214 | printf("confirm button\n"); 215 | mode = 3; 216 | PasswordInputFlag = 0; 217 | NameInputFlag = 0; 218 | } 219 | if(keyBoardInput == userIdButton){ 220 | printf("user id button\n"); 221 | NameInputFlag = 1; 222 | PasswordInputFlag = 0; 223 | } 224 | if(keyBoardInput == passwordButton){ 225 | printf("password button\n"); 226 | PasswordInputFlag = 1; 227 | NameInputFlag = 0; 228 | } 229 | if(keyBoardInput == confirmButton){ 230 | printf("confirm Button\n"); 231 | if(userNameInput == 0 || userPasswordInput == 0){ 232 | displayBmpPicture(0,0,"picture/error.bmp"); 233 | printf("error!!\n"); 234 | sleep(1); 235 | mode = 0; 236 | } 237 | userLink = userHead; 238 | while (userLink->next != NULL){ 239 | userLink = userLink -> next; 240 | printf("read user name = %d;password = %d\n",userLink->userName,userLink->userPassword); 241 | printf("input name = %d; input password = %d\n",userNameInput,userPasswordInput); 242 | if(userLink->userName == userNameInput && userLink->userPassword == userPasswordInput){ 243 | userLink->isSelected = 1; 244 | passFlag = 1; 245 | } 246 | } 247 | if(passFlag){ //密码正确 248 | displayBmpPicture(0,0,"picture/success.bmp"); 249 | printf("success in\n"); 250 | sleep(1); 251 | mode = 3; 252 | return 1; 253 | }else{ 254 | displayBmpPicture(0,0,"picture/error.bmp"); 255 | printf("error in\n"); 256 | sleep(1); 257 | mode = 0; 258 | return 0; 259 | } 260 | } 261 | if(NameInputFlag && 0<=keyBoardInput && keyBoardInput<=9){ //输入用户名 262 | loginPageFreshFlag = 1; 263 | userNameInput = keyBoardInput + userNameInput*10; 264 | printf("userName = %5d; keyboardInput = %d\n",userNameInput,keyBoardInput); 265 | } 266 | if(PasswordInputFlag && 0<=keyBoardInput && keyBoardInput<=9){ //输入密码 267 | loginPageFreshFlag = 1; 268 | userPasswordInput = keyBoardInput + userPasswordInput*10; 269 | printf("password = %5d\n",userPasswordInput); 270 | } 271 | if(PasswordInputFlag && keyBoardInput == backOffButton){ 272 | loginPageFreshFlag = 1; 273 | userPasswordInput = userPasswordInput/10; 274 | printf("password = %5d\n",userPasswordInput); 275 | } 276 | if(NameInputFlag && keyBoardInput == backOffButton){ 277 | loginPageFreshFlag = 1; 278 | userNameInput = userNameInput/10; 279 | printf("user name = %5d\n",userNameInput); 280 | } 281 | if(loginPageFreshFlag){ 282 | loginPageFreshFlag = 0; 283 | char buf[30]; 284 | int userDigit = 0, passwordDigit = 0, userTemp = userNameInput, passwordTemp = userPasswordInput; 285 | while(userTemp%10) { 286 | userDigit++; 287 | userTemp = userTemp/10; 288 | } 289 | while(passwordTemp%10){ 290 | passwordDigit++; 291 | passwordTemp = passwordTemp/10; 292 | } 293 | switch (userDigit) 294 | { 295 | case 0: 296 | displayColorBlock(390,40,780,96,white); 297 | Display_characterX(390,35,"****",black,5); 298 | break; 299 | case 1: 300 | displayColorBlock(390,40,780,96,white); 301 | sprintf(buf,"%1d***",userNameInput); 302 | Display_characterX(390,35,buf,black,5); 303 | break; 304 | case 2: 305 | displayColorBlock(390,40,780,96,white); 306 | sprintf(buf,"%2d**",userNameInput); 307 | Display_characterX(390,35,buf,black,5); 308 | break; 309 | case 3: 310 | displayColorBlock(390,40,780,96,white); 311 | sprintf(buf,"%3d*",userNameInput); 312 | Display_characterX(390,35,buf,black,5); 313 | break; 314 | case 4: 315 | displayColorBlock(390,40,780,96,white); 316 | sprintf(buf,"%4d",userNameInput); 317 | Display_characterX(390,35,buf,black,5); 318 | break; 319 | default: 320 | break; 321 | } 322 | switch (passwordDigit) 323 | { 324 | case 0: 325 | displayColorBlock(390,120,780,185,white); 326 | Display_characterX(390,120,"****",black,5); 327 | break; 328 | case 1: 329 | displayColorBlock(390,120,780,185,white); 330 | sprintf(buf,"%1d***",userPasswordInput); 331 | Display_characterX(390,120,buf,black,5); 332 | break; 333 | case 2: 334 | displayColorBlock(390,120,780,185,white); 335 | sprintf(buf,"%2d**",userPasswordInput); 336 | Display_characterX(390,120,buf,black,5); 337 | break; 338 | case 3: 339 | displayColorBlock(390,120,780,185,white); 340 | sprintf(buf,"%3d*",userPasswordInput); 341 | Display_characterX(390,120,buf,black,5); 342 | break; 343 | case 4: 344 | displayColorBlock(390,120,780,185,white); 345 | sprintf(buf,"%4d",userPasswordInput); 346 | Display_characterX(390,120,buf,black,5); 347 | break; 348 | default: 349 | break; 350 | } 351 | } 352 | } 353 | 354 | /**struct Food{ 355 | int foodIdentify; 356 | int attribute; 357 | int pageRowPosition; 358 | int pageColumePosition; 359 | int orderNum; 360 | struct Food* next; 361 | };*/ 362 | 363 | int initOrderPage(){ 364 | char foodBmpName[30],strBuf[30]; 365 | if(firstInModeFlag){ //第一次进入,刷新背景 366 | firstInModeFlag = 0; 367 | //清空点餐记录 368 | foodLink = head; 369 | while (foodLink->next != NULL){ 370 | foodLink = foodLink -> next; 371 | foodLink->orderNum = 0; 372 | } 373 | displayBmpPicture(0,0,"picture/menu.bmp"); 374 | } 375 | if(firstInMenuPage){ //第一次进入本页菜单 376 | firstInMenuPage = 0; 377 | orderRefreshFlag = 1; 378 | displayBmpPicture(0,0,"picture/menu.bmp"); 379 | displayColorBlock(200,15,200+10,15+10,white); 380 | displayColorBlock(330,15,330+10,15+10,white); 381 | displayColorBlock(480,15,480+10,15+10,white); 382 | displayColorBlock(630,15,630+10,15+10,white); 383 | switch (menuPage) 384 | { 385 | case 1: 386 | displayColorBlock(200,15,200+10,15+10,green); 387 | break; 388 | case 2: 389 | displayColorBlock(330,15,330+10,15+10,green); 390 | break; 391 | case 3: 392 | displayColorBlock(480,15,480+10,15+10,green); 393 | break; 394 | case 4: 395 | displayColorBlock(630,15,630+10,15+10,green); 396 | break; 397 | default: 398 | break; 399 | } 400 | foodLink = head; 401 | while (foodLink->next != NULL){ 402 | foodLink = foodLink -> next; 403 | if(foodLink -> attribute == menuPage){ //该食物为本页面所属 404 | sprintf(foodBmpName,"picture/%d.bmp",foodLink->foodIdentify); 405 | displayBmpPicture((foodLink->pageColumePosition)*200,(foodLink->pageRowPosition - 1)*200 + 65,foodBmpName); 406 | displayColorBlock((foodLink->pageColumePosition)*200,(foodLink->pageRowPosition - 1)*200 + 65,\ 407 | (foodLink->pageColumePosition)*200+10,(foodLink->pageRowPosition - 1)*200 + 65+10,white); 408 | } 409 | } 410 | } 411 | if(orderRefreshFlag == 1){ //页面需要刷新 412 | int listPosition = 0; 413 | int money = 0; 414 | orderRefreshFlag = 0; 415 | foodLink = head; 416 | displayColorBlock(0,56,185,420,white); 417 | while (foodLink->next != NULL){ 418 | foodLink = foodLink -> next; 419 | if(foodLink -> attribute == menuPage){ //该食物为本页面所属 420 | if(foodLink -> orderNum>0){ 421 | displayColorBlock((foodLink->pageColumePosition)*200,(foodLink->pageRowPosition - 1)*200 + 65,\ 422 | (foodLink->pageColumePosition)*200+10,(foodLink->pageRowPosition - 1)*200 + 65+10,green); 423 | }else{ 424 | displayColorBlock((foodLink->pageColumePosition)*200,(foodLink->pageRowPosition - 1)*200 + 65,\ 425 | (foodLink->pageColumePosition)*200+10,(foodLink->pageRowPosition - 1)*200 + 65+10,white); 426 | } 427 | } 428 | if(foodLink->orderNum>0){ //本菜品被点 429 | money = money + (foodLink->orderNum)*(foodLink->money); 430 | displayColorBlock(0,395,185,420,white); 431 | FreshList(foodLink->foodIdentify,foodLink->orderNum,black,listPosition++,foodLink->money); 432 | FreshList(0,0,black,-1,money); 433 | } 434 | } 435 | } 436 | } 437 | 438 | int modeOrder(){ 439 | int orderInput; 440 | int foodId,foodNum,foodPosition; 441 | 442 | initOrderPage(); 443 | 444 | orderInput = getOrderInput(); 445 | 446 | if(orderInput != wrongInput){ //有效输入 447 | orderRefreshFlag = 1; 448 | printf("order input : %d\n",orderInput); 449 | switch (orderInput) 450 | { 451 | case submitButton: //提交订单 452 | mode = 4; 453 | submitFlag = 1; 454 | printf("subumit\n"); 455 | break; 456 | case UnsubmitButton: //返回 457 | mode = 2; 458 | printf("unsubmit\n"); 459 | break; 460 | case leftSlip: 461 | printf("left slip\n"); 462 | menuPage++; 463 | if(menuPage>4) menuPage = 4; 464 | printf("menu page:%d\n",menuPage); 465 | firstInMenuPage = 1; 466 | break; 467 | case rightSlip: 468 | printf("right slip\n"); 469 | menuPage--; 470 | if(menuPage<1) menuPage = 1; 471 | printf("menu page:%d\n",menuPage); 472 | firstInMenuPage = 1; 473 | break; 474 | default: //菜单操作 475 | printf("position Input: %d\n",orderInput); 476 | if(1<=orderInput && orderInput<=6){ //加菜功能 477 | foodLink = head; 478 | while (foodLink->next != NULL){ 479 | foodLink = foodLink -> next; 480 | if(foodLink -> attribute == menuPage){ //该食物为本页面所属 481 | foodPosition = ((foodLink -> pageRowPosition) - 1) *3 + foodLink -> pageColumePosition; //计算食物编码 482 | if(foodPosition == orderInput){ 483 | foodLink->orderNum = foodLink->orderNum + 1; 484 | printf("food = %d orderNum = %d\n",foodLink->foodIdentify,foodLink->orderNum); 485 | } 486 | } 487 | } 488 | }else{ //减菜功能 489 | foodLink = head; 490 | while (foodLink->next != NULL){ 491 | foodLink = foodLink -> next; 492 | if(foodLink -> attribute == menuPage){ //该食物为本页面所属 493 | foodPosition = ((foodLink -> pageRowPosition) - 1) *3 + foodLink -> pageColumePosition; //计算食物编码 494 | if((foodPosition + 6 ) == orderInput){ 495 | foodLink->orderNum = foodLink->orderNum - 1; 496 | if (foodLink->orderNum < 0) foodLink->orderNum = 0; 497 | printf("food = %d orderNum = %d\n",foodLink->foodIdentify,foodLink->orderNum); 498 | } 499 | } 500 | } 501 | } 502 | break; 503 | } 504 | } 505 | } 506 | 507 | int modeSubmit(){ 508 | if(firstInModeFlag){ //第一次进入,刷新背景 509 | firstInModeFlag = 0; 510 | displayBmpPicture(0,0,"picture/wait.bmp"); 511 | } 512 | if(sendFlag){ 513 | sendFlag = 0; 514 | submitFlag = 0; 515 | displayBmpPicture(0,0,"picture/success.bmp"); 516 | mode = 0; 517 | } 518 | } 519 | 520 | //默认模式 0->主页; 1->注册; 2->登录; 521 | int taskSchedule(){ 522 | if(mode != lastMode){ 523 | firstInModeFlag = 1; 524 | lastMode = mode; 525 | } 526 | switch (mode) 527 | { 528 | case 0: 529 | modeIndex(); 530 | break; 531 | case 1: 532 | modeRegister(); 533 | break; 534 | case 2: 535 | modeLogin(); 536 | break; 537 | case 3: 538 | modeOrder(); 539 | break; 540 | case 4: 541 | modeSubmit(); 542 | default: 543 | break; 544 | } 545 | } 546 | 547 | #endif 548 | -------------------------------------------------------------------------------- /touchScreen.h: -------------------------------------------------------------------------------- 1 | #ifndef __TOUCHSCREEN__ 2 | #define __TOUCHSCREEN__ 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "MyLib.h" 14 | 15 | 16 | 17 | void *start_routine(void *arg) 18 | { 19 | while(1){ 20 | read(touchFilePoint,&touchEvent,sizeof(touchEvent)); 21 | } 22 | 23 | } 24 | 25 | int startTouchScreen(void){ 26 | 27 | pthread_t tid; //定义线程号 28 | 29 | //打开屏幕触摸文件 30 | touchFilePoint = open(touchFile, O_RDONLY); 31 | if(touchFilePoint == -1){ 32 | perror("open touchFile failed:"); 33 | return -1; 34 | } 35 | 36 | pthread_create(&tid, NULL, start_routine, NULL); //创建一个线程 37 | 38 | 39 | return 1; 40 | } 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /user.h: -------------------------------------------------------------------------------- 1 | #ifndef __USER__ 2 | #define __USER__ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #define UserFile "user.txt" 9 | 10 | int NameInputFlag = 0; 11 | int PasswordInputFlag = 0; 12 | int userNameInput = 0; 13 | int userPasswordInput = 0; 14 | int loginPageFreshFlag = 1; 15 | 16 | 17 | struct User{ 18 | int userName; 19 | int userPassword; 20 | int isSelected; 21 | struct User* next; 22 | }; 23 | 24 | 25 | struct User* initUserFile(){ 26 | struct User* head = (struct User*)malloc(sizeof(struct User)); //创建头结点 27 | struct User* node = NULL,* end = head; 28 | FILE* filePoint; 29 | filePoint = fopen(UserFile,"r"); 30 | int user,password; 31 | 32 | /*打开文件操作*/ 33 | if(filePoint == NULL){ 34 | printf("fail to open the User file\n"); 35 | return NULL; 36 | }else{ 37 | printf("open the User file\n"); 38 | } 39 | while( fscanf(filePoint,"%d %d",&user,&password) != EOF ) { //按行读取用户文件 40 | //printf("read user name = %d;password = %d\n",user,password); 41 | node = (struct User*)malloc(sizeof(struct User)); 42 | node->userName = user; 43 | node->userPassword = password; 44 | node->isSelected = 0; 45 | end->next = node; 46 | end = node; 47 | } 48 | end->next = NULL; //结束创建 49 | fclose(filePoint); //关闭文件 50 | return head; 51 | } 52 | 53 | int writeUserInFile(int userName,int password){ 54 | char buf[30]; 55 | FILE* filePoint; 56 | filePoint = fopen(UserFile,"a"); //追加文本 57 | sprintf(buf,"%4d\n%4d\n",userName,password); 58 | fputs(buf,filePoint); 59 | fclose(filePoint); 60 | return 1; 61 | } 62 | 63 | #endif -------------------------------------------------------------------------------- /user.txt: -------------------------------------------------------------------------------- 1 | 1234 2 | 1234 3 | -------------------------------------------------------------------------------- /点单记录.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangxinshuo0421/self-service-ordering-system-based-on-ARM-A53/a93d2bac25bde90075fe773594196bed905990db/点单记录.txt --------------------------------------------------------------------------------