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

📄 tft.c

📁 一款收款机C源代码!因为是几年前的代码了
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "ecrsys.h"
#include "ads7846.h"
#include "tft.h"
#include "font.h"
#include "ftype.h"

#define	TFT_WrCmd(cmd)	(*(volatile unsigned char *)0x0c00000 = cmd)
#define	TFT_WrDat(dat)	(*(volatile unsigned char *)0x0c00002 = dat)
#define putpixel(x, y, color)   Lcd_Draw_Pixel(x, y, color)

void Lcd_Draw_Pixel(int x, int y, unsigned char color);
void Lcd_Draw_HLine(int x0, int y, int x1, byte c);
void Lcd_Draw_Line(int x1,int y1,int x2,int y2, unsigned char c);
#define Lcd_Draw_VLine(x, y0, y1, c)   Lcd_Draw_Line(x, y0, x, y1, c)

int Lcd_Draw_Char(byte qu, byte wei, byte size, byte font, byte color, int x0, int y0);

/*********************************************************************************
*	Clear the mapped memory buffer of TFT
*********************************************************************************/
void	TFT_ClrDispBuffer(void)
{
	
}
/*
********************************************************************************
*	Initialize the TFT
*	Clear the TFT display buffer
*	Clear the TFT panel with TFT_Clear function
*	
********************************************************************************
*/
void	Init_TFT(void)
{
	TFT_ClrDispBuffer();		/*Need add later*/
	TFT_Clear(0x00);				/*Clear the TFT with black background*/
}


/*********************************************************************************
*	Clear the TFT display with specify color
*	Input	:	color -- the color which used for background
*
*********************************************************************************/
void TFT_Clear(char	color) 		//colorb: 背景色
{
	unsigned char	i,j;		/*To save time for scanning fast*/
	/*Write lower address*/
	TFT_WrCmd(0x00);
	TFT_WrDat(0x00);
	TFT_WrCmd(0x01);
	TFT_WrDat(0x00);
	TFT_WrCmd(0x02);
/*------------------------------------------------------------------------------
此处为了加快屏幕的刷新速度,采用了重复代码的方式, 所以也把9"和12"的代码分开
此函数考虑了优化,请不要修改此函数	
*-----------------------------------------------------------------------------*/
	for ( i = 0; i < 240; i ++ )//当使用800*600的TFT屏时, 此处就不能直接使用常数了
	{
		for ( j = 0; j < 200; j ++)
        {
            TFT_WrDat(color);
            TFT_WrDat(color);
            TFT_WrDat(color);
            TFT_WrDat(color);
            TFT_WrDat(color);
            TFT_WrDat(color);
            TFT_WrDat(color);
            TFT_WrDat(color);
            	#if (TFT_SIZE == TFT_12INCH)		/*清除12"后面的120个点行*/
            TFT_WrDat(color);
            TFT_WrDat(color);
            	#endif
		}		
	}
}

/*
    判断是否为一个汉字的区
*/
bool TFT_Text_Qu_Judge(byte dat)
{
    return (dat>=0xa1);
}

bool TFT_Text_Wei_Judge(byte dat)
{
    return (dat>=0xa1);
}

// 取得一种字体的扩展度
byte TFT_Font_Get_Size(byte size)
{
    size &= 0x0f;
    if (size < 1)
        size = 1;
    else if (size > 8)
        size = 1;
    return (size);
}

