📄 scanner.c
字号:
/******************************************************************************
* Module: Scanner.C
* Modified by: X.C.Zheng WeiHua
* Modified on: Date: 03-8-11 14:03
* Copyright(c) WeiHua Tech Ltd.
* Description:
* UART / KB -> GetIN -> Prg / Sale / Rpt / Disp
* CodeBuf_Bak
******************************************************************************/
#include "ecrsys.h"
#include "ftype.h"
#include "sysdata.h"
#include "data.h"
#include "mathes.h"
#include "stdlib.h"
#include "keydef.h"
#include <string.h>
/*
设置为条码扫描模式.
*/
void SetBarCodeMode(void)
{
#ifdef SCANNER
BarRecFlag = 0;
#endif
}
/*
设置为非条码扫描模式.
*/
void ClrBarCodeMode(void)
{
#ifdef SCANNER
BarRecFlag = 1;
#endif
}
void InitBarCode(void)
{
#ifdef SCANNER
ClrRsBuf(PORT1);
SC_ClrFlag();
SetBarCodeMode();
#endif
}
#ifdef SCANNER /* Support the scanner function */
#define BARCODE_NUM 7
/******************************************************************************
* Describe: Clear scanner routine flag and Uart buffer
* Input : void
* Output: void
* return: void
******************************************************************************/
void SC_ClrFlag(void)
{
BarCnt = 0;
BarCnt_bak = 0;
}
/******************************************************************************
* Describe: transfer bar code from ASCCII format to BCD format
* CodeBuf_Bak[] --> Barbuf[]
* Input : void
* Output: void
* return: OK / NG
******************************************************************************/
byte SC_TranToBcd(void)
{
byte tmpc, i, j;
if (BarCnt_bak == 0)
{
return (NG);
}
switch (BarCnt_bak)
{
case 16:
j = 0;
for (i=2; i<15; i++)
{
tmpc = CodeBuf_Bak[i] & 0x7F;
if ((tmpc >= 0x30) && (tmpc <= 0x39))
{
tmpc &= 0x0F;
Barbuf[j] = tmpc;
j++;
}
else
{
SC_ClrFlag();
return (NG);
}
}
break;
case 11:
// memset(Barbuf, 0, 5);
for(j = 0; j < 3; j ++)
Barbuf[j] = 0x00;
for (i=0; i<10; i++)
{
tmpc = CodeBuf_Bak[i] & 0x7F;
if ((tmpc >= 0x30) && (tmpc <= 0x39))
{
tmpc &= 0x0F;
Barbuf[j] = tmpc;
j++;
}
else
{
SC_ClrFlag();
return (NG);
}
}
break;
case 10:
// memset(Barbuf, 0, 6);
for(j = 0; j < 4; j ++)
Barbuf[j] = 0x00;
for (i=0; i<9; i++)
{
tmpc = CodeBuf_Bak[i] & 0x7F;
if((tmpc >= 0x30) && (tmpc <= 0x39))
{
tmpc &= 0x0F;
Barbuf[j] = tmpc;
j++;
}
else
{
SC_ClrFlag();
return (NG);
}
}
break;
case 14:
j = 0;
for (i=0; i<13; i++)
{
tmpc = CodeBuf_Bak[i] & 0x7F;
if ((tmpc >= 0x30) && (tmpc <= 0x39))
{
tmpc &= 0x0F;
Barbuf[j] = tmpc;
j++;
}
else
{
SC_ClrFlag();
return (NG);
}
}
break;
case 13: /* The UPC-A bar code */
// memset(Barbuf, 0, 1);
for(j = 0; j < 1; j ++)
Barbuf[j] = 0x00;
for (i=0; i<12; i++)
{
tmpc = CodeBuf_Bak[i] & 0x7F;
if ((tmpc >= 0x30) && (tmpc <= 0x39))
{
tmpc &= 0x0F;
Barbuf[j] = tmpc;
j++;
}
else
{
SC_ClrFlag();
return (NG);
}
}
break;
case 9:
// memset(Barbuf, 0, 5);
for(j = 0; j < 5; j ++)
Barbuf[j] = 0x00;
for (i=0; i<8; i++)
{
tmpc = CodeBuf_Bak[i] & 0x7F;
if ((tmpc >= 0x30) && (tmpc <= 0x39))
{
tmpc &= 0x0F;
Barbuf[j] = tmpc;
j++;
}
else
{
SC_ClrFlag();
return (NG);
}
}
break;
case 8:
// memset(Barbuf, 0, 6);
for(j = 0; j < 6; j ++)
Barbuf[j] = 0x00;
for (i=0; i<7; i++)
{
tmpc = CodeBuf_Bak[i] & 0x7F;
if ((tmpc >= 0x30) && (tmpc <= 0x39))
{
tmpc &= 0x0F;
Barbuf[j] = tmpc;
j++;
}
else
{
SC_ClrFlag();
return (NG);
}
}
break;
case 7: /* The UPC-E bar code */
// memset(Barbuf, 0, 7);
for(j = 0; j < 7; j ++)
Barbuf[j] = 0x00;
for (i=0; i<6; i++)
{
tmpc = CodeBuf_Bak[i] & 0x7F;
if ((tmpc >= 0x30) && (tmpc <= 0x39))
{
tmpc &= 0x0F;
Barbuf[j] = tmpc;
j++;
}
else
{
SC_ClrFlag();
return (NG);
}
}
break;
default:
SC_ClrFlag();
return (NG);
}
SC_ClrFlag();
return (OK);
}
/******************************************************************************
* Describe: transfer bar code from ASCCII format to BCD format
* InBuf[] --> Barbuf[] -> BcdBuf[]
* KeyBoard
* Input : void
* Output: void
* return: OK / NG
******************************************************************************/
void SC_KBToBcd(byte *str)
{
int i = 0;
int length;
while (str[i] != 0xFF)
{
i++;
}
length = i - 1;
memset(Barbuf, 0, 13);
for (i=12; (i >= 0) && (length >= 0); i--,length--)
{
Barbuf[i] = str[length];
}
// for (i=0; (i <= 12) && (length >= 0); i++,length--)
// {
// Barbuf[i] = str[length] ;
// }
SC_TransBcd(); // Barbuf[] -> BCDbuf[]
}
/******************************************************************************
* Describe: transfer bar code from BCD format to Compress BCD format
* Barbuf[] -> BcdBuf[]
* Input : void
* Output: void
* return: OK / NG
******************************************************************************/
void SC_TransBcd(void)
{
byte i, j = 0;
for (i=12; i>0; i=i-2)
{
BCDbuf[j] = (Barbuf[i-1] << 4) | Barbuf[i];
j++;
}
BCDbuf[6] = Barbuf[0];
}
/******************************************************************************
* Describe: compare two bar code.
* Input : bar code1, bar code2
* Output: void
* return: 0--> bar1 == bar2
* 1--> bar1 > bar2
* -1--> bar1 < bar2
******************************************************************************/
int SC_CmpCode(const byte *bar1, const byte *bar2)
{
byte i;
for (i = BARCODE_NUM; i>0; i--)
{
if (bar1[i-1] == bar2[i-1])
{
continue;
}
if (bar1[i-1] > bar2[i-1])
{
return 1;
}
else
{
return -1;
}
}
return 0;
}
/******************************************************************************
* Describe:search the PLU which bar code is "code" in the index database
* Input : bar code.
* Output: void
* Return: The return value is in the range of 1 ---> Max_Plu_No
* < 0 not found and give the position to insert
* > 0 found and give the position in the index
******************************************************************************/
//int SC_SearchIndex(byte *scode)
//{
// word i;
//
// for (i=0; i< Max_Plu_No; i++)
// {
// if (SC_CmpCode(scode, plu[i].barcode) == 0)
// {
// return i;
// }
// }
//
// return -1;
//}
int SC_SearchIndex(byte *scode) /* The binary find */
{
int head,tail,idx;
int plu_no;
int cmp_rslt; /* The compare result */
head = 0;
tail = Max_Plu_No - 1;
plu_no = 0;
idx = 0;
while(head <= tail)
{
idx = (head + tail) / 2;
plu_no = Sindex[idx];
cmp_rslt = SC_CmpCode(scode, plu[plu_no].barcode);
if(cmp_rslt == 0)
return (idx); /* Find, return the position */
else if(cmp_rslt == 1)
head = idx + 1;
else
tail = idx - 1;
}
if(SC_CmpCode(scode, plu[plu_no].barcode) > 0)
return -(idx+1+1); /* Return the not found insert position */
else
return -(idx+1); /* return the not found insert position */
}
/******************************************************************************
* Describe:update the index database according to the two position of old
* and new code in the index database.
* Input : "old" is in the range of 0---> PLU_MAX_CNT-1
* "new" is in the range of 0---> PLU_MAX_CNT
* Output: void
* Return: void
******************************************************************************/
void SC_UpdateIndex(int oldCode, int newCode)
{
int i, saveoldCode;
if (newCode > oldCode)
{
saveoldCode = Sindex[oldCode];
for (i=oldCode; i < newCode-1; i++) /* Note : In this is the delete position,
And the function SC_SearchIndex return the insert
position */
{
Sindex[i] = Sindex[i+1];
}
Sindex[newCode-1] = saveoldCode;
}
else
{
saveoldCode = Sindex[oldCode];
for (i=oldCode; i>newCode; i--)
{
Sindex[i] = Sindex[i-1];
}
Sindex[newCode] = saveoldCode;
}
}
/******************************************************************************
* Describe:display bar code
* Input : bar code
* Output: void
* Return: void
******************************************************************************/
void SC_DispCode(byte *Bcode)
{
byte i;
byte str[20];
byte j;
memset(str, ' ', 20);
j = 13;
for (i=0; i<7; i++)
{
str[j] = (Bcode[i] & 0x0f) + '0';
if (str[j] > '9')
str[j] += 7;
j--;
str[j] = ((Bcode[i] >> 4) & 0x0f) + '0';
if (str[j] > '9')
str[j] += 7;
j--;
}
// ... display
}
/*
条码扫描,从串口接收缓冲区中获取数据,并加以解析.
*/
void Sc_Scan(void)
{
// byte CurrScanPort = PORT_NULL;
byte CurrScanPort = PORT2; /*For speed up, set it to fix*/
byte CheckRsBufEmpty(byte port);
#define BARBUFLEN 0x1f
#define ETX 0x03
#define CR 0x0D
#define LF 0x0A
// 检查是否在条码扫描模式.
if (BarRecFlag != 0)
return;
// 检查串口缓冲区是否为空,若为空则返回.
#if 0
if((ser_port[PORT0].device != DEV_TYPE_SC)||(CheckRsBufEmpty(PORT0) == 0))
CurrScanPort = PORT_NULL;
else
CurrScanPort = PORT0;
if(CurrScanPort == PORT_NULL)
{
if((ser_port[PORT1].device != DEV_TYPE_SC)||(CheckRsBufEmpty(PORT1) == 0))
CurrScanPort = PORT_NULL;
else
CurrScanPort = PORT1;
}
if(CurrScanPort == PORT_NULL)
{
if((ser_port[PORT2].device != DEV_TYPE_SC)||(CheckRsBufEmpty(PORT2) == 0))
CurrScanPort = PORT_NULL;
else
CurrScanPort = PORT2;
}
if(CurrScanPort == PORT_NULL)
{
if((ser_port[PORT3].device != DEV_TYPE_SC)||(CheckRsBufEmpty(PORT3) == 0))
CurrScanPort = PORT_NULL;
else
CurrScanPort = PORT3;
}
if(CurrScanPort == PORT_NULL)
{
if((ser_port[PORT4].device != DEV_TYPE_SC)||(CheckRsBufEmpty(PORT4) == 0))
CurrScanPort = PORT_NULL;
else
CurrScanPort = PORT4;
}
if(CurrScanPort == PORT_NULL)
return;
#endif /*mast it temporary*/
/*Change the compare sequence for speed up*/
// 检查条码数据区是否为空,若不为空则返回.
if (BarCnt_bak != 0)
return;
// 检查键盘缓冲区是否满,若满则返回.
if (((Khead + 1) % KEY_BUFF_SIZE) == Ktail)
return;
// 若为LOCK模式,则返回.
if (currmodeInt == X_OFF)
return;
{
extern volatile WORD rs2_In, rs2_Out;
if (rs2_In == rs2_Out) /*如果调用Buffer 空检查函数,则由于函数会开中断
* 造成系统不稳定,所以改为直接判断,比较
*/
return;
}
// if ( CheckRsBufEmpty(CurrScanPort) == 0 )
// return;
// 读入一个串口缓冲区字节,
Uart_ReadByte(CurrScanPort, &CodeBuf[BarCnt]);
// 判断读入字节是否为条码结束标志,若是,则保存到条码数据区,压入SPLU按键.
if (CodeBuf[BarCnt] == LF)
return;
BarCnt++;
BarCnt &= BARBUFLEN; // 防止错误数据输入时,引起缓冲区溢出.
if ((CodeBuf[BarCnt-1] == ETX) || (CodeBuf[BarCnt-1] == CR))
{
if (BarCnt != 0)
{
BarCnt_bak = BarCnt;
memcpy(CodeBuf_Bak, CodeBuf, 32);
BarCnt = 0;
KeyBuffer[Khead] = SPLU;
Khead = (Khead+1)%KEY_BUFF_SIZE;
bellcnt = 40;
g_LCDBLCnt = 1000*sysflag->LCD_BL_Time;
}
return;
}
}
/*****************************************************
* Check and store the scanner input data.
* If the data is the end flag, then set the flag
*====================================================*/
void Uart_Scan_Data_Store(byte port, byte ch)
{
#if 0
switch(port)
{
case PORT0:
if (((rs0_In + 1) & RSBUFLEN0) != rs0_Out)
{
rs0_Buff[rs0_In] = ch;
rs0_In++;
rs0_In &= RSBUFLEN0;
}
else
{
// rs0_Buff[rs0_In] = ch; /*Discard the latest received data*/
}
break;
case PORT1:
if (((rs1_In + 1) & RSBUFLEN1) != rs1_Out)
{
rs1_Buff[rs1_In] = ch;
rs1_In++;
rs1_In &= RSBUFLEN1;
}
else
{
// rs1_Buff[rs1_In] = ch; /*Discard the latest received data*/
}
break;
case PORT2:
if (((rs2_In + 1) & RSBUFLEN2) != rs2_Out)
{
rs2_Buff[rs2_In] = ch;
rs2_In++;
rs2_In &= RSBUFLEN2;
}
else
{
// rs2_Buff[rs2_In] = ch; /*Discard the latest received data*/
}
break;
case PORT3: /*it is the actual port 3 of MCU*/
if (((rs3_In + 1) & RSBUFLEN3) != rs3_Out)
{
rs3_Buff[rs3_In] = ch;
rs3_In++;
rs3_In &= RSBUFLEN3;
}
else
{
// rs3_Buff[rs3_In] = ch; /*Discard the latest received data*/
}
break;
case PORT4:
if (((rs4_In + 1) & RSBUFLEN4) != rs4_Out)
{
rs4_Buff[rs4_In] = ch;
rs4_In++;
rs4_In &= RSBUFLEN4;
}
else
{
// rs4_Buff[rs4_In] = ch; /*Discard the latest received data*/
}
break;
default:
break;
}
return;
#endif
/*每次串口有数据进入的时候,如果端口为条码抢,则直接在此判断是否完整输入了
* 一串Barcode,如果是,则把数据直接放在CodeBuf中,如果不是,则继续等待数据
* 这样写程序,有一个地方需要特别注意,系统中只能允许有一个端口连接的是Scanner
*/
if (!BarRecFlag) /*没有条码在处理,即没有处于条码需要处理的状态*/
{
CodeBuf[BarCnt] = ch;
if((CodeBuf[BarCnt] == ETX) || (CodeBuf[BarCnt] == CR)) /*结束条码的输入?*/
{
BarRecFlag = 1;
bellcnt = 0xfe;
}
else if(CodeBuf[BarCnt] != LF)
{
BarCnt++;
BarCnt &= BARBUFLEN; /*最多允许32个字符存放在缓冲区中*/
}
}
}
#endif /* End SCANNER */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -