1. 程式人生 > >A53開發板——WIFI(ESP8266)的應用例子

A53開發板——WIFI(ESP8266)的應用例子

首先你得需要ESP8266得詳細資料,瞭解模式和AT指令

其餘程式碼中有詳細得註釋



#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <sys/mman.h>
#include <termios.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <math.h>
#include <linux/input.h>


int *plcd = NULL;//用來儲存對映首地址
int lcd_fd;//螢幕的檔案描述符
int flag_music=0;//音樂開關描述符 0是暫停狀態 1是播放狀態
int flag_yaolan=0;//搖籃開關描述符 0是暫停狀態 1是開啟狀態

char Buf3[80];
char Buf2[80];
char Buf1[80];


/*初始化lcd屏*/
int  lcd_init()
{
	/*1、開啟螢幕檔案*/
	lcd_fd = open("/dev/fb0",O_RDWR);
	if(lcd_fd == -1)
	{
		perror("oepn lcd error");
		return -1;
	}
	
	/*2、對映*/
	plcd = mmap(NULL,    //對映地址,NULL表示讓系統自行選擇
				800*480*4,	//對映地址大小
				PROT_READ|PROT_WRITE, //對映地址的許可權
				MAP_SHARED, //對映標識位
				lcd_fd, //檔案描述符,表示要對映的檔案
				0); //檔案偏移量,0表示不偏移
}

/*解除lcd*/
void lcd_uninit()
{
	/*解除對映*/
	munmap(plcd,800*480*4);
	close(lcd_fd);
}

/*
	畫點函式
	x/y 座標點的值
	colour 顏色
	
*/
void lcd_draw_point(int x,int y,int colour)
{
	*(plcd + x + y*800) = colour;
}

/*
	清屏函式
	x0,y0 清屏的起始座標
	w 清屏寬度
	h 清屏高度
	colour 顏色
*/
void lcd_draw_clear(int x0,int y0,int w,int h,unsigned int colour)
{
	int x,y;
	for(y=0;y<h;y++)
	{
		for(x=0;x<w;x++)
		{
			lcd_draw_point(x0+x,y0+y,colour);
		}
	}
}

/*
	顯示影象
	x0/y0 影象從哪開始顯示
	w/h   影象的寬和高
	file  要顯示的圖片名
*/
int image_show(int x0,int y0,int w,int h,char *file)
{
	int fd = open(file,O_RDONLY); //開啟圖片檔案
	if(fd == -1)
	{
		printf("open failed!\n");
		return -1;
	}
	char *buf = malloc(w*h*24/8);
	
	//去掉bmp前54位元組資訊頭
	lseek(fd,54,SEEK_SET);	
	
	read(fd, buf, w*h*24/8);
	//讀取畫素陣列
	//組合顏色值,呼叫畫點函式顯示
	int colour;
	char a, r, g, b;
	int x, y;
	for(y=0;y<h;y++)
	{
		for(x=0;x<w;x++)
		{
			a = 0;
			b = *buf++;
			g = *buf++;
			r = *buf++;
			colour = a << 24 | r << 16 | g << 8 | b;
			lcd_draw_point(x+x0,h-1-y+y0,colour);
		}
	}
	close(fd);
	return 0;
}




int image_show1(int l,int x0,int y0,int w,int h,char *file)
{
	int fd = open(file,O_RDONLY); //開啟圖片檔案
	if(fd == -1)
	{
		printf("open failed!\n");
		return -1;
	}
	char *buf = malloc(w*h*24/8);
	
	//去掉bmp前54位元組資訊頭
	lseek(fd,54,SEEK_SET);	
	
	read(fd, buf, w*h*24/8);
	//讀取畫素陣列
	//組合顏色值,呼叫畫點函式顯示
	int colour;
	char a, r, g, b;
	int x, y;
	int d;
	for(y=0;y<h;y++)
	{
		for(x=0;x<w;x++)
		{
			a = 0;
			b = *buf++;
			g = *buf++;
			r = *buf++;
			colour = a << 24 | r << 16 | g << 8 | b;
			if((l*l) >= (abs(x-l)*abs(x-l)+abs(y-l)*abs(y-l)))
			{
				lcd_draw_point(x+x0,h-1-y+y0,colour);
			}
		}
	}
	close(fd);
	return 0;
}



