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

📄 prog_cm.c

📁 一款收款机C源代码!因为是几年前的代码了
💻 C
📖 第 1 页 / 共 2 页
字号:
/*-----------------------------------------------------------------------------
 * Program the Cooking Message
 *---------------------------------------------------------------------------*/
#include "ecrsys.h"
#include "ftype.h"
#include "sysdata.h"
#include "data.h"
#include "keydef.h"
#include "iccard.h"
#include "mathes.h"
#include <string.h>
#include "disp.h"
#include "lcd2.h"
#include "PC_Comm.h"
#include "lcd_pop.h"
#include "program.h"
#include "stdio.h"

#if 1
static const word *Bak_Ts_Key_Tab1;			/* The current key table */
static const byte *Bak_Ts_Key_Table_Size1;

word Dept_Pop_Key_Tabl[MAX_LAYOUT_KEY];		/*Popup the dept key layout on right side*/
byte Dept_Pop_Key_Tabl_Size[MAX_LAYOUT_KEY]; /*size*/

const word Dept_Pop_Key_Cmd[] = 			/*Command key for edit the C.M.*/
{
   KD_DPSF, KD_ADD, KD_DEL, KD_ENTER, KD_CANCEL, KD_CANCEL,
};
const byte Dept_Pop_Key_Cmd_Size[] = 		/*Default command key size*/
{
    0x11, 0x11, 0x11, 0x11, 0x12, 0x10,
};
const char Str_Cooking_message_desc[] = {"The limit description length is 24"};
const char Str_CM_Prog_Sel[][MAX_BTN_DESC_LEN+1]    =   
{
        {"Edit"},
        {"Add New"},
        {"Delete"}
};
/*------------------------------------------------------------------------------
 *统计总的可用CM的数量,即用户已经输入编辑的CM的数量
 -----------------------------------------------------------------------------*/
WORD	CM_TtlNumGet(void)
{
	WORD	i;
	WORD	cnt;
	
	for (i = 0, cnt = 0; i < MAX_KP_SFX_NUM; i ++)
	{
		if (KP_Sfx_Desc[i][0] == '\0')
			cnt ++;
	}
	return(cnt);
}
/*------------------------------------------------------------------------------
 *统计某个部门已经连接的CM的数量.
 *部门所能连接的CM数目<200
 -----------------------------------------------------------------------------*/
BYTE	CM_DeptTtlNumGet(BYTE dp_idx)
{
	BYTE	i;
	BYTE	cnt;
	
    for (i=0,cnt = 0;i<MAX_DEPT_CM_NO; i++)
    {
    	if (dept[dp_idx].CkMsg[i] !=0 )	/*Used record*/
    		cnt++;
    }
	return(cnt);
}
/*------------------------------------------------------------------------------
 *根据指定部门号,找寻到此部门中第一个为空的CM的序号
 *如果已经满(没有空的记录),则返回0xff)
 *参数输入: dp_idx ---- department index
 *参数输出: None:
 *函数返回: 0xff -- 没有空记录
 *          0 -- MAX_DEPT_CM_NO -1
 *----------------------------------------------------------------------------*/
BYTE	Dept_Cm_FindBlankRcrd(char dp_idx)
{
	BYTE	i;
	
    for (i=0;i<MAX_DEPT_CM_NO; i++)
    {
    	if (dept[dp_idx].CkMsg[i] ==0)	/*Found one blank record*/
    		break;
    }
    if (i >= MAX_DEPT_CM_NO)
    	i = 0xff;
	return(i);
}
/*----------------------------------------------------------------------------*
*   查找输入的cm编号开始的前一条有效的cm,查找包含对此条cm的查找
*       Idx: (0 ~ MAX_KP_SFX_NUM-1)
*   返回: 
*       Idx: (0 ~ MAX_KP_SFX_NUM-1)
*   注意查找结束位置为0, 也即查找到编号为0 为止.
*----------------------------------------------------------------------------*/
byte CM_Srch_Pre(byte Idx)
{
    byte Idx_Bak;
    if(Idx >= MAX_KP_SFX_NUM)
        return Idx;
    Idx_Bak = (Idx + 1)%MAX_KP_SFX_NUM;
    while((KP_Sfx_Desc[Idx][0] == '\0')&&(Idx != Idx_Bak))
        Idx = (Idx + MAX_KP_SFX_NUM -1)%MAX_KP_SFX_NUM;
    if(Idx == Idx_Bak)
        Idx = MAX_KP_SFX_NUM;
    return Idx;
}

