第一阶段的学习已经完成,老师布置了一个阶段验收项目,我以为是电子相册,谁知道,是这个,售货机,来说一下自己的心得体会吧
1 大二下学期的时候,有一个一周的简易项目需要完成,学生信息管理系统,不涉及到UI,数据库,网络,就是一个简简单单的vc6环境下的学生信息管理系统,功能?增删改查即可,老师说完要求,所有人,一半的人开始抱怨,难,另一半的人开始敲了,少数人开始思考怎么写,过了一会老师才说,你们是不是没做过项目呀,“是!”,“我去”,教你们,先画流程图,框架图,功能模块图,先写报告,编程是小事,第一次听老师提及项目这个词
2培训班老师说完,就开始想我应该怎么写,老师给我支招,先画流程图,再在主函数中写自己要做的东西的备注,先做什么再做什么
3画完流程图,写完备注后,思路果然清晰了许多,知道自己应该怎么做,做完后哪里可以优化升级一下了,编程?一天完成的差不多了,编程确实是小事
好了,给大家带来代码吧
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <linux/input.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <stdbool.h>
#include "fp.h"
extern int *lcd_memory;
extern int lcd_fd ;
extern char n_16x32[][64] ;
extern char n_buf[][16];
int main()
{
int x , y ;
int pet_number = 0 ;//代表pet的标号,范围为 1~8,
int page_current = 1 ;//代表当前页数
int pet_select = 0 ;
struct input_event events ;
int touch_fd = open_lcd() ;
// 2 打开触摸屏
// 3 初始化链表
listnode head = init_list() ;
// 4 信息录入(从文件夹下的data.txt录入)如果没有自己插入
int struNumber = info_entering(head,"./petData.txt") ;//信息录入
show_all(head);
printf(" struNumber : mainfile : %d\n",struNumber);
listnode newOne = head->next ;
if(struNumber == 0)// if no member in txt , aumotically add pets information
{
add_node(head,1,"Pikachu",1,100,"./pica.bmp");
add_node(head,2,"cabi",0,150,"./cabi.bmp");
add_node(head,3,"jng",0,130,"./jng.bmp");
add_node(head,4,"littleGray",1,170,"./littleGray.bmp");
add_node(head,5,"mwzz",1,200,"./mwzz.bmp");
add_node(head,6,"spike",1,300,"./spike.bmp");
add_node(head,7,"pinkball",1,200,"./pinkBall.bmp");
add_node(head,8,"xhl",1,300,"./xhl.bmp");
}
//电脑端显示所有的信息
show_all(head);
// 5 进入欢迎界面 3秒后进入售卖界面
show_bmp( "./bg.bmp");
pageshow( head , 1);//刚开始显示第一页
// 6 如果点击上一页或者下一页,便刷新
int pos[3] = {-1,-1,-1};
while(1)
{
kick_pos(pos);
printf("x = %d y = %d pressure = %d\n", pos[0], pos[1], pos[2]);
x = pos[0];
y = pos[1];
if(CANCEL_SIGN)
{
//cancel(head);
pet_select = 0 ;
if(page_current == 1)
{
pageshow(head,1) ;
}
else
{
pageshow(head,2) ;
}
}
if(PREV)
{
Next_And_Prev( &page_current , head , pet_select );
}
if(NEXT)
{
Next_And_Prev( &page_current , head , pet_select );
}
if(PET_1)
{
kick_pet( page_current , &pet_select , head , 1 ) ;
show_all(head);
}
if(PET_2)
{
kick_pet( page_current , &pet_select , head , 2 ) ;
show_all(head);
}
if(PET_3)
{
kick_pet( page_current , &pet_select , head , 3 ) ;
show_all(head);
}
if(PET_4)
{
kick_pet( page_current , &pet_select , head , 4 ) ;
show_all(head);
}
if(CHECK)
{
if(pet_select >= 1 && pet_select <= 8 )
{
show_bmp( "./bg.bmp");
//show_pay1( "./pay.bmp" , head, pet_select, "./paysign.bmp");
confirm_mode("./payConfirm.bmp" , head , &pet_select);
//confirm_mode(char *confirmPic , listnode head , int petNumber , int *pet_select)
pet_select = 0 ;
if(page_current == 1)
{
pageshow(head,1) ;
}
else
{
pageshow(head,2) ;
}
}
show_all(head);
}
if(ZONE_EXIT)
{
info_save( head );
clear_lcd();
break;
}
}
return 0;
}
#ifndef _FP_H_
#define _FP_H_
typedef struct node{
int petNumber;
char petName[20] ;
int petSurplus;
double petPrice;
char petPic[50] ;
struct node *next; //next指向后一个节点指针(后继指针),
}*listnode;
extern char n_buf[][16];
extern char n_16x32[][64];
extern int *lcd_memory;
extern int lcd_fd ;
#define PAY_1 x >= 124 && y >= 24 && x < 230 && y < 120
#define PAY_2 x >= 276 && y >= 24 && x < 380 && y < 120
#define PAY_3 x >= 426 && y >= 24 && x < 530 && y < 120
#define PAY_4 x >= 576 && y >= 24 && x < 680 && y < 120
#define PET_1 x >= 40 && y >= 60 && x < 190 && y < 360
#define PET_2 x >= 230 && y >= 60 && x < 380 && y < 360
#define PET_3 x >= 420 && y >= 60 && x < 570 && y < 360
#define PET_4 x >= 610 && y >= 60 && x < 760 && y < 360
#define CANCEL_SIGN x >= 40 && y >= 370 && x < 190 && y < 470
#define PREV x >= 230 && y >= 370 && x < 380 && y < 470
#define NEXT x >= 420 && y >= 370 && x < 570 && y < 470
#define CHECK x >= 610 && y >= 370 && x < 760 && y < 470
#define ZONE_CONFIRM x >= 0 && y >= 380 && x < 360 && y < 480
#define ZONE_CANCEL x >= 440 && y >= 380 && x < 800 && y < 480
#define ZONE_EXIT x >= 770 && y >= 0 && x < 800 && y < 30
int lcd_draw_bmp( int x0 , int y0 , char* bmpAddress );
int open_lcd();
void show_all(listnode head);
listnode init_list();
int info_entering( listnode head , char* fileAddress );
int show_bmp( char* bmpAddress);
int add_node(listnode head,int petNumber,char* petName,int petSurplus,double petPrice ,char* petPic);
int pageshow(listnode head , int page);
void kick_pos(int *pos);
void show_num16x32(int x,int y, int num, int color);
void show_money(int x, int y, int money);
int show_pay( char* payAddress , listnode head, int petNumber ,char* paySignAddress);
void kick_pet( int page_current , int* pet_select , listnode head , int zoneNumber );
void Next_And_Prev( int* page_current , listnode head , int pet_select );
void confirm_mode(char *confirmPic , listnode head , int *pet_select);
int soldout_draw_bmp( int picNumber, char *bmpname);
bool soldout_judge( listnode head , int petNumber);
int pay_way(listnode tmp, int petNumber);
void draw_bar(int x0, int y0, int width, int height, int speed, int color);
int info_save( struct node *head );
void close_lcd();
void clear_lcd();
#endif
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <linux/input.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <stdbool.h>
#include "fp.h"
int *lcd_memory ;
int lcd_fd ;
//8*16
char n_buf[][16] ={
{0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,
0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00},/*"0",0*/
{0x00,0x00,0x00,0x08,0x0E,0x08,0x08,0x08,
0x08,0x08,0x08,0x08,0x08,0x3E,0x00,0x00},/*"1",1*/
{0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x20,
0x20,0x10,0x08,0x04,0x42,0x7E,0x00,0x00},/*"2",2*/
{0x00,0x00,0x00,0x3C,0x42,0x42,0x20,0x18,
0x20,0x40,0x40,0x42,0x22,0x1C,0x00,0x00},/*"3",3*/
{0x00,0x00,0x00,0x20,0x30,0x28,0x24,0x24,
0x22,0x22,0x7E,0x20,0x20,0x78,0x00,0x00},/*"4",4*/
{0x00,0x00,0x00,0x7E,0x02,0x02,0x02,0x1A,
0x26,0x40,0x40,0x42,0x22,0x1C,0x00,0x00},/*"5",5*/
{0x00,0x00,0x00,0x38,0x24,0x02,0x02,0x1A,
0x26,0x42,0x42,0x42,0x24,0x18,0x00,0x00},/*"6",6*/
{0x00,0x00,0x00,0x7E,0x22,0x22,0x10,0x10,
0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00},/*"7",7*/
{0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x24,
0x18,0x24,0x42,0x42,0x42,0x3C,0x00,0x00},/*"8",8*/
{0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,
0x64,0x58,0x40,0x40,0x24,0x1C,0x00,0x00} /*"9",9*/
};
//16*16
char n_16x32[][64] = {
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xC0,0x07,0x60,0x0C,
0x30,0x18,0x18,0x30,0x18,0x30,0x18,0x20,
0x0C,0x60,0x0C,0x60,0x0C,0x60,0x0C,0x60,
0x0C,0x60,0x0C,0x60,0x0C,0x60,0x0C,0x60,
0x0C,0x60,0x18,0x20,0x18,0x30,0x18,0x30,
0x30,0x18,0x60,0x0C,0xC0,0x07,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"0",0*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,
0xF8,0x01,0x80,0x01,0x80,0x01,0x80,0x01,
0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,
0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,
0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,
0x80,0x01,0xC0,0x03,0xF8,0x1F,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"1",1*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xE0,0x07,0x10,0x1C,
0x08,0x18,0x04,0x30,0x04,0x30,0x0C,0x30,
0x0C,0x30,0x00,0x30,0x00,0x18,0x00,0x08,
0x00,0x04,0x00,0x02,0x00,0x01,0x80,0x00,
0x40,0x00,0x20,0x20,0x10,0x20,0x08,0x20,
0x04,0x30,0xFC,0x1F,0xFC,0x1F,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"2",2*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xE0,0x03,0x18,0x0E,
0x0C,0x0C,0x0C,0x18,0x0C,0x18,0x0C,0x18,
0x00,0x18,0x00,0x0C,0x00,0x06,0xC0,0x03,
0x00,0x0E,0x00,0x18,0x00,0x10,0x00,0x30,
0x00,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x10,
0x0C,0x18,0x18,0x0C,0xE0,0x03,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"3",3*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x0E,
0x00,0x0E,0x00,0x0F,0x80,0x0E,0x80,0x0E,
0x40,0x0E,0x60,0x0E,0x20,0x0E,0x10,0x0E,
0x10,0x0E,0x08,0x0E,0x04,0x0E,0x04,0x0E,
0xFE,0x7F,0x00,0x0E,0x00,0x0E,0x00,0x0E,
0x00,0x0E,0x00,0x0E,0x00,0x0E,0xC0,0x7F,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"4",4*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xF0,0x3F,0xF0,0x3F,
0x10,0x00,0x10,0x00,0x10,0x00,0x08,0x00,
0x08,0x00,0xC8,0x07,0x28,0x0C,0x18,0x18,
0x08,0x10,0x00,0x30,0x00,0x30,0x00,0x30,
0x00,0x30,0x0C,0x30,0x0C,0x30,0x04,0x18,
0x04,0x18,0x08,0x0C,0xF0,0x03,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"5",5*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x80,0x0F,0xC0,0x10,
0x20,0x30,0x10,0x30,0x18,0x00,0x18,0x00,
0x08,0x00,0x0C,0x00,0x8C,0x0F,0x6C,0x18,
0x3C,0x30,0x1C,0x60,0x0C,0x60,0x0C,0x60,
0x0C,0x60,0x0C,0x60,0x18,0x60,0x18,0x20,
0x30,0x30,0x60,0x18,0xC0,0x07,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"6",6*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xF8,0x3F,0xF8,0x3F,
0x1C,0x10,0x0C,0x08,0x04,0x08,0x04,0x04,
0x00,0x04,0x00,0x02,0x00,0x02,0x00,0x01,
0x00,0x01,0x00,0x01,0x80,0x00,0x80,0x00,
0x80,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,
0xC0,0x00,0xC0,0x00,0xC0,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"7",7*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xE0,0x07,0x30,0x0C,
0x18,0x18,0x0C,0x30,0x0C,0x30,0x0C,0x30,
0x1C,0x30,0x38,0x18,0x70,0x08,0xE0,0x07,
0xB0,0x07,0x18,0x0E,0x0C,0x1C,0x06,0x38,
0x06,0x30,0x06,0x30,0x06,0x30,0x06,0x30,
0x0C,0x18,0x18,0x0C,0xE0,0x03,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"8",8*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xE0,0x03,0x18,0x04,
0x0C,0x08,0x0C,0x18,0x06,0x10,0x06,0x30,
0x06,0x30,0x06,0x30,0x06,0x30,0x06,0x38,
0x0C,0x3C,0x18,0x36,0xF0,0x31,0x00,0x30,
0x00,0x18,0x00,0x18,0x00,0x18,0x0C,0x0C,
0x0C,0x06,0x0C,0x03,0xF0,0x01,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}/*"9",9*/
};
//void draw_bar(int x0, int y0, int width, int height, int speed, int color);
// 1 打开lcd
/******************************************
*
* 函数功能: 打开显示屏,并关联一块与显示屏规格相同的内存
*
* 函数版本: v1.0
*
* 编写作者: 荆州张球王
*
* 编写时间: 2019,8,19
*
* 参数说明: 全局变量 int *lcd_memory; int lcd_fd ;
*
*
*********************************************/
int open_lcd()
{
//打开显示屏
lcd_fd = open("/dev/fb0",O_RDWR);
if(lcd_fd == -1)
{
perror("open lcd error");
return -1;
}
//把显存映射到用户空间
lcd_memory = mmap(NULL, //由系统自己寻找一个合适起始地址
800*480*4, //要映射多大的空间
PROT_READ|PROT_WRITE,//得到空间权限 可读可写
MAP_SHARED, //作为共享内存使用
lcd_fd, //可用的描述符,入口
0);
}
/******************************************
*
* 函数功能: 初始化链表
*
* 函数版本: v1.0
*
* 编写作者: 荆州张球王
*
* 编写时间: 2019,8,19
*
*
* 返回头结点地址
*
*********************************************/
//初始链表
listnode init_list()
{
listnode head = malloc(sizeof(struct node)); //申请头结点空间
if(head == NULL)
{
perror("list init error");
return NULL;
}
head->next = NULL;
return head;//返回头结点地址
}
/******************************************
*
* 函数功能: 将数据数据从文件(fileAddress)录入到head链表中
*
* 函数版本: v1.0
*
* 编写作者: 荆州张球王
*
* 编写时间: 2019,8,19
*
* 参数说明: 链表的头结点
*
* 返回值: 录入成功的个数
*
*********************************************/
int info_entering( listnode head , char* fileAddress )
{
FILE *fp = fopen(fileAddress,"r");
if(fp == NULL)
{
perror("fopen petData error");
return -1;
}
else
{
printf("fopen petData succeed\n");
}
int sizeOfStru = sizeof(struct node);
long sizeOfTXT ;
int struNumber;//stru number
if( fseek(fp,0,SEEK_END) == -1 )
{
perror(" set seek failed\n");
return -1;
}//get the size of txt
else
sizeOfTXT = ftell(fp);
printf(" number :%ld\n",sizeOfTXT);
rewind(fp);
struNumber =(int) (sizeOfTXT/sizeOfStru);// get how many strus
int i,ret;
printf(" fp : %ld\n",ftell(fp));
struct node tmp;
printf(" struNUmber : %d\n",struNumber);
for( i = 0 ; i < struNumber ; i++ )
{
ret = fread(&tmp,sizeOfStru,1,fp);
if( ret == 0 )
perror("fread txt file error\n");
//add_node(head,tmp.id_num,tmp.status,tmp.chinese,tmp.math,tmp.English,tmp.passwd,tmp.address,tmp.sex);
printf(" fp : %ld\n",ftell(fp));
}
fclose(fp);
return struNumber;
}
/******************************************
*
* 函数功能: 将数据数据从文件(fileAddress)录入到head链表中
*
* 函数版本: v1.0
*
* 编写作者: 荆州张球王
*
* 编写时间: 2019,8,19
*
* 参数说明: 自己定义的链表新节点,以及新节点中的所有元素数据
*
* 返回值: 无
*
*********************************************/
//初始化数据,将参数中的数据按结点中的成员的数据类型赋给新的成员结点
void data_init(listnode newnode ,int petNumber,char* petName,int petSurplus,double petPrice ,char* petPic)
{
newnode->petNumber = petNumber;
strcpy(newnode->petName,petName);
newnode->petSurplus = petSurplus;
newnode->petPrice = petPrice;
strcpy(newnode->petPic,petPic);
}
/******************************************
*
* 函数功能: 显示bmp图片
*
* 函数版本: v1.0
*
* 编写作者: 荆州张球王
*
* 编写时间: 2019,8,19
*
* 参数说明: 图片地址
*
* 返回值: 错误返回 -1
*
*********************************************/
//显示 bmp图片
int show_bmp( char* bmpAddress)
{
if( bmpAddress == NULL )
{
printf(" wrong address\n") ;
return -1 ;
}
char bmp_info[54] = {0};
char bmp_data[800*480*4] = {0};
char *p = bmp_data;
//3 打开bmp图片
int bmp_fd = open(bmpAddress,O_RDWR);
if(bmp_fd == -1)
{
perror(" open lcd error");
return -1;
}
//4 读取54个字节的头信息
int bmpinfo_read_ret = read(bmp_fd,bmp_info,54);
if(bmpinfo_read_ret == -1)
{
perror(" read bmp error \n");
return -1;
}
int bmp_width = bmp_info[18] | bmp_info[19] << 8;
int bmp_height = bmp_info[22] | bmp_info[23] << 8;
printf(" width : %d\n",bmp_width);
printf(" height : %d\n",bmp_height);
int bmp_type = 24;
//5 读取颜色数据
int bmpcolor_read_ret = read(bmp_fd,bmp_data,800*480*4);
if(bmpcolor_read_ret == -1)
{
perror(" read bmp color error \n");
return -1;
}
//6 处理数据
int i,j, color;
for(i = 0; (i < 480) && (i < bmp_height); i++)
{
for(j = 0; (j < 800) && (j < bmp_width); j++)
{
color = *p | *(p+1) << 8 | *(p+2) << 16;
p += 3;
* (lcd_memory + 800*480 - 1 - ( 800*i + j)) = color;
}
}
}
/******************************************
*
* 函数功能: 插入新节点
*
* 函数版本: v1.0
*
* 编写作者: 荆州张球王
*
* 编写时间: 2019,8,19
*
* 参数说明: 链表头节点,新节点的所有数据
*
* 返回值: 无
*
*********************************************/
int add_node(listnode head,int petNumber,char* petName,int petSurplus,double petPrice ,char* petPic)
{
listnode newnode = malloc(sizeof(struct node));
if(newnode == NULL)
{
perror("malloc newnode error");
return -1;
}
//2、初始化节点数据
data_init( newnode, petNumber, petName, petSurplus, petPrice , petPic);
//3找到链表尾部
listnode p = head;
while(p->next != NULL) //如果p->next不等于 NULL,证明后面还有节点
{
p = p->next;
}
newnode->next = p->next;
p->next = newnode;
//printf("尾插法所接入的数据 %d,%c\n", p->next->id_num,p->next->status);
return 0;
}
/******************************************
*
* 函数功能: 将图片展现在特定的位置(x0,y0将会为图片的左上角)
*
* 函数版本: v1.0
*
* 编写作者: 荆州张球王
*
* 编写时间: 2019.8.19
*
* 参数说明: 链表头节点,图片起始位置
*
* 返回值: 无
*
*********************************************/
int lcd_draw_bmp(int x0, int y0, char *bmpname)
{
int i, j;
int bmp_fd = 0;
int color = 0; //存储整理好颜色
char blue, green, red; //临时存储单个颜色
int bmp_height, bmp_width; //存储高度信息和宽度信息
char bmp_info[54] = {0};
char bmp_data[800*480*4] = {0};
char *data_p = bmp_data;
//把图片的颜色数取出,整理一下,写入
bmp_fd = open(bmpname, O_RDONLY);
if(bmp_fd == -1)
{
perror("open bmp error");
return -1;
}
read(bmp_fd, bmp_info, 54); //读取属性信息
//得到宽度信息
bmp_width = bmp_info[18];
bmp_width |= bmp_info[19] << 8;
//得到高度信息
bmp_height = bmp_info[22];
bmp_height |= bmp_info[23] << 8;
printf("width = %d\nheight = %d\n", bmp_width, bmp_height);
read(bmp_fd, bmp_data, 800*480*4);
//-----------------------------------------------
//写颜色数据到入口
for(i = y0+bmp_height-1; i >= y0; i--)
{
for(j = x0; j < x0+bmp_width; j++)
{
blue = *data_p++; //i*3
green = *data_p++;
red = *data_p++;
color = blue << 0 | green << 8 | red << 16;
*(lcd_memory+i*800+j) = color;
}
}
//把图片关掉
close(bmp_fd);
}
/******************************************
*
* 函数功能: 将链表中的数按表的格式展示在电脑端
*
* 函数版本: v1.0
*
* 编写作者: 荆州张球王
*
* 编写时间: 2019,8,19
*
* 参数说明: 链表头节点
*
* 返回值: 无
*
*********************************************/
//将链表中的数按表的格式展示在电脑端
void show_all(listnode head)
{
listnode tmp = head;
//printf("\tI\tS\tC\tM\tE\tA\t\tSEX\n\n");
while(tmp->next != NULL)
{
printf("\t%d\t%s\t%d\t%f\t%s\t\n\n",tmp->next->petNumber,tmp->next->petName,tmp->next->petSurplus,tmp->next->petPrice ,tmp->next->petPic);
tmp = tmp->next;
}
}
/******************************************
*
* 函数功能: 按照页号(page),将链表中的指定数据打印出来
*
* 函数版本: v1.0
*
* 编写作者: 荆州张球王
*
* 编写时间: 2019.8.19
*
* 参数说明: 头节点名,页号
*
* 返回值: 出错返回-1
*
*********************************************/
//按照页号(page),将链表中的指定数据打印出来
int pageshow(listnode head , int page )
{
show_bmp("./bg.bmp");
int petX = 40 ;
int petY = 60 ;
int petMoney = 30 ;
int time = 1 ;
listnode p = head;
if( page == 1 )
{
while( p->next != NULL && time %5 != 0) //如果p->next不等于 NULL,证明后面还有节点
{
p = p->next;
lcd_draw_bmp( ((p->petNumber - 1 )*148 + petX * time ), petY, p->petPic);
show_money((( p->petNumber - 1 )*148 + petX *( time - 1 ) )+60, petMoney, p->petPrice);
if( !soldout_judge( head , p->petNumber ) )
{
soldout_draw_bmp(p->petNumber, "./soldout.bmp");
}
time++;
}
}
if( page == 2 )
{
time = 1;
while( time != 5 )
{
p = p->next;
time++;
}
time = 1;
while( time != 5 ) //如果p->next不等于 NULL,证明后面还有节点
{
p = p->next;
lcd_draw_bmp( (( p->petNumber - 5 )*148 + petX * time ), petY, p->petPic);
show_money((( p->petNumber - 5 )*148 + petX *( time - 1 ))+60, petMoney, p->petPrice);
if( !soldout_judge( head , p->petNumber ) )
{
soldout_draw_bmp(p->petNumber, "./soldout.bmp");
}
time++;
}
}
lcd_draw_bmp( 228, 370, "./leftArrow.bmp");
lcd_draw_bmp( 418, 370, "./rightArrow.bmp");
lcd_draw_bmp( 608, 370, "./check.bmp");
lcd_draw_bmp( 40, 370, "./cancel.bmp");
lcd_draw_bmp( 772, 0, "./exit.bmp");
}
/******************************************
*
* 函数功能: 按照图片的编号,将标记图片打印在传入参数的图片的位置上
*
* 函数版本: v1.0
*
* 编写作者: 荆州张球王
*
* 编写时间: 2019.8.19
*
* 参数说明: 图片名,图片编号
*
* 返回值: 出错返回-1
*
*********************************************/
//按照图片的编号,将标记图片打印在传入参数的图片的位置上
int pointer_draw_bmp( int picNumber, char *bmpname)
{
int i, j;
int x0,y0;
if( picNumber <= 4 )
x0 = ( picNumber - 1 )*148 + picNumber*40 ;
else
x0 = ( picNumber - 5 )*148 + (picNumber - 4)*40 ;
y0 = 260;
int bmp_fd = 0;
int color = 0; //存储整理好颜色
char blue, green, red; //临时存储单个颜色
int bmp_height, bmp_width; //存储高度信息和宽度信息
char bmp_info[54] = {0};
char bmp_data[800*480*4] = {0};
char *data_p = bmp_data;
//把图片的颜色数取出,整理一下,写入
bmp_fd = open(bmpname, O_RDONLY);
if(bmp_fd == -1)
{
perror("open bmp error");
return -1;
}
read(bmp_fd, bmp_info, 54); //读取属性信息
//得到宽度信息
bmp_width = bmp_info[18];
bmp_width |= bmp_info[19] << 8;
//得到高度信息
bmp_height = bmp_info[22];
bmp_height |= bmp_info[23] << 8;
printf("width = %d\nheight = %d\n", bmp_width, bmp_height);
read(bmp_fd, bmp_data, 800*480*4);
//-----------------------------------------------
//写颜色数据到入口
for(i = y0+bmp_height-1; i >= y0; i--)
{
for(j = x0; j < x0+bmp_width; j++)
{
blue = *data_p++; //i*3
green = *data_p++;
red = *data_p++;
color = blue << 0 | green << 8 | red << 16;
*(lcd_memory+i*800+j) = color;
}
}
//把图片关掉
close(bmp_fd);
}
/******************************************
*
* 函数功能: 根据用户在触摸屏上的点击,修改pos中数据(数据修改为横坐标,纵坐标,pressure值)
*
* 函数版本: v1.0
*
* 编写作者: 荆州张球王
*
* 编写时间: 2019.8.19
*
* 参数说明: 位置数组
*
* 返回值: 无
*
*********************************************/
//
void kick_pos(int* pos)
{
struct input_event events;
pos[0] = -1, pos[1] = -1, pos[2] = -1;
int touch_fd = open("/dev/input/event0", O_RDWR);
if(touch_fd == -1)
perror("open touch error");
while(1)
{
int ret = read(touch_fd, &events, sizeof(events));
if(ret == -1)
perror("read error");
//分析报告
if(events.type == EV_ABS)
{
if(events.code == ABS_X)
pos[0] = events.value;
if(events.code == ABS_Y)
pos[1] = events.value;
if(events.code == ABS_PRESSURE)
{
pos[2] = events.value;
if(pos[2] == 0)
//printf("x = %d y = %d pressure = %d\n", pos[0], pos[1], pos[2]);
close(touch_fd);
break;
}
}
}
}
/******************************************
*
* 函数功能: 展示支付模块,先显示支付选择的界面,用户可以通过点击按钮选择支付方式
*
* 函数版本: v1.0
*
* 编写作者: 荆州张球王
*
* 编写时间: 2019.8.19
*
* 参数说明: 支付图片的地址,头节点,宠物号,各类图片地址
*
* 返回值: 无
*
*********************************************/
int show_pay( char* payAddress , listnode head, int petNumber ,char* paySignAddress)
{
//先显示支付选择的界面
//用户可以通过点击按钮选择支付方式
listnode tmp = head ;
while( (tmp->next)->petNumber != petNumber )
{
tmp = tmp->next;
}
//lcd_draw_bmp(222, 60, (tmp->next)->petPic);
lcd_draw_bmp(0,0, "./newPay.bmp");
lcd_draw_bmp(250,390, paySignAddress);//115,12
show_money(365, 402, (tmp->next)->petPrice);//三位数时,定位为555,312
pay_way((tmp->next), petNumber);
return 1;
}
/******************************************
*
* 函数功能: 确认模块
*
* 函数版本: v1.0
*
* 编写作者: 荆州张球王
*
* 编写时间: 2019.8.19
*
* 参数说明: 确认的图片地址,头节点,宠物选择
*
* 返回值: 无
*
*********************************************/
void confirm_mode(char *confirmPic , listnode head , int *pet_select)
{
int x, y;
lcd_draw_bmp(0, 360, confirmPic) ;
listnode tmp = head ;
while( (tmp->next)->petNumber != *pet_select )
{
tmp = tmp->next;
}
lcd_draw_bmp(222, 60, (tmp->next)->petPic);
show_money(555, 240, (tmp->next)->petPrice);//三位数时,定位为555,312
int pos_confirm[3] = {-1,-1,-1};
while(1)
{
kick_pos(pos_confirm);
printf("x = %d y = %d pressure = %d\n", pos_confirm[0], pos_confirm[1], pos_confirm[2]);
x = pos_confirm[0];
y = pos_confirm[1];
if(ZONE_CONFIRM)
{
show_pay( "./pay.bmp" , head, *pet_select, "./paysign.bmp");
*pet_select = 0;
break;
}
if(ZONE_CANCEL)
{
*pet_select = 0;
pageshow(head , 1);
break;
}
}
}
/******************************************
*
* 函数功能: 16*32 数字显示
*
* 函数版本: v1.0
*
* 编写作者: 荆州张球王
*
* 编写时间: 2019.8.19
*
* 参数说明: 数字显示的起始地址,颜色
*
* 返回值: 无
*
*********************************************/
//显示数字16*32
void show_num16x32(int x,int y, int num, int color)
{
int i = 0,j = 0, s = 0;
char A = 0x1;
int k;
k = 0;
for(i = 0; i < 32; i++)
{
s = 0;
for(j = 0; j < 8; j++)
{
if(A<<s & n_16x32[num][k])
{
*(lcd_memory+ (i+y)*800 + (j+x)) = color;
}
s++;
}
s = 0;
k++;
for(j = 8 ; j < 16; j++)
{
if(A<<s & n_16x32[num][k])
{
*(lcd_memory+ (i+y)*800 + (j+x)) = color;
}
s++;
}
k++;
}
}
/******************************************
*
* 函数功能: 显示金额
*
* 函数版本: v1.0
*
* 编写作者: 荆州张球王
*
* 编写时间: 2019.8.19
*
* 参数说明: 数字起始地址,金额
*
* 返回值: 无
*
*********************************************/
//显示金额 2300 1 0 0 0 2 int = 2331/1000
void show_money(int x, int y, int money)
{
if(money >= 1000)
show_num16x32(x, y, money/1000, 0xff0000); //显示 千位
show_num16x32(x+20, y, money%1000/100, 0xff0000); //显示 百位
show_num16x32(x+40, y, money%1000%100/10, 0xff0000); //显示 十位
show_num16x32(x+60, y, money%10, 0xff0000); //显示 个位
}
/******************************************
*
* 函数功能: 宠物选择数
*
* 函数版本: v1.0
*
* 编写作者: 荆州张球王
*
* 编写时间: 2019.8.19
*
* 参数说明: 当前页,宠物选择数,头节点,区域数区域选择( zoneNumber = 1 ~ 4 )
*
* 返回值: 无
*
*********************************************/
void kick_pet( int page_current , int* pet_select , listnode head , int zoneNumber )
{
if( page_current == 1 )
{
if( *pet_select != zoneNumber)
{
*pet_select = zoneNumber ;
pageshow(head,1) ;
}
if ( soldout_judge( head , *pet_select ) )
pointer_draw_bmp( *pet_select,"./pointer.bmp");
else
soldout_draw_bmp( *pet_select , "./soldout.bmp" );
}
if( page_current == 2 )
{
if( *pet_select != ( zoneNumber + 4 ) )
{
*pet_select = zoneNumber + 4 ;
pageshow(head,2) ;
}
if ( soldout_judge( head , *pet_select ) )
pointer_draw_bmp( *pet_select,"./pointer.bmp");
else
soldout_draw_bmp( *pet_select , "./soldout.bmp" );
}
}
/******************************************
*
* 函数功能: 上一页,下一页
*
* 函数版本: v1.0
*
* 编写作者: 荆州张球王
*
* 编写时间: 2019.8.19
*
* 参数说明: 当前页,宠物选择数,头节点,
*
* 返回值: 无
*
*********************************************/
void Next_And_Prev( int* page_current , listnode head , int pet_select )
{
if( *page_current == 1 )
{
pageshow(head,2) ;
if(pet_select <= 8 && pet_select >= 5)
{
pointer_draw_bmp(pet_select - 4 , "./pointer.bmp");
}
}
else
{
pageshow(head,1) ;
if(pet_select <= 4 && pet_select >= 1)
{
pointer_draw_bmp(pet_select , "./pointer.bmp");
}
}
if( *page_current == 1 )
*page_current = 2 ;
else if( *page_current == 2 )
*page_current = 1 ;
}
/******************************************
*
* 函数功能: 售尽标志显示
*
* 函数版本: v1.0
*
* 编写作者: 荆州张球王
*
* 编写时间: 2019.8.19
*
* 参数说明: 照片数,图片地址
*
* 返回值: 失败返回负一
*
*********************************************/
int soldout_draw_bmp( int picNumber, char *bmpname)
{
int i, j;
int x0,y0;
if( picNumber <= 4 )
x0 = ( picNumber - 1 )*148 + picNumber*40 ;
else
x0 = ( picNumber - 5 )*148 + (picNumber - 4)*40 ;
y0 = 60;
int bmp_fd = 0;
int color = 0; //存储整理好颜色
char blue, green, red; //临时存储单个颜色
int bmp_height, bmp_width; //存储高度信息和宽度信息
char bmp_info[54] = {0};
char bmp_data[800*480*4] = {0};
char *data_p = bmp_data;
//把图片的颜色数取出,整理一下,写入
bmp_fd = open(bmpname, O_RDONLY);
if(bmp_fd == -1)
{
perror("open bmp error");
return -1;
}
read(bmp_fd, bmp_info, 54); //读取属性信息
//得到宽度信息
bmp_width = bmp_info[18];
bmp_width |= bmp_info[19] << 8;
//得到高度信息
bmp_height = bmp_info[22];
bmp_height |= bmp_info[23] << 8;
printf("width = %d\nheight = %d\n", bmp_width, bmp_height);
read(bmp_fd, bmp_data, 800*480*4);
//-----------------------------------------------
//写颜色数据到入口
for(i = y0+bmp_height-1; i >= y0; i--)
{
for(j = x0; j < x0+bmp_width; j++)
{
blue = *data_p++; //i*3
green = *data_p++;
red = *data_p++;
color = blue << 0 | green << 8 | red << 16;
*(lcd_memory+i*800+j) = color;
}
}
//把图片关掉
//close(bmp_fd);
}
/******************************************
*
* 函数功能: 售尽判断
*
* 函数版本: v1.0
*
* 编写作者: 荆州张球王
*
* 编写时间: 2019.8.19
*
* 参数说明: 宠物编号,头节点
*
* 返回值: 判断相应宠物的数量是否为0,为0返回false,否则返回true;
*
*********************************************/
bool soldout_judge( listnode head , int petNumber )
{
listnode tmp = head->next ;
while( tmp->petNumber != petNumber )
{
tmp = tmp->next;
}
if(tmp->petSurplus == 0)
return false ;
else
return true ;
}
/******************************************
*
* 函数功能: 支付方式选择
*
* 函数版本: v1.0
*
* 编写作者: 荆州张球王
*
* 编写时间: 2019.8.19
*
* 参数说明: 宠物编号,头节点
*
* 返回值: 1
*
*********************************************/
int pay_way(listnode tmp, int petNumber)
{
int pos[3] = { -1 , -1 , -1 };
int x , y;
while(1)
{
kick_pos(pos);
printf(" payway :x = %d y = %d pressure = %d\n", pos[0], pos[1], pos[2]);
x = pos[0];
y = pos[1];
if(PAY_1)
{
lcd_draw_bmp(250, 150, "./cash.bmp");
draw_bar(250, 460, 300, 19, 100, 0xff0000);
(tmp->petSurplus)--;
sleep(3);
break;
}
if(PAY_2)
{
lcd_draw_bmp(250, 150, "./wecharPay.bmp");
draw_bar(250, 460, 300, 19, 100, 0xff0000);
(tmp->petSurplus)--;
sleep(3);
break;
}
if(PAY_3)
{
lcd_draw_bmp(250, 150, "./pay.bmp");
draw_bar(250, 460, 300, 19, 100, 0xff0000);
(tmp->petSurplus)--;
sleep(3);
break;
}
if(PAY_4)
{
lcd_draw_bmp(250, 150, "./bank.bmp");
draw_bar(250, 460, 300, 19, 100, 0xff0000);
(tmp->petSurplus)--;
sleep(3);
break;
}
}
return 1;
}
/******************************************
*
* 函数功能: 画进度条
*
* 函数版本: v1.0
*
* 编写作者: 荆州张球王
*
* 编写时间: 2019.8.19
*
* 参数说明: 进度条起始位置,进度条宽度,高度,速度,颜色
*
* 返回值: 无
*
*********************************************/
//画进度条
void draw_bar(int x0, int y0, int width, int height, int speed, int color)
{
int i, j;
for(i = x0; i < x0+width; i++)
{
for(j = y0; j < y0+height; j++)
{
*(lcd_memory+j*800+i) = color;
}
usleep(speed);
}
}
/******************************************
*
* 函数功能: 数据存储
*
* 函数版本: v1.0
*
* 编写作者: 荆州张球王
*
* 编写时间: 2019.8.19
*
* 参数说明: 头节点
*
* 返回值: 失败返回负一
*
*********************************************/
int info_save( struct node *head )
{
int number = 0;
int i = 0 ;
struct node *tmpSave;
int ret;
FILE *fp = fopen("./petData.txt","w+");
if(fp == NULL)
{
perror("fopen petData.txt error");
return -1;
}
else
{
printf("fopen petData.txt succeed\n");
}
listnode tmp = head;
while(tmp->next != NULL)
{
number++;
tmp = tmp->next;
}
tmp = head;
printf(" head : %d\n",number);
tmpSave = tmp->next;
for( i = 0 ; i < number ; i++ )
{
ret = fwrite(tmpSave,sizeof(struct node),1,fp);
tmpSave = tmpSave->next; //fseek(fp,sizeof(struct node),SEEK_CUR);
}
// printf(" end : %d\n",);
fclose(fp);
return 1;
}
/******************************************
*
* 函数功能: 关闭lcd屏幕
*
* 函数版本: v1.0
*
* 编写作者: 荆州张球王
*
* 编写时间: 2019.8.19
*
* 参数说明: 无
*
* 返回值: 无
*
*********************************************/
void close_lcd()
{
//取消映射和关闭lcd
munmap(lcd_memory, 800*480*4);
close(lcd_fd);
}
/******************************************
*
* 函数功能: 清屏
*
* 函数版本: v1.0
*
* 编写作者: 荆州张球王
*
* 编写时间: 2019.8.19
*
* 参数说明: 无
*
* 返回值: 无
*
*********************************************/
void clear_lcd()
{
//把屏幕描成黑色-------------------------------------------
memset(lcd_memory, 0, 800*480*4);
}
然后我来说说过程中我遇到的问题吧
1 图片的格式问题,开发板为800480的板子,我们图片格式选用的是bmp,24位的,图片格式(height,width)一定要是4的倍数,我刚开始用的是150300,所以图片总是斜着的,颜色也不对,找了半天,发现是图片的问题
2 当把程序分成几个部分时,头文件的问题,以及结构体,全局变量应该怎么放,这需要注意,可以看看我是怎么做的
3 最蠢的问题,多文件编译时,一定要注意,gcc file1.c file2.c … -o xxx 文件要写全,否则会出现一大堆 函数未定义的问题 ,这不是语法,逻辑上的问题,所以怎么找也找不出来,很气人的