条码编码-Code39

近来在研究条码的实现,遇到一些坑,现在把自己遇到的一些情况分享一下。

 

世界上约有225种以上的条形码一般较流行的有 39码、EAN码、UPC 码、128码,以及专门用於书刊管理的ISBN、ISSN等。

 

 

我们先从Code39码开始:

 

  • Code39

 

39码具有以下特性:

条码的长度没有限制,可随着需求作弹性调整。但在规划长度的大小时,应考虑条码阅读机所能允许的范围,避免扫瞄时无法读取完整的资料。


起始码和终止码必须固定为“ * ”字元。允许条码扫瞄器进行双向的扫瞄处理。由於39码具有自我检查能力,故检查码可有可无,不一定要设定。 条码占用的空间较大。

可表示的资料包含有:0~9的数字,A~Z的英文字母,以及“+”、“-”、“*”、“/”、“%”、“$”、“.”等特殊符号,再加上空白字元“ ”,共计44组编码,并可组合出128个ASCII CODE的字元符号,如表所示。

表 ASCII CODE字元符号与39码对照表

 

这里就只研究0~9的数字,A~Z的英文字母,以及“+”、“-”、“*”、“/”、“%”、“$”、“.”等特殊符号,再加上空白字元“ ”,这44组编码,其他ASCII码的组合暂时不考虑;

CODE 39码的编码规则是:

1、9条线表示一个字符;

2、黑线表示1,空线表示0;

3、线宽的表示w,窄的表示n;

4、条形码的首尾各一个*标识开始和结束;

5、宽条和窄条的比率为2-3之间;

6、字符和字符之间的有空白间隔;

7、校验位可不做编码;

编码对映表如下:

字元

逻辑型态

 

字元

逻辑型态

 

A

110101001011

wnnnnwnnwn

N

101011010011

nnnnwnnwwn

B

101101001011

nnwnnwnnwn

O

110101101001

wnnnwnnwnn

C

110110100101

wnwnnwnnnn

P

101101101001

nnwnwnnwnn

D

101011001011

nnnnwwnnwn

Q

101010110011

nnnnnnwwwn

E

110101100101

wnnnwwnnnn

R

110101011001

wnnnnnwwnn

F

101101100101

nnwnwwnnnn

S

101101011001

nnwnnnwwnn

G

101010011011

nnnnnwwnwn

T

101011011001

nnnnwnwwnn

H

110101001101

wnnnnwwnnn

U

110010101011

wwnnnnnnwn

I

101101001101

nnwnnwwnnn

V

100110101011

nwwnnnnnwn

J

101011001101

nnnnwwwnnn

W

110011010101

wwwnnnnnnn

K

110101010011

wnnnnnnwwn

X

100101101011

nwnnwnnnwn

L

101101010011

nnwnnnnwwn

Y

110010110101

wwnnwnnnnn

M

110110101001

wnwnnnnwnn

Z

100110110101

nwwnwnnnnn

 

 

 

 

 

 

 

 

 

 

 

 

0

101001101101

nnnwwnwnnn

100101001001

nwnnnwnwnn

1

110100101011

wnnwnnnnwn

100101011011

nwnnnnwnwn

2

101100101011

nnwwnnnnwn

100101101101

nwnnwnwnnn

3

110110010101

wnwwnnnnnn

100100101001

nwnwnnnwnn

4

101001101011

nnnwwnnnwn

101001001001

nnnwnwnwnn

5

110100110101

wnnwwnnnnn

100100100101

nwnwnwnnnn

6

101100110101

nnwwwnnnnn

110010101101

wwnnnnwnnn

7

101001011011

nnnwnnwnwn

空白

100110101101

nwwnnnwnnn

8

110100101101

wnnwnnwnnn

 

 

9

101100101101

nnwwnnwnnn

 

 

 

这里的逻辑形态,并不包括每个字符之间的空白间隙,所以在编码的时候要再加一个0,很多资料上都未提醒着一点,注意别踩坑。

现在直接上代码:

#include <stdio.h>
#include <string.h>
#include <CODE39.h>
#include "lcd.h"


