μC/OS-II实时内核下的A/D驱动程序设计
在C8051F015单片机中,ADC的转换时钟周期至少在400ns,转换时钟应不大于2MHz。一般在启动ADC之前都要处于跟踪方式,而ADC一次转换完成要用16个系统时钟。另外,在转换之前还要加上3个系统时钟的跟踪/保持捕获时间,所以完成一次转换需19个ADC转换时钟(9.5μs)。
图1中的方法简单,转换时间在ms级以上,一般用于变化慢的模拟输入信号,不适用于C8051F015。图2中的方法,为了减少μC/OS-II内核调用ISR所用时间,ISR一般都用于汇编语言编写。从程序1中ISR伪代码可以看出,尽管ISR用汇编语言编写。代码效率高,但μC/OS-II调用ISR的时间与调用等待信号时间之和大于A/D的转换时间,所以CPU用于ISR和循环检测的开销大。
图3所示的方法显然适合于C8051F015单片机,其优点是:可以获得快速的转换时间;不需要增加一个复杂的ISR;转换时信号改变时间更短;CPU的开销小;循环检测程序可被中断,为中断信号服务。
图4 A/D驱动程序模块流程图
3 A/D驱动程序的编写
外设驱动程序是实时内核和硬件之间的接口,是连接底层硬件和内核的纽带。编写驱动程序模块应满足以下主要功能:①对设备初始化;②把数据从内核传送到硬件从硬件读取数据;③读取应用程序传送给设备的数据和回送应用程序请求的数据;④监测和处理设备出现的异常。
A/D转换电路作为一个模拟输入模块,μC/OS-II内核应把它作为一个独立的任务(以下称为ADTask())来调用。A/D驱动程序模块流程如图4所示。ADInit()初始化所有的模拟输入通道、硬件ADC以及应用程序调用A/D模块的参量,并且ADInit()创建任务ADTask()。ADTb1[]是一个模拟输入通道信息、ADC硬件状态等参数配置以及转换结果存储表。ADUpdate()负责读取所有模拟输入通道,访问ADRd()并传递给它一个通道数。ADRd()负责通过多路复用器选择合适的模拟输入,启动并等待ADC转换,以及返回ADC转换结果到ADUpdate()。
在μC/OS-II这时内核下各原型函数、数据结构和常量的定义如下:
INT16S ADRd(INT8U ch);
/*定义如何读取A/D,A/D必须通过AIRd()来驱动*/
void ADUpdate(void);
/*一定时间内更新输入通道*/
void ADInit(void);
/*A/D模块初始化代码,包括初始化所有内部变量(通过ADInit()初始化ADTb[]),初始化硬件A/D(通过ADInitI())及创建任务ADTask()*/
void ADTask (void data);
/*由ADInit()创建,负责更新输入通道(调用ADUpdate ())*/
void ADInitI (void);
/*初始化硬件A/D*/
AD_TaskPrio:设置任务ADTask()的优先级。
AD_TaskStkSize:设置分配给任务ADTask()的堆栈大小。
AD_MaxNummber:AMUX的输入通道数。
AD_TaskDly:设定更新通道的间隔时间。
AD ADTbl[AD_MaxNummber]:AD类型的数组(AD是定义的数据结构)。
4 结论
《μC/OS-II实时内核下的A/D驱动程序设计(第3页)》