'----------------------------------------------------------------------- '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 chip used $lib "double.lbx" ' We do not use software emulated I2C but the TWI. $lib "i2c_twi.lib" $hwstack = 40 ' use 32 for the hardware stack $swstack = 40 ' use 10 for the SW stack $framesize = 60 ' use 40 for the frame space On URXC OnRxD Enable URXC 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 (in READY from DDS) not yet '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_UART As String * 10 Dim Command As String * 1 ' DDS variables Dim DDSCrystal As Double ' TWI Slave (DDS) crystal DDSCrystal = 22000000 Dim FREQUENCY As Double ' Hz Dim MODUS As Byte Dim DUTY 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 ' Const OffMode = 0 Const NoiseMode = 1 Const SawtoothMode_slow = 2 Const SawtoothMode_fast = 3 Const SineMode_slow = 4 Const SineMode_fast = 5 Const TriangleMode_slow = 6 Const TriangleMode_fast = 7 Const RectangleMode_5050 = 8 Const RectangleMode_var = 9 Const SawtoothMode_precise = 10 Const RectangleMode_fast = 11 ' ' 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 = 400000 ' 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: FREQUENCY = 0 ' off at start ADDER = 0 Str_UART = "" DUTY = 129 MODUS = OffMode Reg24 = 0 call Send_TW(24 , 0) Reg25 = 0 call Send_TW(25 , 0) Reg26 = 0 call Send_TW(26 , 0) command = "" Do if command <> "" then Select Case Command Case "." ' comma If Len(Str_UART) < 10 Then Str_UART = Str_UART + command command = "" else command = CHR(13) End If Case "0" To "9" ' number If Len(Str_UART) < 10 Then Str_UART = Str_UART + command command = "" else command = chr(13) End If Case "a" ' ~ OffMode Call Send_TW(19 , OffMode) Case "b" MODUS = NoiseMode command = "M" Case "c" MODUS = SawtoothMode_slow command = "M" Case "d" MODUS = SawtoothMode_fast command = "M" Case "e" MODUS = SineMode_slow command = "M" Case "f" MODUS = SineMode_fast command = "M" Case "g" MODUS = TriangleMode_slow command = "M" Case "h" MODUS = TriangleMode_fast command = "M" Case "i" MODUS = RectangleMode_5050 command = "M" Case "j" MODUS = RectangleMode_var command = "M" Case "k" MODUS = SawtoothMode_precise command = "M" Case "l" MODUS = RectangleMode_fast command = "M" Case "m" ' incr duty cycle if DUTY < 255 then DUTY = DUTY + 1 command = "D" End If case "n" ' N decr duty cycle if DUTY > 0 then DUTY = DUTY - 1 command = "D" End IF End Select if command = "D" then command = "" Call Send_TW(13 , DUTY) Str_UART = "" endif If command = "M" Then command = "" Call Send_TW(19 , MODUS) call UpDateDDS Str_UART = "" End If If asc(command) = 13 then print if len(Str_UART) > 0 then FREQUENCY = Val(Str_UART) call UpDateDDS endif command = "" print FREQUENCY Str_UART = "" End If End If Loop Sub UpDateDDS() if MODUS <> NoiseMode then Select Case MODUS Case SawtoothMode_precise ADDER = FREQUENCY * 10 ADDER = ADDER * 67108864 Case SawtoothMode_slow ADDER = FREQUENCY * 8 ADDER = ADDER * 33554432 Case SawtoothMode_fast ADDER = FREQUENCY * 5 ADDER = ADDER * 16777216 Case SineMode_fast ADDER = FREQUENCY * 8 ADDER = ADDER * 33554432 Case SineMode_slow ADDER = FREQUENCY * 10 ADDER = ADDER * 67108864 Case TriangleMode_slow ADDER = FREQUENCY * 10 ADDER = ADDER * 67108864 Case TriangleMode_fast ADDER = FREQUENCY * 8 ADDER = ADDER * 33554432 Case RectangleMode_5050 ADDER = FREQUENCY * 7 ADDER = ADDER * 33554432 Case RectangleMode_var ADDER = FREQUENCY * 9 ADDER = ADDER * 16777216 Case RectangleMode_fast ADDER = FREQUENCY * 6 ADDER = ADDER * 131072 End SELECT dbl_Temp = ADDER / DDSCrystal Long_ADDER = dbl_Temp 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 end if End Sub Sub Send_TW(register As Byte , Value As Byte ) Print "SEND TWI "; Print Register; Print " "; Print Value shift , register , left I2Cstart I2Cwbyte register I2Cwbyte Value End Sub OnRxD: command = chr(UDR) Return End