中国汽车设计网
设计资讯 | 汽车图库 | 招聘会 | 车友论坛 | 汽车人才招聘 |
发新话题
打印

[部品试验] 基于C++ Builder的自动变速器电控单元实车试验数据采集系统

基于C++ Builder的自动变速器电控单元实车试验数据采集系统

液力自动变速器是将车速和节气门开度等车辆的状态信号作为电控单元(ECU)的输入信号,经电控单元识别判断处理后,根据换档规律,发出信号给相应电磁阀,利用电磁阀控制油压回路,通过控制油路的通/断(ON/OFF),使各档的变速阀动作,完成变速控制。3 N, h' [& i! A
! W! L$ W( f7 X
  图1为自动变速箱ECU开发的简略技术路线图。自动变速器半实物仿真试验台采用硬件在回路(hardware-in-loop)技术建立,该试验台可模拟自动变速器电子、液压和与此对应的车辆行驶状态,可比较全面的对电控单元进行信号分析、多工况系统仿真,以此进行ECU开发并获得初步的换档规律和控制策略。本文论述的电控单元实车试验数据采集系统作为自动变速器车载分析试验台的核心部分,将采集与存储实车运行过程中ECU各输入输出信号。这样可通过采集的数据发现自开发ECU在功能性、换档规律和换档品质等方面的缺陷,通过对得到的试验结果进行相应的分析,从而提出较好的控制策略,提出改进方案。所以,开发性能较好的电控单元实车试验数据采集系统是对于整个ECU开发工作是必不可少的。
) h* {- Q$ B; }9 H6 s' P, y# ^1 G
6 ~4 t. Y0 d$ r4 T& }3 L6 f: ?# u4 e. m: x( d  v

