I2CSTART
Contents |
Action
I2CSTART generates an I2C start condition.
I2CREPSTART generates an I2C repeated start condition.
I2CSTOP generates an I2C stop condition.
I2CRBYTE receives one byte from an I2C-device.
I2CWBYTE sends one byte to an I2C-device.
Syntax
I2CSTART
I2CREPSTART
I2CSTOP
I2CRBYTE var, ack/nack
I2CWBYTE val
Syntax Xmega
I2CSTART #const
I2CREPSTART #const
I2CSTOP #const
I2CRBYTE var, ack/nack , #const
I2CWBYTE val , #const
Remarks
Var |
A variable that receives the value from the I2C-device. |
ack/nack |
Specify ACK if there are more bytes to read.
Specify NACK if it is the last byte to read. |
Val |
A variable or constant to write to the I2C-device. |
#const |
For the Xmega, a channel constant that was specified with OPEN. |
These statements are provided as an addition to the I2CSEND and I2CRECEIVE statements.
While I2csend and I2CRECEIVE are well suited for most tasks, a slave chip might need a special sequence that is not possible with this I2C routines.
When an error occurs, the internal Err variable will return 1. Otherwise it will be set to 0.
The Xmega has multiple TWI interfaces. You can use a channel to specify the TWI interface.
When using a repeated start, you must use I2CREPSTART on the XMega !
Normal AVR processors may use either I2CSTART or I2CREPSTART.
All I2C statements are master mode statements. They will code from the i2c.lib. There is also an improved version of this library available named i2cv2.lib
Since the repeated start is not compatible with the one from i2c.lib, you need to specify yourself that you want to use the improved lib. See also I2CV2.
I2CSTOP and Xmega
The I2CSTOP statement on the Xmega can be influenced by defining a constant named _TWI_STOP_NEW
The value does not matter. So you can add : CONST _TWI_STOP_NEW = 1
This code will use the preferred code to generate an I2CSTOP command. Why this option? Some Xmega do not respond well to a command to free the bus. As a work around , multiple commands are given till the bus is free.
Some slave chips might have a problem with that. For this reason, the DEFAULT is the old way to send multiple STOP commands till the bus is free.
By defining the _TWI_STOP_NEW constant, you can use the new, preferred method which will give a STOP command and then poll the status till the bus is actually free. Since not all Xmega respond well to this, this is made an option.
ASM
The I2C routines are located in the i2c.lib/i2c.lbx files.
For the XMega, the routines are located in the xmega.lib file.
See also
I2CSEND , I2CRECEIVE , I2CSTOP, I2CRBYTE , I2CWBYTE , I2CV2
Example (using Software I2C Routines)
'----------------------------------------------------------------------------------------- 'name : i2c.bas 'copyright : (c) 1995-2005, MCS Electronics 'purpose : demo: I2CSEND and I2CRECEIVE 'micro : Mega48 'suited for demo : yes 'commercial addon needed : no '----------------------------------------------------------------------------------------- $regfile = "m48def.dat" ' specify the used micro $crystal = 4000000 ' used crystal frequency $baud = 19200 ' use baud rate $hwstack = 32 ' default use 32 for the hardware stack $swstack = 10 ' default use 10 for the SW stack $framesize = 40 ' default use 40 for the frame space Config Scl = Portb.4 Config Sda = Portb.5 Declare Sub Write_eeprom(byval Adres As Byte , Byval Value As Byte) Declare Sub Read_eeprom(byval Adres As Byte , Value As Byte) Const Addressw = 174 'slave write address Const Addressr = 175 'slave read address Dim B1 As Byte , Adres As Byte , Value As Byte 'dim byte Call Write_eeprom(1 , 3) 'write value of three to address 1 of EEPROM Call Read_eeprom(1 , Value) : Print Value 'read it back Call Read_eeprom(5 , Value) : Print Value 'again for address 5 '-------- now write to a PCF8474 I/O expander ------- I2csend &H40 , 255 'all outputs high I2creceive &H40 , B1 'retrieve input Print "Received data " ; B1 'print it End Rem Note That The Slaveaddress Is Adjusted Automaticly With I2csend & I2creceive Rem This Means You Can Specify The Baseaddress Of The Chip. 'sample of writing a byte to EEPROM AT2404 Sub Write_eeprom(byval Adres As Byte , Byval Value As Byte) I2cstart 'start condition I2cwbyte Addressw 'slave address I2cwbyte Adres 'asdress of EEPROM I2cwbyte Value 'value to write I2cstop 'stop condition Waitms 10 'wait for 10 milliseconds End Sub 'sample of reading a byte from EEPROM AT2404 Sub Read_eeprom(byval Adres As Byte , Value As Byte) I2cstart 'generate start I2cwbyte Addressw 'slave adsress I2cwbyte Adres 'address of EEPROM I2cstart 'repeated start I2cwbyte Addressr 'slave address (read) I2crbyte Value , Nack 'read byte I2cstop 'generate stop End Sub ' when you want to control a chip with a larger memory like the 24c64 it requires an additional byte ' to be sent (consult the datasheet): ' Wires from the I2C address that are not connected will default to 0 in most cases! ' I2cstart 'start condition ' I2cwbyte &B1010_0000 'slave address ' I2cwbyte H 'high address ' I2cwbyte L 'low address ' I2cwbyte Value 'value to write ' I2cstop 'stop condition ' Waitms 10
Xmega Example
'---------------------------------------------------------------- ' (c) 1995-2010, MCS ' xm128-TWI.bas ' This sample demonstrates the Xmega128A1 TWI '----------------------------------------------------------------- $regfile = "xm128a1def.dat" $crystal = 32000000 $hwstack = 64 $swstack = 40 $framesize = 40 'include the following lib and code, the routines will be replaced since they are a workaround $lib "xmega.lib" $external _xmegafix_clear $external _xmegafix_rol_r1014 Dim S As String * 20 'first enable the osc of your choice Config Osc = Enabled , 32mhzosc = Enabled 'configure the systemclock Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1 Dim N As String * 16 , B As Byte Config Com1 = 19200 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8 Config Input1 = Cr , Echo = Crlf ' CR is used for input, we echo back CR and LF Open "COM1:" For Binary As #1 ' ^^^^ change from COM1-COM8 Print #1 , "Xmega revision:" ; Mcu_revid ' make sure it is 7 or higher !!! lower revs have many flaws Const Usechannel = 1 Dim B1 As Byte , B2 As Byte Dim W As Word At B1 Overlay Open "twic" For Binary As #4 ' or use TWID,TWIE oR TWIF Config Twi = 100000 'CONFIG TWI will ENABLE the TWI master interface 'you can also use TWIC, TWID, TWIE of TWIF #if Usechannel = 1 I2cinit #4 #else I2cinit #endif Do I2cstart Waitms 20 I2cwbyte &H70 ' slave address write Waitms 20 I2cwbyte &B10101010 ' write command Waitms 20 I2cwbyte 2 Waitms 20 I2cstop Print "Error : " ; Err ' show error status 'waitms 50 Print "start" I2cstart Print "Error : " ; Err ' show error I2cwbyte &H71 Print "Error : " ; Err ' show error I2crbyte B1 , Ack Print "Error : " ; Err ' show error I2crbyte B2 , Nack Print "Error : " ; Err ' show error I2cstop Print "received A/D : " ; W ; "-" ; B1 ; "-" ; B2 Waitms 500 'wait a bit Loop Dim J As Byte , C As Byte , K As Byte Dim Twi_start As Byte ' you MUST dim this variable since it is used by the lib 'determine if we have an i2c slave on the bus For J = 0 To 200 Step 2 Print J #if Usechannel = 1 I2cstart #4 #else I2cstart #endif I2cwbyte J If Err = 0 Then ' no errors Print "FOUND : " ; Hex(j) 'write some value to the pcf8574A #if Usechannel = 1 I2cwbyte &B1100_0101 , #4 #else I2cwbyte &B1100_0101 #endif Print Err Exit For End If #if Usechannel = 1 I2cstop #4 #else I2cstop #endif Next #if Usechannel = 1 I2cstop #4 #else I2cstop #endif #if Usechannel = 1 I2cstart #4 I2cwbyte &H71 , #4 'read address I2crbyte J , Ack , #4 Print Bin(j) ; " err:" ; Err I2crbyte J , Ack , #4 Print Bin(j) ; " err:" ; Err I2crbyte J , Nack , #4 Print Bin(j) ; " err:" ; Err I2cstop #4 #else I2cstart I2cwbyte &H71 'read address I2crbyte J , Ack Print Bin(j) ; " err:" ; Err I2crbyte J , Ack Print Bin(j) ; " err:" ; Err I2crbyte J , Nack Print Bin(j) ; " err:" ; Err I2cstop #endif 'try a transaction #if Usechannel = 1 I2csend &H70 , 255 , #4 ' all 1 Waitms 1000 I2csend &H70 , 0 , #4 'all 0 #else I2csend &H70 , 255 Waitms 1000 I2csend &H70 , 0 #endif Print Err 'read transaction Dim Var As Byte Var = &B11111111 #if Usechannel = 1 I2creceive &H70 , Var , 1 , 1 , #4 ' send and receive Print Bin(var) ; "-" ; Err I2creceive &H70 , Var , 0 , 1 , #4 ' just receive Print Bin(var) ; "-" ; Err #else I2creceive &H70 , Var , 1 , 1 ' send and receive Print Bin(var) ; "-" ; Err I2creceive &H70 , Var , 0 , 1 ' just receive Print Bin(var) ; "-" ; Err #endif End
Languages | English • Deutsch |
---|