//ÿ����ʾ�ַ���Ӧ������
const char *Code39DataBuf[43]= {
//ÿ����Ԫ���������9������ɣ��ַ����ַ�֮��Ŀհ׼��������ÿһ������0���ǿհ׼�϶
//1�ú�ɫ�߱����0�ð�ɫ�߱��
// �߼���̬    //��Ԫ      ACSII(DEC)
"1010011011010",// 0           48
"1101001010110",// 1           49
"1011001010110",// 2           50
"1101100101010",// 3           51
"1010011010110",// 4           52
"1101001101010",// 5           53
"1011001101010",// 6           54
"1010010110110",// 7           55
"1101001011010",// 8           56
"1011001011010",// 9           57
"1101010010110",// A           65
"1011010010110",// B           66
"1101101001010",// C           67
"1010110010110",// D           68
"1101011001010",// E           69
"1011011001010",// F           70
"1010100110110",// G           71
"1101010011010",// H           72
"1011010011010",// I           73
"1010110011010",// J           74
"1101010100110",// K           75
"1011010100110",// L           76
"1101101010010",// M           77
"1010110100110",// N           78
"1101011010010",// O           79
"1011011010010",// P           80
"1010101100110",// Q           81
"1101010110010",// R           82
"1011010110010",// S           83
"1010110110010",// T           84
"1100101010110",// U           85
"1001101010110",// V           86
"1100110101010",// W           87
"1001011010110",// X           88
"1100101101010",// Y           89
"1001101101010",// Z           90
"1001010110110",// -           45
"1100101011010",// .           46
"1001101011010",// sp          32
"1001001001010",// $           36
"1001001010010",// /           47
"1001010010010",// +           43
"1010010010010",// %           37
};


char *code39_Code(char *CharToShow, u8 len)
{
   //PixelPtr�Ǻ������ص��ָ��
//	char *PixelPtr;
	u8 lcd_id[12];				//���LCD ID�ַ���
	static char PixelPtr[520];
  uint8_t  i,j,CheakID; 
  uint32_t CheakSum = 0;

	const char *Space_CODE39    = "000000000";
	const char *BStartEndBuf    = "1001011011010"; // *
	
	 //����У��λ
  for(i=0; i<len; i++)
  {
    if((CharToShow[i]>='0') && (CharToShow[i]<='9'))      CheakSum+=((CharToShow[i]-'0'));//0~9
    else if((CharToShow[i]>='A') && (CharToShow[i]<='Z')) CheakSum+=((CharToShow[i]-'0')-7);//A~Z
    
		else if(CharToShow[i]=='-') CheakSum+=36;
	  else if(CharToShow[i]=='.') CheakSum+=37;
		else if(CharToShow[i]==' ') CheakSum+=38;
    else if(CharToShow[i]=='&') CheakSum+=39;
    else if(CharToShow[i]=='/') CheakSum+=40;
    else if(CharToShow[i]=='+') CheakSum+=41;
    else if(CharToShow[i]=='%') CheakSum+=42;		
	} 

  CheakID = CheakSum%43;
	sprintf((char*)lcd_id,"LCD ID:%d",CheakID);//
	LCD_ShowString(30,40,210,24,24,lcd_id);
	
	//�����ǿհ�����9�����صĿհ�
   strcat(PixelPtr, Space_CODE39);
	
  //��������ʼ�ַ�*
    strcat(PixelPtr, BStartEndBuf);

    for (int i = 0; i < len; i++)
    {//
			
			if((CharToShow[i]>='0') && (CharToShow[i]<='9'))      strcat(PixelPtr, Code39DataBuf[(CharToShow[i]-'0')]);//0~9
			else if((CharToShow[i]>='A') && (CharToShow[i]<='Z')) strcat(PixelPtr, Code39DataBuf[(CharToShow[i]-'0')-7]);//A~Z
			
			else if(CharToShow[i]=='-') strcat(PixelPtr, Code39DataBuf[36]);//
			else if(CharToShow[i]=='.') strcat(PixelPtr, Code39DataBuf[37]);//
			else if(CharToShow[i]==' ') strcat(PixelPtr, Code39DataBuf[38]);//
			else if(CharToShow[i]=='&') strcat(PixelPtr, Code39DataBuf[39]);//
			else if(CharToShow[i]=='/') strcat(PixelPtr, Code39DataBuf[40]);//
			else if(CharToShow[i]=='+') strcat(PixelPtr, Code39DataBuf[41]);//
			else if(CharToShow[i]=='%') strcat(PixelPtr, Code39DataBuf[42]);//	
    }
		//��
//    strcat(PixelPtr,Code39DataBuf[CheakID]);
		
  //�����ǽ����ַ�*
    strcat(PixelPtr, BStartEndBuf);
		
    return PixelPtr;
}

int CODE39_DISPLAY( char *CODE39_data , u8 len)
{
   	u16 i,j,k;
	  u16 x,y,p;
    char *code;
	
	code = code39_Code(CODE39_data,len);

	p = (3-1)*2;//���С
	x = 24;
	y = 80;
	
	for(i=0;i<strlen(code);i++)//width
	{

		k=41;//height
		for(j=0;j<k;j++)
		{
			if(code[i]>'0')
			{
				LCD_Fill(x+p*i,y+p*j,x+p*(i+1)-1,y+p*(j+1)-1,BLACK);
      }
			else
			{
				
			}
		}
	}

}	

 

 

  • 2
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值