6 L- z6 Q; w) N3 [- L: r$ E  2 数据采集系统硬件结构
# d  C, _; r4 d' h# T, p) f; b  u& R; F0 ]5 z
  本数据采集系统硬件结构框图如图2。数据采集系统采集的信号包括从自动变速器ECU引出的所有输入、输出信号。这些信号主要有三种形式,即模拟信号、数字信号和脉冲信号。其中模拟信号和数字信号经过幅值转换等简单的调理之后就可以分别引入数据采集卡的模拟信号输入口和数字信号输入口,而脉冲信号需经过信号调理模块中的F/V信号转换电路将脉冲信号转换为标准的电压信号,然后作为模拟信号输入来采集。研华公司的数据采集卡PCL-818L可以16通道单端模拟信号输入采集,12位A/D转换和16通道数字信号采集,加上PCL-726数据采集卡提供的数字信号输入采集端口,能够满足系统的要求。最后使用工控机作为控制的主体,用以运行数据采集程序。2 e$ b! n! A# H4 m9 A6 e

( W0 F- |2 X2 t0 _8 U" p$ K, T& `% H( `4 x' v0 U  j

" V+ W0 N2 D2 w% q! k3 O  3 数据采集系统软件程序的编制1 E1 j6 q% {! p6 Z
  G# |  H% b# S  w: @+ y$ l
  3.1数据采集程序流程+ ^: t$ o" C7 j
( @9 I& d: h1 W; N9 X. W* v
  本程序采用Borland C++ Builder编写,Borland C++ Builder以其丰富的可视化组件库(VCL)而使程序的编写显得非常容易。根据要求,本系统采集程序的流程图如图3:
# v& t% `: s! a2 V
' p6 T) m4 U" L( G- }9 y9 {9 _- `5 K! t- G( b8 ?) t* d( E& H* v

8 J& d9 F/ V  X2 t, q1 U  程序采集开始调用多媒体定时器给每次采集循环定时。由于自动变速器ECU对各管脚信号每25ms扫描一次,所以对于ECU实车试验数据采集系统的采样频率要求并不高,因此我们把多媒体定时器定时为10ms,即每10ms采集一组信号数据,其中包括17个数字量、6个模拟量和2个经过F/V转换的频率量,并完成数据存储。  U2 z$ A+ Y$ I5 l/ A8 q* J
" S6 Y5 v+ F4 P3 S5 G: z$ Z
  3.2模拟量、数字量采集子函数5 z1 ^: @1 b. a
) E% a2 J7 l2 D; Y
  在确定了采集程序的程序框图和界面之后,就要着手编写采集中最重要的两个子函数了,即模拟量和数字量采集子函数。厂家提供的动态连接库(DLL)中包含了进行数据采集操作的C/C++函数,在C++Builder下可对这些函数进行调用,就可以很方便的对数据采集系统进行设置、采样和数据处理。以下通过对模拟量的采集来概要说明。8 E- G. e3 o( B3 J1 q

, U; p2 `# d6 e- F  使用时先在程序中声明,即把含有函数声明的.h文件包含在程序体中。然后利用项目管理器将包含函数实体的.lib文件加入到项目中。这样在程序体中就可以调用其中的函数了,具体的模拟量数据采集子函数代码如下:
5 t- E" L3 ?) Y/ z7 f( }  float readvoltage(int device,int channel)              //参数为设备号、通道号
4 G7 O4 I; I; H# c' h  { ………………                            //变量定义、说明等, O1 x) o  O6 q: ?! }& K. S4 u" R
  lDevNum=device;
" @4 J; e3 u6 w4 B  usChan=channel;1 _" k# d6 K+ X9 g+ b
  dwErrCde = DRV_DeviceOpen(lDevNum, &lDriverHandle);  //打开设备; r* \1 \2 C5 t0 }+ a
    if (dwErrCde != SUCCESS)
3 {/ w5 q# s0 y    { ErrorHandler(dwErrCde);}
8 q+ a" R  |6 \* x; i  ptAIConfig.DasChan = usChan;  //配置设备; l9 _( Q2 J+ u$ i4 n+ p* l3 C( x, _
ptAIConfig.DasGain = 0;
  v4 W1 E: g2 J2 J8 [  dwErrCde = DRV_AIConfig(lDriverHandle, &ptAIConfig);
% q% |4 M4 B- E5 n: X. h6 g  if (dwErrCde != SUCCESS)
" m0 {$ o* v* ?; {1 G  { ErrorStop(&lDriverHandle, dwErrCde);}
; a$ [$ E) }1 G3 n% g  ptAIVoltageIn.chan = usChan;                         //读一个数据8 D; [: @  \" g& A4 M
  ptAIVoltageIn.gain = 0;                  
& |- O+ u8 L/ n/ v( j  ptAIVoltageIn.TrigMode = 0;             `3 H% n, m" Z" f0 s: O
  ptAIVoltageIn.voltage = &fVoltage;      7 t# r& t$ O, H0 m0 `
  dwErrCde = DRV_AIVoltageIn(lDriverHandle, &ptAIVoltageIn);
; ~1 Y! W7 G1 _- A0 K' E  if (dwErrCde != SUCCESS)/ s# M# i, {; E/ M' b; P- H- v  L
  { ErrorStop(&lDriverHandle, dwErrCde);}! k: h) Z, \1 @* z! g8 r
  dwErrCde = DRV_DeviceClose(&lDriverHandle);         //关闭设备
8 V4 \: b7 E0 o  if (dwErrCde != SUCCESS)
" s9 N/ z% `  h' o% E5 i7 n  { ErrorStop(&lDriverHandle, dwErrCde);}
" t- x5 q3 v0 Y+ B! O  return fVoltage;                                     //返回采集数据" Z; G5 X- D% ?& T3 ]. s" [
  }7 U$ \" C, Q  H- H6 A- I5 A  P* ~' @
  , [. ]8 G! p# }$ s4 {- M: s
   同理,数字量采集子函数也是类似的操作。 ( P4 L+ Q( R4 a1 U2 W$ x- S+ a
3 U; l3 O" T6 y% W
+ P0 ~6 @$ d% |4 o
  3.3多媒体定时器
2 D$ ]2 ^. q- j$ h
0 I8 c2 k1 v  l+ V* m  由于多媒体定时器具有很好的实时性和较高的优先级,最高定时可达1ms,所以我们这个数据采集系统采用多媒体定时器来定时。需要的系统资源为:#include ;在borland环境下首先需要将winmm.lib文件通过implib命令转化为borland下的格式,然后将相应的lib加到工程里。具体的多媒体定时器代码如下:
) r, A; W) I$ @- ]/ a& X  void start_timer(double m_time_val)        //启动多媒体定时器,m_time_val的单位是秒
: M$ B: O2 A5 [( U8 i; l  { TIMECAPS TC;
( a& @  b% p! T/ `) ]6 J  UINT TIMERES="0";
) V& u. _6 A- N  H1 J7 k    UINT TIMEID;
* A1 T/ `1 m2 z0 p5 \; z    m_time_val*=1000;! n/ Z1 E1 u: X* s0 u
    int time_interval;! e: D" `8 w1 L3 P+ d( K  g- X
    time_interval=(int)m_time_val;  k: ~3 @4 S2 K, P& X
    if(timeGetDevCaps(&TC,sizeof(TIMECAPS))!=TIMERR_NOERROR)5 b, a# N, Z5 S, d8 e
    { exit(0);}
/ X6 p. }% }1 ~) H# v4 D  timeBeginPeriod(TIMERES);      TIMEID="timeSetEvent"(time_interval,TIMERES,&(LPTIMECALLBACK)callbackfunction ,0,TIME_PERIODIC); ) ~8 G& C$ G0 c" ]! a% t
5 b% {* D7 b* h* s% j3 H" t& ]
 g_TIMEID=TIMEID;1 N% d/ ]! o, E
  }& ?& N/ i8 N' W4 N$ ^3 c( S
  void end_timer()                   //终止定时
