• We recently switched our forum platform. If you experience any issues please email support@crystalfontz.com

CFA635 with PIC host

PeteG

New member
I have a CFA635-TMF-KL that I am attempting to get working from a PIC microcontroller. At the moment all I am trying to do is to get the display to clear. Could not make sense of the CRC code, but noticed someone else on the forum had got their display to clear using 0x06, 0x00, 0x97, 0xB5, but so far nothing. Here is my C code, any advice would be welcome.

Code:
#include <16F887.h>
#device ICD=TRUE
#fuses HS,NOLVP,NOWDT
#use delay (clock=1843200)//LCD display 115200 baud, 8 data bits, no parity, one stop bit
#use rs232 (baud=115200, xmit=PIN_C6, rcv=PIN_C7)
#define GREEN_LED PIN_A5

//Commands
//Clear screen 6, 0x06
//Cursor position 11, 0x0B, row 0-3, column 0-19
//Cursor style 12, 0x0C, 0-4, 0=no cursor
//LCD Contast 13, 0x0D, contrast 0-254
//LCD Keypad backlight 14, 0x0E, setting 0-100
//Send data to LCD 31, 0x1F, 
//Set baud rate 33

long tx_data;
long tx_data_length;
long tx_command;//8 bit 00, followed by 0-63 command code
long tx_CRC;

void main () {
tx_command=0x06;
tx_data_length=0x00;
tx_data=0x97;
tx_CRC=0xB5;
delay_ms(100);
while(TRUE) {
output_low(GREEN_LED);
putc(tx_command);
putc(tx_data_length);
putc(tx_data);
putc(tx_CRC);
delay_ms(1);
}
}
Looking for additional LCD resources? Check out our LCD blog for the latest developments in LCD technology.
 

CF Tech

Administrator
Try:


Code:
unsigned char tx_command;//8 bit 00, followed by 0-63 command code
unsigned char tx_data_length;
unsigned char tx_data[22];
unsigned char tx_CRC_lo;
unsigned char tx_CRC_hi;

unsigned char i;

void main ()
  {
  tx_command=0x06;
  tx_data_length=0x00;
  //tx_data= data length is 0, data[] field is empty
  tx_CRC_lo=0x97;
  tx_CRC_hi=0x5B;

  delay_ms(100);
  output_low(GREEN_LED);

  putc(tx_command);
  putc(tx_data_length);
  for(i=0;i < tx_data_length;i++)
    putc(data[i]);
  putc(tx_CRC_lo);
  putc(tx_CRC_hi);
  delay_ms(1);
  }
 

PeteG

New member
That code would not run, so I made the change shown in red, but still no response. I am unclear on how the CRC is generated and how it relates to the data, can you direct me to any text that explains CRC generation in more detail? There is a list of 256 CRC codes in the data sheet, but a typical packet is more than one byte, so how can you look up a CRC code for a packet that is 2, 3 or more bytes? The CRC generation seems very over complex just to write one digit to the display. To load a complete screen is going to take a lot of code and a lot of time, as the data sheet implies you have to wait 250mS for an acknowledgement packet before sending another. Do I have to use the CRC system to write to the display? Most LCD displays use a parallel 8 bit data line with 3 control lines which is much faster and easier to program.

Code:
unsigned char tx_command;//8 bit 00, followed by 0-63 command code
unsigned char tx_data_length;
unsigned char tx_data[22];
unsigned char tx_CRC_lo;
unsigned char tx_CRC_hi;
unsigned char i;


void main () {
tx_command=0x06;
tx_data_length=0x00;
tx_CRC_lo=0x97;
tx_CRC_hi=0x5B;//tried B5 too
delay_ms(100);
while(TRUE) {
output_low(GREEN_LED);
putc(tx_command);
putc(tx_data_length);
for(i=0;i < tx_data_length;i++)
[COLOR="Red"]putc(tx_data[i]);[/COLOR]
putc(tx_CRC_lo);
putc(tx_CRC_hi);
delay_ms(1);
}
}
 
