'--------------------------------------------------------------------------------
'name : m328pb.bas
'copyright : (c) 1995-2023, MCS Electronics
'purpose : demonstrates M328pb
'micro : Mega328pb
'suited for demo : yes
'commercial addon needed : no
'--------------------------------------------------------------------------------
$regfile = "m328pbdef.dat"
$crystal = 8000000
$baud = 19200
$hwstack = 40
$swstack = 40
$framesize = 40
' USART TX RX
' 0 D.1 D.0
' 1 B.3 B.4
' ISP programming
' MOSI-PB3 MISO-PB4 SCK-PB5
' TWI SDA SCL
' 0 C.4 C.5
' 1 E.0 E.1
'Configuration
Config Clockdiv = 1 'make sure we get 8 Mhz from internal osc
Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Config Com2 = 19200 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
'we have 2 TWI interfaces
Config Scl = Portc.5 ' we need to provide the SCL pin name
Config Sda = Portc.4 ' we need to provide the SDA pin name
Config Sda1 = Porte.0 'use this for the second TWI
Config Scl1 = Porte.1
Config Twi = 100000 'speed 100 KHz
Config Twi1 = 100000 'speed 100 KHz
Config Twislave = &H70 , Btr = 2 , Bitrate = 100000
dim w as word
'in this demo we only use the second SPI interface
Config Spi1 = Hard , Interrupt = Off , Data_order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 128
'some constants for the signature row
Const Device_signature_byte1 = 0
Const Device_signature_byte2 = 2
Const Device_signature_byte3 = 4
Const Rc_oscillator_calibration = 1
Const Serial_number_byte0 = &H0E
Const Serial_number_byte1 = &H0F
Const Serial_number_byte2 = &H10
Const Serial_number_byte3 = &H11
Const Serial_number_byte4 = &H12
Const Serial_number_byte5 = &H13
Const Serial_number_byte6 = &H14
Const Serial_number_byte7 = &H15
Const Serial_number_byte8 = &H16
Const Serial_number_byte9 = &H17
$lib "I2C_TWI-MULTI.lib" 'important for using 2 TWI interfaces
Dim _i2cchannel As Byte ' you MUST dim this variable yourself when using the above lib
Dim B As Byte 'just a used byte
Dim A(10) As Byte
I2cinit 'default TWI init
I2cinit Twi1 'optional specify TWI1 to init that interface
Open "com2:" For Binary As #2 'create a channel to reference the UART
'print the chip ID
Print "ID : " ; Hex(readsig(device_signature_byte1)) ; Hex(readsig(device_signature_byte2)) ; Hex(readsig(device_signature_byte3))
'all I2C statements will work the same. All you need to do is to set the _i2cchannel variable to 0 or 1
_i2cchannel = 1 'try the second bus
Print "Scan start"
For B = 0 To 254 Step 2 'for all odd addresses
I2cstart
I2cwbyte B 'send address
If Err = 0 Then 'we got an ack
Print "Slave at : " ; B ; " hex : " ; Hex(b) ; " bin : " ; Bin(b)
End If
I2cstop 'free bus
Next
'second SPI
Spi1init
B = 5
Spi1out A(1) , B
Spi1in A(1) , B
A(1) = Spi1move(a(2))
Do
Print "COM1"
Print #2 , "COM2"
Waitms 1000
Loop
'The following labels are called from the library. You need to insert code in these subroutines
'Notice that the PRINT commands are remarked.
'You can unmark them and see what happens, but it will result in occasional errors in the transmission
'The idea is that you write your code in the called labels. And this code must execute in as little time
'as possible. So when you slave must read the A/D converter, you can best do it in the main program
'then the data is available when the master needs it, and you do not need to do the conversion which cost time.
'A master can send or receive bytes.
'A master protocol can also send some bytes, then receive some bytes
'The master and slave must match.
'the following labels are called from the library when master send stop or start
Twi_stop_rstart_received:
' Print "Master sent stop or repeated start"
Return
'master sent our slave address and will not send data
Twi_addressed_goread:
' Print "We were addressed and master will send data"
Return
Twi_addressed_gowrite:
' Print "We were addressed and master will read data"
Return
'this label is called when the master sends data and the slave has received the byte
'the variable TWI holds the received value
Twi_gotdata:
'Print "received : " ; Twi ; " byte no : " ; Twi_btw
Select Case Twi_btw
Case 1 : Portb = Twi ' first byte
Case 2: 'you can set another port here for example
End Select ' the setting of portb has nothing to do with the ADC
Return
'this label is called when the master receives data and needs a byte
'the variable twi_btr is a byte variable that holds the index of the needed byte
'so when sending multiple bytes from an array, twi_btr can be used for the index
Twi_master_needs_byte:
'Print "Master needs byte : " ; Twi_btr
Select Case Twi_btr
Case 1: ' first byte
W = Getadc(0) 'in this example the conversion is done here
' but a better option would have been to just pass the value of W and do the conversion in the main loop
'Print "ADC-SLAVE:" ; W
Twi = Low(w)
Case 2 ' send second byte
Twi = High(w)
End Select
Return
'when the mast has all bytes received this label will be called
Twi_master_need_nomore_byte:
' Print "Master does not need anymore bytes"
Return
|