标题:
单片机条码扫描源码 已调试ok
[打印本页]
作者:
记得微笑
时间:
2017-11-20 10:43
标题:
单片机条码扫描源码 已调试ok
利用条码扫描,含源码,经过调试,可以使用
单片机源程序如下:
//
#include <STC12C2052AD.H>
#include "string.h"
#include "stdlib.h"
//#include <no_hand.h>
#define POLYNOMIAL_IDF 0x08408 //crc16 多项式
#define MAXUSERTIMERS 4
#define MAXTIMERSTICK 1000 //用户定时器最大时间长度(ms)
#define UERTIMESTATUS_STOP 0 //用户定时器状态-停止
#define UERTIMESTATUS_RUN 1 //用户定时器状态-运行
#define UERTIMESTATUS_RINING 2 //用户定时器状态-到时
#define UERTIMESTATUS_ERROR 3 //用户定时器状态-到时
#define Tid_SendTimer 1
#define Tcn_SendTimer 2//20// 2
#define Tid_pcrTimer 2
#define Tcn_pcrTimer 20
#define Tid_tiaomarTimer 3
#define Tcn_tiaomarTimer 20
#define Tid_TiaomaYingQing 0
#define Tcn_TiaomaYingQing 500
typedef struct _TiaoMaDataInfo
{
unsigned char SerialNum; //接收条码的顺序号
unsigned char Sta;
unsigned char CheckData;//校验码
unsigned char TiaoMaBuf[10];
}TiaoMaDataInfo;
typedef struct _TiaoMaBuf
{
unsigned char Sta;//1:表示有 0:表示不存在
unsigned char TiaoMaBuf[6];
}TiaoMaBuf;
typedef struct _ComuStaInfo
{
unsigned char Sta;
unsigned char Cmd;
unsigned char Len;
unsigned char Num;
unsigned char Buf[8];
unsigned char Suc;
unsigned int CRC;
}ComuStaInfo;
//定时器结构定义
typedef struct _SUserTimer{
volatile int Deadline;
volatile int ReLoadTickNum;
} SUserTimer;
TiaoMaDataInfo gTiaoMaData;
TiaoMaBuf TiaoMaBufData;
ComuStaInfo idata ComuStaData;
SUserTimer UserTimer[MAXUSERTIMERS];
sbit pc_txd =P3^2; //模拟串口接收
sbit pc_rxd =P3^3; //模拟串口发送
bit byte_waiting_flag; //接收字节时的等待时间,在未收到校验之前
bit Sendtopcflag; //模拟串口发送数据标志
bit Sendtopcendflag; //模拟串口发送数据字节结束标志
bit Revfrompcendflag; //模拟串口接收数据字节结束标志
bit Revfrompcflag; //模拟串口接收数据标志
bit YQflag =0;
bit DelayScanFlag =0;
unsigned char Revfrompcdata,Sendtopcdata;
unsigned char T0timeouttimesR,T0timeouttimesT;
unsigned char idata wait_receive_num;
unsigned char idata SendToPc[12];
unsigned int TimeTick =0;
unsigned char Send_Flag =0;
unsigned char idata Send_Len =0;
//unsigned char DelayScanFlag =0;
unsigned long idata DelayScanTime =0;
void UART0_SendByte(unsigned char dat);
//*--------------------------------------------------------------------------------------
//* Function Name : GetTickCount()
//* Object : Return the number of systimer tick
//* Input Parameters :
//* Output Parameters :
//*--------------------------------------------------------------------------------------
unsigned long GetTickCount(void)
{
return TimeTick;
}
//*--------------------------------------------------------------------------------------
//* Function Name : ResetTickCount()
//* Object : systimer tick = 0
//* Input Parameters :
//* Output Parameters :
//*--------------------------------------------------------------------------------------
void ResetTickCount(void)
{
int TimerID;
TimeTick = 0;
for(TimerID=0;TimerID<MAXUSERTIMERS;TimerID++)
{
UserTimer[TimerID].Deadline = 0;
}
}
//*--------------------------------------------------------------------------------------
//* Function Name : CheckResetTickCount()
//* Object : systimer tick = 0
//* Input Parameters :
//* Output Parameters :
//*--------------------------------------------------------------------------------------
void CheckResetTickCount(void)
{
int TimerID;
if(1)
{
for(TimerID=0;TimerID<MAXUSERTIMERS;TimerID++)
{
if(UserTimer[TimerID].Deadline != 0)
{
UserTimer[TimerID].Deadline -= 0x10000;
}
}
//stop the timer0 int
TimeTick -= 0x10000;
//start the timer0 int
}
}
//*--------------------------------------------------------------------------------------
//* Function Name : BeginTimer()
//* Object : Begin a user timer with tick
//* Input Parameters :
//* Output Parameters :
//*--------------------------------------------------------------------------------------
unsigned int StartTimer(unsigned int TimerID, unsigned int TimerTickCount)//1 ticket =5ms
{
if( TimerID > MAXUSERTIMERS) return 0;
if(TimerTickCount == 0)
TimerTickCount = UserTimer[TimerID].ReLoadTickNum;
if(TimerTickCount > MAXTIMERSTICK)
TimerTickCount = MAXTIMERSTICK;
UserTimer[TimerID].ReLoadTickNum = TimerTickCount;
UserTimer[TimerID].Deadline = TimeTick+TimerTickCount;
return TimerID;
}
//*--------------------------------------------------------------------------------------
//* Function Name : HaltTimer()
//* Object : Stop a user timer with tick
//* Input Parameters :
//* Output Parameters :
//*--------------------------------------------------------------------------------------
unsigned int HaltTimer(unsigned int TimerID)
{
if( TimerID > MAXUSERTIMERS) return UERTIMESTATUS_ERROR;
UserTimer[TimerID].Deadline = 0;
return TimerID;
}
//*--------------------------------------------------------------------------------------
//* Function Name : GetTimerStatus()
//* Object : Begin a user timer with tick
//* Input Parameters :
//* Output Parameters :
//*--------------------------------------------------------------------------------------
unsigned int GetTimerStatus( unsigned int TimerID,const int AutoStop) //反绕问题
{
unsigned int retcode;
if(TimerID > MAXUSERTIMERS)
retcode = UERTIMESTATUS_ERROR;
else if(UserTimer[TimerID].Deadline == 0)
retcode = UERTIMESTATUS_STOP;
else if(UserTimer[TimerID].Deadline > TimeTick)
{
if((UserTimer[TimerID].Deadline - TimeTick) > TimeTick+UserTimer[TimerID].ReLoadTickNum)
StartTimer(TimerID,0);
else
retcode = UERTIMESTATUS_RUN;
}
else
{
if(AutoStop)
UserTimer[TimerID].Deadline = 0;
else
UserTimer[TimerID].Deadline = TimeTick+UserTimer[TimerID].ReLoadTickNum;
retcode = UERTIMESTATUS_RINING;
}
return retcode;
}
//#include <reg52.h>/**************THIS IS A 模拟串口接收中 定时器0初始化**************/
void board_init(void)
{
// unsigned char test;
SCON =0x050;
TMOD =0x22;
TH1 =0xfa; //9600baud,11.0592m
TL1 =0xfa;
PCON =0x80;
TCON =0x01;
//////////
WDT_CONTR =0x3e;
CMOD =80; //在空闲模式下停止PCA计时器工作
CCON =0;
CCAPM0 =0x49; //CCAPM1用作软件定时器。当CCF1和ECCF1都置位时中断,CCF1和ECCF1必须由软件清零
CL =0;
CH =0;
CCAP0L =0x00;
CCAP0H =0x12;
// CCAP0L =0xb8;//200us
// CCAP0H =0x00;
EPCA_LVD =1;
CR =1;
////////////
// AUXR &=0x3f;
//TH0 =0x7f;// 给定时器0赋初值255-11059200/12/4800+1=40
//TL0 =0x7f;
EA =1;
ES =1;
// ES =1;
TR1 =1;
EX0 =1;
//EX1 =1;
ET0 =1;
IP =0;
PT0 =1; //TEST ,T0 IS PRIVATY
IT0 =1; //the edge interrupt
pc_txd =1;
pc_rxd =1;
//TX_EN =1;
}
/////////
void DataInit(void)
{
memset(&gTiaoMaData,0,sizeof(TiaoMaDataInfo));
memset(&TiaoMaBufData,0,sizeof(TiaoMaBuf));
memset(&ComuStaData,0,sizeof(ComuStaInfo));
Revfrompcendflag =0;
Sendtopcflag =0;
}
void externint0 (void) interrupt 0
{
TR0 =0;
TH0 =0x0A0;
TL0 =0x0A0;
T0timeouttimesR =8;
Revfrompcflag =1;
ET0=1;
TR0 =1;
EX0 =0;
//wait_receive_num =0;
byte_waiting_flag =0;
}
/************************************************************
timer0 interrupt subprogram
*************************************************************/
void t0int(void) interrupt 1
{
if( Sendtopcflag==1)
{
if( Sendtopcdata & 0x01)
pc_rxd =1; //T1=P1.6
else
pc_rxd =0;
Sendtopcdata =Sendtopcdata >> 1; //右移
Sendtopcdata =Sendtopcdata |0x80;
T0timeouttimesT--;
if( T0timeouttimesT==0)
{
Sendtopcflag =0;
pc_rxd =1; //停止位
Sendtopcendflag =1;
// TR0 =0;
EX0 =1;
}
}
if ( Revfrompcflag==1)
{ //test =~test; //test
Revfrompcdata = Revfrompcdata >> 1;
if (pc_txd ==1) //PC_txd=P3^2
Revfrompcdata =Revfrompcdata | 0x80;
T0timeouttimesR--;
if(T0timeouttimesR==0)
{
Revfrompcflag =0;
Revfrompcendflag =1;
IE0 =0;
EX0 =1;
byte_waiting_flag =1;
TR0 =0;
TH0 =0;
TL0 =0;
TR0 =1;
}
}
}
///////////////
/************************************************************
PCA interrupt subprogram
*************************************************************/
void pcaint(void) interrupt 6
{
//int i;
//static int i;
CCF0 =0;
// i =(CCAP0H*256)+CCAP0L;
//i +=0xb8;
//CCAP0H =(unsigned char )(i>>8);
//CCAP0L =(unsigned char )i;
// CL =0;
// CH =0;
CCAP0L +=0x00;
CCAP0H +=0x12;
// UART0_SendByte(CCAP0H);
//UART0_SendByte(CCAP0L);
//CCAP0L +=0xb8;
// CCAP0H +=0x00;
TimeTick++;
}
/*********************sending a byte of simulate serial port**********/
void sendbyte(unsigned char simdata)
{
// txd_sel =1;
Sendtopcdata =simdata;
EX0=0; //模拟串口接收
TR0=0; //定时器0停止计数
TH0=0x0A0; //给定时器0赋初值255-11.0592/12/9600+1=A0
TL0=0x0A0;
TR0=1;
ET0=1; //定时器0开始计数
pc_rxd=0; //串口传输数据的开始BIT=0
T0timeouttimesT=0x0a; // //1 start bit ;8 bit data ,1 stop bit
Sendtopcflag=1; //在定时其中断中,根据该标志
Sendtopcendflag=0;
while(!Sendtopcendflag); //waiting the simulate serial port sending end
Sendtopcendflag=0;
// //允许模拟串口接收
}
void emulator_send_string(unsigned char *array,unsigned char array_length)
{
unsigned int i;
for (i=0;i<array_length;i++)
{
sendbyte(array[i]);
}
}
/*
*********************************************************************************************************
** 函数名称 :UART0_SendByte()
** 函数功能 :向串口0发送1字节数据
** 入口参数 :dat 要发送的数据
** 出口参数 :无
*********************************************************************************************************
*/
void UART0_SendByte(unsigned char dat)
{
//TB8 =Even_Checkout(dat);
SBUF =dat;
//if(IcWayDefineFlag ==1)
// TB8 =~TB8;
while(!TI);
TI =0;
}
/*
*********************************************************************************************************
** 函数名称 :UART0_SendString()
** 函数功能 :向串口0发送一个字符串
** 入口参数 :aa 一个字符串的首地址,length,字符串的长度
** 出口参数 :无
*********************************************************************************************************
*/
void UART0_SendString(char *aa,unsigned int length)
{
unsigned int i;
for (i=0;i<length;i++)
{
UART0_SendByte(aa[i]);
}
}
void TiaoMaRev(void)
////////
{
unsigned char temp;
temp =0;
if (Revfrompcendflag == 1)
{
Revfrompcendflag =0;
temp =Revfrompcdata;
//UART0_SendByte(temp);
switch(gTiaoMaData.Sta)
{
case 0://开始位
if(temp ==0x36)
{
gTiaoMaData.Sta++;
//BeginTimer(uint8 TimerId,uint32 ValueCount)
//StartTimer(TID_TIAOMAREV1,TIN_TIAOMAREV1);
StartTimer(Tid_tiaomarTimer,Tcn_tiaomarTimer);//定义条码接收时间,超时状态归零
}
else
{
gTiaoMaData.SerialNum =0;
}
break;
case 1://条码接收
gTiaoMaData.TiaoMaBuf[gTiaoMaData.SerialNum]=(temp-0x30);
gTiaoMaData.SerialNum++;
if(gTiaoMaData.SerialNum==6)
{
gTiaoMaData.Sta++;
gTiaoMaData.SerialNum =0;
}
break;
case 2://条码校验位
gTiaoMaData.CheckData =(temp-0x30);
gTiaoMaData.Sta++;
case 3://
gTiaoMaData.Sta++;
case 4:
gTiaoMaData.Sta++;
HaltTimer(Tcn_tiaomarTimer);
}
}
}
//////////条码校验算法
unsigned char TiaoMaCheck(void)
{
unsigned char i=0;
unsigned char CheckDat1;
unsigned char CheckDat2;
CheckDat1 =gTiaoMaData.TiaoMaBuf[5]+gTiaoMaData.TiaoMaBuf[3]+gTiaoMaData.TiaoMaBuf[1]+6;
CheckDat1 =CheckDat1*3;
CheckDat2 =gTiaoMaData.TiaoMaBuf[4]+gTiaoMaData.TiaoMaBuf[2]+gTiaoMaData.TiaoMaBuf[0];
CheckDat2 =CheckDat2+CheckDat1;
while(i*10 <CheckDat2)
{
i++;
}
CheckDat1 =i*10-CheckDat2;
if(gTiaoMaData.CheckData ==CheckDat1)
return 0; //校验成功
else
return 1; //校验失败
}
//////////////
void tiaomadis(void)
{
if(gTiaoMaData.Sta ==5)//表示收到了条码校验位
{
gTiaoMaData.Sta =0;
//UART0_SendByte(0x99);
//UART0_SendString(TiaoMaBufData.TiaoMaBuf,6);
HaltTimer(Tid_tiaomarTimer);//条码接收完毕
if(TiaoMaCheck() ==0)
{
//if(YQflag ==1)
//if(GetTimerStatus(Tid_TiaomaYingQing,1)!=UERTIMESTATUS_RUN)
if(DelayScanFlag ==0)
{
//UART0_SendByte(0x66);
TiaoMaBufData.Sta =1;
YQflag =0;
DelayScanFlag =1;
//拷贝条码数据
memcpy(TiaoMaBufData.TiaoMaBuf,gTiaoMaData.TiaoMaBuf,10);
//StartTimer(Tid_TiaomaYingQing,Tcn_TiaomaYingQing);
}
//UART0_SendString(TiaoMaBufData.TiaoMaBuf,6);
}
}
}
/*********************************************************************************************************
** 函数名称 :GetCRC16
** 函数功能 :得到CRC16值
** 入口参数 : bufData:要进行CRC校验的串,sizeData:串的长度
** 出口参数 :无
*********************************************************************************************************
*/
unsigned int GetCRC16(unsigned char *bufData, unsigned int sizeData)
{
unsigned int CRC_buf, i;
unsigned char j;
CRC_buf = 0;
for(i=0; i < sizeData; i++)
{
CRC_buf ^= bufData[i];
for(j=0; j < 8; j++)
{
if(CRC_buf & 0x0001) {CRC_buf >>= 1; CRC_buf ^= POLYNOMIAL_IDF;}
else CRC_buf >>= 1;
}
}
return CRC_buf;
}
/////////////////////////////
//条码协议
//为半双工,条码板被动,主板主动查询
//协议格式为: SYNC(1 byte) ADR(1 byte) LNG(1 byte) CMD(1 byte) DATA(0 to 250 bytes) CRC2( bytes)
////条码回应时ADR: 0X10,空闲data:0X83H
//有条码dat:0X84H +6 HEX
/////////////////////////////
/////////////////////////////////////////////////////
void serial (void) interrupt 4
{
unsigned char serial_buf;
// unsigned char i;
if(RI ==1)
{
RI =0;
serial_buf =SBUF;
// UART0_SendByte(serial_buf);
//sendbyte(serial_buf);
switch(ComuStaData.Sta)
{
case 0:
{
if(serial_buf ==0x02)
{
ComuStaData.Buf[ComuStaData.Sta]=serial_buf;
ComuStaData.Sta++;
ComuStaData.Num =0;
StartTimer(Tid_pcrTimer,Tcn_pcrTimer);
}
else
ComuStaData.Sta =0;
}
break;
case 1://adr
{
ComuStaData.Buf[ComuStaData.Sta]=serial_buf;
ComuStaData.Sta++;
}
break;
case 2://lng
{
//if(serial_buf ==6)
{
ComuStaData.Buf[ComuStaData.Sta]=serial_buf;
ComuStaData.Sta++;
ComuStaData.Len =serial_buf;
}
//UART0_SendByte(0xcc);
//else
// ComuStaData.Sta =0;
if(ComuStaData.Len>7)
ComuStaData.Sta =0;
}
break;
/*
case 3://cmd
{
ComuStaData.Buf[ComuStaData.Sta]=serial_buf;
ComuStaData.Sta++;
ComuStaData.Cmd =serial_buf;
}
break;
*/
case 3:
{
ComuStaData.Buf[ComuStaData.Num+3]=serial_buf;
ComuStaData.Num++;
if(ComuStaData.Num ==(ComuStaData.Len-3))
{
ComuStaData.Suc =1;
//UART0_SendByte(0xaa);
ComuStaData.CRC=((ComuStaData.Buf[ComuStaData.Len-1]<<8)+ComuStaData.Buf[ComuStaData.Len-2]);
ComuStaData.Sta =0;
HaltTimer(Tid_pcrTimer);
}
}
break;
}
}
}
///////
void pcdis(void)
{
int crc;
unsigned char i;
if(ComuStaData.Suc ==1)
{
ComuStaData.Suc =0;
if(ComuStaData.CRC ==GetCRC16(ComuStaData.Buf,(ComuStaData.Len-2)))
{
//if(ComuStaData.Buf[1] ==0x10)//ADR为条码
{
if(ComuStaData.Buf[3]==0x33)//polling
{
if(TiaoMaBufData.Sta ==0)//空闲位,表示没有扫描值
{
SendToPc[0] =0x02;//head
SendToPc[1] =0x10;//adr
SendToPc[2] =0x6;//len
SendToPc[3] =0x83;//dat
crc =GetCRC16(SendToPc,4);
SendToPc[4] =(unsigned char)crc;
SendToPc[5] =(unsigned char)(crc>>8);
Send_Flag =1;
Send_Len =6;
//UART0_SendString(SendToPc,6);
StartTimer(Tid_SendTimer,Tcn_SendTimer);
}
else if(TiaoMaBufData.Sta ==1)//为1,表示有扫描值
{
SendToPc[0] =0x02;//head
SendToPc[1] =0x10;//adr
SendToPc[2] =0x0c;//len
SendToPc[3] =0x84;//dat
for(i =0;i<6;i++)
SendToPc[i+4]=TiaoMaBufData.TiaoMaBuf[i];
crc =GetCRC16(SendToPc,10);
SendToPc[10] =(unsigned char)crc;
SendToPc[11] =(unsigned char)(crc>>8);
Send_Flag =1;
Send_Len =12;
StartTimer(Tid_SendTimer,Tcn_SendTimer);
//UART0_SendString(SendToPc,12);
}
}
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
0.png
(8.41 KB, 下载次数: 34)
下载附件
2017-11-20 20:11 上传
全部资料下载地址:
code_saomiaoban.zip
(111.36 KB, 下载次数: 34)
2017-11-20 10:41 上传
点击文件名下载附件
条码扫描源码,调试过,可以使用
下载积分: 黑币 -5
作者:
lizhendong
时间:
2017-11-20 20:36
真的可以吗?谢谢
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1