/********************************************************************************
* 函数说明:	在LCD上面,显示一串字符, 注意不能换行显示
* 输入参数:	text, len, font, size, effect, c, x0, y0
*               size为横向和纵向扩展的倍数,其中低四位为纵向扩展的\
*               高四位为横向扩展的。(1~8, 取值非法时,表明以默认字体来显示)
*               x0, y0表示为它的起始显示位置。
*               typedef EFFECT{
*                   dir:    2;  // 旋转显示, 有四种模式, 顺时针旋转90度,
*                                  逆时针旋转90度, 和倒置显示, 注意: 当
*                                  进行旋转和倒置的时候, 它的显示方向也是随之而变化
*                                  即有纵向的方向和横向的方向, 这一点与POS打印机不同.
*                   udl_line:1; // 下划线
*                   color_rvs:1;// 颜色反显的模式(不过这个需要知道背景色)
*                   blink:  1;  // 闪烁, 也需要知道背景色, 比较难以实现
*               };
*               目前, Effect的功能完全先保留, 先把扩展的功能先做上去
*               说明: 当显示中文字体的时候, 如果有ASCII码, 会取一个最相匹配的字体显示
* 输出参数:	void
* 返回值:	void
********************************************************************************/
void TFT_Lcd_Disp_Text(char *text, byte len, byte font, byte size, byte effect, byte c, int x0, int y0)
{
    byte *dot_src;      // 字库点阵首地址
    byte qu=0, wei;       // 汉字时使用,存储区和位
    bool store_qu_flag = 0; // 是否存储区的标志
    byte cur_font;      // Current font, 在中文显示中, 也会有显示英文的情况
    byte dot_buf[FONT_HOR_MAX*FONT_ELG_MAX/8];  // 开辟一个最大的行缓冲区.
    word dot_dst_inc;       // 打印一个字符时候的点长
    byte i, j, k;       // 循环变量
    byte src_inc;       // 字库的行增量
    byte hor_size;      // 横向扩展倍数
    byte vrt_size;      // 纵向扩展倍数
    int x, y;           // 当前显示的x, y增量

    hor_size = TFT_Font_Get_Size(size>>4);
    vrt_size = TFT_Font_Get_Size(size&0x0f);

//    if(font != FONT_ASC_24x48)
//        font = FONT_ASC_9x17;
    while(len--)
    {
        // 取得字体的首地址
        if (font == FONT_HZ_12x12 || font == FONT_HZ_16x16 || font == FONT_HZ_24x24)     // 中文字体
        {
            font = FONT_HZ_16x16; 
            if (!store_qu_flag)
            {
                if (TFT_Text_Qu_Judge(*text) == TRUE)
                {
                    qu = *text;
                    store_qu_flag = 1;
                    text++;
                    continue;
                }
                else
                {
                    cur_font = FONT_HZ_ASC_8x16;
                    dot_src = (byte *)&Font_Addr[cur_font][(dword)(*text-0x20)*((Font_Size[cur_font][2]+7)>>3)*(Font_Size[cur_font][3])];
                }
            }
            else
            {
                // 这里为了处理上的方便, 只要发现了区的判断是正确的, 则认为位也是正确的
                wei = *text;
                cur_font = font;
                dot_src = (byte *)&Font_Addr[cur_font][((dword)(Font_Search_Offset(qu, wei)))*((Font_Size[cur_font][2]+7)>>3)*(Font_Size[cur_font][3])];
                store_qu_flag = 0;
            }
        }
        else    // 英文字体
        {
            qu = ((*text < 0x20)? 0x20: *text);		/*此处将控制字符使用空格表示*/
            cur_font = font;
            dot_src = (byte *)&Font_Addr[cur_font][(qu-0x20)*((Font_Size[cur_font][2]+7)>>3)*(Font_Size[cur_font][3])];
            if((cur_font == BTN_DFT_FONT)&&(qu >= 0x80))//在显示特殊字符时,  需要取新的点阵地址, 目前只有9*17的点阵具有这些特殊字符的字库
                Get_Font_Addr(qu, &((dword)dot_src));
        }
        text++;

        // 根据所取得的点阵的首地址, 进行横向或者纵向扩展, 和字体效果的显示(目前,暂时还不支持字体效果)
        src_inc = (Font_Size[cur_font][2]+7)>>3;    // 每一种字体所需的移动变量
        dot_dst_inc = (word)Font_Size[cur_font][0] * hor_size;
        
        if (cur_font == FONT_HZ_16x16 )     // 中文字体
            dot_dst_inc *= 2;        
        
        y = y0;
        for (i = 0; i < Font_Size[cur_font][3]; i++)    // 总共需要显示的行数,由于有些字库最后一行可能没有,这样就可以直接不用显示
        {
            memset(dot_buf, 0, FONT_HOR_MAX*FONT_ELG_MAX/8);

            // 对点阵进行横向扩展
            if (hor_size == 1)      // 字体按照原始大小进行打印, 由于这种情况最多,所以为了节约时间,又单独进行了处理
            {
                memcpy(dot_buf, dot_src, src_inc);
                dot_src += src_inc;
            }
            else    // 字体有一定的扩展倍数
            {
                TFT_Font_Dot_ELg(dot_buf, dot_src, Font_Size[cur_font][2], hor_size); // 把扩展后的目标点阵拷贝到点阵缓冲区中。
                dot_src += src_inc;
            }

            // 把转换后的点阵显示出来, 纵向扩展等于把一列进行重复显示就行了。
            for (j = 0; j < vrt_size; j++)      // 重复显示的列数
            {
                x = x0;
                for (k = 0; k < dot_dst_inc; k++)
                {
                    if (dot_buf[k>>3]&and_table2[k&0x07])
                        putpixel(x, y, c);
                    x++;
                }
                y++;
            }
        }

        x0 += dot_dst_inc;
    }
}

