|
基于【EVAL-ADICUP360】的毫欧计-项目提交
[复制链接]
本帖最后由 fxyc87 于 2022-11-2 16:07 编辑
基于【EVAL-ADICUP360】的毫欧计
作者:EEWORLD_fxyc87
- 作品简介
- 工作中遇到过几次电脑板损坏,表现为电源短路,也不太好查出是哪个地方短路。如果有红外热成像应该很好查出来,但这成本较高,如果有毫欧计,就能根据短路点的对地电阻进行比较,准确测量出短路点的位置。当然这就要求毫欧计测量误差小,稳定,至少能到0.1毫欧级别。所以用ADUP360这款带有24位ADC的芯片就很方便了。该芯片自带24位ADC,并且有4个IO可以精准输出电流源。最多同时2路同时输出。共有8路外部ADC通道。两路ADC组件。参见下图:
- 系统框图
-
- 主芯片输出2路电流源,两路电流源可以独立配置,从10uA-1mA可以自由配置。用于适配这毫欧级别电阻至千欧级别。测量采用4线制开尔文夹,这样能有效的消除线阻带来的影响响。然后测量结果通过串口传到PC端,由上位机负责显示。
- 硬件说明
- 下位机
-
#include "ADuCM360.h"
#include "DioLib.h"
#include "DacLib.h"
#include "AdcLib.h"
#include "IexcLib.h"
#include "UrtLib.h"
#include "DmaLib.h"
#include "string.h"
#include "stdio.h"
char uart_tx_bf[256];
uint32_t sysTick=0;
uint32_t delayCount=0;
uint32_t ad;
void PrintStr(); //打印发送缓冲区的字符串
int main(void){
SystemCoreClockUpdate(); //SystemCoreClock
SysTick_Config(SystemCoreClock/1000);
//串口配置==============================
UrtCfg(pADI_UART,B115200,COMLCR_WLS_8BITS,0);
//p0.1 p0.2 uart模式 只有一个UART,可分配有两块引脚上。 p0.6/p0.7
DioCfgPin(pADI_GP0,PIN1,3);
DioCfgPin(pADI_GP0,PIN2,3);
//紫色LED灯 输出模式
DioDrv(pADI_GP0,BIT4,0,0);
//电流源配置==============================
//掉电关,参考源选择内部,输出0选AIN7,输出1选择AIN6
IexcCfg(IEXCCON_PD_off,IEXCCON_REFSEL_Int,IEXCCON_IPSEL1_AIN5,IEXCCON_IPSEL1_Off);
//电流源200uA,辅助10uA禁用 电流源可配置为0.01mA-1mA AIN4/5/6/7可配置为电流源输出
IexcDat(IEXCDAT_IDAT_1mA,IDAT0Dis);
//AD1引脚配置==============================
//ad1 -AIN1 +AIN3
AdcPin(pADI_ADC1,ADCCON_ADCCN_AGND,ADCCON_ADCCP_AIN0);
//ADC配置 外部参考源
AdcRng(pADI_ADC1,ADCCON_ADCREF_INTREF,ADCMDE_PGA_G128,ADCCON_ADCCODE_UINT);
//ADC零点校准
AdcGo(pADI_ADC1,ADCMDE_ADCMD_INTOCAL);
while((AdcSta(pADI_ADC1)&(1<<5))==0); //bit5 or ADCxSTA_CAL
AdcGo(pADI_ADC1,ADCMDE_ADCMD_SINGLE);
while(1){
if(delayCount==0){
DioTgl(pADI_GP0,BIT4);
delayCount=500;
}
if(AdcSta(pADI_ADC1)&1){ //bit0 or ADCxSTA_RDY
ad= AdcRd(pADI_ADC1);
sprintf(uart_tx_bf,"%d\r\n",ad);
PrintStr();
AdcGo(pADI_ADC1,ADCMDE_ADCMD_SINGLE);
}
}
}
void PrintStr(){ //打印发送缓冲区的字符串
char * ptr=uart_tx_bf;
while(*ptr){
UrtTx(pADI_UART,*ptr);
ptr++;
while((UrtLinSta(pADI_UART)&COMLSR_THRE)==0);
}
}
void SysTick_Handler(){
sysTick++;
if(delayCount>0)
delayCount--;
}
//end
- 上位机
-
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;
using System.Reflection.Emit;
namespace Aducm360毫欧计
{
public partial class Form1 : Form
{
List<string> bf = new List<string>();
int offset;
int LastAD = 0;
SerialPort port;
public Form1()
{
InitializeComponent();
}
private void btnRefresh_Click(object sender, EventArgs e)
{
ReloadComs();
}
void ReloadComs() {
cmbCom.Items.Clear();
cmbCom.Items.AddRange(SerialPort.GetPortNames());
if (cmbCom.Items.Count > 0)
{
cmbCom.SelectedIndex = 0;
}
}
private void Form1_Load(object sender, EventArgs e)
{
ReloadComs();
}
private void btnConnction_Click(object sender, EventArgs e)
{
if (cmbCom.Text == "")
return;
if (port != null&&port.IsOpen)
port.Close();
port = new SerialPort(cmbCom.Text);
port.BaudRate = 115200;
port.DataReceived += Port_DataReceived;
port.Open();
}
private void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
bf.Add(port.ReadExisting());
var temp = new string(bf.SelectMany(n => n).ToArray());
if (temp.EndsWith("\r\n")) {
var temp2 = temp.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
try
{
var num= UInt32.Parse(temp2.Last());
//128
LastAD =(int) num;
bf.Clear();
}
catch { }
}
}
private void timer1_Tick(object sender, EventArgs e)
{
if (LastAD == 0x001FFFFF)
{
labAD.Text = "开路";
labRes.Text = "开路";
return;
}
var new_value = LastAD - offset;
labAD.Text = LastAD.ToString();
labCal.Text = new_value.ToString();
var res = 1200.0f / (float)0x001FFFFF * new_value; //mV
//实测电流 1.081mA
labRes.Text =(0.001081f*res).ToString("0.0000毫欧 ")+ res.ToString("0.0000毫伏"); //1.081*r=v
}
private void btnZero_Click(object sender, EventArgs e)
{
offset = LastAD;
}
}
}
- 总结
|
|