串行多路传输总线如CAN或LIN可以解决车内因导线过多所带来的许多问题。低成本的LIN总线很适合应用于车门等这些对传输速率要求不高的场合,最高速率为20kbit/s的LIN总线完全可以满足要求。车外温度显示就是这样一个应用实例,外部温度传感器通常布置在后视镜中,数据产生于车门。但是实际显示位置是距此一定距离的车内,LIN总线可使布线简单,因为LIN节点只有3根导线:LIN数据线、电源线和地线。
本应用介绍了温度显示从机节点的设计。本节点是车门模块的一个从机节点,整个车门模块还包括键盘节点。车门报文帧用后视镜报文响应的一个字节来表示温度(见表1)。作为主机节点的车身控制器一般每隔100ms发送一个含有后视镜标识符的报文帧头,报文响应有两个字节,其中一个字节用于表示温度,变化范围为-30
C~97.5 C,精度为0.5 C。此时,报文响应数据可以直接被温度显示节点读取(从机到从机通信),也可被主机节点读取,再发给其他从机节点。
硬件
温度显示节点微控制器(MCU)选用MC68HC908EY16,在写本文的时候,还没有得到这种微控制器,所以选用了MC68HC908AZ60A。使用MC68HC908EY16能够大幅度降低成本,这是因为MC68HC908EY16不仅管脚数目少,降低了成本,而且集成在片内的时钟发生器模块(ICG)不需要晶体或陶瓷振荡器,可进一步降低成本。
表1 后视镜响应帧数据格式(略)
图1 温度显示节点电路框图(略)
图1是温度显示应用节点的电路框图。一个简单的LIN节点除了微控制器MCU外,还需要两个芯片,即LIN接口芯片(MC33399)和5V的电压调节器。在未来,这两个芯片将被一个芯片(SBC)所代替。电压调节器选用8个管脚的LT1121芯片,在MCU的控制下,该芯片关闭进入低功耗睡眠模式。芯片LT1121可由总线活动通过MC33399来唤醒。因为MC33399已包含30kohm
LIN总线上拉电阻,所以PCB板需要的元件就只有IRQ和Reset管脚的上拉电阻、去耦电容和晶振及其相关元件。除此之外,还需要2个PORTC口的上拉电阻和一个9V稳压管,以便使用串口进入监控模式,实现片内flash存储器在线编程。软件开发是在装有目标接口的MMDS开发板上进行的,没有利用实际的MC68HC908AZ60A。
由于LED由MCU直接驱动,所以要注意避免端口管脚输出太大的电流,防止超过5V电压调节器规定的电流及功耗。但是要达到合适亮度的数字,所需电流对端口管脚来说太高,所以使用了FET缓冲。若选用220R的段电阻,每段电流为10mA,则整个数字电流就达到了80mA。但以25%占空比依次显示4个数字,那么每段平均电流就为2.5mA,则显示一个8段数字的电流只有20mA。例如显示88.0(共21有效段)所需最大总电流为52.5mA(2.5mA
21)。
MCU的Idd是15mA,电压调节器的压降是9V(假设电池电压为14V),则LT1121的最大功耗计算如下:
表2 每段平均电度(略)
功耗=9V (52.5mA+15mA)~610mW设环境温度为26 C,热阻温升为100C /W,则LT1121的最高温度计算如下式:
TJ=TAmb+610mW 100C /W=26+61=87 C此值在最高温度125 C范围之内。如果需要更大的段电流,就要选用段驱动器和具有更好散热效果的电压调节器。
MC68HC908AZ60A手册规定总的电源电流只有10mA,同时要间歇地检测各种条件下Voh和Vol值是否满足手册规定。当然,这些电压不是最重要的,本应用关心的是总电流不要太大以免造成硬件损坏。只要每个管脚的绝对最大电流能达到100mA就不会有危险。此时,最大的Idd会低于100mA。以后的手册会将这些不必要的限制删除。
若在2s内总线没有活动,该节点就进入睡眠模式。当检测到这种状态时,MCU使MC33399的EN管脚变为低电平,同时INH管脚输出低电平给LT1121调节器,使其进入等待模式并停止向MCU提供电源。恢复的总线活动会唤醒MC33399,使电压调节器向MCU提供电源。为了降低睡眠模式的电流,采用一个稳压二极管提供进入监控模式所要求的高电压。在睡眠模式时所测电流消耗为40
A,是MC33399和LT1121静态电流之和(两者都约为20 A)。
软件
温度显示模块使用Motorola/Metrowerks LIN驱动程序,因此只要使用"LIN_GetMsg()"这样简单的代码就能获得位于后视镜的传感器产生的数据,进而处理所有的输入/输出动作。LIN驱动程序的使用使温度节点的应用软件变得相当简单。为了响应主机的请求命令帧(ID
0 3C),用户程序里必须包含函数void LIN_Command()。这就是说,比如,主机是如何要求所有的从节点进入低功耗等待或睡眠模式的。在这项应用中,当总线没有活动时,这个函数就仅仅相当于一个空循环,即进入睡眠模式。只要所有变量都已经被声明了,就初始化CONFIG和I/O寄存器。CONFIG1寄存器设成0
71,禁用看门狗(COP),CONFIG2寄存器设成0 19,将MCU设置成MC68HC908AZ60A(相对于AS60A)。由于中断被允许,因此只要通过LIN_init()进行了初始化,LIN驱动程序就能起作用。主循环使用了可编程中断定时器(PIT),使重复频率基于8MHz的晶振就能达到200Hz。每5ms
PIT的溢出标志就被置位一次,主循环就将二进制输入数据转换成7段码格式。这个200Hz的频率还被用来产生一个50Hz的4位LED多通道显示的循环刷新频率。虽然每一次都读LIN缓冲区,也把温度值转换成4位7段码格式,但实际上每5ms只有一位被刷新。
LIN驱动程序中的函数LIN_IdleClock能够检查是否有总线活动。如果没有就将一个计数器的值加一,然后与LIN_IDLETIMEOUT(在slave.cfg中定义)比较。如果计数器的值超过了LIN_IDLETIMEOUT,那么函数LIN_DriverStatus()就停止返回a1(LIN_STATUS_RUN),表明总线已经空闲了2秒钟。在这个例子中,如果检测到这种情况,就将MC33399的enable管脚拉低,通过禁用LT1121使MCU掉电。程序也将显示设置成"....",但是这种掉电操作在开发环境下并不能作为检测到总线处于空闲状态的标志,因为在开发环境中MCU的电源不通过LT1121来控制。在这项应用中,如果模块没有接收到温度数据,就能进行特别的显示,如没有这个附加功能,则仍将继续显示最近接收到的温度值(或者如果最近一次上电后没有接收到任何信息,就显示
30 C)。使用LIN_MsgStatus(0 0A)并结合变量error_count就能将这些特点结合起来,在一秒钟没收到带0A这个ID的LIN信息之后,将显示变成"----",见图2。
图2 当前存在的温度信息流程图(略)
为了完成换算,将温度字节转换成变量bits,如果温度是正的,就减去偏移量60(30 C)。如果温度是负的(<60),就会造成变量bits的错误下溢,因此如果这种情况下完成了减法,那就用另外一种圆整方式(60bits)来得到符合实际的(正的)温度值。如果事实上温度值是负的话,就通过置negative标志位来记录。
bits的值通过使用数组seg转换成所需要的7段码格式。首先根据bits的最低有效位将小数点后的那一位设置成0或者5。然后将bits除以2,得到二进制的摄氏温度值。再除以10就得到十位的数字,同时余数就是个位的数字。然后将个位,十位和符号位(百位)的数字设置成相应的段码,惟一复杂的地方就是个位数字要带小数点。如果十位的数字是零,就应该不显示出来,除非温度值是负的。在这种情况下,将负号显示在十位上要比显示在百位上好看的多。
为了输出LED显示的信息淞縟count每次都自加一,然后通过利用dcount的最低两个有效位来选中此次应该刷新的那一位。在存放段码数据并输出到portD的数组display和存放位刷新数据并输出到portF的数组scan中,都将用来作为一个标志。
|