ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

搭建介电温谱自动测试数据采集系统(主要设备高低温箱,安捷伦4294a阻抗测试仪)

2021-08-26 18:02:54  阅读:167  来源: 互联网

标签:安捷伦 4294a DMA 自动测试 DAC TIM InitStructure ADC GPIO


为实现电子元器件传感器阻抗特性的自动化测试,使用主控芯片统一统一控制附属各个设备工作

  1. 高低温箱:热电偶
  2. 多路开关继电器
  3. 阻抗测试设备
  4. 气体流量计

主要控制逻辑:测试不同温度下的被测样品的阻抗特性,并实时将记录上传至上位机保存

主要思路:使用恒流源为热电阻PT100供电,然后将其两端电压经运算电路映射到0-3.3V范围内供ADC采集,并获得足够的测试精度,单片机判断后接近设定值时,依次打开四路继电器,随机即发送命令要求阻抗仪测试,并传回测试数据,单片机获得数据后,将温度测试气体流量打包为一个数据帧发送至局域网,并设计命令接口,由上位机随时主动发送命令查询当前测试状态,防止测试人员不在现场时也能及时发现异常

硬件设计:

原理图设计:

单片机核心模块:

模拟部分:恒流源电路为热电阻供电,并将输出结果映射至模数转换器的输入范围,模拟电源使用磁珠与数字电源隔离,模拟地使用0欧姆电阻实现与数字地的单点连接

 

流量计控制器接口说明,使用mos管驱动两个继电器实现清洗阀控与关闭功能

 

 

 

 

 

 

多路继电器使用485接口控制分别发送不同命令打开各路,

 

 

 PCB设计:

 

 主要是模拟部分与数字部分分开,485的两根差分线尽量等长。

STM32主要函数设计:

1、二分法查表,此查表函数返回与当前数值最接近的温度值

 1 unsigned char half(float x, unsigned char* s, unsigned char len)
 2 {
 3     unsigned char i = 0,j,result,num = 0;
 4     j = len-1;
 5 
 6     while(1)
 7 {
 8        if (x <(s[(i+j)/2]))
 9         j = (i+j)/2;
10     else
11         i = (i+j)/2;
12     if (j-i ==1)
13     {
14         if((s[j]-x)>(x-s[i]))
15          {num = i;
16             result=s[num];
17             }   
18             
19         else
20          {num = j;
21              result=s[num];
22             }   
23         break;
24     }    
25     
26 
27     
28 
29 }     
30 return result;    
31     
32     
33 }

 

2、ADC,DAC的使用

  读取温度:

初始化ADC模式:

       uint16_t ADC_ConvertedValue;
1 GPIO_InitTypeDef GPIO_InitStructure; 2 3 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); 4 5 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; 6 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; 7 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; 8 GPIO_Init(GPIOC, &GPIO_InitStructure); 9 /*配置DMA,和ADC寄存器*/ 10 DMA_InitTypeDef DMA_InitStructure; 11 ADC_InitTypeDef ADC_InitStructure; 12 ADC_CommonInitTypeDef ADC_CommonInitStructure; 13 // ------------------DMA Init 结构体参数 初始化-------------------------- 14 15 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); 16 17 DMA_InitStructure.DMA_PeripheralBaseAddr = RHEOSTAT_ADC_DR_ADDR; 18 19 DMA_InitStructure.DMA_Memory0BaseAddr = (u32)&ADC_ConvertedValue; 20 21 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; 22 23 DMA_InitStructure.DMA_BufferSize = 1; 24 25 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 26 27 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; 28 29 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; 30 31 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; 32 33 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular ; 34 35 DMA_InitStructure.DMA_Priority = DMA_Priority_High; 36 37 DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; 38 39 DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; 40 DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; 41 DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; 42 43 DMA_InitStructure.DMA_Channel = DMA_Channel_0; 44 45 DMA_Init(DMA2_Stream0, &DMA_InitStructure); 46 47 DMA_Cmd(DMA2_Stream0, ENABLE); 48 49 //ADC结构体配置 50 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 , ENABLE); 51 // -------------------ADC Common 结构体 参数 初始化------------------------ 52 53 ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; 54 55 ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; 56 57 ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; 58 59 ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles; 60 ADC_CommonInit(&ADC_CommonInitStructure); 61 // -------------------ADC Init 结构体 参数 初始化-------------------------- 62 ADC_StructInit(&ADC_InitStructure); 63 64 ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; 65 66 ADC_InitStructure.ADC_ScanConvMode = DISABLE; 67 68 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; 69 70 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising; 71 72 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO; 73 74 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; 75 76 ADC_InitStructure.ADC_NbrOfConversion = 1; 77 ADC_Init(ADC1, &ADC_InitStructure); 78 79 ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 1, ADC_SampleTime_56Cycles); 80 81 82 ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE); 83 84 ADC_DMACmd(ADC1, ENABLE); 85 86 87 ADC_Cmd(ADC1, ENABLE);

