1 硬件结构
从系统接口看,该控制器具有显示、按键、无线收发、串口、485总线等接口,作遥控面板时用电池供电,内部具有电池和充电电路。硬件框图如图1所示。
图1中无线串口用模块实现系统遥控功能,显示器用并口连接。键盘部分有或门电路,可实现按键中断。电源电路中的外部电压、电池电压可被控制器测量,当测量得到无外部电压输入时,控制器自动切换到遥控面板模式。485总线接口用于和其他子系统通信。
图1 多功能控制器硬件框图
2 系统移植
STM32F1XX固件库最新版本为V3.5.0.μC/OSIII支持的库文件版本为V2.1.0.为了μC/OS-III能够在最新的固件库上运行,首先用新固件库替换原有固件库代码并改变入口头文件名,然后有两处代码需要作修改。一是芯片时钟初始化函数,函数名为“BSP_Init”,修改为:
二是操作系统时钟初始化函数,函数名为“OS_CPU_SysTickInit”,修改为:
这两处都是因为原有固件库需要多条语句才能实现时钟初始化,新版本提供专门的初始化函数。
3 驱动编写
3.1 键盘驱动的编写
μC/OS-III具有任务信号量的功能,该信号量随着任务的创建而创建。键盘驱动有键盘扫描任务实现,按键触发外部中断,外部中断发送任务信号量到键盘扫描任务,键盘扫描任务扫描键盘并把键值保持在全局变量中。代码如下:
3.2 液晶显示器printf函数
液晶显示器一般是输入一个字符的编码和位置然后显示出来,不能实现字符串格式化显示。实现printf,首先使用格式化函数“vsnprintf”得到格式化后的字符串,然后该字符串被打印到屏幕上。具体函数如下:
程序中va_list是在C语言中解决变参问题的一组宏,“va_start(v_args,format);”得到第一个可变参数地址,这样把自定义的变参传递到库函数的变参中。
函数“LCD12864_print_string(buf_str);”为自定义函数,因为CH12864液晶屏内的逻辑行和显示行不同。逻辑行只有两行,起始地址分别为0x80和0x90,为显示行的一三行和二四行。在打印字符串时,每打印一显示行就要重新切换位置,保证显示是连续的。
该显示器显示中文字符的起始位置只能是偶数地址,奇数地址显示中文字符会显示乱码。
3.3 串口接收驱动
在μC/OS-III代码中有串口接收部分的驱动,但经过测试,当无操作系统的模块连续发送时,该驱动接收出现漏接或乱码的现象。其原因为该驱动每接收一个字符都要进行一次系统调用,在这个调用过程中发送的字符无法接收。改变原驱动用信号量同步的办法,使用消息通信和结束字符判定的方法即可完整接收到无操作系统模块连续发送来的字符串。
需要修改两个函数,一是中断接收函数:
该中断函数把每个字符先保存在数组中,当出现结束字符时发送消息到接收函数。
二是串口接收函数:
该函数每次接收完成后关中断,未完成可以挂起并由中断函数进行连续接收,保证了接收速度。
4 软件结构
多功能控制器可能作为手控器、遥控接收器、遥控器使用。根据外部电源状态和按键信号改变程序执行的模式来实现一机多用。
作为手控器时,每个用户界面作为一个任务。每个界面任务需要建立一些子任务协助处理,这些子任务受任务信号量和任务消息控制,当获得信号量或者消息时任务执行,执行完成后挂起。子任务根据用户操作把相关指令发往系统其他单元,各个单元执行多功能控制器的命令并返回用户需要查看的参数。系统单元一般工作在状态机的模式,根据多功能控制器的命令进入不同的运行状态。轨道运输车的电机控制单元就可工作在前进、倒车、停车三种状态,这三种状态可加上速度参数。电机控制器收到状态和参数后自动执行并返回电量功率等参数给用户界面。
作为遥控接收器时,多功能控制器作为一个数据中继器使用,主要任务是首先从无线串口接收数据,然后核对该数据的确认码。核对通过则通过485总线发给系统其他单元,否则丢弃该数据。当系统单元返回数据时,多功能控制器在数据上添加确认码,然后从无线串口对外发送。
作为遥控器时,该模式和手控器工作过程大致一样。不同的是通过无线串口通信,发射时添加确认码,接收时核对确认码。
结语
多功能控制器通信接口多样,具有人机界面,配有μC/OS-III操作系统,有完善的硬件驱动,可在分布式控制系统中完成多种任务。