USB LCD Displays - Graphic and Character LCDs with a Keypad

CF Tech

Administrator
Here is some PIC 16 code that should help you send packets to a CFA-63x

Replace % with space to restore formatting that the forum kills.

Code:
.
.
.
typedef unsigned char ubyte;
typedef signed char sbyte;
typedef unsigned short word;
typedef unsigned long dword;
typedef union
% {
% ubyte
%   as_bytes[2];
% word
%   as_word;
% }WORD_UNION;
typedef union
% {
% ubyte
%   as_bytes[4];
% dword
%   as_dword;
% }DWORD_UNION;
.
.
.
#define MAX_DATA_LENGTH 22
//============================================================================
typedef struct
% {
% ubyte
%   command;
% ubyte
%   data_length; 
% ubyte
%   data[MAX_DATA_LENGTH];
% WORD_UNION
%   CRC;
% }COMMAND_PACKET;
COMMAND_PACKET
% outgoing_command;
.
.
.
//============================================================================
word get_crc(word seed,const ubyte *bufptr,word len)
% {
% //CRC lookup table to avoid bit-shifting loops.
% static const word crcLookupTable[256] =
%   {0x00000,0x01189,0x02312,0x0329B,0x04624,0x057AD,0x06536,0x074BF,
%    0x08C48,0x09DC1,0x0AF5A,0x0BED3,0x0CA6C,0x0DBE5,0x0E97E,0x0F8F7,
%    0x01081,0x00108,0x03393,0x0221A,0x056A5,0x0472C,0x075B7,0x0643E,
%    0x09CC9,0x08D40,0x0BFDB,0x0AE52,0x0DAED,0x0CB64,0x0F9FF,0x0E876,
%    0x02102,0x0308B,0x00210,0x01399,0x06726,0x076AF,0x04434,0x055BD,
%    0x0AD4A,0x0BCC3,0x08E58,0x09FD1,0x0EB6E,0x0FAE7,0x0C87C,0x0D9F5,
%    0x03183,0x0200A,0x01291,0x00318,0x077A7,0x0662E,0x054B5,0x0453C,
%    0x0BDCB,0x0AC42,0x09ED9,0x08F50,0x0FBEF,0x0EA66,0x0D8FD,0x0C974,
%    0x04204,0x0538D,0x06116,0x0709F,0x00420,0x015A9,0x02732,0x036BB,
%    0x0CE4C,0x0DFC5,0x0ED5E,0x0FCD7,0x08868,0x099E1,0x0AB7A,0x0BAF3,
%    0x05285,0x0430C,0x07197,0x0601E,0x014A1,0x00528,0x037B3,0x0263A,
%    0x0DECD,0x0CF44,0x0FDDF,0x0EC56,0x098E9,0x08960,0x0BBFB,0x0AA72,
%    0x06306,0x0728F,0x04014,0x0519D,0x02522,0x034AB,0x00630,0x017B9,
%    0x0EF4E,0x0FEC7,0x0CC5C,0x0DDD5,0x0A96A,0x0B8E3,0x08A78,0x09BF1,
%    0x07387,0x0620E,0x05095,0x0411C,0x035A3,0x0242A,0x016B1,0x00738,
%    0x0FFCF,0x0EE46,0x0DCDD,0x0CD54,0x0B9EB,0x0A862,0x09AF9,0x08B70,
%    0x08408,0x09581,0x0A71A,0x0B693,0x0C22C,0x0D3A5,0x0E13E,0x0F0B7,
%    0x00840,0x019C9,0x02B52,0x03ADB,0x04E64,0x05FED,0x06D76,0x07CFF,
%    0x09489,0x08500,0x0B79B,0x0A612,0x0D2AD,0x0C324,0x0F1BF,0x0E036,
%    0x018C1,0x00948,0x03BD3,0x02A5A,0x05EE5,0x04F6C,0x07DF7,0x06C7E,
%    0x0A50A,0x0B483,0x08618,0x09791,0x0E32E,0x0F2A7,0x0C03C,0x0D1B5,
%    0x02942,0x038CB,0x00A50,0x01BD9,0x06F66,0x07EEF,0x04C74,0x05DFD,
%    0x0B58B,0x0A402,0x09699,0x08710,0x0F3AF,0x0E226,0x0D0BD,0x0C134,
%    0x039C3,0x0284A,0x01AD1,0x00B58,0x07FE7,0x06E6E,0x05CF5,0x04D7C,
%    0x0C60C,0x0D785,0x0E51E,0x0F497,0x08028,0x091A1,0x0A33A,0x0B2B3,
%    0x04A44,0x05BCD,0x06956,0x078DF,0x00C60,0x01DE9,0x02F72,0x03EFB,
%    0x0D68D,0x0C704,0x0F59F,0x0E416,0x090A9,0x08120,0x0B3BB,0x0A232,
%    0x05AC5,0x04B4C,0x079D7,0x0685E,0x01CE1,0x00D68,0x03FF3,0x02E7A,
%    0x0E70E,0x0F687,0x0C41C,0x0D595,0x0A12A,0x0B0A3,0x08238,0x093B1,
%    0x06B46,0x07ACF,0x04854,0x059DD,0x02D62,0x03CEB,0x00E70,0x01FF9,
%    0x0F78F,0x0E606,0x0D49D,0x0C514,0x0B1AB,0x0A022,0x092B9,0x08330,
%    0x07BC7,0x06A4E,0x058D5,0x0495C,0x03DE3,0x02C6A,0x01EF1,0x00F78};

% //Initial CRC value is 0x0FFFF.
% register word
%   newCrc;
% newCrc=seed;
% //This algorithim is based on the IrDA LAP example.
% while(len--)
%   newCrc = (newCrc >> 8) ^ crcLookupTable[(newCrc ^ *bufptr++) & 0xff];
% //Make this crc match the one's complement that is sent in the packet.
% return(~newCrc);
% }     
//============================================================================
//                              send_packet()
//
// send_packet() will set the CRC in outgoing_response
//----------------------------------------------------------------------------
void send_packet(void)
%  {
%  //Set the CRC, outgoing_response.data_length includes data[], command and
%  //CRC. We need to CRC over data_length, command and data[].
%  outgoing_command.CRC.as_word=
%    get_crc(0xFFFF,(ubyte *)&outgoing_command,outgoing_command.data_length-1);

%  //Move the CRC into position.
%  outgoing_command.data_length-=3;
%  outgoing_command.data[outgoing_command.data_length]=
%    outgoing_command.CRC.as_bytes[0];
%  outgoing_command.data_length++;
%  outgoing_command.data[outgoing_command.data_length]=
%    outgoing_command.CRC.as_bytes[1];
%  outgoing_command.data_length+=2;
%  }
//============================================================================
.
.
.

const ubyte
% GimmeHello[11]="Hello World";  // no terminator needed
ubyte
% i;

outgoing_command.command=31;  //Write to LCD
outgoing_command.data_length=2+11; //col, line + 11 bytes
outgoing_command.data[0]=0; //column
outgoing_command.data[1]=1; //line

for(i=2;i&LT;=2+11;i++)
% outgoing_command.data[i]=GimmeHello[i];

send_packet();
.
.
.
 

PeteG

New member
I have tried the code below, which seems the simplest out of all the examples you gave me, but still nothing. Have checked the signal going in and its 0V to 5V on pin H1 1. The module is the CFA635-TMF-KL which has the 5V logic input i.e not RS232 so this should be OK. I am using a PIC development board that came with a 20MHz Crystal, bt have changed this to 18.432MHz, so the baud rate should be correct. Can you suggest anything else I can try?

#include <16F887.h>
#device ICD=TRUE
#fuses HS,NOLVP,NOWDT
#use delay (clock=1843200)//LCD display 115200 baud, 8 data bits, no parity, one stop bit
#use rs232 (baud=115200, xmit=PIN_C6, rcv=PIN_C7)
#define GREEN_LED PIN_A5

void main () {
while(TRUE) {
output_low(GREEN_LED);
putc(31); //LCD
putc(22); //length
putc(0); //x
putc(0); //y
putc('H');
putc('e');
putc('l');
putc('l');
putc('o');
putc(' ');
putc('W');
putc('o');
putc('r');
putc('l');
putc('d');
putc(' ');
putc(' ');
putc(' ');
putc(' ');
putc(' ');
putc(' ');
putc(' ');
putc(' ');
putc(' ');
putc(14); //LSB CRC
putc(229); //MSB CRC
}
}
 

PeteG

New member
Whats the formula for the CRC? I cannot seem to find this anywhere. Found a look up table for values from 0 to 256, but not sure how this is related to the packet or how you would know which value to use.
 

PeteG

New member
I have replaced the hard coded CRC with one of the sample C code routines in the data sheet (Algorithm 2B) and changed it a bit so its called correctly from my program. Needless to say, it compiles but does not work! What I cannot see is how this algorithm evaluates the packet data. It refers to a variable "data", but the remark says "current byte being shifted", so does that mean I have to run this algorithm after every byte sent? i.e. not just at the end of the packet as I have done below. Guess I also need to somehow store each byte sent as "data" so the algotithm can read it, but then surely it would then just recalculate the CRC based on the last byte and not the whole packet?

#include <16F887.h>
#device ICD=TRUE
#fuses HS,NOLVP,NOWDT
#use delay (clock=18432000)//LCD display 115200 baud, 8 data bits, no parity, one stop bit
#use rs232 (baud=115200, xmit=PIN_C6, rcv=PIN_C7)
#define GREEN_LED PIN_A5

int CRC_LSB;
long CRC_MSB;
long crc; //Calculated CRC
unsigned char i; //Loop count, bits in byte
unsigned char data; //Current byte being shifted
long count;
long ptr;

unsigned short get_CRC(unsigned char count,unsigned char *ptr)
{
crc = 0xFFFF; // Preset to all 1's, prevent loss of leading zeros
while(count--)
{
data = *ptr++;
i = 8;
do
{
if((crc ^ data) & 0x01)
{
crc >>= 1;
crc ^= 0x8408;
}
else
crc >>= 1;
data >>= 1;
} while(--i != 0);
}
return (~crc);
}

send_CRC () {
CRC_LSB=crc;
CRC_MSB=crc/256;
putc(CRC_LSB); //LSB CRC, 14 or 0x0E
putc(CRC_MSB); //MSB CRC, 229 or 0xE5
}

main () {
while(TRUE) {
output_low(GREEN_LED);
putc(31); //LCD
putc(22); //length
putc(0); //x
putc(0); //y
putc('H'); //72
putc('e'); //69
putc('l'); //108
putc('l'); //108
putc('o'); //111
putc(' '); //32
putc('W'); //87
putc('o'); //111
putc('r'); //114
putc('l'); //108
putc('d'); //100
putc(' '); //32
putc(' '); //32
putc(' '); //32
putc(' '); //32
putc(' '); //32
putc(' '); //32
putc(' '); //32
putc(' '); //32
putc(' '); //32
get_CRC (count,*ptr);
send_CRC ();

delay_ms(1000);
output_high(GREEN_LED);
delay_ms(1000);
}
}
 
int CRC_LSB; // should be byte
long CRC_MSB; // should be byte
long crc; //Calculated CRC should be short
long count; // could be short
long ptr; // what is this??? should be pointer to byte

unsigned short get_CRC(unsigned char count,unsigned char *ptr)
{
.... SNIP .....
}

main () {
while(TRUE) {
output_low(GREEN_LED);
putc(31); //LCD
putc(22); //length
putc(0); //x
putc(0); //y
putc('H'); //72
putc('e'); //69
putc('l'); //108
putc('l'); //108
putc('o'); //111
putc(' '); //32
putc('W'); //87
putc('o'); //111
putc('r'); //114
putc('l'); //108
putc('d'); //100
putc(' '); //32
putc(' '); //32
putc(' '); //32
putc(' '); //32
putc(' '); //32
putc(' '); //32
putc(' '); //32
putc(' '); //32
putc(' '); //32
get_CRC (count,*ptr);
send_CRC ();
}
}
Its easy to see why none of this works. You are not putting your data in a buffer so the CRC routine can access it, you are just sending literals, which the CRC routine cannot see. As for
Code:
get_CRC (count,*ptr);
what are 'count' and 'ptr' set to? As far as I see, they are uninitialized.

And what is your fascination with the "long" data type? the CRC is a "short" and all of your data types can be short or unsigned char (byte). I'd bet the conversion to/from long is screwing things up, too.

BTW, you should use the "code" box for your code formatting.
 

PeteG

New member
Its easy to see why none of this works. You are not putting your data in a buffer so the CRC routine can access it, you are just sending literals, which the CRC routine cannot see. As for
Code:
get_CRC (count,*ptr);
what are 'count' and 'ptr' set to? As far as I see, they are uninitialized.

And what is your fascination with the "long" data type? the CRC is a "short" and all of your data types can be short or unsigned char (byte). I'd bet the conversion to/from long is screwing things up, too.

BTW, you should use the "code" box for your code formatting.
Cosmicvoid,
thanks for the tips, and what you say makes sense so I will look at that and I was thinking along those lines anyway after I made the post, just need to work out how to do it. I guess I was presumming the code on the data sheet would more or less work, but looks like half of it is missing. I dont see that a CRC is a short though, my hard code example requires a CRC of E50E. My CCS compiler shows a short as an 8 bit and a long as a 16 bit. The putc command will only send 8 bits, so thats why I split it to LSB and MSB and sent them seperatly.
 

PeteG

New member
#include <16F887.h>
#device ICD=TRUE
#fuses HS,NOLVP,NOWDT
#use delay (clock=18432000)//LCD display 115200 baud, 8 data bits, no parity, one stop bit
#use rs232 (baud=115200, xmit=PIN_C6, rcv=PIN_C7)
#define GREEN_LED PIN_A5

unsigned long crc;
char CRC_LSB;
char CRC_MSB;
unsigned char data [25];//lcd packet buffer
unsigned char i; //Loop count, bits in byte
unsigned int count;
unsigned int ptr;

unsigned long get_CRC(unsigned char count,unsigned char *ptr)
{
count=1;
ptr=data [1];
crc = 0xFFFF; // Preset to all 1's, prevent loss of leading zeros
while(count--)
{
data = *ptr++;
i = 8;
do
{
if((crc ^ data) & 0x01)
{
crc >>= 1;
crc ^= 0x8408;
}
else
crc >>= 1;
data >>= 1;
} while(--i != 0);
}
return (~crc);
}

send_CRC () {
CRC_LSB=crc;
CRC_MSB=crc/256;
putc(CRC_LSB); //LSB CRC, 14 or 0x0E, total 1381 or 551
putc(CRC_MSB); //MSB CRC, 229 or 0xE5
}