启用DMA后转换完的ADC数值即存于ADC_ConvertedValue变量中,使用定时器触发

定时器配置

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);     
    TIM_TimeBaseStructure.TIM_Prescaler = 900;
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;
    TIM_TimeBaseStructure.TIM_Period = 10;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
    TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);
    TIM_Cmd(TIM2, ENABLE);    

DAC配置:DAC使用软件配置触发

 1   GPIO_InitTypeDef GPIO_InitStructure;
 2     DAC_InitTypeDef  DAC_InitStructure;
 3 
 4 
 5   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);    
 6 
 7   RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
 8 
 9   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_4;
10   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
11   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
12     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;  
13   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
14   GPIO_Init(GPIOA, &GPIO_InitStructure);
15 
16   DAC_InitStructure.DAC_Trigger = DAC_Trigger_Software;                        
17   DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;    
18   DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;    
19 
20     DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_TriangleAmplitude_4095;
21   DAC_Init(DAC_Channel_1, &DAC_InitStructure);
22   DAC_Cmd(DAC_Channel_1, ENABLE);

 

3、与485接口的通信

485使用 串口2通信:

初始化函数配置PB10 PB11管脚为usart2,并配置串口2

主要发送函数:

 继电器控制命令为,每个命令的执行为打开对应路,并关闭其他路:

1 u8 open1_cmd[4] ="*A1#"; 
2 u8 open2_cmd[4] ="*B2#"; 
3 u8 open3_cmd[4] ="*C3#"; 
4 u8 open4_cmd[4] ="*D4#"; 
为了方便访问定义为2维数组
unsigned char open_cmd[][5]={"*A1#", "*B2#", "*C3#","*D4#"};

 

 1 void send_uart2(char *p)
 2     
 3 {    u8 i =0;
 4     
 5     while(i<strlen(p))
 6     {     
 7         USART2->DR=p[i];
 8         
 9         while((USART2->SR&0X40)==0);
10         
11         i++;
12     }
13             
14 }

 

4、与阻抗仪的通信,查询仪器使用手册查得主要使用功能命令为:

/*主要使用命令为*/
频率设定:WrtCmd(“FREQ 1KHZ”)
WrtCmd(“FUNC:IMP RX”);
WrtCmd(“TRIG”);
WrtCmd(“FETC?”);

 单片机使用UART4访问同惠232串口,初始化函数配置PC10 PC11管脚,启用串口4;

定义以上命令为字符串:

 


u8 set_fre[]=“FREQ 1KHZ”;
u8 set_fun[]=“FUNC:IMP RX”;
u8 trig[]=“TRIG”;
u8 fetch[]=“FETC?”;


void send_uart4(char *p) { u8 i =0; while(i<strlen(p)) { UART4->DR=p[i]; delay_us(100); while((UART4->SR&0X40)==0); i++; } }

发送以上命令后仪器会返回测试结果数据:

