I'm also a beginner, so you might find a better explanation. But I think the problem is as follows.
You are using an external variable called "crc".
An external variable must be defined, exactly once, outside of any function; this sets aside storage for it. The variable must also be declared in each function that wants to access it; this states the type of the variable. The declaration may be an explicit extern statement or may be implicit from context.
Now what happened is this:
in form.h you declared & defined crc unsignedchar crc=0;
In main you are defining it yet again: crc = df1.CHECK(crc,buffer[6]);
This is not allowed.
One way to prevent it is by making the variable static.
If you make the following change in Form.h your code should work: staticunsignedchar crc=0;
This way you force that it is only initialized (defined) once.
Another option is to move the crc definition to the main cpp file.
in Form.h you'd write: externunsignedchar crc;
in the main.cpp file you write: unsignedchar crc=0;
---
To me one question remains (like I said I'm a beginner too). I don't know why it's not allowed to do it exactly the other way around. Why it is that I cannot say in the main.cpp externunsignedchar crc;
and in form.h unsignedchar crc=0;
Maybe this has to do with the order in which the linker treats the definitions & declarations? I would love to know why..