int input(void)
{
	printf("input come in!\n\n");
	/*1.open the file,input file is  /dev/event0*/
	int fd = open("/dev/input/event0",O_RDWR);
	if(fd == -1)
	{
		perror("open event0 error");
		return -1;
	}
	
	/*2.read the file get input event*/
	struct input_event ev;  //用來儲存輸入事件的結構體變數
	int x,y,value;
	int x1,y1;
	while(1)
	{
		read(fd,&ev,sizeof(ev));  //獲取輸入事件
		
		if(ev.type == EV_KEY )
		{
			if(ev.code == BTN_TOUCH)
			{
				value = ev.value;		//獲取壓力值		
			}
		}
		
		if(ev.type == EV_ABS)	//判斷是不是觸控式螢幕事件
		{
			if(ev.code == ABS_X)
			{
				x = ev.value;   //x軸座標值
			}
			if(ev.code == ABS_Y)
			{
				y = ev.value;  // y軸座標值
			}
		}
		printf("111 x : %d   y : %d   value : %d   \n\n",x,y,value);
		if(ev.type == EV_KEY )
		{
			if(ev.code == BTN_TOUCH)
			{
				printf("shijian : touch\n\n");
				if(value == 1 && x>220 && x<300 && y>350 && y<430) //表示手指離開時,xy座標在音樂區域
				{
					if(flag_music == 0)
					{
						image_show1(40,220,350,80,80,"./pause1.bmp");			
						flag_music = 1;
					}
					else if(flag_music == 1)
					{
						image_show1(40,220,350,80,80,"./play.bmp");
						flag_music =0;
					}
				}
				else if(value == 1 && x>470 && x<550 && y>350 && y<430) //表示手指離開時,xy座標在搖籃區域
				{
					if(flag_yaolan == 0)
					{
						image_show1(40,470,350,80,80,"./pause1.bmp");
						flag_yaolan = 1;
					}
					else if(flag_yaolan == 1)
					{
						image_show1(40,470,350,80,80,"./play.bmp");
						flag_yaolan =0;
					}
				}
			}
		}
	}
	/*3.close the file*/
}


/*
	初始化串列埠函式
	file:表示要開啟的串列埠
	bt:表示要設定的波特率
*/
int serial_init(char *file,int bt)
{
	int fd = open(file,O_RDWR);
	if(fd == -1)
	{
		perror("open serial error");
		return -1;
	}
	
	/*設定串列埠屬性*/
	struct termios myserial;
	memset(&myserial,0,sizeof(myserial)); //清空地址
	myserial.c_cflag |= CLOCAL | CREAD;    //設定本地連線,接受使能
	myserial.c_cflag &= ~CSIZE;				//清空資料位
	myserial.c_cflag |= CS8;				//設定資料位 8
	myserial.c_cflag &= ~CSTOPB;     		//停止位1
	myserial.c_cflag &= ~PARENB;			//不要校驗位
	myserial.c_cflag &= ~CRTSCTS;			//不要硬體控制流
	
	/*設定波特率*/
	switch(bt)
	{
		case 9600:
			cfsetispeed(&myserial,B9600);
			cfsetospeed(&myserial,B9600);
			break;
		case 57600:
			cfsetispeed(&myserial,B57600);
			cfsetospeed(&myserial,B57600);
			break;
		case 115200:
			cfsetispeed(&myserial,B115200);
			cfsetospeed(&myserial,B115200);
			break;
	}
	
	/*清空快取佇列*/
	tcflush(fd,TCIOFLUSH);
	
	/*設定生效*/
	tcsetattr(fd,TCSANOW,&myserial);
	
	return fd;	
}

