图1所示的是第1种读取方法。假设A/D 转换器的转换时间较慢(5ms以上),应用程序调用图1所示的驱动程序,并传递要读取的通道。驱动程序通过M U X选择要读取的模拟通道(①)开始读。转换前,延时几μs以便使信号通过M U X传递,并使之稳定下来。接着,ADC被触发开始转换(②)。然后驱动程序延时一段时间以完成转换(③)。延时时间必须比ADC转换时间长。最后驱动程序读取ADC转换结果(④),并将转换结果返回到应用程序(⑤)。
图2所示的是第2种读取方法。当模拟转换完成后,ADC产生的一个中断信号。若ADC转换完成,ISR给信号量发一个信号(⑤),通知驱动程序,ADC已经完成转换。如果ADC在规定的时限内没有完成转换,信号量超时(③),则驱动程序不再等待下去。驱动程序和中断服务子程序(ISR)的伪代码如下:
ADRd(ChannelNumber)
{
选择要读取的模拟输入通道;
等待A M U X 输出稳定;
启动A D C 转换;
等待来自ADC 转换结束中断产生的信号量;
if (超时){
*err=信号错误;
return;
} else {
读取ADC转换结果并将其返回到应用程序 ;
}
}
ADCoversion Complete ISR{
保存全部CPU 寄存器; /* 将CPU的PSW、ACC、 B、
DPL、DPH及Rn入栈*/
通知内核进入ISR(调用OSIntEnter()或OSIntNesTIng直接加1);
发送A D C 转换完成信号; /* 利用μC/OS-II内核的
OSSemPost()*/
通知内核退出ISR(调用OSIntExit());
恢复所有CPU 寄存器; /* 将CPU 的PSW、ACC、B、DPL、DPH及Rn出栈*/
执行中断返回指令(即RETI);
}
在这种方法里,要求ISR执行时间与调用等待信号的时间之和为A/D转换时间。