2017-10-05 101 views
0

我试图创建一个生成CRC查找表的函数。我正在使用一个8051微控制器,我宁愿做表查找方法,但同时我宁愿让我的计算机生成值,然后我可以直接将其加载到微控制器中。 http://www.rajivchakravorty.com/source-code/uncertainty/multimedia-sim/html/crc8_8c-source.html在C中生成的CRC查找表总是给出不同的结果

我只在“主”功能添加

#include <stdio.h> 
#define GP 0x107 
#define DI 0x07 

static unsigned char crc8_table[256]; 
static int made_table=0; 

static void init_crc8() 
{ 
    int i,j; 
    unsigned char crc; 
    if (!made_table) { 
    for (i=0; i<256; i++) { 
     crc = i; 
     for (j=0; j<8; j++) 
     crc = (crc << 1)^((crc & 0x80) ? DI : 0); 
     crc8_table[i] = crc & 0xFF; 
    } 
    made_table=1; 
    } 
} 

void crc8(unsigned char *crc, unsigned char m) 
{ 
    if (!made_table) 
    init_crc8(); 
    *crc = crc8_table[(*crc)^m]; 
    *crc &= 0xFF; 
} 

int main() 
{ 
    unsigned char crc[1]; 
    crc8(crc,'S'); 
    printf("S=%x\n",crc[0]); //different hex code almost every time 
    crc8(crc,'T'); 
    printf("T=%x\n",crc[0]); //different hex code almost every time 
    return 0; 
} 

当我执行该程序,我希望在屏幕上相同的价值观,但在十六进制代码后:这其中大部分源代码已经从借来的在几乎所有的程序执行中都会打印等号。

我能做些什么来纠正这个问题?我不想收集不正确的CRC值。

+2

请记住,本地变量(包括数组)在默认* uninitialized *。他们的价值将是*不确定*。现在在'main'函数的'crc'数组的上下文中考虑一下。 –

+0

在不相关的说明中,您应该了解运算符'&'的地址。 –

+0

@Somepro:你能否更具体地说'&'? –

回答

0

在main中,crc [0]尚未初始化。因此,在crc8中,表达式(* crc)^ m中的* crc是未初始化的,因此是您的随机值。

修复:初始化crc [0]。像

unsigned char crc[1] = { 0 }; 
+0

这是行不通的,但我试过的没有工作是:'crc [0] ='\ 0'; crc [1] ='\ 0';'因为它给了我一个分段错误。我很困惑,为什么你的解决方案的工作,但显然它确实。 – Mike

+0

'crc [1] ='\ 0';'不同于'unsigned char crc [1] = {0};''。前者是越界访问,因为它试图设置'crc []'的_second_元素,但是没有第二个元素,因为它是用一个元素声明的。这样的访问应该导致分段错误。后者是一个单元素数组的初始化,其中一个值将'crc [0]'设置为零。 –

0
  1. crc[0]东西是不初始化。在致电crc8()crc之前,您需要crc[0] = 0;*crc = 0;。那么你将不会从crc[0]的随机初始内容中得到随机答案。
  2. 你不需要在crc8()*crc &= 0xff;。如果char是8位,那么它什么都不做。如果你有一个奇怪的架构,其中char大于8位,那么你需要做*crc = crc8_table[((*crc)^m) & 0xff];以确保你不会超出表格的范围。 (在CRC计算中仅使用m的低8位)。表的内容已被限制为8位,因此在任何情况下您都不需要最终的& 0xff
  3. 您可能需要一个与零不同的初始值,并且您可能需要排除一个或最终的CRC值,具体取决于您想要的CRC-8的定义。在RevEng catalog of CRC's中,有两个不反映该多项式的8位CRC。两者的初始值都是零,但最后还是排除了0x55。此外,您需要的CRC定义可能会反映出来,在这种情况下,移位方向会改变,并且多项式会翻转。如果您的CRC-8需要与其他软件互操作,那么您需要找出正在使用的CRC的完整定义。
  4. 传递指针看起来像是一个奇怪的选择。直接传递并返回CRC值会更有效率。例如。 unsigned crc8(unsigned crc, unsigned ch) {,它将ch中的8位应用于CRC crc,并返回新值。请注意,您不需要使CRC值为char。通常C程序最有效地用作参数和返回。实际上,通常第一个参数是通过寄存器传递的,并返回到同一个寄存器中。
  5. 通常在一个由一系列字节组成的消息上计算CRC。使用循环完成整个消息的例程会更高效,因此您不需要检查消息的每个字节是否已经构建了表。
相关问题