/*---------------------------------------------------------------------------*
*   显示带控制字的字符串.
*   按要求显示Str_Buf的内容.
*   注意 Str_Buf 的格式必须是 Str_Buf[2][2+2*MAX_BTN_DESC_LEN] ;
*   包含的信息有: 
*   1. 共2行显示
*   2. Str_Buf的格式为 
*       Str_Buf[i][0] 表示当前行显示的字符长度
*       Str_Buf[i][1] 表示当前行字符是否采用 Bold 显示
*       Str_buf[i]+2  存放需要显示的字符串
*   此函数主要用于按键键名的显示.
*---------------------------------------------------------------------------*/
void Tft_Disp_Ctl_Str(char *Str_Buf, byte font, byte color, int x0, int y0, int x1, int y1)
{
    char *src_buf;      //取当前需要处理的字符串
    byte qu, wei;            //汉字时的区码
    byte font_type = 0;     //  1 -- 汉字, 0 -- 字符型(默认)
    byte cur_font = font;      // Current font, 在中文显示中, 也会有显示英文的情况
    byte BOLD;          //判断本行是否需要整行显示粗体(双宽字体)
    byte size;
    byte len, line;
    byte i, k;
    int x, y;

    len = Str_Buf[2+2*MAX_BTN_DESC_LEN];//取第二行字符串的长度, 如果为0, 表示只有1行显示
    line = (len) ? 2: 1;

    y0 = y0 + (y1 - y0 - ((int)line)*Font_Size[cur_font][1])/2;//行数按中间对齐方式确定y的起始位置
    
    if (font == FONT_HZ_12x12 || font == FONT_HZ_16x16 || font == FONT_HZ_24x24)     // 中文字体
    {
        font = FONT_HZ_16x16; 
        font_type = 1;
    }
    
    for(k = 0; k < line; k++)
    {
        len = Str_Buf[k*(2+2*MAX_BTN_DESC_LEN)];
        if(len == 0)
            break;

        BOLD = Str_Buf[k*(2+2*MAX_BTN_DESC_LEN) + 1];
        x = x0 + (x1 - x0 - ((BOLD == BOLD_FONT)? 2: 1)*len*Font_Size[font][0])/2;//取当前行的横向起始位置
        y = y0 + k*Font_Size[font][1];//取当前行的纵向起始位置
        src_buf = Str_Buf + k*(2+2*MAX_BTN_DESC_LEN) +2;//取字符串

        size = 1;
        qu = 0;
        wei = 0;
        for(i = 0; i < len; i++)
        {
            wei = src_buf[i];
            if(wei < 0x20)
            {
                if(wei == DB_BOLD_FONT)
                {
                    size = 2;
                    continue;
                }
                else
                    wei = 0x20;
            }
            if (font_type == 1)     // 中文字体
            {
                if(!qu)
                {
                    if(Judge_Qu(wei) == TRUE)//如果判断为汉字
                    {
                        qu = wei;
                        if(size >1)i++;//跳过控制字
                        continue;
                    }
                    else 
                    {
                        cur_font = FONT_HZ_ASC_8x16;
                    }
                }
                else
                {
                    cur_font = font;
                }
            }
            else
            {
                cur_font = font;
            }
            size = (((BOLD == BOLD_FONT)? (size*2) : size)&0x0f)|0x10;
            x +=  Lcd_Draw_Char(qu, wei, size, cur_font, color, x, y);
            
            size = 1;
            qu = 0;
            wei = 0;
        }
    }
}



