Przy okazji pokazuję funkcję MAP która dowolną wartość z jednego zakresu skaluje na inny zakres.
Tak więc tutaj jeden potencjometr 0-1023 skaluję na częstotliwość pomiędzy 20Hz a 2kHz, a drugi 0-1023 na procent Duty 1%-99%
Może się komuś przyda. Wszystko wyświetla na LCD 2x16. Tu jest na Mega, ale powinien pasować do Uno.
Code: [Zaznacz cały] [Rozwiń/Zwiń]
- $regfile = "m2560def.dat" '8K SRAM
- $crystal = 16000000
- $hwstack = 64
- $swstack = 16
- $framesize = 200
- $baud = 115200
- ' FREQ DUTY GENERATOR OPERATED BY TWO POTENTIOMETERS
- Debug Off
- Const Min_freq = 20 'Hz
- Const Max_freq = 2000 'Hz
- Const Min_duty = 1 ' 1%-100%
- Const Max_duty = 100 ' 1%-100%
- Config Submode = New 'Subs first then you can use them
- '***********************************************
- '* ALPHANUMERIC LCD *
- '***********************************************
- Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.5 , Db6 = Portc.7 , Db7 = Porta.6 , E = Portl.5 , Rs = Portl.1 ' , Wr = Porta.1
- Config Lcd = 16x2
- Cursor Off , Noblink
- Cls
- '***********************************************
- '* I/O *
- '***********************************************
- Config Portb.7 = Output : Led Alias Portb.7 'Arduino Mega LED
- Config Portb.5 = Output : Freq_out Alias Portb.5 'Freq/Duty output pin
- '***********************************************
- '* ADC *
- '***********************************************
- 'freq potentiometer on A0
- 'duty potentiometer on A1
- Config Adc = Single , Prescaler = Auto , Reference = Avcc
- Dim New_adc As Word , Freq_adc As Word , Duty_adc As Word
- '***********************************************
- '* VARIABLES *
- '***********************************************
- 'multipurpose
- Dim Helpb As Byte , N As Byte
- 'program
- Dim New_freq As Word , New_duty As Word , Change As Byte
- 'timer
- Dim Value As Dword , Ustaw As Word , Prescaler As Word , Help_d As Dword
- Dim Wartosc_dla_tccr1b As Byte , Wypelnienie As Word , Presc As Byte , Proc As Word
- '***********************************************
- '* TIMER1 *
- '***********************************************
- '----------------------------------------------------------------
- 'TCCR1A -> |COM1A1 COM1A0 COM1B1 COM1B0 -- -- WGM11 WGM10
- 'TCCR1B -> | ICNC1 ICES1 -- WGM13 WGM12 CS12 CS11 CS10 FOR MEGA328P
- 'TCCR1C -> | FOC1A FOC1B -- -- -- -- -- --
- '----------------------------------------------------------------
- Const Freq = _xtal
- ' WGM13-|
- Const Pwm_presc1 = &B00010001 'for TCCR1B
- Const Pwm_presc8 = &B00010010
- Const Pwm_presc64 = &B00010011
- Const Pwm_presc256 = &B00010100
- Const Pwm_presc1024 = &B00010101
- Const Set_output_mode = &B10100000 'for TCCR1A
- Function Map(byval Value As Word , Byval Min_in As Word , Byval Max_in As Word , Byval Min_out As Word , Byval Max_out As Word)as Word
- Local I1 As Long
- Local I2 As Long
- I1 = Value - Min_in
- I2 = Max_out - Min_out
- I1 = I1 * I2
- I2 = Max_in - Min_in
- I1 = I1 / I2
- I1 = I1 + Min_out
- I1 = Abs(i1)
- Map = I1
- 'Map = Abs(i1)
- If Map >= Max_out Then Map = Max_out - 1
- End Function
- Sub Calc_duty()
- Help_d = Value * New_duty
- Help_d = Help_d / 100
- Wypelnienie = Help_d
- Ocr1a = Wypelnienie
- End Sub
- Locate 1 , 1 : Lcd "Freq="
- Locate 2 , 1 : Lcd "Duty="
- Freq_adc = 1024 : Duty_adc = 1024 'refresh even if zero
- Do
- New_adc = 0
- For N = 1 To 64
- New_adc = New_adc + Getadc(0)
- Next
- Shift New_adc , Right , 6
- If Freq_adc <> New_adc Then
- Freq_adc = New_adc
- New_freq = Map(freq_adc , 0 , 1023 , Min_freq , Max_freq)
- Locate 1 , 6 : Lcd New_freq ; "Hz "
- Change = 1
- End If
- New_adc = 0
- For N = 1 To 64
- New_adc = New_adc + Getadc(1)
- Next
- Shift New_adc , Right , 6
- If Duty_adc <> New_adc Then
- Duty_adc = New_adc
- New_duty = Map(duty_adc , 0 , 1023 , Min_duty , Max_duty)
- Locate 2 , 6 : Lcd New_duty ; "% "
- Change = 1
- End If
- If Change = 1 Then
- Change = 0
- Help_d = New_freq
- If Help_d > 0 Then
- Value = Freq 'uC clock speed
- Select Case Help_d
- Case 1
- '256
- Wartosc_dla_tccr1b = Pwm_presc256
- Shift Value , Right , 8
- Presc = 2 'nie miesci sie 256
- Case 2 To 15
- '64
- Wartosc_dla_tccr1b = Pwm_presc64
- Shift Value , Right , 6
- Presc = 64
- Case 16 To 122 '16000000Hz/131072 = 15Hz '
- '8
- Wartosc_dla_tccr1b = Pwm_presc8
- Shift Value , Right , 3
- Presc = 8
- Case Else '16000000Hz/131072 = 122Hz
- '1
- Wartosc_dla_tccr1b = Pwm_presc1
- Presc = 1
- End Select
- Value = Value \ Help_d
- Shift Value , Right , 1 'divide /2
- Decr Value : Ustaw = Value 'substract one
- Call Calc_duty()
- Icr1 = Ustaw
- Tccr1a = Set_output_mode 'set count up, reset count down
- Tccr1b = Wartosc_dla_tccr1b 'set prescaler and WGM13
- End If
- End If
- Loop
- End