×
嵌入式 > 技术百科 > 详情

μC/OS-II实时内核下的A/D驱动程序设计

发布时间:2023-04-28 发布时间:
|

摘要:详细分析在μc/os-ii实时内核下驱动程序读取a/d的三种方法;阐述c8051f015单片机的a/d转换器的配置、转换特点及其驱动程序读取a/d采用的方法;针对c8051f015单片机分析a/d驱动程序设计的方法和思想。这些方法和思想为在μc/os-ii下访问其它类型的a/d提供了很好的借鉴。

关键词:μc/os-ii a/d 驱动程序 c8051f015

a/d转换是单片机数据采集系统的重要组成部分,实时内核下a/d驱动程序的实现过程主取决于a/d转换器的转换时间。本文首先比较和分析μc/os-ii下a/d采样数据的三种方法;其次介绍c8051f015单片机a/d模数转换器配置及特点;最后,在μc/os-ii内核移植到8位单片机c8051f015的基础上,介绍编写a/d驱动程序的一般思想和方法。

1 μc/os-ii实时内核下的a/d读方法

实时内核下,驱动程序采用什么方法读取a/d采样数据是首先考虑的问题。许多因素将影响读取a/d,如a/d的转换时间、模拟值的转换频率、输入通道数等,但最主要的取决于a/d的转换时间。典型的a/d转换典型的a/d转换电路由模拟多路复用器(mux)、放大器和模数转换器(adc)三部分组成。下面描述读取a/d的三种方法。

图1所示的是第1种读取方法。假设a/d转换器的转换时间较慢(5ms以上)。应用程序调用图1所示的驱动程序,并传递要读取的通道。驱动程序通过mux选择要读取的模拟通道(①)开始读。有,延时几μs以便使信号通过mux传递,并之稳定下来。接着,adc被触发开始转换(②)。然后驱动程序延时一段时间以完成转换(③_。延时时间必须比adc转换时间长。最后驱动程序读取adc转换结果(④)。并将转换结果返回到应用程序(⑤)。

图2所示的是第2种读取方法。当模拟转换完成后,adc产生的个中断信号。若adc转换完成,isr给信号量发一个信号(⑤),通知驱动程序,adc已经完成转换。如果adc在规定的时限内没有完成转换。信号量超过(③),则驱动程序不再等待下去。驱动程序和中断服务子程序(isr)的伪代码如下:

adrd(channelnumber)

{

选择要读取的模拟输入通道;

等待amux输出稳定;

启动adc转换;

等待来自adc转换结束中断产生的信号量;

if(超时){

eer=信号错误;

return;

}else{

读取adc转换结果并将其返回到应用程序;

}

}

adcoversion complete isr {

保存全部cpu寄存器; /将cpu的psw、acc、b、dpl、dph及rn入栈/

通知内核进入isr(调用osintenter()或osintnesting直接加1);

发送adc转换完成信号; /利用μc/os-ii内核的ossempost()/

通知内核退出isr(调用osintexit());

恢复所有cpu寄存器;/将cpu的psw、acc、b、dpl、dph及rn出栈/

执行中断返回指令(即reti);

}

在这种方法里,要求isr执行时间与调用等待信号的时间之和为a/d转换时间。

如果a/d转换时间小于处理中断时间与等待信号所需的时间之和,则可以用第三种方法。如图3所示,前两步(①②同以上两种方法)结束后,驱动程序接着在一个软件循环中等待(③)adc直到完成转换。在循环等待时,驱动程序检测adc的状态(busy)信号。如果等待时间超过设定的定时值(软件定时),则结束等待循环(循环等超时)。如果在循环等待中,检测到adc发出转换结束的信号(busy)时,驱动程序读取adc转换结果(④)并将结果返回到应用程序(⑤)。驱动程序伪代码如下:

adrd(channelnumber){

选择要读取的模拟输入通道;

等待amux输出稳定;

启动adc转换;

启动超时定时器;

while(adc busy & counter 0);/循环检测/

if(counter==0){

err=信号错误;

return;

}else{

读取adc转换结果并将其返回到应用程序;

}

}

a、d转换速度快,这种驱动程序的实现是最好的。

2 c8051f015单片机的a/d转换器

2.1 c8051c015单片机

c8051c015的美国cygnal公司新推出的高速soc型c8051fxxx系列单片机。它的内核cip-51与mcs-51的指令集完全兼容,cip-51的系统时钟频率在0~25mhz。c8051fxxx系列单片机采用流水线结构,与标准的8051相比,指令执行速度有很大的提高。cip-51内核的指令执行时间是以系统时钟为单位,70%的指令执行时间为1个或2个系统时钟周期。c8051f015具有32kb的内存、2304b的ram(片内256b、片外2048b)。cip-51内核具有标准8052的所有外设部件,片上还集成有9通道10位a/d转换接口电路、smbus/i2c、spi串行接口。

2.2 c8051f015的a/d转换电路

c8051f015的a/d转换电路包括1个9通道可配置模拟多路开关amux(8路用于外部模拟输入、1路用于芯片环境温度的测量)、1个可编程增益放大器pga和1个100ksps 10位分辨率的逐次逼近型adc。a/d中还集成了跟踪保持电路和可编程窗口检测器。

adc有4种启动方式:软件命令、定时器2溢出、定时器3溢出及外部信号输入。寄存器adc0cn是配置启动和跟踪方式的控制寄存器。每次转换结束时,adc0ch的adbusy(忙标志)的下降沿触发中断,也可用软件查询这个状态位。

2.3 adc转换速度

c8051fxxx系列单片机中adc的速率都是可编程设置的。表1给出了所需最小分频系数与sysclk(系统时钟)的关系(adc0cf为adc配置寄存器)。

表1 adc时钟分频系数与sysclk频率的关系

sysclk频率/mhz adc时钟分频系数 adc0cf的adcsc2~1
时钟频率<2.5 1 000
2.5~5 2 001
5~10 4 010
10~20 8(复位值) 011
时钟频率>20 16 1xx

在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 结论

对于a/d转换器接口电路驱动程序的编写归纳出以下几点:

①在决定采用具体的驱动方案之前,分析接口电路的特点,尤其是了解a/d的转换速度;

②对于转换速度快的a/d转换器,可能出现cpu的处理速度与a/d转换速度不匹配,一般的a/d中不带有fifo缓冲区,须有内存中开辟缓冲区;

③在应用程序读取设备之前,一定要初始化硬件(调用初始化函数),合理定义硬件的信息和状态变量;

④不同的输入通道采集到不同类型数据,环境、转换精度都会影响到转换结果,要对各个模拟输入通道进行校准和补偿(通常在应用程序中编写通道补偿函数)。




『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
ADI 高精度低功耗精密放大器