说明书给出的测试结果格式为:<DATA A>,<DATA B>格式: <DATA A>(主参测量数据),<DATA B>(副参测量数据)结束符

例如:b'+5.11094E+03,-1.19979E+05,+0\r\n' 以字节流形式返回

使用串口4接收此字节流

 

 1 void UART4_IRQHandler(void)
 2 {
 3   uint8_t ucTemp;
 4     
 5     if(USART_GetITStatus(UART4,USART_IT_RXNE)!=RESET)
 6     {        ;
 7         
 8     ucTemp = USART_ReceiveData(UART4);
 9     data4[u4_num] = ucTemp ;
10     u4_num++;        
11         if(ucTemp=='\n')
12         { data4[u4_num] = ucTemp ;
13             USART_ITConfig(UART4, USART_IT_RXNE, DISABLE);
14                 u4_finish_flag=1;
15         }        
16     }     
17 
18 } 

 

 

 

5、打包向上位机发送数据

 1 res = half(tem_value,tem, strlen(tem));
 2         if(tem_value-res<0.5)
 3         {    
 4             for(i=0; i<4; i++)
 5             {
 6             send_uart4(open_cmd[i])
 7             send_uart4(trig);
 8             send_uart4(fetch);
 9             while(u4_finish_flag==0);
10             data4[u4_num] = res ;
11             u4_num = 0;
12             send_usart1(data4);
13             
14             
15             } 
tem_value即为当前温度值,当此温度值与标准值小于设计误差时触发四路测试并将结果返回、

 

 python 上位机设计

 主循环中接收数据并存入excel中

 1 import xlwings as xw
 2 import time
 3 import socket
 4 import tkinter
 5 import time
 6 import win32api
 7 from tkinter import filedialog
 8 import os
 9 
10 #GetValue = rng.Cells(rng.Cells.Count).Value 访问单个单元格
11 import sys 
12 sys.setrecursionlimit(1000000)
13 root = tkinter.Tk()
14 root.minsize(1000, 600)
15 root.title('lxy')
16 global file_path
17 ser = serial.Serial('COM3', 9600, timeout=1)
18 
19 global number
20 global colnum
21 colnum=1
22 global wb
23 global sht1
24 global fig
25 
26 
27 def select():
28     global file_path
29     file_path = filedialog.askdirectory()
30     file_path = file_path.replace('/', '\\')
31 
32 def read():
33     global file_path
34     global colnum
35     global number
36     global fig
37     Cp=[]
38     D=[]
39     fre=[]
40     sampleName = en1.get()
41     path = os.path.join(file_path, sampleName)
42     wb = xw.Book(os.path.join(file_path, 'Cp.xlsx'))
43    
44     sht1 = wb.sheets[0]
45     while(1):
46         data = ser.readline()
47         tem = a[-1]
48         data = a.decode(encoding="utf-8")
49         R = data.split(',')[0]
50         X = data.split(',')[1]
51         sht1.cells(colnum,1).value = tem
52         sht1.cells(colnum,2).value = R
53         sht1.cells(colnum,3).value = X
54         colnum=colnum+1
55 
56     
57     
58 b1 = tkinter.Button(root, text='文件夹', font=('times new roman', 24), command=select)
59 b2 = tkinter.Button(root, text='测试', font=('times new roman', 24), command=test)
60 b3 = tkinter.Button(root, text='获取数据', font=('times new roman', 24), command=read)
61 en1 = tkinter.Entry(root, text='起始', font=('times new roman', 24))   
62 b1.place(x=0, y=100, width=200, height=100)
63 b2.place(x=210, y=0, width=200, height=100)
64 b3.place(x=510, y=0, width=200, height=100)
65 en1.place(x=0, y=0, width=200, height=100)      
66 
67 root.mainloop()

 

标签:安捷伦,4294a,DMA,自动测试,DAC,TIM,InitStructure,ADC,GPIO
来源: https://www.cnblogs.com/liuboyan/p/15187153.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有