'----------------------------------------------------------------------- 'copyright : (c) 2012, Werner Braun 'purpose : simple DDS control 'micro : Mega16 'suited for demo : Yes 'commercial addon needed : Yes, for your private use only 'version : 1.0 '------------------------------------------------------------------------ $regfile = "M16def.dat" ' the used chip $lib "double.lbx" ' We do not use software emulated I2C but the TWI. $lib "i2c_twi.lbx" $hwstack = 40 ' use 32 for the hardware stack $swstack = 40 ' use 10 for the SW stack $framesize = 40 ' use 40 for the frame space 'Config Serialin = Buffered , Size = 20 'Config Serialout = Buffered , SIZE = 20 'Enable Interrupts ' Master crystal $crystal = 14745600 $baud = 38400 ' baud rate 'Pin kind (used for) 'PB0 : XCK/T0 () 'PB1 : T1 () 'PB2 : INT2/AIN0 () 'PB3 ; OC0/AIN1 () 'PB4 : SS () 'PB5 : MOSI () 'PB6 : MISO () 'PB7 : SCK () 'PD0 : RXD (UART serial in) 'PD1 : TXD (UART serial out) 'PD2 : INT0 () 'PD3 : INT1 () 'PD4 : OC1B () 'PD5 : OC1A () 'PD6 : ICP1 () 'PD7 : OC2 () 'PC0 . SCL (SCL TWI) 'PC1 : SDA (SDA TWI) 'PC2 : TCK () 'PC3 : TMS () 'PC4 : TDO () 'PC5 : TDI () 'PC6 : TOSC1 () 'PC7 : TOSC2 () 'PA0 : ADC0 () 'PA1 : ADC1 () 'PA2 : ADC2 () 'PA3 : ADC3 () 'PA4 : ADC4 () 'PA5 : ADC5 () 'PA6 : ADC6 () 'PA7 : ADC7 () ' Global variables Dim Adder As Double Dim dbl_Temp As Double Dim Long_adder As Long Dim Str_temp As String * 20 Dim Str_uart As String * 20 Dim Command As Byte ' DDS variables Dim DdsCrystal As Double ' TWI Slave (DDS) crystal DdsCrystal = 16000000 Dim Dds_adress As Byte Dim Ddsregister As Byte Dim Ddsvalue As Byte Dim Frequency As Double ' Hz Dim Last_frequency As Double Dim Modus As Byte ' ' r24,r25,r26,(r27) is the adder value determining the frequency Dim Reg24 As Byte Dim Temp_r24 As Byte Dim Reg25 As Byte Dim Temp_r25 As Byte Dim Reg26 As Byte Dim Temp_r26 As Byte Dim Reg27 As Byte ' r28,r29,r30,r31 is the max 32bit phase accumulator Dim Reg28 As Byte Dim Reg29 As Byte Dim Reg30 As Byte Dim Reg31 As Byte Dim Temp_r31 As Byte ' Const OffMode = &h00 Const NoiseMode = &H01 Const SawtoothMode_slow = &h02 Const SawtoothMode_fast = &h03 Const SineMode_slow = &h04 Const SineMode_fast = &h05 Const TriangleMode_slow = &h06 Const TriangleMode_fast = &h07 Const RectangularMode_slow = &h08 Const RectangularMode_fast = &h09 ' ' Initialize TWI ' The chip will work in TWI/I2C master mode. Config Scl = Portc.0 ' we need to provide the SCL pin name Config Sda = Portc.1 ' we need to provide the SDA pin name Config Twi = 100000 ' wanted clock frequency will set TWBR and TWSR I2cinit ' we need to set the pins in the proper state ' Subs used Declare Sub Send_tw(byval Register As Byte , Byval Value As Byte) Declare Sub Updatedds() Program: Reg24 = 0 'call Send_TW(24 , 0) Reg25 = 0 'call Send_TW(25 , 0) Reg26 = 0 'call Send_TW(26 , 0) Reg28 = 0 'call Send_TW(28 , 0) Reg29 = 0 'call Send_TW(29 , 0) Reg30 = 0 'call Send_TW(30 , 0) Reg31 = OffMode 'call Send_TW(31 , 0) Dds_adress = 2 Rotate Dds_adress , Left , 1 ' *2 ( LSL ) 7 bit plus R/W Frequency = 0 ' off at start Last_frequency = 0 Str_uart = "" Do Command = 0 ' scan serial port If Ischarwaiting() = 1 Then Inputbin Command Print Chr(command); If Command = 44 Then Command = 46 ' comma = dot Select Case Command Case 46 ' comma If Len(str_uart) < 20 Then Str_uart = Str_uart + Chr(command) Else Command = 13 End If Case 13 Case 48 To 57 ' number If Len(str_uart) < 20 Then Str_uart = Str_uart + Chr(command) Else Command = 13 End If Case 97 ' A ~ OffMode Temp_r31 = 0 UpDateDDS Str_uart = "" Case 98 ' B ~ NoiseMode Temp_r31 = 1 UpDateDDS Str_uart = "" Case 99 ' C ~ SawtoothMode_slow Temp_r31 = 2 UpDateDDS Str_uart = "" Case 100 ' D ~ SawtoothMode_fast Temp_r31 = 3 UpDateDDS Str_uart = "" Case 101 ' E ~ SineMode_slow Temp_r31 = 4 UpDateDDS Str_uart = "" Case 102 ' F ~ SineMode_fast Temp_r31 = 5 UpDateDDS Str_uart = "" Case 103 ' G ~ TriangleMode_slow Temp_r31 = 6 UpDateDDS Str_uart = "" Case 104 ' H ~ TriangleMode_fast Temp_r31 = 7 UpDateDDS Str_uart = "" Case 105 ' I ~ RectangularMode_slow Temp_r31 = 8 UpDateDDS Str_uart = "" Case 106 ' J ~ RectangularMode_fast Temp_r31 = 8 UpDateDDS Str_uart = "" Case Else Command = 0 End Select If Command = 13 Then Frequency = Val(str_uart) Str_uart = "" UpDateDDS End If Command = 0 End If 'If Last_frequency <> Frequency Then UpdateDds 'If Reg31 <> Temp_r31 Then UpdateDds Loop Sub Updatedds() If Reg31 <> Temp_r31 Then ' mode has changed Call Send_tw(31 , Temp_r31) Reg31 = Temp_r31 Modus = Reg31 End If Select case Modus Case SawtoothMode_slow Adder = Frequency * 8 Adder = Adder * 33554432 Adder = Adder / DdsCrystal case SawtoothMode_fast Adder = Frequency * 5 Adder = Adder * 16777216 Adder = Adder / DdsCrystal case SineMode_fast Adder = Frequency * 8 Adder = Adder * 33554432 Adder = Adder / DdsCrystal case SineMode_slow Adder = Frequency * 10 Adder = Adder * 67108864 Adder = Adder / DdsCrystal case TriangleMode_slow Adder = Frequency * 10 Adder = Adder * 67108864 Adder = Adder / DdsCrystal case TriangleMode_fast Adder = Frequency * 8 Adder = Adder * 33554432 Adder = adder / DdsCrystal case RectangularMode_slow Adder = Frequency * 10 Adder = adder * 67108864 Adder = adder / DdsCrystal case RectangularMode_fast Adder = Frequency * 8 Adder = Adder * 33554432 Adder = Adder / DdsCrystal end SELECT If Modus > 1 then ' trunicate print frequency print adder Long_adder = Adder print long_adder Temp_r24 = Long_adder Mod 256 Rotate Long_adder , Right , 8 Temp_r25 = Long_adder Mod 256 Rotate Long_adder , Right , 8 Temp_r26 = Long_adder Mod 256 'If Temp_r24 <> Reg24 Then Call Send_tw(24 , Temp_r24) Reg24 = Temp_r24 'End If 'If Temp_r25 <> Reg25 Then Call Send_tw(25 , Temp_r25) Reg25 = Temp_r25 'End If 'If Temp_r26 <> Reg26 Then Call Send_tw(26 , Temp_r26) Reg26 = Temp_r26 'End If endif End Sub Sub Send_tw(register As Byte , Value As Byte ) 'print Adder Print "SEND TWI "; Print Register; Print Value I2cstart I2cwbyte Dds_adress I2cwbyte Register I2cwbyte Value End Sub End