📄 ledrv.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 + -