#include #include #include #include #include /*********** Belegung Port A fuer CAN-Controller *************/ #define _WINKEL (PINA & (1<A/D_Wandler #define DIN_AD_OFF (PORTB &= ~(1<A/D_Wandler #define DOUT_AD (PINB & (1< Data Ready #define _CS_AD_OFF (PORTB |= (1< inaktiv #define _CS_AD_ON (PORTB &= ~(1< aktiv #define _RES_AD_ON (PORTB &= ~(1< Reset #define _RES_AD_OFF (PORTB |= (1< AD laeuft #define _EN_PH_LAY_ON (PORTB &= ~(1<= 14) { return; } // RXOK-Flag löschen CANSTMOB &= ~(1<A if (buffer & 0x01) mirror |= 0x08; // Bits spiegeln, da Anschluss verkehrt 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; id_hb |=buffer; // Bits aus Codierschalter (PORTA) hinzu // Wert fuer identifier_hb speichern // (ist fuer Message 0...7 konstant) idf1 = (((id_hb<<8) | 0x37)>>5); // Message1 Identifier idf2 = (((id_hb<<8) | 0x55)>>5); // Message2 Identifier // 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; _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; _delay_ms(200); // Calibration Time = 9*20ms = 180ms ! clrwdg(); }; // Init CAN-Controller **************************************************** for (mob = 0; mob < 15; mob++) { CANPAGE = (mob << 4); CANSTMOB = 0; CANCDMOB = 0; } // CAN_setBaudrate CANBT1 = 0x04; /************************ war 04 */ CANBT2 = 0x6c; /************************ war 0c */ CANBT3 = 0x37; /************************ war 37 */ // CAN_setInterrupt CANGIE &= ~(1< 0;count--) { if ((adwert & maske) == maske) { DIN_AD_ON; // DIN_AD entsprechend setzen } else { DIN_AD_OFF; } SCLK_AD_OFF; // Bit in den A/D-Wandler einschreiben _delay_us(1); SCLK_AD_ON; _delay_us(1); maske = (maske>>1); // } } void read_from_ad(void) { unsigned char maske = 0b10000000; _delay_us(1); for (count=8;count > 0;count--) { SCLK_AD_OFF; // Datenbit wird auf die Leitung gelegt _delay_us(1); if (DOUT_AD) // Wenn Bit = 1 { datenwert |= maske; // Datenwert mit Masken-1 belegen } else { datenwert &= ~(maske); // Datenwert mit 0 belegen } SCLK_AD_ON; _delay_us(1); maske = (maske>>1); // Maskenbit eins weiterschieben } } void hole_mw(void) { _CS_AD_ON; while (_DRDY) { ; // warten bis A/D-Wandler fertig }; write_to_ad(0X38); // Vorbereitung Messwert abholen read_from_ad(); // 8 Bit auslesen ==> HB mw_hb=datenwert; read_from_ad(); // 8 Bit auslesen ==> LB mw_lb=datenwert; mw = (mw_hb<<8); mw |= (mw_lb); mw &= 0XFFF0; // Aufloesung auf 12 bit begrenzen mw >>= 4; mw &= 0X0FFF; mw +=0X400; // Offset 400hex hinzufuegen mw_hb = (mw>>8); mw_lb = (mw & 0x00FF); _CS_AD_OFF; } void message1_to_can(void) { unsigned char i = 0; unsigned int idm = 0xFFFF; //CAN_getMOB CANPAGE = 0x10; // mob = 1 while ((CANCDMOB & (1<> 3); //CAN_setID CANIDT2 = (uint8_t)(idf1 << 5); CANIDT1 = (uint8_t)(idf1 >> 3); //CAN_setData CANCDMOB |= (1<> 3); //CAN_setID CANIDT2 = (uint8_t)(id << 5); CANIDT1 = (uint8_t)(id >> 3); //CAN_setData CANCDMOB |= (1< 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" adcaninit(); // 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 clrwdg(); // Watchdog zuruecksetzen }; }