也算是电源吧-续:上来亮骚一下最近做的样机
在热心网友 TR 的帮助下,最近做了几台新的样机,修正了之前的一些问题,上来亮骚一下 {:lol:}另外把电路原理图整理了一下,原来画的图比较乱,程序也模块化整理了一下,并增加了对硬件的启动自检部分以方便 DIY 的时候排查错误。这个是用金箔电阻的版本
这个是普通电阻版本
开机
自检
测试中
不错,期待楼主的资料 上一版传送门:http://www.amobbs.com/thread-5483204-1-1.html
整理后的电路图,和上一版相比
1、主 DAC 为更加稳定的 MAX541(DAC5541),副 DAC 为 MAX515 不变
2、将副 DAC 输出电路更改为一个 x-1 反相放大器以调整电路的零点失调
3、使用了光耦(磁耦)将模数完善隔离了
本版程序(陆续编写中,所以一些注释还没写,我会慢慢加上)
'///////////////////////////////////////////////////////////////////////////////////////////////////
'Voltage Generator
'By Lilith Washu
'///////////////////////////////////////////////////////////////////////////////////////////////////
$Device= m32 ' 使用的单片机名称
$Stack = 32
$Clock = 11.0592 ' 使用的单片机主频
$ShiftIn Data = PORTB.4, Clock = PORTB.3, Msb
$ShiftOut Data = PORTB.1, Clock = PORTB.2, Msb
$Baud = 19200,n,8,1
$1Wire = PORTD.6
$LeadChar="0", Format(2,6)
'************** Config the IO **************
' the Display Screen IO Connect
$Def IO_SCR_RST = PORTC.7
$Def IO_SCR_CSA = PORTC.6
$Def IO_SCR_CSB = PORTC.5
$Def IO_SCR_DoI = PORTC.4
$Def IO_SCR_RoW = PORTC.3
$Def IO_SCR_STB = PORTC.2
$Def IO_SCR_DAT = PORTA
' the Analog Board IO Connect
$Def IO_REG_STB = PORTB.0
$Def IO_REG_DAT = PORTB.1
$Def IO_REG_CLK = PORTB.2
$Def IO_ADC_CLK = PORTB.3
$Def IO_ADC_DAT = PINB.4
$Def IO_KEY_STB = PORTB.5
$Def IO_KEY_DAT = PINB.6
$Def IO_KEY_CLK = PORTB.7
'///////////////////////////////////////////////////////////////////////////////////////////////////
' Constant
'///////////////////////////////////////////////////////////////////////////////////////////////////
Const fMasterReference = 7.042665e+00'7.080451E+00 'LM399 Voltage Value
Const fDACReference = 5.000000E+00 'DAC Voltage Reference Value
Const fDACenter = 2.500000E+00 'Slave DAC Default Output Voltage Value
Const fDACGain = 2.500000E+06 'DAC Output buff Gain
Const fMResistance = 2.49E+02 'DAC Voltgae Compound Resistance, the Master
Const fSResistance = 1E+06 'DAC Voltgae Compound Resistance, the Slave
Const Quadratic = -3.6031e+00 'No-line Error Adjuest Quadratic Coefficient 二次项系数
Const Linear = 4.5495e+01 'No-line Error Adjuest Linear Coefficient 一次项系数
Const Constant = 5.6295e+01 'No-line Error Adjuest Offset Coefficient 常数
Const fDacal = 1.005258e+00'1.012857e+00 'DAC Fullscale Error Adjuest Vale
Const Synthesis = &b00000001 ' Analog Switch = Synthesis Voltage Output | DG412 Pin
Const Reference = &b00000010 ' Analog Switch = Internal Reference(LM399) | DG412 Pin
Const ExternaIN = &b00000100 ' Analog Switch = Externa Voltage Input | DG412 Pin
Const GndOffset = &b00001000 ' Analog Switch = Auto Zero | DG412 Pin
'///////////////////////////////////////////////////////////////////////////////////////////////////
' String Variables
'///////////////////////////////////////////////////////////////////////////////////////////////////
Dim Ft1 As Flash Byte ' 软字体码表
Dim Ft2 As Flash Byte ' 软字体码表
Dim Charat As String *33' 要显示的字符缓冲区
Dim tTxt As String *15
Dim tm As String *7
Dim tCmd As String *4
Dim iCursors(8) As Byte
'///////////////////////////////////////////////////////////////////////////////////////////////////
' Gen Variables
'///////////////////////////////////////////////////////////////////////////////////////////////////
Dim i As Byte
Dim bUartset As Byte
Dim bUartlk As Byte
Dim bAdjuest As Byte
Dim bDigitaLoop As Byte
Dim bRun As Byte
Dim bTrigcompleted As Byte
Dim bRefsource As Byte
Dim iErrlimit As Byte
Dim bSregister As Byte
Dim iSmlen As Byte
Dim iSmsetp As Byte
Dim iBusystp As Byte
Dim iTrd As Byte
Dim iDraw As Word
Dim CurrentChannel As Byte
Dim bNextchannel As Byte
Dim itm As Byte
Dim iDa As Byte
Dim iDb As Byte
Dim iDc As Byte
Dim iDd As Byte
Dim iTa As Byte
Dim iTb As Byte
Dim iTc As Byte
Dim iTd As Byte
Dim bADCResult(3) As Byte
Dim bREGa(64) As Byte
Dim bREGb(64) As Byte
Dim bREGc(64) As Byte
Dim bREGd(64) As Byte
Dim dTempdatum(1) As Byte
Dim dTempresult As Word
Dim iError As Integer
Dim wError As Word
Dim IsTempresultSense As Byte
Dim iTestcode As Byte
'///////////////////////////////////////////////////////////////////////////////////////////////////
' Float Variables
'///////////////////////////////////////////////////////////////////////////////////////////////////
Dim fTrn As Float
Dim fOut As Float
Dim fGndOffset As Float
Dim fReference As Float
Dim fSynthesis As Float
Dim fCalsacles As Float
Dim fCalfSynth As Float
Dim fSetting As Float
Dim fVoltage As Float
Dim fError As Float
Dim fVset As Float
Dim fVtrn As Float
Dim fTemperature As Float
Dim Vseth As Word
Dim Vsetl As Word
'///////////////////////////////////////////////////////////////////////////////////////////////////
' Screen Function
'///////////////////////////////////////////////////////////////////////////////////////////////////
Declare Function WriteKS(Code As Byte, Channel As Byte) As Byte ' 向显示屏写数据的函数
Declare Function SetKS(Code As Byte, Channel As Byte) As Byte ' 向显示屏写指令的函数
Declare Function InitKS() As Byte ' 初始化显示屏
Declare Function ResetKS() As Byte ' 显示屏上电函数,可用硬件电路代替
Declare Function ClsKS(GRAM As Byte) As Byte ' 清屏函数
Declare Function DrawPix(x As Byte, y As Byte) As Byte ' 在显示屏上画一个点
Declare Function DrawPage(x As Byte, Page As Byte, Code As Byte) As Byte ' 在显示屏上画一个页
Declare Function DrawChr(x As Byte, Page As Byte) As Byte ' 显示一行标准 ASCII 字符
Declare Function DrawChrLarge(x As Byte, Page As Byte) As Byte ' 显示一行标准 ASCII 字符
Declare Function DrawCursors(x As Byte, Page As Byte, Length As Byte) As Byte
'///////////////////////////////////////////////////////////////////////////////////////////////////
' IO Function
'///////////////////////////////////////////////////////////////////////////////////////////////////
Declare Function WriteSReg(bDat As Byte) As Byte
Declare Function SetChannel(Channel As Byte) As Byte
Declare Function ReadADC() As Byte
Declare Function ReadKEY() As Byte
'///////////////////////////////////////////////////////////////////////////////////////////////////
' Mathematical Function
'///////////////////////////////////////////////////////////////////////////////////////////////////
Declare Function SetVoltage(fVoltage As Float) As Byte
Declare Function Getinlerr(fVoltage As Float) As Float
Declare Function ReadADConvert(NextChannel As Byte) As Long
Declare Function FixADCResult() As Byte
Declare Function WriteResultREG(bSetp As Byte, bArea As Byte) As Byte
Declare Function MoveResultREG(bSetp As Byte, bArea As Byte) As Byte
Declare Function ReadADCResult(bChannel As Byte) As Float
Declare Sub StatusDisplay()
Declare Function UpdateTempresultInfo() As Byte
Declare Sub Trigcompleted()
Declare Function ADCheck(bNextChannel As Byte) As Integer
'///////////////////////////////////////////////////////////////////////////////////////////////////
' UART Interrupt
'///////////////////////////////////////////////////////////////////////////////////////////////////
Declare Interrupt Urxc()
Enable Interrupts
Enable Urxc
'///////////////////////////////////////////////////////////////////////////////////////////////////
' Config the MCU IO Register
'///////////////////////////////////////////////////////////////////////////////////////////////////
DDRA = &b11111111 'Display Screen Data Bus
'Parallel 8bit Data bus
DDRC = &b11111111 'Display Screen Control Bus
'PC0: (Saved)
'PC1: (Saved)
'PC2: Screen Strobe
'PC3: Screen Write or Read
'PC4: Screen Data or Instructions
'PC5: Screen Area Enable LO Bit
'PC6: Screen Area Enable HI Bit
'PC7: Screen Reset
DDRB = &b10101111 'Analog Board Connect
'REG STB <--- PB0
'REG DAT <--- PB1
'REG CLK <--- PB2
'ADC CLK <--- PB3
'ADC DAT ---> PB4
'KEY STB <--- PB5
'KEY DAT ---> PB6
'KEY CLK <--- PB7
DDRD = &b11111111 'INT, UART and PWM Control
'PD0: UART RX
'PD1: UART TX
'PD2: INT0 TRIG(Key)
'PD3: INT1 TRIG(Saved)
'PD4: PWM OC1B(Saved)
'PD5: PWM OC1A(Saved)
'PD6: 1Wire BUS(DS18b20)
'PD7: PWM OC2(Saved)
PORTA = &b00000000
PORTB = &b00000000
PORTC = &b00000000
PORTD = &b00000000
'///////////////////////////////////////////////////////////////////////////////////////////////////
' Program Initialization
'///////////////////////////////////////////////////////////////////////////////////////////////////
' Analog Board Initialization, Open all Analog Switch
bSregister = &b00000000
WriteSReg(bSregister)
' DAC Initialization to 0V Output
SetVoltage(0)
InitKS() ' 初始化显示屏
ClsKS(0) ' 清屏
' LCD Test and Init Display Charat
Charat = "Voltage Generator" : DrawChrLarge(6,1)
Charat = "Version 1.0" : DrawChr(32,3)
Charat = "Build 173" : DrawChr(44,4)
Charat = "By Lilith Washu" : DrawChr(38,6)
Wait 2 'Wait the LM399 Initialization
ClsKS(0)
Charat = "Initialization" : DrawChr(1,0)
'Initialization Var?
Charat = "Initialization OK" : DrawChr(1,0)
'///////////////////////////////////////////////////////////////////////////////////////////////////
' EEPROM Initialization
'///////////////////////////////////////////////////////////////////////////////////////////////////
'///////////////////////////////////////////////////////////////////////////////////////////////////
' Self Test
'///////////////////////////////////////////////////////////////////////////////////////////////////
iTestcode = 0
Charat = "Self Test......" : DrawChr(1,1)
Format(5,0)
' Check the Tempresult Sense(DS18b20)
IsTempresultSense = 1Wreset
If Not(IsTempresultSense) Then
Charat = ">TepSense not install" : DrawChr(1,2)
IsTempresultSense = 0
Else
Charat = ">TemperatureSense Chk" : DrawChr(1,2)
1Wwrite &hcc; &h44
WaitMs 500
1Wreset
1Wwrite &hcc; &hbe
1Wread dTempdatum ,2
1Wreset
1Wwrite &hcc; &h44
dTempresult = dTempdatum(0)
'Charat = Str(dTempresult) : DrawChr(156,2)
If dTempresult = 0 Then
Charat = ">TemperatureSense Err" : DrawChr(1,2)
IsTempresultSense = 0
iTestcode = iTestcode Or &b00000001
Else
Charat = ">Temperature Sense OK" : DrawChr(1,2)
IsTempresultSense = 1
End If
End If
' Check the ADC(LTC2400)
'Charat = ">ADC Checked..." : DrawChr(1,3)
If IO_ADC_DAT = 1 Then
Charat = ">ADC Detect...Failed" : DrawChr(1,3)
iTestcode = iTestcode Or &b00000010
Else
SetChannel(GndOffset)
bADCResult(3) = ShiftIn : bADCResult(2) = ShiftIn : bADCResult(1) = ShiftIn : bADCResult(0) = ShiftIn
iBusystp = 0
For i = 1 To 200
iBusystp = iBusystp + 1
If IO_ADC_DAT = 0 Then Exit For
WaitMs 1
Next i
If iBusystp < 155 Or iBusystp > 166 Then
Charat = ">ADC ChK Failed" : DrawChr(1,3)
Charat = Str(iBusystp) : DrawChr(94,3)
iTestcode = iTestcode Or &b00000100
Else
Charat = ">ADC Checked...Passed" : DrawChr(1,3)
iError = ADCheck(Reference) 'Result = GND Offset < +10~-10 >
If iError <> 0 Then
If iError > -10 And iError < 10 Then
Charat = ">COM Checked...Passed" : DrawChr(1,4)
Else
Charat = ">COM ChK Failed " : DrawChr(1,4)
Charat = Str(iError) : DrawChr(94,4)
iTestcode = iTestcode Or &b00001000
End If
Else
Charat = ">COM Checked...Passed" : DrawChr(1,4)
End If
'Check the Reference
Charat = ">Reference Chk:" : DrawChr(1,5)
SetVoltage(0) : WaitMs 10
iError = ADCheck(Synthesis) 'Result = Reference, Next is Synthesis Out Voltage <6500*1.024~7500*1.024 / 6655~7680>
wError = iError * 25 / 8
If wError > 6800 And wError < 7475 Then
Charat = ">REF Checked...Passed" : DrawChr(1,5)
Else
Charat = Str(wError) : DrawChr(94,5)
iTestcode = iTestcode Or &b00010000
End If
'Check the DAC Offset
Charat = ">DAC Check 1st." : DrawChr(1,6)
WaitMs 200 'Wait the ADC to Converting...
SetVoltage(12000000) : WaitMs 10 'Set Next Check Item = DAC Fullscale Out
iError = ADCheck(Synthesis) 'Result = Synthesis Out Voltage(Set=0V) <+~-1>
If iError <> 0 Then
If iError > -10 And iError < 10 Then
Charat = ">DAC Check 1st Passed" : DrawChr(1,6)
Else
Charat = Str(iError) : DrawChr(94,6)
iTestcode = iTestcode Or &b00100000
End If
Else
Charat = ">DAC Check 1st Passed" : DrawChr(1,6)
End If
'Check the DAC Full Scale
Charat = "2nd" : DrawChr(67,7)
WaitMs 200
'SetVoltage(0)
iError = ADCheck(Synthesis) 'Result = Synthesis Out Voltage(Set=12V) <12282 +/- 10word, 12270~12295>
wError = (iError / 2) * 25 / 4
If wError > 12000 And wError < 12575 Then
Charat = "Passed" : DrawChr(91,7)
Else
Charat = Str(wError) : DrawChr(94,7)
iTestcode = iTestcode Or &b01000000
End If
End If
End If
If iTestcode > 1 Then
Charat = "Failed" : DrawChr(91,1)
Charat = "Code:" : DrawChr(1,7)
Format(3,0) : Charat = Str(iTestcode) : DrawChr(31,7)
End
Else
Charat = "OK" : DrawChr(115,1)
End If
'///////////////////////////////////////////////////////////////////////////////////////////////////
' Self Test End
'///////////////////////////////////////////////////////////////////////////////////////////////////
Wait 1 'Wait the LM399 Warmed
ClsKS(0)
' Screen Fixed Display Initialization
Charat = "SET:"
DrawChrLarge(1,0)
Charat = "REB:"
DrawChrLarge(1,2)
Charat = "VDC"
DrawChrLarge(105,0)
DrawChrLarge(105,2)
' Right Sataus Lable Display
'Charat = "MH:"
'DrawChr(156,0)
'Charat = "ML:"
'DrawChr(156,1)
'Charat = "SH:"
'DrawChr(156,2)
'Charat = "SL:"
'DrawChr(156,3)
'Charat = "WAT:" : DrawChr(156,4)
'Charat = "ADJ:"
'DrawChr(156,5)
'Botton Sataus Label Display
Charat = "IGNO" : DrawChr(9,4)
Charat = "EXEC" : DrawChr(9,5)
'Charat = "TemP" : DrawChr(12,6)
'Charat = "Filt" : DrawChr(96,6)
Charat = "ErroR" : DrawChr(52,6)
Charat = "RuN" : DrawChr(100,5)
Charat = "StP" : DrawChr(100,4)
' Cursors Draw
'MemLoad(VarPtr(iCursors), &b00001000, &b00011100, &b00111110, &b01111111) : DrawCursors(1, 4, 4) ' Display a "<" Cursors
'MemLoad(VarPtr(iCursors), &b01111111, &b00111110, &b00011100, &b00001000) : DrawCursors(1, 4, 4) ' Display a ">" Cursors
'MemLoad(VarPtr(iCursors), &b00000100, &b00000110, &b00000111, &b00000110, &b00000100) : DrawCursors(1, 4, 5) ' Display a "^" Cursors
If IsTempresultSense = 1 Then
MemLoad(VarPtr(iCursors), &b00000110, &b00001001, &b00001001, &b000000110) : DrawCursors(31, 7, 4) ' Display aDegree Cursors
Charat = "C" : DrawChr(37,7)
UpdateTempresultInfo()
End If
'///////////////////////////////////////////////////////////////////////////////////////////////////
' Program Initialization End
'///////////////////////////////////////////////////////////////////////////////////////////////////
' Start the Temperature Sense(DS18b20) Convert
'1Wreset
'1Wwrite &hcc; &h44
'///////////////////////////////////////////////////////////////////////////////////////////////////
' RunningRegister Initialization
'///////////////////////////////////////////////////////////////////////////////////////////////////
' Init the DAC Output Default
fSetting = 10000000
fVoltage = fSetting
' Program Reset Point:
stt:
fVoltage = fVoltage / fDacal
SetVoltage(fVoltage)
' All Setting Register Value Initialization to Default
fReference = 0
fSynthesis = 0
fCalsacles = fMasterReference
iSmlen = 16 ' the Sommth Length, 1 Trig Cycle(Adjuest Cycle) = 3 x Sommth Length
bDigitaLoop = 1 ' Digital Loop = Close Loop(0=Open Loop)
itm = 0
iSmsetp = 0 ' Current Program Running Setp
bRun = 1 ' Flag the Program Run or Setp, 1 = Run
bRefsource = 0 ' Flag the Reference Source, 0 = INT, 1 = EXT
bNextchannel = 0 ' Flag the Analog Switch Channel
bAdjuest = 0 ' Flag is/isnot Adjuest Output Voltage
bUartlk = 1 ' Flag the UART Port Talk,bit 8 = All Talk; bit 1 = talk when Trigcompleted.
bUartset = 2
' Display and Update the Output Voltage Setting Value
Format(2,0)
Charat = Str(iSmlen) : DrawChr(104,7)
'Charat = Str(iSmlen * 3 + 1) : DrawChr(179,7)
Charat = "pt":DrawChr(116,7)
Charat = "/" :DrawChr(98,7)
Format(2,6)
fTrn = fSetting / 1000000
Charat = Str(fTrn)
DrawChrLarge(28,0)
'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
'Program Main Loop
'///////////////////////////////////////////////////////////////////////////////////////////////////
Do
If bRun = 0 Then
Charat = " ---------" : DrawChrLarge(28,2)
MemLoad(VarPtr(iCursors), &h00, &h00, &h00, &h00) : DrawCursors(122, 5, 4)
MemLoad(VarPtr(iCursors), &h08, &h1C, &h3E, &h7F) : DrawCursors(122, 4, 4)
iSmsetp = 0
WaitMs 100
GoTo Runout
Else
MemLoad(VarPtr(iCursors), &h00, &h00, &h00, &h00) : DrawCursors(122, 4, 4)
MemLoad(VarPtr(iCursors), &h08, &h1C, &h3E, &h7F) : DrawCursors(122, 5, 4)
End If
bNextchannel = bNextchannel + 1
If bNextchannel > 3 Then bNextchannel = 1
iBusystp = 0
Do
iBusystp = iBusystp + 1
WaitMs 1
Loop While IO_ADC_DAT = 1
Select Case bNextChannel
Case 1 : CurrentChannel = SetChannel(Reference)
Case 2 : CurrentChannel = SetChannel(GndOffset)
Case 3 : CurrentChannel = SetChannel(Synthesis)
End Select
'Charat = Hex(iBusystp) : DrawChr(64,4)
bADCResult(3) = ShiftIn
bADCResult(2) = ShiftIn
bADCResult(1) = ShiftIn
bADCResult(0) = ShiftIn
FixADCResult()
For i = 1 To iSmlen
MoveResultREG(i, bNextchannel)
Next i
WriteResultREG(iSmlen, bNextchannel)
iSmsetp = iSmsetp + 1
Format(2,0)
Charat = Str(iSmsetp/3)
DrawChr(86,7)
fSynthesis = ReadADCResult(1) 'syn
fReference = ReadADCResult(2) 'ref
fGndOffset = ReadADCResult(3) 'gnd
fCalfSynth = (fSynthesis - fGndOffset) / ((fReference - fGndOffset) / fCalsacles)
'fCalfSynth = fCalfSynth - Getinlerr(fCalfSynth) * 1000000
fError = fSetting - fCalfSynth * 1000000
iError = fError
wError = iError * iError
Format(2,6)
Charat = Str(fCalfSynth)
DrawChrLarge(28,2)
Format(4,0)
Charat = " " : DrawChr(52,7)
Charat = Str(iError) : DrawChr(52,7)
'Charat = Str(wError) : DrawChr(1,5)
iErrlimit = 0
If wError > 99 Then iErrlimit = 1
bAdjuest = bDigitaLoop And iErrlimit
'Format(2,0)
'Charat = Str(bAdjuest) : DrawChr(180,5)
If iSmsetp = iSmlen * 3 + 1 Then
iSmsetp = 0
Trigcompleted()
End If
Runout:
If bUartset = 1 Then
bUartset = 0
iSmsetp = 0
fVoltage = fSetting
fVoltage = fVoltage / fDacal
SetVoltage(fVoltage)
fTrn = fSetting / 1000000
Format(2,6)
Charat = Str(fTrn)
DrawChrLarge(28,0)
End If
If bUartset = 2 Then
bUartset = 0
StatusDisplay()
End If
Loop
End
'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
'Operation Sub and Function
'///////////////////////////////////////////////////////////////////////////////////////////////////
Sub StatusDisplay()
If bDigitaLoop = 1 Then
MemLoad(VarPtr(iCursors), &h00, &h00, &h00, &h00) : DrawCursors(1, 4, 4)
MemLoad(VarPtr(iCursors), &h7F, &h3E, &h1C, &h08) : DrawCursors(1, 5, 4)
Else
MemLoad(VarPtr(iCursors), &h00, &h00, &h00, &h00) : DrawCursors(1, 5, 4)
MemLoad(VarPtr(iCursors), &h7F, &h3E, &h1C, &h08) : DrawCursors(1, 4, 4)
End If
End Sub
Function UpdateTempresultInfo() As Byte
1Wreset
1Wwrite &hcc; &hbe
1Wread dTempdatum ,2
1Wreset
1Wwrite &hcc; &h44
dTempresult = dTempdatum(0)
fTemperature = dTempresult
fTemperature = fTemperature / 16
Format(2,1) : Charat = Str(fTemperature) : DrawChr(1,7)
End Function
Sub Trigcompleted()
If bAdjuest = 1 Then
fVoltage = fVoltage + fError
SetVoltage(fVoltage)
End If
If IsTempresultSense = 1 Then UpdateTempresultInfo()
If bUartlk = 1 Then
Format(5,2)
Print fError; fTemperature
End If
End Sub
'///////////////////////////////////////////////////////////////////////////////////////////////////
' Return the 24bit Result from 32bit Data
'///////////////////////////////////////////////////////////////////////////////////////////////////
Function FixADCResult() As Byte
iDa = bADCResult(3)
iDb = bADCResult(2)
iDc = bADCResult(1)
iDd = bADCResult(0)
' Casting out the lower 4bit Data and Return the low 8bit Result
iDd = iDd And &b11110000
iDd = Swap(iDd)
iTrd = iDc And &b00001111
iTrd = Swap(iTrd)
iTd = iDd + iTrd
' Move and Return the middle 8 bit Result
iTrd = iDc And &b11110000
iTc = Swap(iTrd)
iTrd = iDb And &b00001111
iTrd = Swap(iTrd)
iTc = iTrd + iTc
' Move and Return the hihg 8 bit Result
iTrd = iDb And &b11110000
iTb = Swap(iTrd)
iTrd = iDa And &b00001111
iTrd = Swap(iTrd)
iTb = iTrd + iTb
' Return the Overload and Sign Bit
iTrd = iDa And &b00110000
iTa = Swap(iTrd)
' Copy Result to Public Array
bADCResult(3) = iTa
bADCResult(2) = iTb
bADCResult(1) = iTc
bADCResult(0) = iTd
Return 0
End Function
'///////////////////////////////////////////////////////////////////////////////////////////////////
' Write a ADC Result to FIFO Movewindow Array
'///////////////////////////////////////////////////////////////////////////////////////////////////
Function WriteResultREG(bSetp As Byte, bArea As Byte) As Byte
iTrd = (bArea - 1) * iSmlen + bSetp
bREGa(iTrd) = bADCResult(3)
bREGb(iTrd) = bADCResult(2)
bREGc(iTrd) = bADCResult(1)
bREGd(iTrd) = bADCResult(0)
End Function
'///////////////////////////////////////////////////////////////////////////////////////////////////
' Move the FIFO Array
'///////////////////////////////////////////////////////////////////////////////////////////////////
Function MoveResultREG(bSetp As Byte, bArea As Byte) As Byte
iTrd = (bArea - 1) * iSmlen + bSetp
bREGa(iTrd) = bREGa(iTrd + 1)
bREGb(iTrd) = bREGb(iTrd + 1)
bREGc(iTrd) = bREGc(iTrd + 1)
bREGd(iTrd) = bREGd(iTrd + 1)
End Function
'///////////////////////////////////////////////////////////////////////////////////////////////////
' Return a Float Format Smohth ADC Result
'///////////////////////////////////////////////////////////////////////////////////////////////////
Function ReadADCResult(bChannel As Byte) As Float
fTrn = 0
fOut = 0
For i = 1 To iSmlen
iTrd = (bChannel - 1) * iSmlen + i
iTa = bREGa(iTrd)
iTb = bREGb(iTrd)
iTc = bREGc(iTrd)
iTd = bREGd(iTrd)
fTrn = 5 * 2.5 * (16777216 * iTa + 65536 * iTb + 256 * iTc + iTd - 33554432) / 16777216
fOut = fOut + fTrn
Next i
fOut = fOut / iSmlen
Return fOut
End Function
Function DrawCursors(x As Byte, Page As Byte, Length As Byte) As Byte
For i = 0 To Length - 1
DrawPage(x + i, Page, iCursors(i))
Next i
End Function
Function ADCheck(bNextChannel As Byte) As Integer
Local iChkresutl As Integer
Local iChk1 As Byte
Local iChk2 As Byte
Local iChk3 As Byte
Local iChk4 As Byte
Do
Loop While IO_ADC_DAT = 1
SetChannel(bNextChannel) : WaitMs 10
iChk4 = ShiftIn : iChk3 = ShiftIn : iChk2 = ShiftIn : iChk1 = ShiftIn
iChkresutl = iChk4 * 4
iChkresutl = iChkresutl * 256 + iChk3 * 4 - 32768
Return iChkresutl / 4
End Function
'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
'Shiftreg IO
'///////////////////////////////////////////////////////////////////////////////////////////////////
'///////////////////////////////////////////////////////////////////////////////////////////////////
' Wrtie the Analog board Control Shift-Register
'///////////////////////////////////////////////////////////////////////////////////////////////////
Function WriteSReg(bDat As Byte) As Byte
Local i As Byte
Local bWritedat As Byte
Local bWritebit As Byte
bWritedat = bDat
IO_REG_DAT = 0
IO_REG_CLK = 0
IO_REG_STB = 0
WaitUs 1
For i = 1 To 8
bWritebit = bWritedat And &b10000000
If bWritebit = 128 Then
IO_REG_DAT = 1
Else
IO_REG_DAT = 0
End If
WaitUs 1
IO_REG_CLK = 1 : WaitUs 1 : IO_REG_CLK = 0
bWritedat = Shift(Left, 1, bWritedat)
Next i
WaitUs 1
IO_REG_STB = 1 : WaitMs 1 : IO_REG_STB = 0
IO_REG_DAT = 0
IO_REG_CLK = 0
Return 0
End Function
'///////////////////////////////////////////////////////////////////////////////////////////////////
' Setting the Analog Switch(ADC Input Channel)
'///////////////////////////////////////////////////////////////////////////////////////////////////
Function SetChannel(Channel As Byte) As Byte
Local Channelset As Byte
Channelset = bSregister And &b11110000
WriteSReg(Channelset) ' Open all Analog Switch when Close Next Switch
WaitMs 10
bSregister = Channelset + Channel
WriteSReg(bSregister)
Return bSregister
End Function
'///////////////////////////////////////////////////////////////////////////////////////////////////
' Read Analog Board ADC Result Shift-Register
'///////////////////////////////////////////////////////////////////////////////////////////////////
Function ReadADC() As Byte
Local myByte As Byte
Local i As Byte
myByte = 0
' Read 8bit = 1 Byte Result form ADC Shift-Out Register(2Wire Serial Bus ADC)
For i = 0 To 7
IO_ADC_CLK = 1
Rotate(Left,1,myByte)
myByte = myByte + IO_ADC_DAT
WaitUs 1
IO_ADC_CLK = 0
WaitUs 1
Next i
' Return 1 Byte Result to Function
Return myByte
End Function
'///////////////////////////////////////////////////////////////////////////////////////////////////
' Read MCU Block Keyboard Status Shift-Register
'///////////////////////////////////////////////////////////////////////////////////////////////////
Function ReadKey() As Byte
Local myByte As Byte
Local i As Byte
myByte = 0
' Read 8bit = 1 Byte Result form Keyboard Shift-Out Register(74HC165)
For i = 0 To 7
Rotate(Left,1,myByte)
myByte = myByte + IO_KEY_DAT
IO_KEY_CLK = 1
WaitUs 1
IO_KEY_CLK = 0
WaitUs 1
Next i
' Return 1 Byte Result to Function
myByte = Not myByte
Return myByte
End Function
'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
'Mathematical Function
'///////////////////////////////////////////////////////////////////////////////////////////////////
'///////////////////////////////////////////////////////////////////////////////////////////////////
' Setting the Analogboard DAC Output Voltage
'///////////////////////////////////////////////////////////////////////////////////////////////////
Function SetVoltage(fVoltage As Float) As Byte
Local Vsetm As Word ' The Master DAC Setting Return
Local Vsets As Word ' The SlaveDAC Setting Return
Local mbMSB As Byte
Local mbLSB As Byte
Local sbMSB As Byte
Local sbLSB As Byte
' the VOut = Gain * (Vmaster * Rs + Vslave * Rm) / (Rm+Rs), Fullscale of the Vm = 5V and Vs = -5V, Gain = 2.5
fVtrn = fVoltage
fVtrn = fVtrn / fDACGain
fVset = fVtrn
'Get the MasteDAC Voltage Setting Value, Vm=/Rs , at Default, the Slave DAC Output = -2.5V
fVtrn = (fVtrn * (fMResistance + fSResistance) + fDACenter * fMResistance) / fSResistance
fVtrn = fVtrn * 65535 / fDACReference 'The Master DAC(MAX541) is 16bit DAC, Fullscale = 2^16 = 65536
Vsetm = fVtrn
mbMSB = Msb(Vsetm) 'Split the Setting Word to two Byte, Get the MSB Byte
mbLSB = Vsetm - mbMSB * 256 'Split the Setting Word to two Byte, Get the LSB Byte
' Get the SlaveDAC Voltage Setting Value,Vs=/Rm
fVtrn = Vsetm * fDACReference / 65535
fVtrn = 0 - ((fVset * (fMResistance + fSResistance) - fVtrn * fSResistance) / fMResistance)
fVtrn = fVtrn * 4096 / fDACReference 'The Slave DAC(MAX515) is 12bit DAC, Fullscale = 2^12 = 4096
Vsets = fVtrn
sbMSB = Msb(Vsets) 'Split the Setting Word to two Byte, Get the MSB Byte
sbLSB = Vsets - sbMSB * 256 'Split the Setting Word to two Byte, Get the LSB Byte
' Write the Setting to DAC
'Setp 1:
bSregister = bSregister And &b00001111 'Hold the Analog Switch Status and Setting the DAC to Write Mode
ShiftOut mbMSB;mbLSB;sbMSB;sbLSB;bSregister 'Write to Serial Bus
IO_REG_STB = 1 : WaitUs 10 : IO_REG_STB = 0 'Update the Control Shift-Register, DAC tobe Write
'Setp 1:
bSregister = bSregister + &b10000000 'Hold the Analog Switch Status and Setting the DAC to Update
ShiftOut mbMSB;mbLSB;sbMSB;sbLSB;bSregister
IO_REG_STB = 1 : WaitUs 10 : IO_REG_STB = 0 'Update the Control Shift-Register, DAC tobe Update
Return 0
End Function
'///////////////////////////////////////////////////////////////////////////////////////////////////
' ADC No-line Error Adjuest
'///////////////////////////////////////////////////////////////////////////////////////////////////
Function Getinlerr(fVoltage As Float) As Float
fVtrn = fVoltage
fVset = fVtrn * fVtrn * Quadratic - fVtrn * Linear + Constant
Return fVset
End Function
'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
'Self Test Code
'///////////////////////////////////////////////////////////////////////////////////////////////////
Interrupt Urxc(),Save All
Local uVseth As Word
Local uVsetl As Word
'Local uMSBh As Byte
'Local uLSBh As Byte
'Local uMSBl As Byte
'Local uLSBl As Byte
Local bMSB As Byte
Local bLSB As Byte
Local bRebtype As Byte
Local bSett As Byte
InputBin tTxt
tCmd = Mid(tTxt, 1, 3)
If tCmd = "STV" Then
tm = Mid(tTxt,4,4)
uVseth = Val(tm)
tm = Mid(tTxt,8,4)
uVsetl = Val(tm)
fVtrn = uVseth
fVtrn = fVtrn * 10000
fVtrn = fVtrn + uVsetl
tm = Mid(tTxt,12,1)
bSett = Val(tm)
If bSett = 0 Then
fSetting = fVtrn
bUartset = 1
End If
If bSett = 1 Then
fCalsacles = fVtrn
bUartset = 1
End If
End If
If tCmd = "STS" Then
tm = Mid(tTxt,4,1)
If tm <> "x" Then bDigitaLoop = Val(tm)
tm = Mid(tTxt,12,1)
If tm <> "x" Then bRun = Val(tm)
tm = Mid(tTxt,11,1)
If tm <> "x" Then bRefsource = Val(tm)
bUartset = 2
End If
If tCmd = "REB" Then
tm = Mid(tTxt,4,1)
bRebtype = Val(tm)
Select Case bRebtype
Case 0 ' Readback Measure Value(0-?)
Case 8 ' Readback Cal
Case 9 ' Readback Setting Status
End Select
End If
Enable Interrupts
End Interrupt
$Include "k12864drv.bas"
$Include "..\font1.bas"
$Include "..\font2.bas" 本帖最后由 lilith 于 2013-1-25 17:44 编辑
上面的 k12864drv.bas 是屏的驱动,连同字体码表在我的帖子
http://www.amobbs.com/thread-5487162-1-1.html
有,就不再帖了;原理和部分程序注释上一版帖子也有,所以也就不再重复赘述啦 {:lol:} 也算是电压表吧,也算是牛人吧。 显示屏是不是自己换的红色背光。 仪器不错 basic搞AVR……强大! 显示屏是不是自己换的红色背光。 很漂亮,精度也够高的了 我做了一个数控电源也是用的MAX541,但是这个是没有输出缓冲器的,直接用的误差不是很大。最近我那个电源调试了一点,因为单点接地的问题还是有点误差,恒压恒流的时候都有误差,更改了接地线以后精度终于达到了预期的效果。{:smile:} 不错哈~~~~ 精密电源啊~~ 佩服!强 大神、、膜拜。。。。 很不错的东东。
顶!
楼主您能给将一下你这个PCB在布线过程中单点接地以及地的问题能给讲一下吗?我做的两版数控电源都是因为单点接地的问题会有误差。{:mad:} 看那个显示的初始化过程感觉像台pc机,很骚包{:lol:} 这设备挺好的,真不错!
这个是你以前的电路,第一次见你这个电路的时候,感觉很别扭
现在想不通这样做有啥用,你的目的的:频率补偿?降低带宽来降低噪声?
Cc的零点很低,在Cout引入的极点抵消。最后在高频处回路的相位裕度很小!!
你如果是要降低带宽来降低噪声?消除Cout引入的极点,那把Cc去掉,Rc搞个50欧就行了 {:smile:}此贴必火,收藏。 或者ad588中的这个电路 PCBBOY1991 发表于 2013-1-25 21:09 static/image/common/back.gif
楼主您能给将一下你这个PCB在布线过程中单点接地以及地的问题能给讲一下吗?我做的两版数控电源都是因为单点 ...
电压电流采集端,画pcb时可以模拟“开尔文流量法”
说简单点就是不要让其他无关的电流在‘信号线’上流过,而让它流回地去 475627406 发表于 2013-1-25 22:31 static/image/common/back.gif
电压电流采集端,画pcb时可以模拟“开尔文流量法”
说简单点就是不要让其他无关的电流在‘信号线’上流 ...
今天测试的时候我还发现一个问题,本来在OPA177构成的差分放大器(对电压输出进行运算到0~2.5V)和DA出来的电压分别加在另外一个OPA177的反相端和同相端,模拟电路部分和春风的第二版几乎一样。
U11A和U11B我用的OPA177,U11B(OPA177)的输出端到U11A(OPA177)的反相端本来我接的是1。9K欧的电阻(整个电路的微调电容和春风的一样),在空载的时候电压值和设定值一样,但是一旦负载变大后,输出电压下降了大概10mV,然后我测得R21两端有压降,已经不符合工作在线性放大输入电阻为无穷大的理论了,然后我换成2.7K,5%的电阻后,无论设定多少电压,负载电流多大,输出压降就有1~2mV,我确保差分电路没有问题,可能出在U11B到U11A之间上。能给解释下吗。 PCBBOY1991 发表于 2013-1-25 22:48 static/image/common/back.gif
今天测试的时候我还发现一个问题,本来在OPA177构成的差分放大器(对电压输出进行运算到0~2.5V)和DA出来 ...
虽然op177的Iib比084大,但在R21上应该还表现不出来
“无论设定多少电压,负载电流多大,输出压降就有1~2mV”这个够怪异
你测u11a两个输入端电压差为多少?应该很小
再测下R20上是否有电压降 等待出套件,LZ什么时候出套件? 电压基准够奢侈的 程控电压源,楼主牛B,还两台6581,好想去你家抢劫{:funk:} 楼主照片啥手机拍的,爱疯四吗{:lol:} 本帖最后由 marshallemon 于 2013-1-25 23:36 编辑
475627406 发表于 2013-1-25 22:13 static/image/common/back.gif
这个是你以前的电路,第一次见你这个电路的时候,感觉很别扭
现在想不通这样做有啥用,你的目的的:频率补 ...
电压跟随,也为了接容性负载稳定把 475627406 发表于 2013-1-25 22:13 static/image/common/back.gif
这个是你以前的电路,第一次见你这个电路的时候,感觉很别扭
现在想不通这样做有啥用,你的目的的:频率补 ...
降低带宽来降低噪声?
--------------
是的,你都说了,其实是我不知道要如何才能降低电路中的噪声,所以用了这样糟糕的办法限制带宽来降低噪声 {:sweat:}至于是否有效,我刚买了一台动态分析仪准备测试这个问题,谁知道(动分)才到手第二天就挂了 {:cry:} marshallemon 发表于 2013-1-25 23:34 static/image/common/back.gif
电压跟随,也为了接容性负载稳定把
这个结构出现了几个地方,其中 2400 的 Vin/Ref in 是这样的缘故,因为它们都是开关电容输入(用动分或示波器以很低频率很大增益和动态范围能看到这个抖动),需要一个驱动(这个电路在 2440 手册上也有);但在两个 DAC 基准和最终电压输出 buff 上,只是为了降低噪声而已,不过是否有效还待测量,而杯具的是测量这个问题的动分给我挂掉了 {:funk:} lilith 发表于 2013-1-25 23:47 static/image/common/back.gif
这个结构出现了几个地方,其中 2400 的 Vin/Ref in 是这样的缘故,因为它们都是开关电容输入(用动分或示 ...
出套件不?我对你这个期待很久了 PCBBOY1991 发表于 2013-1-25 21:09 static/image/common/back.gif
楼主您能给将一下你这个PCB在布线过程中单点接地以及地的问题能给讲一下吗?我做的两版数控电源都是因为单点 ...
25 楼的解释很好了,对于直流电压源类电路而言,单点接地其实就是考核每一个地线上的电流,把每一个地线视为一个电阻,看看这些电流在这个电阻上产生的压降有什么影响,比如反馈回路和电压参考回路,他们的地基准点应该是你的负载,如果你放到电源里边去,那肯定有问题;可是我们是没有办法把反馈回路和电压参考回路的地基准点丢到负载上的,因为负载通过引线和电源链接嘛,那么就要补偿这个引线上产生的电压降了。
在完善了接地布局之后,补偿导线上的压降的方法,可以参考一下 HP 662x 系列电源的手册,我找找看 marshallemon 发表于 2013-1-25 23:51 static/image/common/back.gif
出套件不?我对你这个期待很久了
群里和好几个我经常厮混的论坛上都有很多人希望我能出套件,可是这里面有几个具体问题,
1、我没有那么多时间精力对付套件的问题,业余一点时间来嘀咕这个就很不够了,你看进度多慢 {:funk:}
2、最麻烦的就是,这个玩意如果没有校准是没有意义的,而校准它需要足够的仪器设备,因此实际上除非购买者有自己校准的能力,否则购买套件没有意义对吧。那么,也就是说我如果要发行它只能把它做成成品,调试、校准好才能出售,就好像本坛的 jj3055 那样,但这样对我的时间精力来说是做不到的。
这一次帮我绘制PCB 还在制作中提供了很多帮助的网友 TR 我曾经动员他发行套件或成品,不过他对此不是很有信心,这里面涉及到调试校准的步骤说实话比较烦人、主要是花时间,因此作为业余爱好自己嘀咕可能无所谓,否则就有点头疼了。jj3055 以前也通过阿莫兜售过他的 LTZ1000 基准,不过也是他自己焊接调试好并测试标定的,而且 LTZ1000 一般来说焊接好基本上没有太大问题需要调试,标定也只是很简单的事情;但我这个调试、校准是相对繁琐很多的事情 {:sweat:}
基本上我还是倾向于爱好者可以自制,反正源程序和电路原理图是完全公开的。当然有爱人士愿意发行套件我也是非常欢迎的事情 {:lol:}不过很显然的,发行者必须具有调试、校准它的能力对吧,也就是说至少需要可以观察(测试就算了)低频噪声的速度足够快的万用表(Agilent 3458 /Advantest 6581),以及校准线性的万用表(前面两者或其它 8 位半万用表)或相当仪器(KVD 也可以),以及校准准确度的电压基准设备(Fluke 732/734、4910 等)。
另外,网友 TR 不太乐意涉足套件的一个原因也是成本问题 {:sweat:} HYLG 发表于 2013-1-25 17:56 static/image/common/back.gif
显示屏是不是自己换的红色背光。
不是的唷,是买来就是这样的 {:lol:} kxm2008 发表于 2013-1-25 21:22 static/image/common/back.gif
看那个显示的初始化过程感觉像台pc机,很骚包
其实这个“初始化”其实是自检的过程本来没有的,我自己焊接好一块 PCB 调试的时候也很顺利,但网友 TR 焊接了几块 PCB,并把其中两块拿给我测试的时候,有一块不能正常工作,查了很久查不出原因,所以才写了这一大段用来自检的代码,发现了问题所在,又写了(今晚上)不少 Debug 代码,最终找到是一片 MAX515 有问题,其实这也是因为这些元器件全新购买非常昂贵(估计一两千、两三千软妹币可能需要),我用的几乎都是二手的拆机货,所以各种问题的缘故 {:curse:} 475627406 发表于 2013-1-25 23:10 虽然op177的Iib比084大,但在R21上应该还表现不出来 “无论设定多少电压,负载电流多大,输出压降就有1~ ...
除了那个R21其他的都符合运放虚短和虚短的理论,并且我把电阻改为2.7K后,两个运放输出和反向输入端也符合虚断了,然后测到的电压调整率很好了。我说的一到二毫伏是指在恒压模式下的空载与满载之间的电压降,也就是电压调整率。现在改电阻和把原来单点接地的问题用飞线解决后,精度已经很高了,这次真实积累了经验。电压采样我采用了远端补偿,这样以后电源采样点就可以在负载两端了,你可以参考下,对导线上的压降有很好的消除作用。 lilith 发表于 2013-1-26 00:07 其实这个“初始化”其实是自检的过程本来没有的,我自己焊接好一块 PCB 调试的时候也很顺利,但网友 TR ...
楼主你可以到美信那边去申请样片啊,我做的时候就是申请的 PCBBOY1991 发表于 2013-1-26 05:55 static/image/common/back.gif
除了那个R21其他的都符合运放虚短和虚短的理论,并且我把电阻改为2.7K后,两个运放输出和反向输入端也符 ...
电压调整率 = 从满载到空载时主运放输出电压变化范围/主运放的开环增益
你看,“开尔文流量法”
远端补偿{:dizzy:} ,没那么深沉{:smile:} marshallemon 发表于 2013-1-25 23:34 static/image/common/back.gif
电压跟随,也为了接容性负载稳定把
http://www.amobbs.com/thread-5514313-1-1.html
问题是这个电路最终稳定了没有的问题{:lol:} 楼主的显示屏是不是贴了一层纸啊? lilith 发表于 2013-1-25 23:45 static/image/common/back.gif
降低带宽来降低噪声?
在主要器件已经确定后,一个比较有效的方法就是降低带宽,同时增加的是电容,对直流性能不会有多大影响
你用的这个电路结构,带宽却没有降低
lilith 发表于 2013-1-25 23:53 25 楼的解释很好了,对于直流电压源类电路而言,单点接地其实就是考核每一个地线上的电流,把每一个地线 ...
单点接地的那个参考地我取的是AD,DA和电压基准的地,这些地线上的流过的电流很小,但是给运放供电,单片机和其他芯片工作电流流过的地是和这个分开的,这个我做的很好,我AD用的MX7705,带有差分输入端,很好。而电流检测的那个地(见原图)我没有接在基准,AD,DA的那个地,而是接在给运放供电的正负电源的地上,由于正负电源的到基准参考地之间导线上电流形成压降,对恒压恒流都有误差影响,当我把电流检测的地接在基准那边的参考地的时候,终于电流电压符合理论值了。 475627406 发表于 2013-1-26 09:28 电压调整率 = 从满载到空载时主运放输出电压变化范围/主运放的开环增益 你看,“开尔文流量法” 远端补偿 ...
在原理图上我懂,关键是PCB布线和单点接地的参考地的选择问题 明年有时间了,我也搞个这种类型的东西耍下
打算用这种结构
http://cds.linear.com/docs/cn/design-note/dn400f%20chs.pdf
475627406 发表于 2013-1-26 09:51 static/image/common/back.gif
明年有时间了,我也搞个这种类型的东西耍下
打算用这种结构
http://cds.linear.com/docs/cn/design-note/dn ...
是的,我用的就是这个结构呀,你这个图对带宽的抑制没我厉害 {:sweat:}
不过一个麻烦的地方是,并非这里只需要考虑直流性能,首先 LTC2400 一类 ADC 的 Vin、REF IN 是数十 KHZ 的一个开关电容输入,它对运放环路稳定性的影响需要考虑;其次,在自校准的时候,模拟开关(在本设计中)以大约 6-7HZ 速度切换,因此 ADC Vin 的跟随电路实际上的输入信号是一个幅度不确定,频率数 HZ 的信号,如果把电路带宽抑制到比数 HZ 更低,那显然也是不行的对吧 {:sweat:} 所以到底应该怎么取舍,我也在头疼。
如果电路不稳定,可以用动分观察到这个现象,杯具的是前几天它挂了 {:funk:}
Top -60dBV,Bottom -160dBV,10dBv/Div;Freq 大约 1.2HZ lilith 发表于 2013-1-26 11:08 static/image/common/back.gif
是的,我用的就是这个结构呀,你这个图对带宽的抑制没我厉害
不过一个麻烦的地方是,并非这 ...
大体结构差相同,只是2449内部有模拟开关。
降低电路带宽主要是减小电路中产生的噪声吧
对于输入,用滤波来解决呀。只要让这个滤波电路不影响其他电路工作就行了
动分,好像以前的公司有,从来没摸过
测试一级电路的性能,一个古老而又简单的方法,输入级注入方波(50hz就行),示波器测输出就行了
学习了,好东西。
50hz方波(方波就表示里面有大量高次谐波)注入,输出平滑,稳定后值准确
如果前面的骨头都啃得动
那你的“一个幅度不确定,频率数 HZ 的信号”那不是小菜么{:lol:}
要果你要这样测试,最好把那些值钱的、易坏的东西拆了,你搞坏了我可不赔{:sleepy:} 硬件自检是什么原理呢楼主 475627406 发表于 2013-1-26 12:03 static/image/common/back.gif
50hz方波(方波就表示里面有大量高次谐波)注入,输出平滑,稳定后值准确
如果前面的骨头都啃得动
那你的 ...
这个测过啦,我用 HP 3324A 产生的 7HZ(我的模拟开关切换频率大致是这么多)方波、正弦波、三角波、锯齿波都测试过的 {:lol:}不过动分挂了不好对比出入的畸变 {:cry:} 475627406 发表于 2013-1-26 11:44 static/image/common/back.gif
大体结构差相同,只是2449内部有模拟开关。
降低电路带宽主要是减小电路中产生的噪声吧
降低电路带宽主要是减小电路中产生的噪声吧
对于输入,用滤波来解决呀。只要让这个滤波电路不影响其他电路工作就行了
不不不,我又不在乎速度,输入噪声就算比较大(其实 LTC2400 这颗 ADC 的本底噪声也挺大)也可以用数字滤波解决,我倒不是很在乎(相反你用滤波电路的话也要考虑响应速度的问题,因为这里的噪声频谱是 0.1HZ-10HZ,你可以想想电路的响应);关键是输出噪声,不是指 ADC 输出的 Code,这个数字滤波等着它呢,是说我这个东西本身就是要输出一个可指定的电压,而这个电压的噪声才是最糟糕的事情,因为这是很难解决的 {:cry:} PCBBOY1991 发表于 2013-1-26 12:33 static/image/common/back.gif
硬件自检是什么原理呢楼主
其实这个自检就是因为帮我完成这个设计的网友 TR 自己焊接的 PCB 送过来给我测试的时候发现不能工作,在排查不出问题的情况下我写了一些检测抹泥板那边一些受控器件是否正确工作的代码,具体说就是
1、启动 ADC,然后判断 ADC 读忙状态和周期,看看 ADC 有没有工作,有工作那么读忙周期就是 167ms
2、1 通过后,将模拟开关接地,判断 ADC 返回值是否为 0(有一定容差),目的是看模拟开关是否正确工作,ADC 是否正确响应输入电压
3、同 2,模拟开关接 7V 内基准,看返回值是否在一个约定的范围内
4、以上通过,开始测试 DAC,发送 0x0000,ADC 回读(此时也可以用外部万用表测试),看看 DAC 输出是否为 0V(有一定容差)
5、发送 0xff00,看是否为约定的值(有一定容差)
6、发送 0x0080 (检查副 DAC,它输出的电压是负值)看是否为约定的值(有一定容差)
7、发送 0x00ff(检查副 DAC,它输出的电压是负值)看是否为约定的值(有一定容差)
以上通过就认为没问题,如果有不通过的,进入 Debug 模式,Debug 模式循环以上步骤,且增加 0 步骤为抹泥板控制寄存器(HC4094)检查,步骤之间有几秒停顿,可以用万用表依次检查 lilith 发表于 2013-1-26 13:04 其实这个自检就是因为帮我完成这个设计的网友 TR 自己焊接的 PCB 送过来给我测试的时候发现不能工作,在 ...
OK,大概了解了 学习....有机会一定要copy一下.......{:lol:} 屏很漂亮,楼主的界面布置得也很漂亮,能介绍下这屏吗? 谢谢楼主的分享。 楼主的LCD屏也很漂亮 楼主能不能传个PDF版的原理图?图片版的放大后看不清了,对双DAC电压合成部分感兴趣。 lz有空麻烦将这次的原理图发个pdf,3楼发布的图没法看清楚. 楼主的LCD在哪里买的?看起来很像OLED啊! 工程师030 发表于 2013-1-26 22:52 static/image/common/back.gif
楼主的LCD在哪里买的?看起来很像OLED啊!
楼上几位,这个屏只是一个普通的红色背光 TN LCD,可视角度也很窄的,只是在这个视角上看上去还行,稍微偏一点就看不见了,还不如这种没有背光的普通 LCD,你们要是去买了恐怕要把我骂死 {:funk:}
wzavr 发表于 2013-1-26 22:44 static/image/common/back.gif
lz有空麻烦将这次的原理图发个pdf,3楼发布的图没法看清楚.
我用的绘制电路图软件无法导出 PDF {:sweat:}不知道为何 PNG 格式文件上传后会缩小,我打一个压缩包吧
lilith 发表于 2013-1-27 17:11 static/image/common/back.gif
楼上几位,这个屏只是一个普通的红色背光 TN LCD,可视角度也很窄的,只是在这个视角上看上去还行,稍微 ...
哈哈……楼主好心人啊!看出来了,还是不带背光的好! 本帖最后由 lilith 于 2013-1-27 17:28 编辑
dreampet 发表于 2013-1-26 22:35 static/image/common/back.gif
楼主能不能传个PDF版的原理图?图片版的放大后看不清了,对双DAC电压合成部分感兴趣。 ...
不知道为何会缩小,我刚才发了一个压缩包你看看,另外我把 DAC 电压合成部分单独截上来了,其实就是把主 DAC 和副 DAC 的输出电压经过两个电阻进行叠加,这个应该很熟悉吧,运放(加法)上有说过的,Vo=V1*R2+V2*R1/(R1+R2),你可以看我的程序里 Setvoltage 函数就是根据这个公式写的。注意这个公式是根据电流导出的,也就是说输出缓冲运放的 Ib 会对 Vo 造成一定的影响,不过在这里,Vmaster 对应的合成电阻 Rmaster 很小(实际取值 249 欧),因此运放 Ib 的影响是不大的;而 Ib 受影响较大的 RSlave 对系统的贡献被弱化了 Rs/Rm = 4016 倍,所以耶可以认为没有什么影响。并且,由于本设计是数字闭环的,也就是说最终输出电压会被纠正到 ADC 上,因此整个电路 DAC 部分的误差,都不是很重要。
实际电路中由于买不到 4M 电阻,Rm 取值为 249 欧姆,Rs 为 1M,TCR=100ppm、精度为 1%。这两个电阻的具体阻值需要在程序中声明
Const fMResistance = 2.49E+02 'DAC Voltgae Compound Resistance, the Master
Const fSResistance = 1E+06 'DAC Voltgae Compound Resistance, the Slave
SetVoltage 函数是根据这样的逻辑写的:
1、首先将 Vs(副 DAC 的 MAX515)预设为 -2.5V,然后求 Vm 的设定电压 Vm=/Rs
fVtrn = (fVtrn * (fMResistance + fSResistance) + fDACenter * fMResistance) / fSResistance <---
2、得到 Vm 设置值,它只有 16bit 分辨率,所以结果肯定略高或略低于被要求的 Vo,那么将 Vm 重新带入公式,得到完整分辨率下的 Vs
fVtrn = 0 - ((fVset * (fMResistance + fSResistance) - fVtrn * fSResistance) / fMResistance)
副 DAC 输出的电压依然是正的,电路中有一个 -1 倍放大器将其转换为负压,所以程序重要予以注意。这样就在硬件和软件上完成了两个电压的合成。
屏幕显示够骚,哈哈 楼主求惠普E66系列的电源手册啊 不错,{:smile:} 楼主太牛了,膜拜一下~~~~~~~~~~~ 你运气真好啊,这么多钽电容都没事,前些天俺的板子炸得那叫一个欢快,眼镜都给烧了几个小点点!
{:lol:} lilith 发表于 2013-1-27 17:12 static/image/common/back.gif
我用的绘制电路图软件无法导出 PDF 不知道为何 PNG 格式文件上传后会缩小,我打一个压缩包吧
...
如果装一个pdf模拟打印的驱动,只要软件支持打印输出的,就可以制作成pdf文件,不需要软件中有特意的一项pdf输出功能. 前面交流为什么不加个滤波器呢?作为仪表,加了会更好!{:lol:} 支持出散件套装!标定自己想办法,或者找JJ3055收费成批校准。。 gxluozhi 发表于 2013-1-28 17:01 static/image/common/back.gif
前面交流为什么不加个滤波器呢?作为仪表,加了会更好!
您看到的是没装壳、制作调试中的裸板,装壳进行完成调试的时候,就有装这个电源滤波器啦 {:lol:}
fsclub 发表于 2013-1-28 21:33 static/image/common/back.gif
支持出散件套装!标定自己想办法,或者找JJ3055收费成批校准。。
关于这个问题我和帮我做 PCB 的网友 TR 谈过,他表示提供 PCB 倒是没啥问题,套件这个是比较花精力的,我们都倾向于交给专业为爱好者提供各种套件服务的商家来做这个,具体怎么样我和他,还有一些淘宝上的 JS 们慢慢谈吧,或者坛里也有哪些 JS 愿意掺一脚?我很乐意,并且对于能自制并调试好的我可以在一定程度*上提供免费的校准(调试的功夫我就实在是抽不出来了),因为我也有兴趣收集我这个设计的可靠性样本 {:lol:}考虑到原材料成本和调试的精力,我想自己制作出足够样本数的样机显然不如让大家来做现实 {:shy:}
wzavr 发表于 2013-1-27 22:39 static/image/common/back.gif
如果装一个pdf模拟打印的驱动,只要软件支持打印输出的,就可以制作成pdf文件,不需要软件中有特意的一项pdf ...
这样出来的图是黑白的,看起来挺费劲呢,我还是传上来吧
PCBBOY1991 发表于 2013-1-27 19:22 static/image/common/back.gif
楼主求惠普E66系列的电源手册啊
E66?安捷伦现在不给下载了吗,对了 E66 是啥 {:funk:} lilith 发表于 2013-1-29 00:02 static/image/common/back.gif
这样出来的图是黑白的,看起来挺费劲呢,我还是传上来吧
哈哈,转换的结果有点奇怪,很多都黑白了,但是那几条粗线还是可以显示绿色的,
不过这样的pdf非常清晰,即使放大很多.
谢谢你. 学习,谢谢!!! 看着楼主的资料,热泪盈眶。。。 显示屏是亮点 {:3_46:}必须mark学习
PS:论坛为什么没有搜索某一个人所有发言的功能呢? lilith 发表于 2013-1-29 00:06 E66?安捷伦现在不给下载了吗,对了 E66 是啥
不是您在36楼说给传以下HP E66系列的手册么 此贴必火,楼主牛F(比牛B级别高几个数量级){:victory:} 看起来很漂亮 干净利落 牛人啊真是牛人 一定收藏了 请教一下楼主,LM399的输出电压变化范围有多大,我看datasheet上面是在6.75~7.3V之间,我看到你的基准电路里面,全部用的是固定电阻,难道说所使用到的LM399输出电压都是7.000V么?? dudududu 发表于 2013-6-25 10:40 static/image/common/back.gif
请教一下楼主,LM399的输出电压变化范围有多大,我看datasheet上面是在6.75~7.3V之间,我看到你的基准电路 ...
我想你问的是“LM399 电压分布范围”而不是“变化范围”。根据一些朋友的数据统计和我自己的统计,年份较早的 LM399 电压分布在 6.8V 附近,年份较新的在 7V 附近分布(2011-2012 年份)。你可以看一下我目前的几台样机的观测:
http://bbs.38hot.net/forum.php?mod=viewthread&tid=41988
里面有几个 399 的电压数据,最小的大约 7.012V,最大的 7.042V。
至于为何我的设计中没有可调电阻,因为我是设计为闭壳校准的,由单片机运算介入校准,自然不需要任何可调元件。同时,可调电阻的温度系数普遍很大,稳定性也不好,使用可调电阻要实现我的预设目标也是很难的。从上个世纪八十年代开始,仪表就普遍采用没有任何可调元件,完全依靠单片机内程序进行闭壳校准的高可靠方式设计了。 哦,了解了,我手里40个LM399,分布电压从7.025V开始到7.088V的都有,不用可调电阻的话,也就意味着每一台电压源,在程序上设置的参数都不一样了,是么? 楼主强啊,又是网站一大力作。 有营养的帖子要顶!!mark 来学习的,都是牛人啊, 有营养的帖子要顶!!mark lilith 发表于 2013-1-25 23:53
25 楼的解释很好了,对于直流电压源类电路而言,单点接地其实就是考核每一个地线上的电流,把每一个地线 ...
求联系方式 学习学习谢谢楼主资料
页:
[1]