/*
	WIFI模組初始化函式
	
*/
int wifi_init(int fd)
{
	printf("come in !!\n");
	char order1[]="AT+CWMODE=1\r\n";//WIFI初始化指令
	char order2[]="AT+CWJAP=\"WIFI-ESP8266\",\"66666666\"\r\n";//WIFI連線路由
	char order3[]="AT+CIPSTART=\"TCP\",\"192.168.4.1\",6666\r\n";//連線伺服器
	char ack[200]={0};//回覆資料包
	int ff;
	while(1)
	{
		ff = tcflush(fd,TCIOFLUSH);
		printf("ff1 :%d\n",ff);
		while(1)
		{
			/*傳送命令*/
			int ret0 = write(fd,order1,strlen(order1));
			ff = tcflush(fd,TCIOFLUSH);
			printf("order1:%s\n",order1);
			sleep(1);
			if(ret0 > 0)
			{	
				break;
			}
		}
		memset(ack,0,sizeof(ack));//清空字元陣列
		/*接收回複數據*/
		while (1)
		{
			int ret;
			ret = read(fd,ack,200);
			sleep(1);
			if (ret > 0)
				break;
		}
		ff = tcflush(fd,TCIOFLUSH);
		sleep(1);
		if(strstr((char const*)ack,"OK") != NULL)
		{
			printf("first if come!!! \n\n");
			while(1)
			{
				ff = tcflush(fd,TCIOFLUSH);
				/*傳送命令*/
				write(fd,order2,strlen(order2));
				ff = tcflush(fd,TCIOFLUSH);
				memset(ack,0,sizeof(ack));//清空字元陣列
				sleep(1);	
				/*接收回複數據*/
				while (1)
				{
					int ret1;
					ret1 = read(fd,ack,200);
					if (ret1 > 0)
						break;
				}
				if(strstr((char const*)ack,"OK") != NULL)
				{
					printf("2222 if come!!! \n\n");
					while(1)
					{
						ff = tcflush(fd,TCIOFLUSH);
						/*傳送命令*/
						write(fd,order3,strlen(order3));
						ff = tcflush(fd,TCIOFLUSH);
						memset(ack,0,sizeof(ack));//清空字元陣列
						/*接收回複數據*/
						while (1)
						{
							int ret2;
							ret2 = read(fd,ack,200);
							sleep(1);
							if (ret2 > 0)
								break;
						}
						if(strstr((char const*)ack,"OK") != NULL)
						{
							break;
						}
						else
						{
							continue;
						}
					}
				}
				else
				{
					continue;
				}
				break;
			}	
		}
		else
		{
			continue;
		}
		break;
	}
	return 1;
}

