| 本帖最后由 manwjh 于 2015-3-3 09:51 编辑 
 代码范例(期待您的参与?)
 /**
 
 ******************************************************************************
 * @file    graphical.c
 * @author  SZQVC
 * @version V0.2.8
 * @date    2015.2.14
 * @brief   灯塔计划.海啸项目 (QQ:49370295)
 ******************************************************************************
 * @Attention                                                                 *
 *                                                                            *
 * <h2><center>© COPYRIGHT 2015 SZQVC</center></h2>                      *
 *                                                                            *
 * 文件版权归“深圳权成安视科技有限公司”(简称SZQVC)所有。                   *
 *                                                                            *
 *        http://www.szqvc.com                                                *
 *                                                                            *
 ******************************************************************************
 
 **/
 #include "sys_includes.h"
 #include "font.c"
 #include "my_ico.c"
 
 #define PI  3.14159265358979324
 #define TWOPI (PI*2)
 
 /*----------------------------------------------------------------------------*/
 void Glph_ClrArea(uint8_t x1,uint8_t y1, uint8_t width, uint8_t high)
 {
 DrawFill(x1,y1,x1+width-1,y1+high-1,0);
 }
 
 
 /*******************************************************************************
 * Function Name  : GetASCIICode
 * Description    : 读取ASCII字符点阵数据
 * Input          : 字体(font_t),字符(a)
 * Output         :
 * Return         : 数据起始指针
 * Attention      : None
 *******************************************************************************/
 const uint8_t *GetAsciiBitmap(uint8_t font_t, char a)
 {
 char tmp;
 const uint8_t *bitmap_p;
 
 tmp = a;
 
 if( font_t==MS_GOTHIC_8X16 ){
 if( (tmp>=' ')&&(tmp<='~') ){
 bitmap_p = (uint8_t*)&Bitmap_MsGothic_8X16[tmp-32];
 }
 }else if( font_t==LED_8X16 ){
 if( (tmp>='0')&&(tmp<='9') ){
 bitmap_p = (uint8_t*)&Bitmap_LED_8X16[tmp-'0'];
 }else{
 switch( tmp ){
 case ' ':
 bitmap_p = (uint8_t*)&Bitmap_LED_8X16[10];
 break;
 case ':':
 bitmap_p = (uint8_t*)&Bitmap_LED_8X16[13];
 break;
 case '.':
 bitmap_p = (uint8_t*)&Bitmap_LED_8X16[11];
 break;
 case '`':
 bitmap_p = (uint8_t*)&Bitmap_LED_8X16[12];
 break;
 case '/':
 bitmap_p = (uint8_t*)&Bitmap_LED_8X16[14];
 break;
 case '-':
 bitmap_p = (uint8_t*)&Bitmap_LED_8X16[15];
 break;
 }
 }
 }else if( font_t==ASCII_5X7 ){
 tmp -= 32;
 if( tmp<sizeof(Bitmap_ASCII_5X7)/5 )
 bitmap_p = (uint8_t*)&Bitmap_ASCII_5X7[tmp];
 else
 bitmap_p = (uint8_t*)&Bitmap_ASCII_5X7['?'-32];
 }else if( font_t==LED_5X7 ){
 tmp -= 32;
 if( tmp<sizeof(Bitmap_LED_5X7)/5 )
 bitmap_p = (uint8_t*)&Bitmap_LED_5X7[tmp];
 else
 bitmap_p = (uint8_t*)&Bitmap_LED_5X7['?'-32];
 }
 return bitmap_p;
 }
 
 /*******************************************************************************
 * Function Name  : Glph_Print
 * Description    : 字符打印输出
 * Input          : 屏幕坐标(x,y), 字体(font_t), 字符串( *dt)
 * Output         :
 * Return         : None
 * Attention      : None
 *******************************************************************************/
 void Glph_Print(uint8_t x, uint8_t y, uint8_t font_t, char *dt)
 {
 char byte_cnt=0,tmp;
 const uint8_t *p;
 uint8_t font_width,font_high,bitmap_t;
 
 switch(font_t&0x7f){
 case LED_8X16:
 font_width=8;
 font_high=16;
 bitmap_t = BIT_MAP_HORI;
 break;
 
 case LED_5X7:
 font_width = 5;
 font_high = 8;
 bitmap_t = BIT_MAP_VERT;
 break;
 
 case MS_GOTHIC_8X16:
 font_width=8;
 font_high=16;
 bitmap_t = BIT_MAP_HORI;
 break;
 
 
 default:
 font_t = ASCII_5X7;
 case ASCII_5X7:
 font_width=5;
 font_high=8;
 bitmap_t = BIT_MAP_VERT;
 break;
 }
 
 byte_cnt = 0;
 do{
 tmp = *dt++;
 if( (tmp!=0)&&(tmp!='\r')&&(tmp!='\n')&&(tmp<0x80) ){
 p = GetAsciiBitmap( font_t&0x7f,tmp);
 if( font_t&FONT_HIGHLIGHT )
 DrawBitmap(x+byte_cnt*font_width,y,bitmap_t|BIT_MAP_REVERSE,font_width,font_high,(uint8_t*)p);
 else
 DrawBitmap(x+byte_cnt*font_width,y,bitmap_t,font_width,font_high,(uint8_t*)p);
 byte_cnt++;
 }else
 break;
 }while(1);
 }
 
 
 /*******************************************************************************
 * Function Name  : Glph_Wave
 * Description    : 绘制波形曲线
 * Input          : 屏幕坐标(x,y), 波形数据WAVE_INFO(*cfg)
 * Output         :
 * Return         : None
 * Attention      : None
 *******************************************************************************/
 void Glph_Wave(uint8_t x, uint8_t y, WAVE_INFO *cfg)
 {
 uint16_t i;
 int16_t y_value;
 int16_t *p=(int16_t*)cfg->buffer;
 int16_t val_mid,tmp;
 int16_t scale;
 //
 cfg->max_value=-32768,cfg->min_value=32767;
 
 //寻找最大值,最小值
 if( cfg->buffer_cnt>1 ){
 for( i=0; i<cfg->buffer_cnt; i++){
 if( *p>cfg->max_value )
 cfg->max_value = *p;
 if( *p<cfg->min_value )
 cfg->min_value = *p;
 p++;
 }
 }else if(cfg->buffer_cnt==1) {
 cfg->min_value = *p;
 cfg->max_value = *p;
 }else
 return;
 //Y坐标中心
 val_mid = (cfg->max_value/cfg->minification+cfg->min_value/cfg->minification)/2;
 
 //绘制波形
 DrawFill(x,y,x+cfg->img_width,y+cfg->img_high,0);
 //
 if( cfg->wave_type==0 ){
 i = cfg->buffer_cnt;
 p = cfg->buffer;
 do{
 tmp = *p++/cfg->minification-val_mid;
 //中心坐标偏值
 y_value = cfg->img_high/2-tmp;
 //是否超出坐标
 if( y_value<0 )
 y_value = 0;
 else if( y_value>(cfg->img_high-1) )
 y_value = cfg->img_high-1;
 
 DrawPoint(x+i,y+y_value,1);
 i--;
 }while(i>0);
 }else{
 scale = (cfg->max_value-cfg->min_value)/cfg->img_high;
 if(scale<cfg->minification)
 scale = cfg->minification;
 i = cfg->buffer_cnt;
 p = cfg->buffer;
 do{
 y_value = (*p++-cfg->min_value)/scale;
 //是否超出坐标
 if( y_value<0 )
 y_value = 0;
 else if( y_value>(cfg->img_high-1) )
 y_value = cfg->img_high-1;
 //
 //DrawPoint(x+i,y+y_value,1);
 DrawFill(x+i,y+cfg->img_high-y_value-1,x+i,y+cfg->img_high-1,1);
 i--;
 }while(i>0);
 }
 }
 
 /*******************************************************************************
 * Function Name  : Glph_DrawBattery
 * Description    : 绘制电池电量图标
 * Input          : 屏幕坐标(x,y), 电池电量等级(st)
 * Output         :
 * Return         : None
 * Attention      : None
 *******************************************************************************/
 void Glph_DrawBattery(uint8_t x, uint8_t y, uint8_t st)
 {
 uint8_t i = 0;
 
 DrawBitmap(x,y,BIT_MAP_VERT,28,16,(uint8_t*)ICO_V_BAT_28X16);
 if( st==ICO_BAT_CHARGE ){
 DrawBitmap(x+8,y+4,BIT_MAP_VERT,10,8,(uint8_t*)ICO_V_BAT_CHG_10X8);
 }else if( (st>=ICO_BAT_1)&&(st<=ICO_BAT_4) ){
 for( i=0; i<=st ;i++ ){
 DrawBitmap((x+5)+(i-1)*4,y+4,BIT_MAP_VERT,4,8,(uint8_t*)ICO_V_BAT_LEVEL_4X8);
 }
 }
 }
 
 /*******************************************************************************
 * Function Name  : Glph_DrawLine
 * Description    : 绘制直线(从起点到终点)
 * Input          : 屏幕开始坐标(x1,y1), 屏幕开始坐标(x2,y2),白点/黑点(t)
 * Output         :
 * Return         : None
 * Attention      : None
 *******************************************************************************/
 __inline void swap_int(int16_t *a, int16_t *b)
 {
 *a ^= *b;
 *b ^= *a;
 *a ^= *b;
 }
 
 void Glph_DrawLine(int16_t x1,int16_t y1, int16_t x2, int16_t y2, uint8_t t )
 {
 int16_t ix, iy, cx,cy,n2dy,n2dydx,d,
 dx = abs(x2-x1),
 dy = abs(y2-y1),
 yy=0;
 
 if( dx<dy ){
 yy = 1;
 swap_int(&x1,&y1);
 swap_int(&x2,&y2);
 swap_int(&dx,&dy);
 }
 
 ix = (x2-x1)>0 ? 1:-1;
 iy = (y2-y1)>0 ? 1:-1;
 cx = x1;
 cy = y1;
 n2dy = dy*2;
 n2dydx = (dy-dx)*2;
 d = dy*2 - dx;
 
 //如果直线与X轴的夹角大于45度
 if( yy ){
 while( cx!=x2 ){
 if(d<0){
 d += n2dy;
 }else{
 cy += iy;
 d += n2dydx;
 }
 DrawPoint(cy, cx, t);
 cx += ix;
 }
 }
 //如果直线与X轴的夹角小于45度
 else{
 while( cx!=x2 ){
 if( d<0 ){
 d += n2dy;
 }else{
 cy += iy;
 d += n2dydx;
 }
 DrawPoint(cx, cy, t);
 cx += ix;
 }
 }
 }
 
 /*******************************************************************************
 * Function Name  : Glph_DrawXLine
 * Description    : 绘制X射线
 * Input          : 屏幕开始坐标(x1,y1), 射线长度(r),射线角度(angle弧度),白点/黑点(t)
 * Output         :
 * Return         : None
 * Attention      : None
 *******************************************************************************/
 void Glph_DrawXLine(uint8_t x1, uint8_t y1, uint8_t r, float angle, uint8_t t)
 {
 int16_t x2,y2;
 float tmp,tt,radian;
 
 radian = angle;
 tmp = cos(radian);
 tt = tmp*r+0.5;
 x2 = x1 + tt;
 tmp = sin(radian);
 tt = tmp*r+0.5;
 y2 = y1 + tt;
 
 Glph_DrawLine(x1,y1,x2,y2,t);
 }
 
 /*******************************************************************************
 * Function Name  : Glph_Drawcircle
 * Description    : 依据圆点和半径画圆
 * Input          : 屏幕开始坐标(x1,y1), 半径(r),是否填充(fill),白点/黑点(c)
 * Output         :
 * Return         : None
 * Attention      : None
 *******************************************************************************/
 __inline void draw_circle_8( u16 xc, u16 yc, u16 x, u16 y, u16 c)
 {
 // 参数 c 为颜色值
 DrawPoint( xc + x, yc + y, c);
 DrawPoint( xc - x, yc + y, c);
 DrawPoint( xc + x, yc - y, c);
 DrawPoint( xc - x, yc - y, c);
 DrawPoint( xc + y, yc + x, c);
 DrawPoint( xc - y, yc + x, c);
 DrawPoint( xc + y, yc - x, c);
 DrawPoint( xc - y, yc - x, c);
 }
 //Bresenham's circle algorithm
 void Glph_Drawcircle( u16 xc, u16 yc, u16 r, u16 fill, u16 c)
 {
 // (xc, yc) 为圆心,r 为半径
 // fill 为是否填充
 // c 为颜色值
 // 如果圆在图片可见区域外,直接退出
 
 int x = 0, y = r, yi, d;
 d = 3 - 2 * r;
 
 if(xc + r < 0 || xc - r >= 240 || yc + r < 0 || yc - r >= 320)
 {
 return;
 }
 if(fill)
 {
 // 如果填充(画实心圆)
 while(x <= y)
 {
 for(yi = x; yi <= y; yi ++)
 {
 draw_circle_8(xc, yc, x, yi, c);
 }
 if(d < 0)
 {
 d = d + 4 * x + 6;
 }
 else
 {
 d = d + 4 * (x - y);
 y --;
 }
 
 x++;
 }
 }
 else
 {
 // 如果不填充(画空心圆)
 while (x <= y)
 {
 draw_circle_8(xc, yc, x, y, c);
 if(d < 0)
 {
 d = d + 4 * x + 6;
 }
 else
 {
 d = d + 4 * (x - y);
 y --;
 }
 x ++;
 }
 }
 }
 
 /*******************************************************************************
 * Function Name  : Glph_DrawRectangle
 * Description    : 画长方型
 * Input          : 第一点坐标(x1,y1), 第二点坐标(x2,y2),白点/黑点(c)
 * Output         :
 * Return         : None
 * Attention      : None
 *******************************************************************************/
 void Glph_DrawRectangle(uint8_t x1,uint8_t y1, uint8_t x2, uint8_t y2, uint8_t t )
 {
 int i,j;
 if(x1>x2){
 i = x1; j = x2;
 }else{
 i = x2; j = x1;
 }
 do{
 DrawPoint(j,y1,t);
 DrawPoint(j,y2,t);
 j++;
 }while(j<=i);
 //
 if(y1>y2){
 i = y1; j = y2;
 }else{
 i = y2; j = y1;
 }
 do{
 DrawPoint(x1,j,t);
 DrawPoint(x2,j,t);
 j++;
 }while(j<=i);
 }
 
 /*******************************************************************************
 * Function Name  : Glph_LoadGif
 * Description    : 加载GIF
 * Input          : 图象区域坐标(x1,y1), 是否循环(loop), GIF图象指针(*p),
 * Output         : GIF_INFO *gif_play
 * Return         : None
 * Attention      : None
 *******************************************************************************/
 void Glph_LoadGif(uint8_t x, uint8_t y, uint8_t loop, GIF_INFO *gif_play, uint8_t *p)
 {
 gif_play->scr_pos_x = (uint16_t)x;
 gif_play->scr_pos_y = (uint16_t)y;
 gif_play->img_width = (uint8_t)p[0];
 gif_play->img_high = (uint8_t)p[1];
 gif_play->frame_num = (uint8_t)p[2];
 gif_play->speed = (uint8_t)p[3];
 gif_play->play_no = 0;
 gif_play->loop = loop;
 gif_play->p = (uint8_t*)(p+gif_play->img_width);
 }
 
 /*******************************************************************************
 * Function Name  : Glph_PlayGif
 * Description    : 播放GIF
 * Input          : gif播放指针
 * Output         : None
 * Return         : None
 * Attention      : 该函数需要不断运行,依据内部的定时器判断换帧(最小间隔每帧/10ms)
 *******************************************************************************/
 void Glph_PlayGif(GIF_INFO *gif)
 {
 uint16_t p_offset;
 
 if( TimeOutCheck_ms(gif->tick_msk+gif->speed*10) ){
 gif->tick_msk = GetSysTick_ms();
 if( ( gif->loop == 1)&&(gif->play_no >= gif->frame_num) ){
 gif->play_no = 0;
 }
 //
 if( gif->play_no<gif->frame_num ){
 p_offset = gif->play_no*(gif->img_width*gif->img_high/8);
 DrawBitmap(gif->scr_pos_x,gif->scr_pos_y,BIT_MAP_VERT,gif->img_width,gif->img_high,(uint8_t*)(gif->p+p_offset));
 gif->play_no++;
 }
 }
 }
 
 #if 0
 void test_glph(void)
 {
 int i,j;
 float angle=0.0;
 /*
 do{
 Glph_DrawXLine(15,15,15,angle,1);
 OLED_ReflashTask();
 angle +=30.0;
 }while(angle<360);
 Glph_Drawcircle(32,16,5,0,1);
 */
 Glph_DrawLine(0,0,127,31,1);
 //
 display_reflash();
 while(1);
 }
 #endif
 
 
 /*********************************************************************************************************
 END FILE
 *********************************************************************************************************/
 
 
 
 |