// // hier nur Test eines DS18B20 , angeschlossen an EPC2 // PCB LDC1000 für Drehposition Erkennung der Motorsteuerung // program DS18B20; {$NOSHADOW} { $WG} {global Warnings off} Device = XMega8E5, VCC = 3.3; { $BOOTRST $20000} {Reset Jump to $20000} import XMegaSupport,SerportD0; // From System Import LongWord,float; define // The XMegas don't provide any Oscillator fuses. // So the application must setup the desired values // possible OSC types: extXTAL, extClock, ext32kHz, int32Khz, int2MHz, int32MHz //>> CPU=32MHz, PeripherX4=32MHz, PeripherX2=32MHz OSCtype = int32MHz, PLLmul = 4, prescB = 1, prescC = 1; // SysTick = 10; // msec StackSize = $0300, iData; FrameSize = $0300, iData; SerPortD0 = 115200, ParNone, Stop1, Databit8; // an Motorcontrol über RS485 ISL83078 TxBufferD0 = 8, iData; RxBufferD0 = 8, iData; implementation {$EEPROM} var {$IDATA} const {--------------------------------------------------------------} { Type Declarations } type //-------------------------------------------------------------- const //-------------------------------------------------------------- { Var Declarations } {$IDATA} var SecCounter: byte; i:byte; ch: char; CmdStr: String[16]; LCmdStr: byte; Sekbol: boolean; DS1820_Wire[@PortC,2] : bit; DS1820_Readbit[@PinC,2] : bit; DS1820_Dir[@DDRC,2] : bit; DS1820Temperatur: integer;// word; DS1820Celsius: float; //-------------------------------------------------------------- { functions } procedure DS1820write0; Forward; procedure DS1820write1; Forward; procedure DS1820readTemperatur; Forward; //------------------------------------------------------------------------------------------------------------------------- procedure InitPorts; // begin // REMAPC:= $10; // Funktion des UART an Portpin6,7 statt 2,3 REMAPD:= $10; // Funktion des UART an Portpin6,7 statt 2,3 DDRA:= %00000000; // Hall-Sensoren DRV5032 DDRC:= %10110000; // PC0: nc, PC1: LDC1000-iNT, PC2: DS18B20, PC3: DRV5032 , PC4: LDC-CS, 5: ldc-Sclk, 6: LDC-SDO 7: LDC-Mosi(SDI) DDRD:= %10010011; // PD0:ISL83078-Ctrl, PD1:ISL83078-RE\ PD2:RXD-RS485,PD3:TXD-RS485, PD4:Led , PD5:nc ,D6 RX , D7: TX !!!!!!!!!!!!!!!!!!!! DDRR:= %00000011; // PR0:LDC-Clk , PR1: Testpin end InitPorts; //---------------------------------------------------------------------------------------------------------------------------------- procedure ReadDS18B20Temperatur; // 1-wire Bus alten wert lesen und neue Messung anstossen begin // Init resetpuls, ROM-Code $CC:skip ROM, Command: read $BE, / Init resetpuls, ROM-Code $CC:skip ROM, Command: convert $44, // DDRB:= %00010010; // PB0:ADCB-Refextern , PB1: ULN2003-1, PB2: MAX4173 / ULN2003-2, PB3: +12V / ULN2003-3 / LDR PB4: ULN2003-4 ,PB5: ULN2003-5, PB6 LDR / ULN2003-6, PB7: DS18B20 /ULN2003-7 // Init DS1820_Dir:= true; //DDRB.7:= true; // PB7 auf Ausgang // PC2 auf Ausgang DS1820_Wire:= false; udelay(55); // 500µsec warten DS1820_Dir:= false; //DDRB.7:= false; // PB7 auf Eingang PC2 auf Eingang udelay(55); // nur warten und gar nicht nachschauen, ob Antwort kommt //........................................................................................................ // Romcode $CC senden, pro bit min 60 µsec , min 1,2 µsec pause 0: 60sec low, 1: 1.2 µsec low // All data and commands are transmitted least significant bit first over the 1-Wire bus. DS1820write0; DS1820write0; DS1820write1; // aus $CC >> %$33 LSB first DS1820write1; DS1820write0; DS1820write0; DS1820write1; DS1820write1; //........................................................................................................ // udelay_1(200); // udelay(70); // // Command $BE senden, Read Scratchpad [BEh], alte Messung abholen // All data and commands are transmitted least significant bit first over the 1-Wire bus. DS1820write0; DS1820write1; DS1820write1; DS1820write1; // aus $BE >>>> $FD LSB first DS1820write1; DS1820write1; DS1820write0; DS1820write1; //........................................................................................................ // Read Scratchpad pro bit min 60 µsec, min 1.2 µsec pause byte0 und byte1 sind zu lesen //The data transfer starts with the least significant bit of byte 0 and continues through the scratchpad until the 9th byte (byte 8 – CRC) is read. // The master may issue a reset to terminate reading at any time if only part of the scratchpad data is needed DS1820readTemperatur; // die ersten 2 Bytes lesen DS1820_Dir:= true; // das Lesen abbrechen mit Reset, das ist gleichzeitig eine neues Init !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! DS1820_Wire:= false; // PB7 low udelay(55); // 500µsec warten //........................................................................................................ DS1820_Dir:= false; //DDRB.7:= false; // PB7 auf Eingang PC2 udelay(55); // nur warten und gar nicht nachschauen, ob Antwort kommt //........................................................................................................ // Romcode $CC senden, pro bit min 60 µsec , min 1,2 µsec pause 0: 60sec low, 1: 1.2 µsec low // All data and commands are transmitted least significant bit first over the 1-Wire bus. DS1820write0; DS1820write0; DS1820write1; // aus $CC >> %$33 DS1820write1; DS1820write0; DS1820write0; DS1820write1; DS1820write1; //........................................................................................................................ // Command $44 senden = Messung starten , pro bit min 60 µsec , min 1,2 µsec pause 0: 60sec low, 1: 1.2 µsec low // All data and commands are transmitted least significant bit first over the 1-Wire bus. DS1820write0; DS1820write0; DS1820write1; // aus $44 >> %$22 DS1820write0; DS1820write0; DS1820write0; DS1820write1; DS1820write0; // die Messung wird dann in dem nächsten Sekundeninterrupt wieder gelesen //........................................................................................................ end ReadDS18B20Temperatur; //---------------------------------------------------------------------------------------------------------------------------------- procedure DS1820write0; //All write time slots must be a minimum of 60µs, 1µs recovery time between individual write slots begin // initiated by the master pulling the 1-Wire bus low 1µsec, DS1820_Dir:= true; // DDRB.7:= true; // PB7 auf Ausgang PortC,2 DS1820_Wire:= false; // ist eh low udelay_1(2); // >= 1µsec warten initialisierung writeslot udelay_1(72); // 60 µsec warten write 0 DS1820_Dir:= false; // DDRB.7:= false; // PB7 auf Eingang, entspricht: high udelay_1(2); // 1µsec warten minimum of a 1µs recovery time between individual write end; //---------------------------------------------------------------------------------------------------------------------------------- procedure DS1820write1; begin DS1820_Dir:= true; // DDRB.7:= true; // PB7 auf Ausgang PortC,2 DS1820_Wire:= false; // ist eh low udelay_1(2); // 1µsec warten initialisierung writeslot DS1820_Wire:= true; // // wäre eigentlich unnötig !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! DS1820_Dir:= false; // DDRB.7:= false; // PB7 auf Eingang, entspricht: high PortC,2 auf EIngang >> write 1 udelay_1(72); // 2µsec warten udelay_1(2); // 2µsec warten minimum of a 1µs recovery time between individual write end; //---------------------------------------------------------------------------------------------------------------------------------- procedure DS1820readTemperatur; // byte 0 : LSB, Byte1 : MSB var // The data transfer starts with the least significant bit of byte 0 and continues through the scratchpad Readbit: boolean; begin for i:= 0 to 15 do // DS1820_Dir:= true; // DDRB.7:= true; // PB7 auf Ausgang PortC,2 DS1820_Wire:= false; // ist eh low udelay_1(2); // 1µsec warten DS1820_Dir:= false; // DDRB.7:= false; // PB7 auf Eingang, entspricht: high PortC,2 auf EIngang udelay_1(20); // 20µsec warten , dann kann der Wert gelesen werden Readbit:= DS1820_readbit; // DS1820_Readbit[@PinC,2] : bit; if Readbit = true then incl(DS1820Temperatur,i); else excl(DS1820Temperatur,i); endif; udelay_1(40); // 38µsec warten udelay_1(2); // 2µsec warten minimum of a 1µs recovery time between individual write/read endfor; DS1820Celsius:= float(DS1820Temperatur) / 16; // wert8 >> 0,5° 2000 >> 125° end DS1820readTemperatur; //------------------------------------------------------------------------------------------------ procedure CmdStrAuswertungD; begin LCmdStr:= length(CmdStr); // aktuell belegte Länge mit führenden 2 Chars ( ohne #13) für Wandlung nach Longint case CmdStr[1] of 'Z' : mdelay(25); Write(SeroutD0,'DS18B20 Reset' + #13 + #10); mdelay(35); System_Reset; | endcase; CmdStr:= ''; end CmdStrAuswertungD; //--------------------------------------------------------------------------------------------------------------------------------------- Interrupt TCC4_INTOVF; // TCD0_INTOVF; // counterzeit für 1 sec begin TCC4INTFLAGS:= $01; SekBol := true; // SecCounter:= SecCounter+1; // wird bei LDC-Messung genutzt bzw ds18b20 end; //--------------------------------------------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------ { Main Program } {$IDATA} begin mdelay(300); EnableInts($87); Initports; //......................................................................................................................................................... // Timer setzen für 1000 ms Overflow @32MHz // $0C35 : 100 msec, $3D09: 500 msec // $7A12 = 1 sek TCC4CTRLA := $00; TCC4PERL := $12; // PERL - Period Register L Bite 7..0 TCC4PERH := $7A; // PERH - Period Register H 15..8 // $9C40 = dez 40000 , bei clk/4 = clk 8 MHz > 0,000000125 * 40000 = 5 msec TCC4INTCTRLA := $02; TCC4CTRLA := $07; // bei $00 ist Timer Off //.......................................................................................................................................................... // Init resetpuls, ROM-Code $CC:skip ROM, Command: read $BE, / Init resetpuls, ROM-Code $CC:skip ROM, Command: convert $44, // Init DS1820_Dir:= true; //DDRB.7:= true; // PB7 auf Ausgang // PC2 auf Ausgang DS1820_Wire:= false; udelay(51); // 500µsec warten DS1820_Dir:= false; //DDRB.7:= false; // PB7 auf Eingang // PC2 auf Eingang udelay(51); // nur warten und gar nicht nachschauen, ob Antwort kommt //........................................................................................................ // Romcode $CC senden, pro bit min 60 µsec , min 1,2 µsec pause 0: 60sec low, 1: 1.2 µsec low // All data and commands are transmitted least significant bit first over the 1-Wire bus. DS1820write0; DS1820write0; DS1820write1; // aus $CC >> %$33 DS1820write1; DS1820write0; DS1820write0; DS1820write1; DS1820write1; //........................................................................................................................ // Command $44 senden = Messung starten , pro bit min 60 µsec , min 1,2 µsec pause 0: 60sec low, 1: 1.2 µsec low // All data and commands are transmitted least significant bit first over the 1-Wire bus. DS1820write0; DS1820write0; DS1820write1; // aus $44 >> %$22 DS1820write0; DS1820write0; DS1820write0; DS1820write1; DS1820write0; // die Messung wird dann in dem nächsten Sekundeninterrupt wieder gelesen //........................................................................................................ mdelay(1000); loop if SekBol = true then Sekbol:= false; ReadDS18B20Temperatur; // Writeln(SeroutD0,'M_DS1820:'+ floattostr(DS1820Celsius:2:3) +' '+ inttohex(DS1820Temperatur)); endif; //------------------------------------------------------------------------------------------------------------------------ if SerStatD0 then Read(SerInpD0, CmdStr, #13); // // es wird gelesen bis #13 kommt CmdStrAuswertungD; endif; endloop; end DS18B20.