⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ledrv.c

📁 是一个键盘测试程序
💻 C
字号:
#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <termios.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <errno.h>#include "ledrv.h"#define	MAX_CHARACTERS		6#define	FONT_SIZE		16#define	FONT_IN_BYTES		((FONT_SIZE * FONT_SIZE + 7) / 8)#define	MAX_DOTFONT_BUFFER	(1 + (8 + 1) * 4 * MAX_CHARACTERS)	// 一个长度字节,每个字分4块,每块8个字节加一个异或#define	START_OFFSET		0#define	MAX_PATH 		2048#define	MAX_LINE		4096#define MIN(x ,y)		(x < y ? x : y)#define	DATA_ONLY/***@brief  设置串口通信速率*@param  fd     类型 int  打开串口的文件句柄*@param  speed  类型 int  串口速度*@return  void*/void SetSerialSpeed(int fd, int speed){	int   i; 	int   status; 	struct termios   Opt;	int speed_arr[] = 	{ 		B38400, B19200, B9600, B4800, B2400, B1200, B300,		B38400, B19200, B9600, B4800, B2400, B1200, B300, 	};		int name_arr[] = 	{		38400,  19200,  9600,  4800,  2400,  1200,  300, 38400,  		19200,  9600, 4800, 2400, 1200,  300, 	};	tcgetattr(fd, &Opt);	for ( i= 0;  i < sizeof(speed_arr) / sizeof(speed_arr[0]);  i++) 	{		if  (speed == name_arr[i]) 		{     			tcflush(fd, TCIOFLUSH);     			cfsetispeed(&Opt, speed_arr[i]);  			cfsetospeed(&Opt, speed_arr[i]);#ifdef DATA_ONLY			Opt.c_lflag  &= ~(ICANON | ECHO | ECHOE | ISIG);  /*Input*/			Opt.c_oflag  &= ~OPOST;   /*Output*/#endif			status = tcsetattr(fd, TCSANOW, &Opt);  			if  (status != 0) 			{        				perror("SetSerialSpeed");  				return;     			}    			tcflush(fd, TCIOFLUSH);		}  	}}/***@brief   设置串口数据位,停止位和效验位*@param  fd     类型  int  打开的串口文件句柄*@param  databits 类型  int 数据位   取值 为 7 或者8*@param  stopbits 类型  int 停止位   取值为 1 或者2*@param  parity  类型  int  效验类型 取值为N,E,O,,S*/int SetSerialParity(int fd, int databits, int stopbits, int parity){ 	struct termios options; 	if(tcgetattr(fd, &options)  !=  0) 	{ 		perror("SetParity 1");     		return	-1;	}	options.c_cflag &= ~CSIZE; 	switch (databits) /*设置数据位数*/	{   	case 7:				options.c_cflag |= CS7; 		break;	case 8:     		options.c_cflag |= CS8;		break;   	default:    		fprintf(stderr, "Unsupported data size\n"); 		return -2;  	}	switch (parity) 	{   	case 'n':	case 'N':    		options.c_cflag &= ~PARENB;				/* Clear parity enable */		options.c_iflag &= ~INPCK;				/* Disable parity checking */ 		break;	case 'o':   	case 'O':     		options.c_cflag |= (PARODD | PARENB);	/* 设置为奇效验*/  		options.c_iflag |= INPCK;				/* Enable parity checking */ 		break;	case 'e':  	case 'E':   		options.c_cflag |= PARENB;				/* Enable parity */    		options.c_cflag &= ~PARODD;				/* 转换为偶效验*/     		options.c_iflag |= INPCK;				/* Enable parity checking */		break;	case 'S': 	case 's':  /*as no parity*/   		options.c_cflag &= ~PARENB;		options.c_cflag &= ~CSTOPB;		break;	default:   		fprintf(stderr,"Unsupported parity\n");    		return -3;	}	/* 设置停止位*/  	switch (stopbits)	{   	case 1:    		options.c_cflag &= ~CSTOPB;  		break;	case 2:    		options.c_cflag |= CSTOPB;  		break;	default:    		fprintf(stderr,"Unsupported stop bits\n");  		return -4; 	}	/* Set input parity option */ 	if (parity != 'n')	{		options.c_iflag |= INPCK;	}	tcflush(fd, TCIFLUSH);	options.c_cc[VTIME] = 150;	/* 设置超时15 seconds*/   	options.c_cc[VMIN]	= 0;	/* Update the options and do it NOW */	if (tcsetattr(fd, TCSANOW, &options) != 0)   	{ 		perror("SetParity 3");   		return -5;  	}	return 0;}typedef unsigned char SET;/* add(s,i): Add a single integer to a set. */#define setbit(set,i)		         ((set) | singleset (i))/* singleset(i): Return a set with one element in it. */#define singleset(i)         (((SET) 1) << (i))#define getbit(i,set)       (singleset((i)) & (set))void _led_compress(ledrv_t* drv, unsigned char* ob) {	//[16][16*6]	int x, y, i, pos;	pos = 0;	for(y = 0; y< 96; y+= 16) {		for(x = 0 ;x <16; x++) {			for(i = 0; i < 8; i++) {				if(drv->buffer[x][y+i])					ob[pos] = setbit(ob[pos],7 - i);			}			pos++;			for(i = 8; i < 16; i++) {				if(drv->buffer[x][y+i])					ob[pos] = setbit(ob[pos],15 - i );			}			pos++;		}	}}unsigned char SwapBits(unsigned char byIn){#if 0		int i;	unsigned char byOut = 0;	for(i = 0; i < 8; i++)	{		if(byIn & (1 << i))		{			byOut |= 1 << (7 - i);		}	}		return	byOut;#else	return	byIn;#endif}void FillBlock(int nBlock, unsigned char* pbyBufBase, unsigned char* pbyDots){	int j = 0;	unsigned char byXor = 0;		switch(nBlock)	{	case	0:		// 块0		pbyBufBase[j++] = SwapBits(pbyDots[14]);		pbyBufBase[j++] = SwapBits(pbyDots[12]);		pbyBufBase[j++] = SwapBits(pbyDots[10]);		pbyBufBase[j++] = SwapBits(pbyDots[8]);		pbyBufBase[j++] = SwapBits(pbyDots[6]);		pbyBufBase[j++] = SwapBits(pbyDots[4]);		pbyBufBase[j++] = SwapBits(pbyDots[2]);		pbyBufBase[j++] = SwapBits(pbyDots[0]);		byXor = 0;		byXor ^= SwapBits(pbyDots[0]);		byXor ^= SwapBits(pbyDots[2]);		byXor ^= SwapBits(pbyDots[4]);		byXor ^= SwapBits(pbyDots[6]);		byXor ^= SwapBits(pbyDots[8]);		byXor ^= SwapBits(pbyDots[10]);		byXor ^= SwapBits(pbyDots[12]);		byXor ^= SwapBits(pbyDots[14]);		pbyBufBase[j++] = byXor;		break;		case	1:		// 块1		pbyBufBase[j++] = SwapBits(pbyDots[30]);		pbyBufBase[j++] = SwapBits(pbyDots[28]);		pbyBufBase[j++] = SwapBits(pbyDots[26]);		pbyBufBase[j++] = SwapBits(pbyDots[24]);		pbyBufBase[j++] = SwapBits(pbyDots[22]);		pbyBufBase[j++] = SwapBits(pbyDots[20]);		pbyBufBase[j++] = SwapBits(pbyDots[18]);		pbyBufBase[j++] = SwapBits(pbyDots[16]);		byXor = 0;		byXor ^= SwapBits(pbyDots[16]);		byXor ^= SwapBits(pbyDots[18]);		byXor ^= SwapBits(pbyDots[20]);		byXor ^= SwapBits(pbyDots[22]);		byXor ^= SwapBits(pbyDots[24]);		byXor ^= SwapBits(pbyDots[26]);		byXor ^= SwapBits(pbyDots[28]);		byXor ^= SwapBits(pbyDots[30]);		pbyBufBase[j++] = byXor;				break;		case	2:		// 块2		pbyBufBase[j++] = SwapBits(pbyDots[15]);		pbyBufBase[j++] = SwapBits(pbyDots[13]);		pbyBufBase[j++] = SwapBits(pbyDots[11]);		pbyBufBase[j++] = SwapBits(pbyDots[9]);		pbyBufBase[j++] = SwapBits(pbyDots[7]);		pbyBufBase[j++] = SwapBits(pbyDots[5]);		pbyBufBase[j++] = SwapBits(pbyDots[3]);		pbyBufBase[j++] = SwapBits(pbyDots[1]);		byXor = 0;		byXor ^= SwapBits(pbyDots[1]);		byXor ^= SwapBits(pbyDots[3]);		byXor ^= SwapBits(pbyDots[5]);		byXor ^= SwapBits(pbyDots[7]);		byXor ^= SwapBits(pbyDots[9]);		byXor ^= SwapBits(pbyDots[11]);		byXor ^= SwapBits(pbyDots[13]);		byXor ^= SwapBits(pbyDots[15]);		pbyBufBase[j++] = byXor;				break;			case	3:		// 块3		pbyBufBase[j++] = SwapBits(pbyDots[31]);		pbyBufBase[j++] = SwapBits(pbyDots[29]);		pbyBufBase[j++] = SwapBits(pbyDots[27]);		pbyBufBase[j++] = SwapBits(pbyDots[25]);		pbyBufBase[j++] = SwapBits(pbyDots[23]);		pbyBufBase[j++] = SwapBits(pbyDots[21]);		pbyBufBase[j++] = SwapBits(pbyDots[19]);		pbyBufBase[j++] = SwapBits(pbyDots[17]);		byXor = 0;		byXor ^= SwapBits(pbyDots[17]);		byXor ^= SwapBits(pbyDots[19]);		byXor ^= SwapBits(pbyDots[21]);		byXor ^= SwapBits(pbyDots[23]);		byXor ^= SwapBits(pbyDots[25]);		byXor ^= SwapBits(pbyDots[27]);		byXor ^= SwapBits(pbyDots[29]);		byXor ^= SwapBits(pbyDots[31]);		pbyBufBase[j++] = byXor;			break;		default:		break;			}}int _flushtoled(int fd, unsigned char* abyDots){	int nCount;	int i, j, nRow, nCol;	//unsigned char abyDots[(MAX_CHARACTERS+1) * FONT_IN_BYTES];	nCount = 6;	unsigned char gabyDotFont[MAX_DOTFONT_BUFFER];	memset(gabyDotFont, 0, sizeof(gabyDotFont));	for(i = 0; i < nCount; i++)	{		j = 1 + i * (8 + 1) * 4 ;				// 块0, 1, 2, 3		FillBlock(0, &gabyDotFont[j], abyDots + i * FONT_IN_BYTES);		FillBlock(1, &gabyDotFont[j + 9], abyDots + i * FONT_IN_BYTES);		FillBlock(2, &gabyDotFont[j + 18], abyDots + i * FONT_IN_BYTES);		FillBlock(3, &gabyDotFont[j + 27], abyDots + i * FONT_IN_BYTES);	}		gabyDotFont[0] = nCount * (8 + 1) * 4;		/*	printf("len:%d",1+gabyDotFont[0]);	{		int i;		for(i = 1;i<1+gabyDotFont[0];i++) {			printf(":%d",gabyDotFont[i]);		}		}	*/	write(fd, gabyDotFont, 1 + gabyDotFont[0]);	return	nCount;}ledrv_t* ledrv_init_default(){	return ledrv_init("/dev/ttyS0",9600);}ledrv_t* ledrv_init(const char* devfile, int bps){	FT_Error error;	FT_UInt glyph_index;	ledrv_t* drv = (ledrv_t*)malloc(sizeof(ledrv_t));   memset(drv,0,sizeof(ledrv_t));   drv->fd = open(devfile, O_RDWR);   SetSerialSpeed(drv->fd, bps);	//SetSerialSpeed(fd, 12800);   SetSerialParity(drv->fd, 8, 1, 'E');	/* change this value if you wanna to greater the space between chars */	drv->char_sep = 2; 	//load fonts	/* handle to face object */  	error = FT_Init_FreeType( &(drv->library) ); 	if ( error ) { 		//ledrv_destory(drv);				goto ERROR_OPEN;	} 	//error = FT_New_Face( library, "simsun.ttc", 0, &face ); 	error = FT_New_Face( drv->library, "wq9pt.pcf", 0, &(drv->face) );	if ( error == FT_Err_Unknown_File_Format ) { 		//... the font file could be opened and read, but it appears ... that its font format is unsupported		printf("unsupport font"); 		goto ERROR_OPEN;	} else if ( error ) { 		//... another error code means that the font file could not ... be opened or read, or simply that it is broken...		printf("file read error %d",error); 		goto ERROR_OPEN;	}	drv->bStop_show = 0;		error = FT_Set_Char_Size( drv->face, /* handle to face object */  									0, /* char_width in 1/64th of points */  								  	16*64, /* char_height in 1/64th of points */								    600, /* horizontal device resolution */  //600x75									300 ); /* vertical device resolution */   return drv;ERROR_OPEN:	ledrv_destory(drv);	return NULL;}void ledrv_clear(ledrv_t* drv){	memset(drv->buffer,0,sizeof(drv->buffer));}int ledrv_flush(ledrv_t* drv){   unsigned char abyDots[(MAX_CHARACTERS+1) * FONT_IN_BYTES];	memset(abyDots,0,sizeof(abyDots));   _led_compress(drv,abyDots);	_flushtoled(drv->fd,abyDots);	return 0;}void ledrv_destory(ledrv_t* drv){	if(drv->fd)		close(drv->fd);	if(drv->face){		FT_Done_Face(drv->face);	}	if(drv->library) 		FT_Done_FreeType(drv->library);   free(drv);}static void my_draw_bitmap(ledrv_t* drv, int basex, int basey, FT_Bitmap * bitmap){	int i,j;	unsigned char* line;	int x, y;	for(i = 0;i<bitmap->rows;i++) {		line = bitmap->buffer+bitmap->pitch*i;		/*printf("LINE%2d:%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",			i,			line[0],line[1],line[2],line[3],			line[4],line[5],line[6],line[7]);*/		//printf("LINE%2d:",i);		x = basex + i;		for(j=0;j<bitmap->pitch;j++) {			int p;			//printf("\t%d",line[j]);			for(p = 0; p < 8 ; p++) {				y = basey + p +8*j;				if(getbit(7 - p,line[j])) {					if((x>0 && x < 16) && (y>0 && y < 96)) {						drv->buffer[x][y] = 1;					}					//printf("x=%d,y=%d\n",x,y);				} //end if getbit				//printf("x=%d,y=%d\n",x,y);			} //end if for p		} //end if for j		//printf("\n");	} //end if for i}int __draw_text(ledrv_t* drv, short x, short y, unsigned short text, short bDraw){	FT_Error error;	FT_UInt glyph_index;	int next_pos = y;	glyph_index = FT_Get_Char_Index( drv->face, 			text);//			//0x0057);//			//0x56FD ); 	//printf("%d\n",glyph_index);	error = FT_Load_Glyph(		drv->face, /* face对象的句柄 */		glyph_index, /* 字形索引 */		FT_LOAD_TARGET_MONO  |FT_LOAD_MONOCHROME); /* 装载标志,参考下面 */	if(error) {		printf("load graph error");		return -1;	} 	 	if(FT_GLYPH_FORMAT_BITMAP != drv->face->glyph->format) {		//convert to bitmap		FT_GlyphSlot slot = drv->face->glyph;		int pen_x, pen_y, n;				pen_x = 300; pen_y = 200; 		error = FT_Render_Glyph( drv->face->glyph, /* 字形槽 */				FT_RENDER_MODE_MONO ); /* 渲染模式 */ 		if(error) {			printf("to bitmap error");			return -2;		}		//printf("heell");		//my_draw_bitmap( &slot->bitmap, pen_x + slot->bitmap_left, pen_y - slot->bitmap_top );	} else{		FT_GlyphSlot slot = drv->face->glyph;		int pen_x = 12 - slot->bitmap_top;		int pen_y = slot->bitmap_left;		int block_w = slot->advance.x/48;		//printf("l:%d,w:%d.pw:%d\n", slot->bitmap_left ,slot->bitmap.width,slot->advance.x);		//next_pos = y + slot->bitmap.width + drv->char_sep; //3 the chars sep		//next_pos = slot->bitmap_left + y + slot->bitmap.width + drv->char_sep;// + drv->char_sep;		next_pos = y + block_w;		pen_y = (block_w - slot->bitmap.width)/2; 		//drv->buffer[0][next_pos] = 1;		if(bDraw)			my_draw_bitmap(drv, pen_x + x, pen_y + y ,&slot->bitmap);	}		return next_pos;}int draw_text(ledrv_t* drv, short x, short y, unsigned short* text, int * nextpos){	int i = 0;	unsigned short * chr = text;	int next_pos = y;	while(*chr) {		int next_pos1 = __draw_text(drv, x ,next_pos, *chr,0);		if(next_pos1>0)			next_pos = __draw_text(drv, x ,next_pos, *chr,1);		else			next_pos = next_pos1;		if(next_pos > 96)			break;		//i++;		chr ++;	}	if(nextpos)		*nextpos = next_pos;	return chr - text;}int get_text_draw_length(ledrv_t* drv, unsigned short* text) {	unsigned short * chr = text;	int next_pos = 0;	while(*chr) {		next_pos = __draw_text(drv, 0 ,next_pos, *chr,0);		chr ++;	}	return next_pos;}int draw_line(ledrv_t* drv, short sx, short sy, short ex, short ey){	drv->buffer[0][0] = 1;	drv->buffer[0][2] = 1;	drv->buffer[1][1] = 1;	drv->buffer[2][2] = 1;	drv->buffer[3][3] = 1;	drv->buffer[4][4] = 1;	drv->buffer[5][5] = 1;	drv->buffer[6][6] = 1;	drv->buffer[7][7] = 1;	drv->buffer[8][8] = 1;	drv->buffer[9][9] = 1;	drv->buffer[10][10] = 1;	drv->buffer[10][12] = 1;	/*	drv->buffer[11][11] = 1;	drv->buffer[12][12] = 1;	drv->buffer[13][13] = 1;	drv->buffer[14][14] = 1;	drv->buffer[15][15] = 1;	drv->buffer[15][94] = 1;	*/	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -