Forum: Mikrocontroller und Digitale Elektronik Problem mit CRC-Test wenn Tabelle im EEPROM - mega88


von Willi W. (williwacker)


Lesenswert?

Hallo,

ich habe einen ROM-Test, der auch soweit gut funktioniert, wenn die 
CRC-Tabelle im Flash steht. Lagere ich sie ins EEPROM aus (ich benötige 
den Platz im Flash), dann spielt die Routine nicht mehr.

Die Routine wird aus einem Interrupt heraus aufgerufen.

Hat jemand eine Tipp was zu tun oder wo zu suchen ?

Ciao
Willi Wacker

word eeprom crctttab[256] =
{
/*            00      01      02      03      04      05      06      07 
*/
/*            08      09      0a      0b      0c      0d      0e      0f 
*/
/* 00 */  0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 
0x70E7,
/* 08 */  0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 
0xF1EF,
/* 10 */  0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 
0x62D6,
/* 18 */  0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 
0xE3DE,
/* 20 */  0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 
0x5485,
/* 28 */  0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 
0xD58D,
/* 30 */  0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 
0x46B4,
/* 38 */  0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 
0xC7BC,
/* 40 */  0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 
0x3823,
/* 48 */  0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 
0xB92B,
/* 50 */  0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 
0x2A12,
/* 58 */  0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 
0xAB1A,
/* 60 */  0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 
0x1C41,
/* 68 */  0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 
0x9D49,
/* 70 */  0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 
0x0E70,
/* 78 */  0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 
0x8F78,
/* 80 */  0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 
0xE16F,
/* 88 */  0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 
0x6067,
/* 90 */  0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 
0xF35E,
/* 98 */  0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 
0x7256,
/* a0 */  0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 
0xC50D,
/* a8 */  0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 
0x4405,
/* b0 */  0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 
0xD73C,
/* b8 */  0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 
0x5634,
/* c0 */  0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 
0xA9AB,
/* c8 */  0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 
0x28A3,
/* d0 */  0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 
0xBB9A,
/* d8 */  0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 
0x3A92,
/* e0 */  0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 
0x8DC9,
/* e8 */  0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 
0x0CC1,
/* f0 */  0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 
0x9FF8,
/* f8 */  0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
};


/**
 * Method generates partial CRC16 checksum, for using in time critical
 * conditions and applications.
 */
void calc_crc_partial(void)
{
  byte bTemp;
  byte bix;
  word wTab;

  u_crc.b_CRC[3] = u_crc.b_CRC[2];
  u_crc.b_CRC[2] = u_crc.b_CRC[1];
  bTemp = u_crc.b_CRC[0];
  bix = u_crc.b_CRC[2] ^ b_ROM;
  wTab = crctttab[bix];
  u_crc.w_CRC[0] = wTab;
  u_crc.b_CRC[1] = u_crc.b_CRC[1] ^ bTemp;
}

von Der M. (steinadler)


Lesenswert?

Hallo,

was ist denn b_ROM und wie oft wird der Interrupt ausgeführt??

von Willi W. (williwacker)


Lesenswert?

b_ROM ist die neue Zelle, die der Checksumme hinzugefügt wird und der 
Interrupt kommt alle 10ms

von Joerg X. (Gast)


Lesenswert?

Brauchst du nicht eine Funktion/Makro um die Daten aus dem EEPROM zu 
lesen? das läuft ja anders als beim RAM oder Flash.

von Willi W. (williwacker)


Lesenswert?

Doch !
Sorry da hab ich was wichtiges vergessen, wir benutzen CodeVisionAVR, 
der kann das.

Aber genau darin scheint das Problem zu liegen. Ich habe die 
Einleseroutine aus dem EEPROM neu geschrieben und damit funktioniert es, 
nur das nötigste und entsprechend meinem Anwendungsfall sehr stark 
vereinfacht.

Wen es interessiert: so sieht es aus:

  // wTab = crctttab[bix];
  EEARL = bix*2;
  EEARH = bix/128;
  EECR  = 0x1;
  b1    = EEDR;
  EEARL = bix*2+1;
  EECR  = 0x1;
  b2    = EEDR;
  wTab  = b2*256 + b1;

Ich weiß, das geht noch schöner, aber morgen ist auch noch ein schöner 
Tag.

Danke an alle die halfen

Ciao
Willi Wacker

von Jörg (Gast)


Lesenswert?

Was hältst Du davon, Deinen CRC mit einer Bitschleife zu berechnen? Dann 
brauchst Du gar keine Tabelle.
Tabellen nimmt "man", wenn es sehr schnell gehen muß. Aus dem EEPROM 
lesen könnte dem entgegenstehen, das ist nicht das schnellste...

Du benutzt offensichtlich das CCITT Standardpolynom 0x1021, siehe Index 
1 der Tabelle. Die WinAVR Library hat eine assembleroptimierte Funktion 
dafür, siehe crc16.h. In C geht es aber auch ganz gut.

von Willi W. (williwacker)


Lesenswert?

Gute Idee, Danke für Deinen Tipp.

Ich habe die Checksumme von meinem Vorgänger übernommen und es hieß: sie 
tut. Aber dann wurde das Programm immer größer und die Tabelle (die ich 
natürlich auch übernommen habe) musste ausgelagert werden. Ein 
Zeitproblem während der Laufzeit haben wir nicht, damit könnte man auf 
die Tabelle komplett verzichten. Allerdings haben wir keine 
Entwicklungszeit mehr, wir müssen damit wohl oder übel raus, wir sind 
ohnehin schon überfällig und dann kam auch noch der stress mit dem 
EEPROM.

Ich denke, dass ich es so machen werde, wie Du vorgeschlagen hast, aber 
nicht jetzt.

Merke: Es gibt immer ein Update!

Ciao

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.