TMC32_QJB/App/scanmode.c
2026-04-30 16:23:12 +08:00

534 lines
13 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
******************************************************************************
* @file scanmode.c
* @author TMC Scan Team
* @version V1.0.0
* @date 09/06/2019
* @brief This file provides the different modes of scanning.
******************************************************************************
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, TMC SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>&copy; COPYRIGHT 2016 TMC</center></h2>
******************************************************************************
**/
#include "global.h"
uint8_t gAutoModeOverTimeFlag = TRUE; //连续模式下,同码延时和异码延时,第一次解码不需要延时;或者扫码一直不成功,定时器如果超时,解码也不需要延时
uint8_t gCmdStartFlag = FALSE; //命令模式下开启扫码命令标记FALSE表示禁止扫码TRUE表示使能扫码
uint8_t gSensorChangeFlag = FALSE; //环境变化标记,FALSE表明环境无变化TRUE表明环境有变化
ImageSizeType gLastPictureSize = DCMI_640_480; //感应模式下上一次采图标记感知环境变化时由于RAM不足需要采集小图当进入解码状态时采集图像尺寸恢复到640*480
uint32_t gCurrentPictureAddr = DCMIBUFADDR; //感应模式下,需要采集两张图像,标记当前采集图像的地址
uint8_t gPreImage[MAXCODELEN] = {0};
uint32_t gPrebarcodelen = 0;
int gPreCodeType = Communication_Id;
uint8_t gCmdModeTimeFlag = FALSE; //命令模式下,定时器开启标志,默认未开启
extern uint8_t gLicenseFlag;
extern uint32_t gFunTrace;
/**
* @function AppScanModeInit
* @brief 配置识读模块的初始条件
* @param[in] 无
* @return 无
*/
void AppScanModeInit(void)
{
switch(gConfgBuf.scanCodeMode)
{
case AUTOMODE:
gAutoModeOverTimeFlag = TRUE;
break;
case CMDMODE:
gCmdStartFlag = TRUE; //命令模式下开启扫码命令标记FALSE表示禁止扫码TRUE表示使能扫码
break;
case CMDTIMEMODE:
gCmdStartFlag = FALSE; //命令模式下开启扫码命令标记FALSE表示禁止扫码TRUE表示使能扫码
break;
case SENSORMODE:
gAutoModeOverTimeFlag = TRUE;
gSensorChangeFlag = FALSE; //环境变化标记,FALSE表明环境无变化TRUE表明环境有变化
gLastPictureSize = DCMI_640_480;
gCurrentPictureAddr = DCMIBUFADDR;
break;
default:
break;
}
}
/**
* @function AutoScanMode
* @brief 连续模式,一直处于解码状态
* @param[in] BarData 结构体,存放解码数据
* @return 返回值为正,则为成功解码
*/
int AutoScanMode(BarData *pCode)
{
int result = 0;
//灯光控制
AppLEDControl(gConfgBuf.ledStatus);
//采集图像
if(!DCMI_CaptureOnePic(DCMIBUFADDR, DCMI_640_480))return FALSE;
//解码
result = TMC_Scan_Decode(pCode);
if(result > 0)
{
if(gPrebarcodelen && (gPrebarcodelen == pCode->datalen))
{
if(!memcmp(gPreImage, pCode->bardata, pCode->datalen))
{
//同码延时,定时器时间大于延时,输出;或者超时标记为真
if((gAutoModeOverTimeFlag == TRUE) || (TimerHSIClockCount(TIM4, GET_TIMER) >= (gConfgBuf.sameCodeInterval * CLK_BASE)))
{
gPrebarcodelen = pCode->datalen;
Memcpy(gPreImage, pCode->bardata, pCode->datalen);
gAutoModeOverTimeFlag = FALSE;
TimerHSIClockCount(TIM4, STOP_TIMER);
TimerHSIClockCount(TIM4, START_TIMER);
return TRUE;
}
else
{
return FALSE;
}
}
}
//异码延时,定时器时间大于延时,输出;或者超时标记为真
if((gAutoModeOverTimeFlag == TRUE) || (TimerHSIClockCount(TIM4, GET_TIMER) >= (gConfgBuf.differentCodeInterval * CLK_BASE)))
{
gPrebarcodelen = pCode->datalen;
Memcpy(gPreImage, pCode->bardata, pCode->datalen);
gAutoModeOverTimeFlag = FALSE;
TimerHSIClockCount(TIM4, STOP_TIMER);
TimerHSIClockCount(TIM4, START_TIMER);
return TRUE;
}
}
else
{
if((TimerHSIClockCount(TIM4, GET_TIMER) >= (gConfgBuf.sameCodeInterval * CLK_BASE))
&& (TimerHSIClockCount(TIM4, GET_TIMER) >= (gConfgBuf.differentCodeInterval * CLK_BASE)))
{
gAutoModeOverTimeFlag = TRUE;
}
}
return FALSE;
}
/**
* @function CmdScanMode
* @brief 命令模式,如果接收到开启扫码命令,才开始解码
* @param[in] BarData 结构体,存放解码数据
* @return 返回值为正,则为成功解码
*/
int CmdScanMode(BarData *pCode)
{
int result = 0;
//判断是否收到解码命令
if(gCmdStartFlag)
{
//灯光控制
AppLEDControl(gConfgBuf.ledStatus);
//采集图像
if(!DCMI_CaptureOnePic(DCMIBUFADDR, DCMI_640_480))return FALSE;
//解码
result = TMC_Scan_Decode(pCode);
//识读成功
if(result > 0)
{
//灯光控制
AppLEDControl(!gConfgBuf.ledStatus);
//记录码制类型
gPreCodeType = pCode->bartype;
//清除命令标记
gCmdStartFlag = FALSE; //关闭扫码
TimerHSIClockCount(TIM5, STOP_TIMER);
return result;
}
}
else
{
//灯光控制
AppLEDControl(!gConfgBuf.ledStatus);
}
return result;
}
/**
* @function CmdScanTimeMode
* @brief 命令超时模式,如果接收到开启扫码命令,才开始解码,如果超时则自动关闭扫码
* @param[in] BarData 结构体,存放解码数据
* @return 返回值为正,则为成功解码
*/
int CmdScanTimeMode(BarData *pCode)
{
int result = 0;
//判断是否收到解码命令
if(gCmdStartFlag)
{
//如果开启定时,并且时间未超时,则扫码
if(TimerHSIClockCount(TIM5, GET_TIMER) <= gConfgBuf.cmdModeTime * 12000)
{
//灯光控制
AppLEDControl(gConfgBuf.ledStatus);
//采集图像
if(!DCMI_CaptureOnePic(DCMIBUFADDR, DCMI_640_480))return FALSE;
//解码
result = TMC_Scan_Decode(pCode);
//识读成功
if(result > 0)
{
//灯光控制
AppLEDControl(!gConfgBuf.ledStatus);
//记录码制类型
gPreCodeType = pCode->bartype;
//清除命令标记
gCmdStartFlag = FALSE; //关闭扫码
TimerHSIClockCount(TIM5, STOP_TIMER);
return result;
}
}
else
{
//超时则关闭扫码
gCmdStartFlag = FALSE;
TimerHSIClockCount(TIM5, STOP_TIMER);
//灯光控制
AppLEDControl(!gConfgBuf.ledStatus);
}
}
else
{
//灯光控制
AppLEDControl(!gConfgBuf.ledStatus);
}
return result;
}
#ifdef LIGHTING
/**
* @function SensorScanMode
* @brief 感应模式,如果感应环境有变化,再开启解码
* @param[in] BarData 结构体,存放解码数据
* @return 返回值为正,则为成功解码
*/
int SensorScanMode(BarData *pCode)
{
int result = 0;
//环境是否有变化,默认值是"无变化"
if(!gSensorChangeFlag) //环境无变化
{
//灯光控制
AppLEDControl(!gConfgBuf.ledStatus);
//判断上一次采图尺寸是否为640*480是的情况下需要采两张图
if(gLastPictureSize == DCMI_640_480)
{
TimerDelay(TIM2, gConfgBuf.stableTime);
gLastPictureSize = DCMI_320_240;
gCurrentPictureAddr = DCMIBUFADDR;
if(!DCMI_CaptureOnePic(gCurrentPictureAddr, gLastPictureSize))return FALSE;
gCurrentPictureAddr += HALF_BUF_SIZE;
}
if(!DCMI_CaptureOnePic(gCurrentPictureAddr, gLastPictureSize))return FALSE;
if(gCurrentPictureAddr == DCMIBUFADDR)
{
gCurrentPictureAddr += HALF_BUF_SIZE;
}
else
{
gCurrentPictureAddr = DCMIBUFADDR;
}
//图像差异明显?
if(DCMI_Differ(HALF_BUF_SIZE) == TMC_OK)
{
gSensorChangeFlag = TRUE;
gLastPictureSize = DCMI_640_480;
TimerHSIClockCount(TIM5, START_TIMER);
}
else
{
return result;
}
}
//环境有变化
//灯光控制
AppLEDControl(gConfgBuf.ledStatus);
//图像采集
if(!DCMI_CaptureOnePic(DCMIBUFADDR, gLastPictureSize))return FALSE;
//解码
result = TMC_Scan_Decode(pCode);
//识读成功 或 超时
if(result > 0)
{
if(gPrebarcodelen && (gPrebarcodelen == pCode->datalen))
{
if(!memcmp(gPreImage, pCode->bardata, pCode->datalen))
{
//同码延时,定时器时间大于延时,输出;或者超时标记为真
if((gAutoModeOverTimeFlag == TRUE) || (TimerHSIClockCount(TIM4, GET_TIMER) >= (gConfgBuf.sameCodeInterval * CLK_BASE)))
{
Memcpy(gPreImage, pCode->bardata, pCode->datalen);
gPrebarcodelen = pCode->datalen;
gAutoModeOverTimeFlag = FALSE;
TimerHSIClockCount(TIM4, STOP_TIMER);
TimerHSIClockCount(TIM4, START_TIMER);
TimerHSIClockCount(TIM5, STOP_TIMER);
gSensorChangeFlag = FALSE;
return TRUE;
}
return FALSE;
}
}
//异码延时,定时器时间大于延时,输出;或者超时标记为真
if((gAutoModeOverTimeFlag == TRUE) || (TimerHSIClockCount(TIM4, GET_TIMER) >= (gConfgBuf.differentCodeInterval * CLK_BASE)))
{
Memcpy(gPreImage, pCode->bardata, pCode->datalen);
gPrebarcodelen = pCode->datalen;
gAutoModeOverTimeFlag = FALSE;
TimerHSIClockCount(TIM4, STOP_TIMER);
TimerHSIClockCount(TIM4, START_TIMER);
TimerHSIClockCount(TIM5, STOP_TIMER);
gSensorChangeFlag = FALSE;
return TRUE;
}
return FALSE;
}
else
{
if((TimerHSIClockCount(TIM4, GET_TIMER) >= (gConfgBuf.sameCodeInterval * CLK_BASE)) && (TimerHSIClockCount(TIM4, GET_TIMER) >= (gConfgBuf.differentCodeInterval * CLK_BASE)))
{
gAutoModeOverTimeFlag = TRUE;
TimerHSIClockCount(TIM4, STOP_TIMER);
}
}
if ((TimerHSIClockCount(TIM5, GET_TIMER) >= SENSOR_TIME_OUT))
{
TimerHSIClockCount(TIM5, STOP_TIMER);
gSensorChangeFlag = FALSE;
}
return result;
}
#else
/**
* @function SensorScanMode
* @brief 感应模式,如果感应环境有变化,再开启解码
* @param[in] BarData 结构体,存放解码数据
* @return 返回值为正,则为成功解码
*/
int SensorScanMode(BarData *pCode)
{
int result = 0;
//环境是否有变化,默认值是"无变化"
if(!gSensorChangeFlag) //环境无变化
{
//灯光控制
AppLEDControl(!gConfgBuf.ledStatus);
//判断上一次采图尺寸是否为640*480是的情况下需要采两张图
if(gLastPictureSize == DCMI_640_480)
{
gLastPictureSize = DCMI_320_240;
gCurrentPictureAddr = DCMIBUFADDR;
if(!DCMI_CaptureOnePic(gCurrentPictureAddr, gLastPictureSize))return FALSE;
gCurrentPictureAddr += HALF_BUF_SIZE;
}
if(!DCMI_CaptureOnePic(gCurrentPictureAddr, gLastPictureSize))return FALSE;
if(gCurrentPictureAddr == DCMIBUFADDR)
{
gCurrentPictureAddr += HALF_BUF_SIZE;
}
else
{
gCurrentPictureAddr = DCMIBUFADDR;
}
//图像差异明显?
if(DCMI_Differ(HALF_BUF_SIZE) == TMC_OK)
{
gSensorChangeFlag = TRUE;
gLastPictureSize = DCMI_640_480;
TimerHSIClockCount(TIM4, START_TIMER);
memset(gPreImage, 0, MAXCODELEN);
}
else
{
return result;
}
}
//环境有变化
//灯光控制
AppLEDControl(gConfgBuf.ledStatus);
//图像采集
if(!DCMI_CaptureOnePic(DCMIBUFADDR, gLastPictureSize))return FALSE;
//解码
result = TMC_Scan_Decode(pCode);
//识读成功 或 超时
if(result > 0)
{
if(!memcmp(gPreImage, pCode->bardata, pCode->datalen)) //如果成功,相同条码延时
{
TimerHSIClockCount(TIM4, START_TIMER);
return FALSE;
}
else
{
Memcpy(gPreImage, pCode->bardata, pCode->datalen);
TimerHSIClockCount(TIM4, START_TIMER);
return TRUE;
}
}
if(TimerHSIClockCount(TIM4, GET_TIMER) >= TIME_OUT)
{
gSensorChangeFlag = FALSE;
//灯光控制
AppLEDControl(!gConfgBuf.ledStatus);
TimerHSIClockCount(TIM4, STOP_TIMER);
}
return result;
}
#endif
/**
* @function SingleMode
* @brief 扫码成功一次,移开,再移入才成功
* @param[in] BarData 结构体,存放解码数据
* @return 返回值为正,则为成功解码
*/
int SingleMode(BarData *pCode)
{
int result = 0;
//灯光控制
AppLEDControl(gConfgBuf.ledStatus);
//采集图像
if(!DCMI_CaptureOnePic(DCMIBUFADDR, DCMI_640_480))return FALSE;
//解码
result = TMC_Scan_Decode(pCode);
//识读成功
if(result > 0)
{
//长度相等
if(gPrebarcodelen && (gPrebarcodelen == pCode->datalen))
{
if(memcmp(pCode->bardata, gPreImage, gPrebarcodelen)) //码不同
{
gPrebarcodelen = pCode->datalen;
memcpy(gPreImage, pCode->bardata, gPrebarcodelen);
return TRUE;
}
}
else //长度不等,码不同
{
gPrebarcodelen = pCode->datalen;
memcpy(gPreImage, pCode->bardata, gPrebarcodelen);
return TRUE;
}
}
else
{
gPrebarcodelen = 0;
memset(gPreImage, 0, MAXCODELEN);
}
return FALSE;
}
/**
* @function ScanModeReceiveData
* @brief 扫码模块
* @param[in] BarData 结构体,存放解码数据
* @return TRUE 解码成功
* FALSE 解码失败
*/
uint8_t ScanModeReceiveData(BarData *bardata)
{
int ret = 0;
if(gLicenseFlag)
{
return FALSE;
}
gFunTrace = 36;
switch(gConfgBuf.scanCodeMode)
{
case AUTOMODE:
ret = AutoScanMode(bardata);
break;
case CMDMODE: //命令模式
ret = CmdScanMode(bardata);
break;
case CMDTIMEMODE: //命令时间模式
ret = CmdScanTimeMode(bardata);
break;
case SENSORMODE://感应模式
ret = SensorScanMode(bardata);
break;
case SINGLEMODE: //单次模式
ret = SingleMode(bardata);
break;
default:
ret = AutoScanMode(bardata);
break;
}
if(ret > 0)
{
return TRUE;
}
return FALSE;
}