main () {
//CRC=0xE50E;
data [1]=31;//LCD
data [2]=22;
data [3]=0;//y
data [4]=0;//x
data [5]='H';
data [6]='e';
data [7]='l';
data [8]='l';
data [9]='o';
data [10]=' ';
data [11]='W';
data [12]='o';
data [13]='r';
data [14]='l';
data [15]='d';
data [16]=' ';
data [17]=' ';
data [18]=' ';
data [19]=' ';
data [20]=' ';
data [21]=' ';
data [22]=' ';
data [23]=' ';
data [24]=' ';

while(TRUE) {
output_low(GREEN_LED);
putc(data [1]); //LCD
putc(data [2]); //length
putc(data [3]); //x
putc(data [4]); //y
putc(data [5]); //72
putc(data [6]); //69
putc(data [7]); //108
putc(data [8]); //108
putc(data [9]); //111
putc(data [10]); //32
putc(data [11]); //87
putc(data [12]); //111
putc(data [13]); //114
putc(data [14]); //108
putc(data [15]); //100
putc(data [16]); //32
putc(data [17]); //32
putc(data [18]); //32
putc(data [19]); //32
putc(data [20]); //32
putc(data [21]); //32
putc(data [22]); //32
putc(data [23]); //32
putc(data [24]); //32
get_CRC ();
send_CRC ();
delay_ms(1000);
output_high(GREEN_LED);
delay_ms(1000);
}
}
I think this is much nearer, but at the moment it wont compile, it does not like the get_crc () sub routine and says "a numerric expression should appear here". I am not convinced the crc algorithm is configured correctly for my calling routine.
 
Last edited:
My CCS compiler shows a short as an 8 bit and a long as a 16 bit.
Hmm, I see. That's unusual. What length is an int?
it does not like the get_CRC () sub routine and says "a numerric expression should appear here"
Thats because you have declared get_CRC() as returning a value so it expects that value to be assigned when get_CRC() is called, but you are not assigning it so the result goes unused. You would need to have
Code:
crc = get_CRC([COLOR="Red"]missing arguments[/COLOR]);
Also you declare get_CRC as
Code:
unsigned long get_CRC(unsigned char count,unsigned char *ptr)
yet you call it with no arguments. Whats the deal with that??

Pointing out a few more inconsistancies:
Code:
[COLOR="Red"]// here is array of 25 bytes, indices from 0 to 24
// but you don't use index 0, I wonder why??[/COLOR]
unsigned char data [25];//lcd packet buffer

unsigned int ptr;  [COLOR="Red"]// this is never referenced[/COLOR]

unsigned long get_CRC(unsigned char count,unsigned char *ptr)
{
    count=1;[COLOR="Red"]  // this arg should have been passed in the func call, not loaded here.[/COLOR]
    [COLOR="Red"]// this "ptr" refers to the "*ptr" declared in the function call[/COLOR]
    ptr=data [1];
    [COLOR="Red"]// but you should use 'address of' operator, else it means use data[/COLOR]
    [COLOR="DarkGreen"][B]ptr = &data[1];[/B][/COLOR][COLOR="Red"]  // but this arg should have been passed in the func call, not loaded here.[/COLOR]
    .... SNIP ....
}
I see you still don't want to use the 'code' box to preserve your code indenting, eh?, else your code looks bad and hard to read. Look at the "#" icon above the edit compose box next time you post.

I am not aiming to rewrite your code, I am just pointing out errors :).
 

PeteG

New member
Hmm, I see. That's unusual. What length is an int?
Cosmicvoid,
thanks for your reply. I got the int slightly wrong, a short is 1 bit, an int is 8 bit and a long is 16 bit. The 16F887 I am using is an 8 bit device, so I am guessing on a 16 bit device an int might be 16 instead of 8 bit.

Quote:
it does not like the get_CRC () sub routine and says "a numerric expression should appear here"
Thats because you have declared get_CRC() as returning a value so it expects that value to be assigned when get_CRC() is called, but you are not assigning it so the result goes unused. You would need to have
Code:

crc = get_CRC(missing arguments);

Also you declare get_CRC as
Code:

unsigned long get_CRC(unsigned char count,unsigned char *ptr)

yet you call it with no arguments. Whats the deal with that??

I copied this bit off the data sheet, so I am not sure. It certanly does not look right to me. I made the changes you sugested, but the thing stopping assembly was

Code:
unsigned long get_CRC(unsigned char count,unsigned char *ptr)