/*----------------------------------------------------------------------------*
*   查找输入的cm编号开始的后一条有效的cm,查找包含对此条cm的判断
*       Idx: (0 ~ MAX_KP_SFX_NUM-1)
*   返回: 
*       Idx: (0 ~ MAX_KP_SFX_NUM-1)
*----------------------------------------------------------------------------*/
byte Cm_Srch_Next(byte Idx)
{
   
    byte Idx_Bak;
    if(Idx >= MAX_KP_SFX_NUM)
        return Idx;
    Idx_Bak = (Idx + MAX_KP_SFX_NUM - 1)%MAX_KP_SFX_NUM;
    while((Idx != Idx_Bak)&&(KP_Sfx_Desc[Idx][0] == '\0'))Idx++;
    if(Idx == Idx_Bak)
        Idx = MAX_KP_SFX_NUM;
    return Idx;
}
/*----------------------------------------------------------------------------*
*   查找输入的cm编号对应当前的显示行号
*       Idx: (0 ~ MAX_KP_SFX_NUM-1)
*       *Cm_Disp_Tbl: 查找的table,也即当前显示的cm的序号集
*   返回: 
*       i: (0 ~ DISP_LCD_TEXT_LINE-1)
*----------------------------------------------------------------------------*/
byte CM_Srch_Line_Posi(byte Idx,  byte *Cm_Disp_Tbl)
{
    byte i;
    for(i = 0; i < DISP_LCD_TEXT_LINE; i++)
    {
        if(Cm_Disp_Tbl[i] == Idx+1)
            break;
    }
    return i;
}
/*-----------------------------------------------------------------------------
 * Display the full Cooking Message lists 
 *-----------------------------------------------------------------------------
 */
void Disp_Full_CM_List(byte *Cm_Disp_Tbl, byte curr_line, byte Max_Line)
{
    byte i;
    
    Rst_Lcd_Text();     /* Reset the text*/
    if(Max_Line == 0)
        return;
    
    Text_Lcd.CurrLine = curr_line;
    for (i = 0; i < Max_Line; i++)   // Display 8CMs information
    {
        memset(Text_Lcd.text[i], 0x20, MAX_TEXT);
        if(Cm_Disp_Tbl[i] != 0)
            xtr_strcpy(Text_Lcd.text[i], KP_Sfx_Desc[Cm_Disp_Tbl[i]-1]);
    }
    Lcd_Reflush_List(0);
}
/*----------------------------------------------------------------------------*
    Display the cooking message 
    Refresh_mode --
        0: 向下全屏更新 --> *Idx 是开始向下查找的起始位置
        1: 向上全屏更新 --> *Idx 是开始向上查找的起始位置
        2: Edit更新 -->  *Idx 是刚才进行了更新的单项,此函数需要对*Idx进行步进 
        3: 插入 ------>  *Idx 是当前插入的单项, 也是当前需要反显的单项
        4: 删除 ------>  *Idx 是刚才删除的单项,此函数需要对*Idx进行步进
*----------------------------------------------------------------------------*/
void CM_Prog_Disp(byte Idx, byte *Cm_Disp_Tbl, byte Refresh_mode, byte *curr_line)
{
    byte i;
    byte tmp_idx = 0;
    byte step;
    byte mode = 0xff;   /*0xff-全屏刷新,0xfe-部分刷新(目前保留), 0~DISP_LCD_TEXT_LINE-1, 更新mode指定的单行*/
    byte str[MAX_TEXT];
    byte len;

    if(Refresh_mode > 4)
        return;
    if(Refresh_mode == 1)/*向前查找*/
    {
        memset(Cm_Disp_Tbl, 0, DISP_LCD_TEXT_LINE);//清除原缓冲区的所有记录.
        tmp_idx = Idx;
        for(i = 0; i < DISP_LCD_TEXT_LINE; i++)
        {
            tmp_idx = CM_Srch_Pre(tmp_idx);
            if(tmp_idx >= MAX_KP_SFX_NUM)
                break;
            if(tmp_idx > Idx)//查到头了
                break;
            Cm_Disp_Tbl[DISP_LCD_TEXT_LINE-1-i] = tmp_idx + 1;
            if(tmp_idx > 0)tmp_idx--;
            else {i++; break;}//注意这里的i++ 一定不可省略
        }
        *curr_line = i - 1;

        if(i < DISP_LCD_TEXT_LINE)//如果缓冲区没有装满中途退出, 准备向后填充.
        {
            memmove(Cm_Disp_Tbl, &Cm_Disp_Tbl[DISP_LCD_TEXT_LINE-i], i);//移位
            memset(&Cm_Disp_Tbl[i], 0, DISP_LCD_TEXT_LINE-i);
            tmp_idx = Idx+1;
            for(; i < DISP_LCD_TEXT_LINE; i++)//继续向后填充
            {
                tmp_idx = Cm_Srch_Next(tmp_idx);
                if(tmp_idx >= MAX_KP_SFX_NUM)
                    break;
                if(tmp_idx < Idx )//查到头了
                    break;
                Cm_Disp_Tbl[i] = ++tmp_idx;
            }
        }
        mode = 0xff;
    }    
    else if(Refresh_mode == 2)//edit
    {
        if((*curr_line >= DISP_LCD_TEXT_LINE-1)||(Cm_Disp_Tbl[*curr_line+1] == 0))//修改完毕最后一行, 转到新的一页
        {  
            Refresh_mode = 0;
        }
        else//页内更新
        {
            mode = *curr_line;
            (*curr_line) ++;
        }
    }
    else if(Refresh_mode == 3)//Add new one
    {
        if(KP_Sfx_Desc[Idx][0] == '\0')// 如果新增的一行不是可用行, 不予更新。
            return;
        for(i = 0; i < DISP_LCD_TEXT_LINE; i++)
        {
            if(Cm_Disp_Tbl[i] > Idx)break;
        }
        if((i >= DISP_LCD_TEXT_LINE)||(i == 0))
        {
            if(Cm_Disp_Tbl[DISP_LCD_TEXT_LINE-1] == 0)
            {
                for(i = DISP_LCD_TEXT_LINE; i > 0; i--)
                {
                    if(Cm_Disp_Tbl[i-1] != 0)
                        break;
                }
                *curr_line = i;
                Cm_Disp_Tbl[i] = Idx+1;
                mode = 0xfe;
            }
            else
            {
                Refresh_mode = 0;//如果新加的一项不在本页内, 转到新的一页
            }
        }
        else
        {
            *curr_line = i;
            for(i = DISP_LCD_TEXT_LINE-1; i > *curr_line; i--)
            {
                Cm_Disp_Tbl[i] = Cm_Disp_Tbl[i-1];
            }
            Cm_Disp_Tbl[*curr_line] = Idx+1;
            mode = 0xfe;
        }
    }
    else if(Refresh_mode == 4)//  delete
    {
        if(*curr_line < DISP_LCD_TEXT_LINE-1)
        {
            memmove(Cm_Disp_Tbl + *curr_line, Cm_Disp_Tbl + *curr_line +1, DISP_LCD_TEXT_LINE - *curr_line - 1);
        }
        tmp_idx = Cm_Srch_Next(Cm_Disp_Tbl[DISP_LCD_TEXT_LINE - 2]-1);
        Cm_Disp_Tbl[DISP_LCD_TEXT_LINE - 1] = (tmp_idx >= MAX_KP_SFX_NUM)? 0 : (tmp_idx+1);
        mode = 0xfe;
    }
    if(Refresh_mode == 0)
    {
        memset(Cm_Disp_Tbl, 0, DISP_LCD_TEXT_LINE);
        tmp_idx = Idx;
        for(i = 0; i < DISP_LCD_TEXT_LINE; i++)
        {
            tmp_idx = Cm_Srch_Next(tmp_idx);
            if(tmp_idx >= MAX_KP_SFX_NUM)
                break;
            if(tmp_idx < Idx)
                break;
            Cm_Disp_Tbl[i] = ++tmp_idx;
        }
        *curr_line = 0;//
        mode = 0xff;
    }
    Disp_Full_CM_List(Cm_Disp_Tbl, *curr_line, DISP_LCD_TEXT_LINE);

    // Display the note information
    Lcd_Disp_Str_Btn(BUF_ID_TL_SUB, Str_Modify_Step[0]);
    
}

