程序采用分层的程序结构。最底层是一些硬件驱动程序,如键盘扫描、LCD状态读取和LCD数据写入等。在这些底层驱动程序的基础上再组织一些上层子程序供主程序调用。在编程语言的选择上,考虑到程序的结构相对比较复杂,程序主体采用C语言编程,只有少部分涉及到DSP一些底层操作的部分才使用汇编语言。软件的主体流程图如图4所示。
初始化包括对CAN控制寄存器的初始化以及屏幕初始化,并在这之后读取拨码开关的状态,确定波特率及通信对象,向被监控节点发出“发送允许”命令等。
程序主体是一个大循环。在初始化之后便不断扫描键盘。首先判断是否有键按下,如果用户没有操作,则检查CAN模块是否接收到数据。如果没有接收到数据,则继续扫描键盘。如果接收到了数据(即相应的CAN接收中断标志位置位),则将接收到的数据包按上述协议进行分析、整合处理,然后在屏幕上显示出接收到的数值;同时,在曲线的对应位置上描点,完成曲线的绘制。如果在键盘扫描过程中发现有按键按下,则分析按键的类别,然后转相应的子程序处理。处理完毕再返回主程序。
这里数据接收并不采用中断驱动方式,因为LCD的响应速度较慢。当LCD的响应速度低于CAN接收数据的速度时,会形成中断嵌套,时间长了就会出现堆栈溢出。此外,采用中断方式在数据量大时会出现DSP无暇顾及用户键盘输入的现象。实践表明,采用查询的方式可以很好地发挥DSP和LCD的固有能力,而且整体响应速度也比中断方式快。
LCD显示涉及的子程序比较多,分层也很多。在编写程序时首先在DSP的Flash ROM里定义一个段,将LCD显示过程中可能涉及的字符、汉字等点阵数据做成一个库,放入段内,在使用时再通过ROM访问指令读取。
曲线的绘制过程如下:首先确定坐标的原点位置、X方向和Y方向的最大坐标以及输入数值的范围,然后在内存中开辟一个同X坐标点数一样大小的缓冲区BUFF,用于记忆已经绘制的各点的坐标;同时设定一个X指针,用于存储当前的X坐标。当接收到新的数据,确定好Y方向的坐标后,首先查找BUFF,得到原来显示在该X位置的点的Y坐标,将这个位置上的点清除,然后在新的Y坐标上描点,最后在BUFF的相应X位置上记录下新描点的Y坐标值,此时便完成了一个点的绘制。后面还要调整屏幕上的指针以标明当前显示的X坐标。当绘制到X方向的最大位置时,再返回X=0的位置继续绘图。
屏幕下方有关菜单的操作也是采用树结构实现的,这里不再详述。
CAN监控终端向悬浮节点发送数据的过程一般是伴随在相应的菜单操作并按下ENTER键生效后进行的。在每次数据发送之前,程序都需要读入拨码开关的状态,以确定通信的波特率和通信对象的标识符。在实现上,拨码开关的最高位控制着波特率,后面7位则决定了通信的发送标识符。
4 结束语
使用表明,这种基于TMS320LF2407A DSP的CAN总线监控终端在多悬浮控制器组成的网络中可以发挥很好的监控和调试作用,其结构小巧、界面友好,使用相当方便。