I changed this to

Code:
get_CRC(crc)
and moved the specifier to the start of the program and it now compiles, but does not work. I have made a few of the other changes you suggested as well to tidy it up a bit. I think the problem now is the code I copied from the data sheet. I called my packet buffer aray "data" as I thought this was referenced in the CRC algorithm, but I think this is just a varible used when the crc is calculated and ptr is what is used to refference the packet buffer. Any ideas would be welcome, here is the code as it stands now (and I have worked out how to use the code box!);

Code:
#include <16F887.h>
#device ICD=TRUE
#fuses HS,NOLVP,NOWDT
#use delay (clock=18432000)//LCD display 115200 baud, 8 data bits, no parity, one stop bit
#use rs232 (baud=115200, xmit=PIN_C6, rcv=PIN_C7)
#define GREEN_LED PIN_A5

unsigned long crc;
char CRC_LSB;
char CRC_MSB;
unsigned char data [25];//lcd packet buffer
unsigned char i; //Loop count, bits in byte
unsigned char count;
unsigned char ptr;

get_CRC(crc) {
crc = 0xFFFF; // Preset to all 1's, prevent loss of leading zeros
while(count--)
{
data = *ptr++;
i = 8;
do
{
if((crc ^ data) & 0x01)
{
crc >>= 1;
crc ^= 0x8408;
}
else
crc >>= 1;
data >>= 1;
} while(--i != 0);
}
return (~crc);
}

send_CRC () {
CRC_LSB=crc;
CRC_MSB=crc/256;
putc(CRC_LSB);   //LSB CRC, 14 or 0x0E
putc(CRC_MSB);  //MSB CRC, 229 or 0xE5
}

main () {
//CRC=0xE50E;
data [0]=31;//LCD
data [1]=22;
data [2]=0;//y
data [3]=0;//x
data [4]='H';
data [5]='e';
data [6]='l';
data [7]='l';
data [8]='o';
data [9]=' ';
data [10]='W';
data [11]='o';
data [12]='r';
data [13]='l';
data [14]='d';
data [15]=' ';
data [16]=' ';
data [17]=' ';
data [18]=' ';
data [19]=' ';
data [20]=' ';
data [21]=' ';
data [22]=' ';
data [23]=' ';

while(TRUE) {
output_low(GREEN_LED);
putc(data [0]);   //LCD
putc(data [1]);   //length
putc(data [2]);    //x
putc(data [3]);    //y
putc(data [4]);  //72
putc(data [5]);  //69
putc(data [6]);  //108
putc(data [7]);  //108
putc(data [8]);  //111
putc(data [9]);  //32
putc(data [10]);  //87
putc(data [11]);  //111
putc(data [12]);  //114
putc(data [13]);  //108
putc(data [14]);  //100
putc(data [15]);  //32
putc(data [16]);  //32
putc(data [17]);  //32
putc(data [18]);  //32
putc(data [19]);  //32
putc(data [20]);  //32
putc(data [21]);  //32
putc(data [22]);  //32
putc(data [23]);  //32
count=0;
ptr=&data [0];
crc=get_CRC (crc);
send_CRC ();
delay_ms(1000);
output_high(GREEN_LED);
delay_ms(1000);
}
}
 
Last edited:
Cosmicvoid,
thanks for your reply. I got the int slightly wrong, a short is 1 bit, an int is 8 bit and a long is 16 bit. The 16F887 I am using is an 8 bit device, so I am guessing on a 16 bit device an int might be 16 instead of 8 bit.

Any ideas would be welcome, here is the code as it stands now (and I have worked out how to use the code box!);
I decided that it would save a lot of time if I just fixed your code, although I can't say it is error free. BTW, you were setting count to 0 before you called get_CRC (and then doing while(count--):eek:); is that because you have 0 bytes in your packet?

