void message1_to_can(void) { unsigned char i=0; unsigned char mob=0; crc = 2; // CRC-Vorgabewert fuer message 1 crc ^= id_hb; crc ^= umlauf; crc ^= mw_hb; crc ^= mw_lb; crc ^= prog_stat; crc ^= weekunit_low; CANBT1 = 0x04; CANBT2 = 0x0C; CANBT3 = 0x37; setbit(CANGCON, ENASTB); // CAN-Controller in Enabled Mode setzen // Warten bis der CAN-Controller das Enabled-Bit gesetzt hat und einsatzbereit ist while (!getbit(CANGSTA, ENFG)); CAN_message msg; msg.id = 0x0201; msg.idm = 0xFFFF; msg.data[0] = id_hb; msg.data[1] = umlauf; msg.data[2] = mw_hb; msg.data[3] = mw_lb; msg.data[4] = prog_stat; msg.data[5] = weekunit_low; msg.data[6] = crc; // CANCDMOB = 0b10100111; setbit(CANCDMOB, DLC0); setbit(CANCDMOB, DLC1); setbit(CANCDMOB, DLC2); clearbit(CANCDMOB, DLC3); CAN_enableMOB(1, AUTO_REPLY, msg); } void adcaninit(void) { // Berechnung der Seite des Identifier aus der Stellung der Codierbrücke if (_WINKEL) { datenwert=0X04; // Seite für Längengeber } else { datenwert=0X02; // Seite für Winkelgeber } // Berechnung des Identifier aus der Stellung des Codierschalters datenwert <<= 4; // 4 Stellen links schieben buffer = (0x0f & PINA); // Codierschalter (PORTA) lesen // Bit 0...2: Steckercode 0...7, aktiv high // Bit 3: Knoten A/B, 0 ==>A if (buffer & 0x01) mirror |= 0x08; else mirror &= ~0xF8; if (buffer & 0x02) mirror |= 0x04; else mirror &= ~0xF4; if (buffer & 0x04) mirror |= 0x02; else mirror &= ~0xF2; if (buffer & 0x08) mirror |= 0x01; else mirror &= ~0xF1; buffer = mirror; datenwert |=buffer; // Bits aus Codierschalter (PORTA) hinzu id_hb=datenwert; // Wert fuer identifier_hb fuer DSCR0X...DSCR7X speichern // (ist fuer Message 0...7 konstant) // Init Programmvariablen *********************************************************** prog_stat |= (1<<2); // Vorgabewert Programmstatus nach der Initialisierung, Bit 2 umlauf = 0; // Programmumlaufzaehler Startwert // Vorberechnung der Seriennummer ***************************************** weekunit = (WEEK & 0X003F); // Variable aus Woche und Einheit zusammensetzen weekunit <<= 10; // WEEK, UNIT siehe Datei Seriennr.inc weekunit &= 0XFC00; weekunit += UNIT; // Init CAN-Controller **************************************************** _RES_AD_OFF; _CS_AD_ON; write_to_ad(0X10); // config Communication-Reg: // naechste Aktion: Schreibe ins Setup Reg. // Gain = 1 für Potigeber write_to_ad(0X64); // config Setup-Reg: // MD1 MD0 CLK FS1 FS0 _B/U BUF FSYNC // 0 1 1 0 0 1 0 0 // Self Calibration Mode, Takt = 2,5 MHz, // Output Update Rate = 50Hz ==> t=20ms while (_DRDY) { // warten bis A/D-Wandler fertig; waitstop(180); // Calibration Time = 9*20ms = 180ms ! clrwdg(); }; CAN_init(125, NONE); return; } int main() { hardwareinit(); adcaninit(); hole_mw(); // aktuellen Messwert vom A/D-Wandler holen message1_to_can(); // Messwerttelegramm an Can-Controller uebertragen message2_to_can(); // Seriennummerntelegramm an Can-Controller uebertragen _EN_PH_LAY_ON; // Physical Layer aktivieren ==> Busverbindung freigeben while (1) { hole_mw(); // aktuellen Messwert vom A/D-Wandler holen message1_to_can(); // Messwerttelegramm an Can-Controller uebertragen test_can_status(); // Programmstatus ermitteln if (prog_stat & 0b01000000) { // bei "Bus off" init(); // neu initialisieren prog_stat |= (1<<6);// Markierung für bus off Bit6 message2_to_can(); // Seriennummerntelegramm an Can-Controller uebertragen _EN_PH_LAY_ON; // Physical Layer aktivieren ==> Busverbindung freigeben } umlauf++; // Umlaufzaehler erhoehen if ((mw > 2400) && (mw < 2600)) (PORTE |= (1<