/*
    删除了一条Cooking Message以后, 部门所连接的Cooking Message也做相应的删除
*/
void CM_Prog_Dept_Ex(byte cm_idx)
{
    byte i;
    byte j;

    cm_idx++;   // 与部门的存储格式相匹配
    for (i = 0; i < Max_Dept_No; i++)
    {
        for (j = 0; j < dept[i].cm_cnt; j++)
        {
            if (cm_idx == dept[i].CkMsg[j])
            {
                memmove(&(dept[i].CkMsg[j]), &(dept[i].CkMsg[j+1]), dept[i].cm_cnt-j-1);
                dept[i].cm_cnt--;
                break;
            }
        }
    }
}

/*----------------------------------------------------------------------------*
    编程cm
    使用一个缓冲区CM_Curr_Disp[]保留当前页显示的cm的所有编号(1~200)
    使用PAGE_UP,PAGE DOWN,UP,DOWN时,如果在页内操作,直接使用显示行号标识
    如果更新页操作,直接更新缓冲区CM_Curr_Disp[]的内容。
    如果进行了单行更新,直接向缓冲区更新显示内容即可。当然需要先判断是否需要显示新的页
    
*----------------------------------------------------------------------------*/
void CM_Prog_Main(void)
{
    word key;
    byte CM_Curr_Disp[DISP_LCD_TEXT_LINE];/*注意为了避免负数的计算, 此处空时为0。序号记录从1~200*/
    byte CM_Idx;    /*当前起始寻找的CM编号*/
    byte Curr_Line;     /*当前显示的行*/
    byte Refresh_mode; /*0-向下更新, 1-向上更新,2-Edit后更新,
                            3-Add New 后更新,4-Delete 后更新,0xff-不必更新*/
    
    Lcd_Send_Text_Buff_Str(BUF_ID_TL_TITLE, 1, Str_ParaSet_Menu[10], ALIGN_MID);
    Lcd_Disp_Text_Buff(BUF_ID_TL_TITLE);
    
    Last_Prg_Idx = IDX_NULL;
    Last_Prg_Step = STEP_NULL;
    CM_Idx = 0;
    Refresh_mode = 0;
    while(1)
    {
        if(GetMainMode() != CurrMode)
            return;
        if(Refresh_mode != 0xff)
        {
            CM_Prog_Disp(CM_Idx, CM_Curr_Disp, Refresh_mode, &Curr_Line);
            if(Curr_Line >= DISP_LCD_TEXT_LINE)
                Curr_Line = DISP_LCD_TEXT_LINE - 1;
            Refresh_mode = 0xff;
        }
        key = GetKey();
        
        switch(key)
        {
            case KD_CLEAR:
                Do_Clear();
                break;

            case KD_PAGE_DOWN:
                if(CM_Curr_Disp[DISP_LCD_TEXT_LINE-1] == 0)//如果发现当前页没有装满, 说明需要从头开始显示
                    CM_Idx = 0;
                else     //否则, 使用本页最后一个显示项的单项作为新的一页查找的起点。
                    CM_Idx = CM_Curr_Disp[DISP_LCD_TEXT_LINE-1]-1;
                Refresh_mode = 0;
                break;
                
            case KD_PAGE_UP:
                CM_Idx = CM_Curr_Disp[0]-1;//定位到当前第一条C.M.的单项准备查找
                Refresh_mode = 1;
                break;
                
            case KD_DOWN:
                if((Curr_Line < DISP_LCD_TEXT_LINE-1)&&(CM_Curr_Disp[Curr_Line+1] > 0))//页内变化
                {
                    Lcd_Text_Line_Disp(Curr_Line++, FALSE);
                    Lcd_Text_Line_Disp(Curr_Line, TRUE);
                    Refresh_mode = 0xff;
                }
                else//跨页更新, 类同KD_PAGE_DOWN
                {
                    if(Curr_Line >= DISP_LCD_TEXT_LINE-1)
                        CM_Idx = CM_Curr_Disp[DISP_LCD_TEXT_LINE-1]-1;

⌨️ 快捷键说明

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