'------------------------------------------------------------------------------- ' Version Française ' (c) 2004 MCS Electronics ' Cette démo montre un exemple de l'emploi de TWI ' Not all AVR chips have TWI (hardware I2C) '------------------------------------------------------------------------------- 'The chip will work in TWI/I2C master mode $regfile = "M128def.dat" ' the used chip $crystal = 8000000 ' frequency used '-------I2C config ------------------------------------------------------ $lib "i2c_twi.lbx" ' we do not use software emulated I2C but the TWI Config Sda = Portd.1 ' I2C Data. Config Scl = Portd.0 ' I2C Clock. '-------LCD----if use-------------------------------------------------- Config Lcd = 20 * 2 Config Lcdpin = Pin , Db4 = Portf.2 , Db5 = Portf.3 , Db6 = Portf.4 , Db7 = Portf.5 , E = Portf.6 , Rs = Portf.7 Cls I2cinit ' we need to set the pins in the proper state Config Twi = 100000 ' wanted clock frequency 'will set TWBR and TWSR 'Twbr = 12 'bit rate register 'Twsr = 0 'pre scaler bits Dim B As Byte , Xbyte As Byte Dim Action As Byte , Xsend As Byte Dim Index As Byte , Kword As Word , Jbyte As Byte Dim Valuesingle As Single Dim Value As Long , Klong As Long , Dummy As Long Dim R1 As Single Dim Arraywork(5) As String * 1 Dim Arrayreceived(5) As Byte Action = 12 ' action to do by the slave 12=COS Valuesingle = 1.151917217 'example :value in radian of 66° Valuesingle = Valuesingle * 1000 'removing the dot Value = Valuesingle Gosub Decomposition Do I2cstart I2cwbyte &H70 ' slave address write I2cwbyte Action ' write choice For Jbyte = 1 To 4 I2cwbyte Arraywork(jbyte) Next I2cstop If Err > 0 Then Locate 2 , 1 : Lcd "Error : " ; Err ' show error status End If Waitms 50 I2cstart I2cwbyte &H71 For Xbyte = 1 To 4 I2crbyte Arrayreceived(xbyte) , Ack Next I2crbyte Arrayreceived(5) , Nack I2cstop If Err > 0 Then Locate 2 , 1 : Lcd "Error : " ; Err ' show error status End If Gosub Recomposition Locate 2 , 1 : Lcd Spc(20) Locate 2 , 1 : Lcd "rec: " ; R1 Waitms 50 'wait a bit Loop End Decomposition: Index = 0 Kword = Highw(value) Jbyte = High(kword) '1° quart du long Index = Index + 1 Arraywork(index ) = Chr(jbyte) Jbyte = Kword '2° quart du long Index = Index + 1 Arraywork(index ) = Chr(jbyte) Kword = Value 'pour prendre le low word de ARG1 Jbyte = High(kword) '3° quart du long Index = Index + 1 Arraywork(index ) = Chr(jbyte) Jbyte = Kword '4° quart du long Index = Index + 1 Arraywork(index ) = Chr(jbyte) Return Recomposition: Jbyte = Arrayreceived(4) : Klong = Jbyte Dummy = Arrayreceived(3) : Dummy = Dummy * 256 : Klong = Klong + Dummy Dummy = Arrayreceived(2) : Dummy = Dummy * 65536 : Klong = Klong + Dummy Dummy = Arrayreceived(1) : Dummy = Dummy * 16777216 : Klong = Klong + Dummy R1 = Klong R1 = R1 / 1000 Waitms 100 Return '--------------------Jean-Pierre Duval 12-12-2005------------------------- ' coprocesseur mathématique I2C ' mathématic coprocessor I2C '------------------------------------------------------------------------------ $regfile = "m8def.dat" $crystal = 8000000 ' ' port I2C SCL= C.5 to be TWI ' port I2C SDA= C.4 Dim J As Byte Dim Choice As Byte , Dummy As Long , Jbyte As Byte Dim Klong As Long Dim Kword As Word Dim Index As Byte ' Dim R1 As Single Dim Arrayreceived(5) As Byte Dim Arraywork(4)as String * 1 ' config LCD------------------------------------------------------------------------------ Config Lcdmode = Port ' config 4 bit Config Lcdpin = Pin , Db4 = Portd.3 , Db5 = Portd.2 , Db6 = Portd.1 , Db7 = Portd.0 , E = Portd.4 , Rs = Portd.5 Config Twislave = &H70 , Btr = 5 , Bitrate = 100000 ' Btr =choice + R1*'4byte,) 'Const Pi = 3.14159265358979 just a pleasure 'calculate PI 'Ms1 = Atn(1) * 4 Cls Locate 1 , 1 : Lcd "M8 TWI-slave" Wait 1 Cls Enable Interrupts '------------main----------------------------- Do nop Loop End '----les sub-routines slaves------------------ Twi_stop_rstart_received: 'reception of Start and stop Return Twi_addressed_goread: 'master sent out slave address and will send data Return Twi_addressed_gowrite: 'Master will go write Return Twi_gotdata: 'here the master send data, Twi_btw is a var which count the number of bytes 'received 'TWI is the var which stock the actual byte 'We need to make an array to collect data. We are here each time we receive a byte Arrayreceived(twi_btw) = Twi If Twi_btw = 5 Then Choice = Arrayreceived(1) If Choice > 0 Then Jbyte = Arrayreceived(5) : Klong = Jbyte Dummy = Arrayreceived(4) : Dummy = Dummy * 256 : Klong = Klong + Dummy Dummy = Arrayreceived(3) : Dummy = Dummy * 65536 : Klong = Klong + Dummy Dummy = Arrayreceived(2) : Dummy = Dummy * 16777216 : Klong = Klong + Dummy R1 = Klong 'R1 is a string, Klong= RI*1000 (do by the master) R1 = R1 / 1000 ' we devise by 1000 to match the real R1 Locate 2 , 1 : Lcd "rec:" ; R1 Gosub Calcul Gosub Preparation End If End If Return ' * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Twi_master_needs_byte: ' this label is needed when Master need response 'The var TWI will be the value sends back to the master 'twi_btr is define in the config. For Jbyte = 1 To Twi_btr Twi = Arraywork(jbyte) Next Return ' * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Twi_master_need_nomore_byte: 'when the mast has all bytes received this label will be called Return Preparation: ' this label is called to prepare the byte to send back R1 = R1 * 1000 'transforme the single in long again Klong = R1 Index = 0 Kword = Highw(klong) Jbyte = High(kword) '1° quart du long Index = Index + 1 Arraywork(index ) = Chr(jbyte) Jbyte = Kword '2° quart du long Index = Index + 1 Arraywork(index ) = Chr(jbyte) Kword = Klong 'pour prendre le low word Jbyte = High(kword) '3° quart du long Index = Index + 1 Arraywork(index ) = Chr(jbyte) Jbyte = Kword '4° quart du long Index = Index + 1 Arraywork(index ) = Chr(jbyte) Return Calcul: Select Case Choice Case 1 ' exponentielle ----------------------------- R1 = Exp(r1) Case 2 ' logarithme ----------------------- R1 = Log(r1) Case 3 ' logarithme base 10-------------- R1 = Log10(r1) Case 4 'Sqr--------------------------------- R1 = Sqr(r1) ' SQR-single---------------------------------------------------------- 'Case 5 'puissance instruction POWER--R1^ R2 ' R1 = Power(r1 , R2 ) Case 10 'deg2rad------------------------- R1 = Deg2rad(r1) Case 11 'rad2deg---------------------- R1 = Rad2deg(r1) Case 12 ' cos--------- R1 = Cos(r1) Case 13 ' sin--------- R1 = Sin(r1) Case 14 ' tan---------------------------------- R1 = Tan(r1) Case 15 ' arctangente------------------- R1 = Atn(r1) Case 16 ' cos hyperbolique R1 = Cosh(r1) Case 17 'sin hyperbolique R1 = Sinh(r1) Case 18 'tangente hyperbolique R1 = Tanh(r1) ' Case 19 ' atn2----------------------------- ' R1 = Atn2(r1 , R2) Case 20 'Arc-sinus--------------------- R1 = Asin(r1) Case 21 ' arc cosinus---------------------- R1 = Acos(r1) Case 30 'int--------------------- R1 = Int(r1) Case 31 ' frac------------------------- R1 = Frac(r1) ' Case 32 'modulo--------------------------- ' R1 = R1 Mod R2 Case 33 R1 = R1 Case Else Return End Select Return