The reason to use code boxes is that they use a mono-pitch font which preserves spacing and indentation. Otherwise, the forum proportional fonts destroy it.
Code:
#include <16F887.h>
#device ICD=TRUE
#fuses HS,NOLVP,NOWDT
#use delay (clock=18432000)//LCD display 115200 baud, 8 data bits, no parity, one stop bit
#use rs232 (baud=115200, xmit=PIN_C6, rcv=PIN_C7)
#define GREEN_LED PIN_A5

unsigned long crc;
unsigned char CRC_LSB;
unsigned char CRC_MSB;
unsigned char data[25];//lcd packet buffer
unsigned char i; //Loop count, bits in byte
unsigned char count;
unsigned char *ptr;  // declare a char pointer, not a char

void get_CRC(void)
{
    crc = 0xFFFF; // Preset to all 1's, prevent loss of leading zeros
    while(count--)
    {
        data = *ptr++;
        i = 8;
        do
        {
            if((crc ^ data) & 0x01)
            {
                crc >>= 1;
                crc ^= 0x8408;
            }
            else 
            {
                crc >>= 1;
            }
            data >>= 1;
        } while(--i != 0);
    }
    return (~crc);
}

void send_CRC(void)
{
    CRC_LSB = crc;
    CRC_MSB = crc/256;
    putc(CRC_LSB);   //LSB CRC, 14 or 0x0E
    putc(CRC_MSB);  //MSB CRC, 229 or 0xE5
}

void main(void)
{
    //CRC=0xE50E;
    data[0]=31;//LCD
    data[1]=22;
    data[2]=0;//y
    data[3]=0;//x
    data[4]='H';
    data[5]='e';
    data[6]='l';
    data[7]='l';
    data[8]='o';
    data[9]=' ';
    data[10]='W';
    data[11]='o';
    data[12]='r';
    data[13]='l';
    data[14]='d';
    data[15]=' ';
    data[16]=' ';
    data[17]=' ';
    data[18]=' ';
    data[19]=' ';
    data[20]=' ';
    data[21]=' ';
    data[22]=' ';
    data[23]=' ';

    while(TRUE)
    {
        output_low(GREEN_LED);
        putc(data[0]);   //LCD
        putc(data[1]);   //length
        putc(data[2]);    //x
        putc(data[3]);    //y
        putc(data[4]);  //72
        putc(data[5]);  //69
        putc(data[6]);  //108
        putc(data[7]);  //108
        putc(data[8]);  //111
        putc(data[9]);  //32
        putc(data[10]);  //87
        putc(data[11]);  //111
        putc(data[12]);  //114
        putc(data[13]);  //108
        putc(data[14]);  //100
        putc(data[15]);  //32
        putc(data[16]);  //32
        putc(data[17]);  //32
        putc(data[18]);  //32
        putc(data[19]);  //32
        putc(data[20]);  //32
        putc(data[21]);  //32
        putc(data[22]);  //32
        putc(data[23]);  //32

        // for (i = 0; i < 24; i++) putc(data[i]);   // alternative method

        count = 24;     // the number of bytes in the packet
        ptr = &data[0];
        crc = get_CRC();
        send_CRC();
        delay_ms(1000);
        output_high(GREEN_LED);
        delay_ms(1000);
    }
}
 

PeteG

New member
Cosmicvoid,
thanks for the reply. I did try setting the count to 24 yesterday, as I figured it was counting down, but what I missed was the

Code:
*ptr
I made your changes but it would not compile, saying "return value not allowed in void fuction", removing both the void's leaving

Code:
get_crc() {
allowed it to compile with no errors or warnings. However, its not returning the correct crc value, my debugger is showing it returning an 8, when E50E is required.
 
Ooops, that was stupid of me to remove the return type from get_CRC. Should be:
Code:
unsigned long get_CRC(void)
{
....
}
Sorry about that. As to why its not calculating the correct CRC, I can't say. Recheck that the CRC code matches whats in the data sheet, in case I might have messed it up.
 
Top