6.6仿真结果如下:
16
七、程序设计
为了在C语言源程序中直接编写中断服务函数的需要,KeilCx51编译器对函数的定义进行了扩展,增加了一个扩展关键字interrupt,它是函数定义是的一个选项,加上这个选项即可以将一个函数定义成中断服务函数。定义中断服务函数的一般形式为:
函数类型 函数名(形式参数表) [interrupt n] [using n] 由于ADC0808的CLOCK的时钟频率不高于640KHZ,在这利用定时器T0的中断产生时钟频率,则可设置为:
void t0(void) interrupt 1 using 0
ADC0809的时序图如下:
由时序图可知,只有在转换期间,EOC处于低电平,因此在AD转换开始前EOC置为低电平,START在上升沿期间将芯片内的所有寄存器清零,在下降沿来临时开始转换,由于所用的时钟为100KHz,比较的缓慢不需要再延时,在此等待转换结束,结束后将其数字量输出。
根据上述分析及原理,可设计程序流程图如下:
17
设计程序如下:
#include #include
#define uchar unsigned char #define uchar unsigned char #define uint unsigned int sbit START=P3^0; sbit OE=P3^1; sbit EOC=P3^2; sbit P07=P0^7; sbit CLK=P3^4; uchar data led[4]; uint data tvdata;
uchar code tv[]={0xfe,0xfd,0xfb,0xf7}; uchar code a[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void delay(void) //延时程序
18
{
uint i;
for(i=0;i<10;i++); }
void ledxianshi(void) //显示模块 {
uchar k,i;
if(tvdata>5000) tvdata=5000;
led[0]=tvdata; led[1]=tvdata/10; led[2]=tvdata/100; led[3]=tvdata/1000;
for(k=0;k<4;k++) {
P2=tv[k]; i=led[k]; P0=a[i]; if(k==3) {
P07 =1; }
delay(); } }
void main(void) {
ET0=1; EA=1;
TMOD=0x02; TH0=216; TL0=216; TR0=1; while(1) {
START=1;
START=0; //启动转换
19
while(EOC==0); OE=1; tvdata=P1;
tvdata*=20-0.01; OE=0;
ledxianshi(); delay(); } }
void t0(void) interrupt 1 using 0 {
CLK=~CLK; }
20