7 m5 D/ V. ?: {, |( d1 o4 k  { timeKillEvent(g_TIMEID);
; O. f4 E, w" |: Z, N  timeEndPeriod(0);
6 r  P" k0 ]( `* Z2 h  }0 {  z. A( Z1 K' }9 V
  void WINAPI callbackfunction(UINT uID,UINT MSG,DWORD DWUSER,DWORD DW1,DWORD DW2). }7 n* N$ q# M8 H
  {                       //在此函数中加入定时内自己要做的内容,本系统即要加入) B1 a; d5 U! q9 |- c& W5 O% i) c9 ]6 Z
                        //模拟量、数字量采集子函数的调用和存储数据等语句4 ~" T0 @( p6 {. i5 w$ ]( r
  } 6 G5 e  `' d, ], i& t1 T

8 f' M- T: ~5 R* O5 l- D/ h; T3 M8 ^$ I7 o" }; O, _4 R& Q" b
  首先调用void start_timer(double m_time_val)启动多媒体定时器,多媒体定时器将每隔一个时间间隔调用void WINAPI callbackfunction(UINT uID,UINT MSG,DWORD DWUSER,DWORD DW1,DWORD DW2)函数,通过改变time_interval的值可以改变时间间隔(time_interval的单位是毫秒),在定时结束时调用void end_timer()来终止定时。
. H/ q7 b/ z6 g  G. w& ^, ~# \* \; X1 @6 J% K, }
  3.4存储数据
- L. |# N$ M3 I9 j- q' B( X+ ?2 M! k+ Z7 b
  本数据采集系统还将把采集到的数据存储起来,以便将来对这些数据进行分析。现在最常用的数据库就是微软的Access,而C++Builder对数据库也有较好的操作,所以我们采取将数据存入Access的方案来实现数据的存储。基本的操作步骤如下:% p( S1 Q) ?  A2 l. X  [' @$ M7 d3 ~
% k( ]2 R7 o) w, e
  ●使用ADO组件页中的ADOTable组件来连接存储数据的数据库。7 D/ T7 O* o5 N# D
# K, b2 s8 C$ G
  ●由于ADOTable组件只负责连接数据库,无法取得数据库文件内的字段数据,所以我们仍得使用Data Access组件页中的DataSource组件来实现,将它的DataSet属性指定为ADOTable1(即前一步骤加入的ADOTable组件名称)。6 D3 y1 B  Z% R5 L
4 P4 g& \8 g. F9 Z* a' T
  ●往数据库存数据的过程即是新增记录的过程,所以只需添加几句简单的语句:
6 {7 V& Z9 h* \# Y0 F- B+ x' R8 b2 Q6 t9 p- k6 H: [" H$ \
  ADOTable1->Insert();
; b  }2 N  J1 v" W+ T. _  ADOTable1->FieldValues["voltage1"]=voltage1;0 ?8 u1 ]4 {) s/ R2 o( q
  …………
/ E: P" Y# E3 I& K' B5 q  ADOTable1->Post();
0 P$ k2 B, C, R% f5 q
! H" X2 A$ r3 G* P  首先调用Insert方法创建一个缓冲区(即成为编辑模式),接着进行数据字段值的编辑,当我们完成数据输入的操作后,必须调用Post方法,或者将当前的数据位置移到另一笔数据上,这样才会将新增的记录内容写入到数据库。# x2 B! H) j5 X  B

, G! c1 m7 b. R; |9 a  W  4 结论
% A& ?: q" q5 ]! Z: E) f$ o
& T' d6 N6 m1 s  o" t4 M  试验结果表明本文基于Borland C++ Builder开发的汽车自动变速器电控单元(ECU)实车试验数据采集系统,能够满足车载分析试验台的要求,这为ECU的开发和优化控制策略打下基础。

TOP

谢谢楼主分享,学习下

TOP

汽车自动变速器电控单元(ECU)$ e0 x& [2 ]5 Q5 k0 A' T
汽车自动变速器电控单元是TCU吧!2 S5 [. g% N! E/ Z$ c8 _! m) h
Transmission control unit! {* }; ^  [/ s
要是TCU和ECU是集成的,那AT也太老了吧!

TOP

发新话题