void* wifi()
{
	int fd = serial_init("/dev/ttySAC1",115200); //開啟WIFI模組通訊串列埠
	int ok = wifi_init(fd);
	if(ok == 1)
	{
		printf("wifi_init is ok!\n");
		lcd_draw_clear(750,30,40,20,0x00EE00);
		
	}
	int ff;
	ff = tcflush(fd,TCIOFLUSH);
	sleep(1);
	
	char wifi_order1[]="AT+CIPSEND=7\r\n";//wifi傳送指令
	
	char yaolan_open[7] = {0x3A,0x00,0x01,0x0A,0x00,0x31,0x23}; //搖籃 開啟命令
	char yaolan_close[7] = {0x3A,0x00,0x01,0x0A,0x01,0x30,0x23}; //搖籃 關閉命令
	
	char music_open[7] = {0x3A,0x00,0x01,0x0A,0x10,0x21,0x23}; //音樂 開啟命令
	char music_close[7] = {0x3A,0x00,0x01,0x0A,0x11,0x20,0x23}; //音樂 關閉命令
	
	char ack[200] = {0};//回覆資料包
	char *pAddr1;
	char *pAddr2;
	char *pAddr3;
	unsigned char len1;
	unsigned char len2;
	unsigned char len3;
	
	while(1)
	{
		memset(ack,0,sizeof(ack));//清空字元陣列
		/*接收回複數據*/
		int ret = read(fd,ack,200);
		printf("ret : %d    ack : %s\n\n",ret,ack);
		sleep(1);
		if(strstr((char const*)ack,"+IPD") != NULL)
		{
			if(strstr((char const*)ack,"E3") != NULL)
			{
				pAddr3 = strstr((char const*)ack,":");
				len3 = *(pAddr3 - 1) - 0x30;//讀取資料的長度
				pAddr3++;
				memcpy(Buf3,pAddr3,len3);
				printf("Buf3 : %c%c%c%c%c\n\n",Buf3[4],Buf3[5],Buf3[6],Buf3[7],Buf3[8]);
			}
			else if(strstr((char const*)ack,"E2") != NULL)
			{
				pAddr2 = strstr((char const*)ack,":");
				len2 = *(pAddr2 - 1) - 0x30;//讀取資料的長度
				pAddr2++;
				memcpy(Buf2,pAddr2,len2);
				printf("Buf2 : %s\n\n",Buf2);
			}
			else if(strstr((char const*)ack,"E1") != NULL)
			{
				pAddr1 = strstr((char const*)ack,":");
				len1 = *(pAddr1 - 1) - 0x30;//讀取資料的長度
				pAddr1++;
				memcpy(Buf1,pAddr1,len1);
				printf("Buf1 : %s\n\n",Buf1);
			}
		}
		printf("flag_music : %d\n\n",flag_music);
		
		//音樂開關
		if(flag_music == 1)
		{
			while(1)
			{
				//ff = tcflush(fd,TCIOFLUSH);
				/*傳送命令*/
				write(fd,wifi_order1,strlen(wifi_order1));
				//ff = tcflush(fd,TCIOFLUSH);
				//memset(ack,0,sizeof(ack));//清空字元陣列
				sleep(1);
				/*接收回複數據*/
				while (1)
				{
					int ret1;
					ret1 = read(fd,ack,200);
					printf("ret1 : %d\n\n");
					if (ret1 > 0)
						break;
				}
				printf("111music  ack : %s\n\n",ack);
				if(strstr((char const*)ack,">") != NULL)
				{
					//ff = tcflush(fd,TCIOFLUSH);
					write(fd,music_open,7);
				//	ff = tcflush(fd,TCIOFLUSH);
					while (1)
					{
						int ret2;
						ret2 = read(fd,ack,200);
						if (ret2 > 0)
							break;
					}
					printf("222music  ack : %s\n\n",ack);
					if(strstr((char const*)ack,"SEND OK") != NULL)
					{
						printf("music ok !!!\n\n");
						break;
					}
				}
			}
		}
		else if(flag_music == 0)
		{
			//ff = tcflush(fd,TCIOFLUSH);
			/*傳送命令*/
			write(fd,wifi_order1,strlen(wifi_order1));
			//ff = tcflush(fd,TCIOFLUSH);
			//memset(ack,0,sizeof(ack));//清空字元陣列
			sleep(1);
			/*接收回複數據*/
			while (1)
			{
				int ret3;
				ret3 = read(fd,ack,200);
				if (ret3 > 0)
					break;
			}
			if(strstr((char const*)ack,">") != NULL)
			{
				//ff = tcflush(fd,TCIOFLUSH);
				write(fd,music_close,7);
				//ff = tcflush(fd,TCIOFLUSH);
				while (1)
				{
					int ret4;
					ret4 = read(fd,ack,200);
					if (ret4 > 0)
						break;
				}
				if(strstr((char const*)ack,"SEND OK") != NULL)
				{
					printf("music close !!!\n\n");
					break;
				}
			}
		}
		
		//搖籃開關
		if(flag_yaolan == 1)
		{
			while(1)
			{
				//ff = tcflush(fd,TCIOFLUSH);
				/*傳送命令*/
				write(fd,wifi_order1,strlen(wifi_order1));
				//ff = tcflush(fd,TCIOFLUSH);
			//	memset(ack,0,sizeof(ack));//清空字元陣列
				sleep(1);
				/*接收回複數據*/
				while (1)
				{
					int ret5;
					ret5 = read(fd,ack,200);
					if (ret5 > 0)
						break;
				}
				if(strstr((char const*)ack,">") != NULL)
				{
					//ff = tcflush(fd,TCIOFLUSH);
					write(fd,yaolan_open,7);
					///ff = tcflush(fd,TCIOFLUSH);
					while (1)
					{
						int ret6;
						ret6 = read(fd,ack,200);
						if (ret6 > 0)
							break;
					}
					if(strstr((char const*)ack,"SEND OK") != NULL)
					{
						printf("yaolan ok !!!\n\n");
						break;
					}
				}
			}
		}
		else if(flag_yaolan == 0)
		{
			//ff = tcflush(fd,TCIOFLUSH);
			/*傳送命令*/
			write(fd,wifi_order1,strlen(wifi_order1));
			//ff = tcflush(fd,TCIOFLUSH);
		//	memset(ack,0,sizeof(ack));//清空字元陣列
			sleep(1);
			/*接收回複數據*/
			while (1)
			{
				int ret7;
				ret7 = read(fd,ack,200);
				if (ret7 > 0)
					break;
			}
			if(strstr((char const*)ack,">") != NULL)
			{
				//ff = tcflush(fd,TCIOFLUSH);
				write(fd,yaolan_close,7);
				//sff = tcflush(fd,TCIOFLUSH);
				while (1)
				{
					int ret8;
					ret8 = read(fd,ack,200);
					if (ret8 > 0)
						break;
				}
				if(strstr((char const*)ack,"SEND OK") != NULL)
				{
					printf("yaolan close !!!\n\n");
					break;
				}
			}
		}
		
		
	}
	close(fd);
	return NULL;
}



int main(void)
{
	pthread_t tid;
	pthread_create(&tid,NULL,wifi,NULL);//執行緒跑WIFI模組並接受資料

	/*1、初始化lcd屏*/
	lcd_init();
	
	/*顯示初始化介面*/
	image_show(0,0,800,480,"./baby.bmp");
	image_show1(40,220,350,80,80,"./play.bmp");
	image_show1(40,470,350,80,78,"./play.bmp");
	
	input();
	
	/*解除對映*/
	lcd_uninit();
	
	return 0;
}