/*---------------------------------------------------------------------------*
*   显示按键的名称. 需要考虑汉字
*   注意按键最多只允许18个字符, 
*   共2行显示
*   ASCII码使用 8*16 点阵字体, 标为9*17字体
*   汉字使用16*16 点阵字体
*   Max_Len 表示当前字符串允许最大长度
*   Text 的最后一个字符是Bold 标志
*   自动换行标准:找到最近的一个空格,如果没有空格,从本行最后一个字符处断开
*---------------------------------------------------------------------------*/
void Lcd_Cvt_Btn_Text(char *text, byte Max_Len,byte BOLD, byte color, int x0, int y0, int x1, int y1)
{
    char src_buf[2][2+2*MAX_BTN_DESC_LEN];
    byte font = BTN_DFT_FONT;
    byte len;
    byte Line_Max;      //每行最大可显字符数
    byte i, j;
    
    len = Get_Desc_Len(text, Max_Len);
    if(len > MAX_BTN_DESC_LEN)
        len = MAX_BTN_DESC_LEN;
    
    memset(src_buf, 0, 4+4*MAX_BTN_DESC_LEN);//缓冲区清0
    Line_Max = (byte)( (x1-x0)/(Font_Size[font][0]));//取每行最大可显字符数.
    
    
    if(len <= Line_Max/2)//需要显示的字符不超过半行,强制 使用Bold 显示
    {
        src_buf[0][0] = len;
        src_buf[0][1] = BOLD_FONT;
        memcpy(src_buf[0]+2, text, len);
        
        Tft_Disp_Ctl_Str(src_buf[0], font, color, x0, y0, x1, y1);
        return;
    }
    if(BOLD == BOLD_FONT)
    {
        if(len > 2*(Line_Max/2))//如果显示空间不够, 只能使用普通方式显示
            BOLD = 0;
        else 
            Line_Max = (Line_Max/2);//如果要求双宽显示,  最大可显长度减半
    }
    src_buf[0][1] = src_buf[1][1] = BOLD;

    if(len <= Line_Max)//如果只用一行显示足够, 
    {
        src_buf[0][0] = len;
        memcpy(src_buf[0]+2, text, len);
        
        Tft_Disp_Ctl_Str(src_buf[0], font, color, x0, y0, x1, y1);
        return;
    }
    else //需要分行处理
    {
        
        byte Chk_Line(char *src, byte src_len, byte max_len);
//        for(i = Line_Max; i>1; i--)
//        {
//            if(text[i] == 0x20)break;//查找本行的最后一个空格
//        }
//        if(i <= 1)//如果没有找到空格, 从最后一个字符处断开
//        {
//            i = Line_Max;
//            if(text[Line_Max-1] < 0x20)//控制字符
//                i = Line_Max-1;
//        }
        i = Chk_Line(text, len, Line_Max);
        src_buf[0][0] = i;
        memcpy(src_buf[0]+2, text, i);
        if(text[i] == 0x20)i++;
        text += i;
        len -= i;

        if(len > Line_Max)//如果剩余长度超过一行, 
        {
            i = Chk_Line(text, len, Line_Max-1);
            src_buf[1][0] = i;
            memcpy(src_buf[1]+2, text, i);
            src_buf[1][2+i] = '-';
        }
        else 
        {
            src_buf[1][0] = len;
            memcpy(src_buf[1]+2, text, len);
        }
    }
    
    Tft_Disp_Ctl_Str(src_buf[0], font,  color, x0, y0, x1, y1);
}

/*-----------------------------------------------------------------------------*
*   画一个单色位图
****
*-----------------------------------------------------------------------------*/
void TFT_LCD_Disp_LOGO(const char *Logo, byte color, int hor, int vrt, int x0, int y0)
{
    int x, y;
    int i, j;
    byte k = 0;

    y = y0;
    for(i = 0; i < vrt; i++)//总行数
    { 
        x = x0;
        for(j = 0; j < hor; j++)
        {
            if((*Logo)&and_table2[k&0x07])

⌨️ 快捷键说明

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