可编程定时/记时器8253工作方式验证实验

来源:互联网 发布:originlab for mac 编辑:程序博客网 时间:2024/05/18 03:00

中央民族大学      03电子班     杨忠学

 

l       实验目的:进一步熟悉TPC_H实验系统是使用,学习运用地址译码技术和基本接口电路,掌握8253的基本工作原理和编程方法。

l       实验要求:

1.        TPC_H实验系统环境下,设计实现对可编程定时/计时器8253的确定译码,即接到8253CS端的信号是唯一有效的,只能支持四个端口地址。

2.       通过相应的电路连接及初始化编程,验证8253的六种工作方式,观察其输出现象。(8253的地址线、数据线和控制线已与系统连接好,连接电路时,只需考虑CSCLKGATEOUT信号的连接。)

l       实验内容:

1.       硬件电路方案


硬件电路说明:定时/计时器1做分频器(工作方式23都可以)。对于方式14,其GATE信号是脉冲信号,其他方式的GATE信号是高电平,因此定时/计时器0,通过开关选择不同的GATE信号。OUT信号:用示波器观测方式23的输出波形,用查询方式查询其他方式的输出跳变。

1.       软件流程以及相关程序

在软件的设计过程中,考虑软件运行程序后,能自主选择当前工作的记时器,又能修改记时器的计数值和工作模式。

我设计了一种在文本模式下定时控制系统:通过控制上下方向键设置工作模式,按回车键确认;数字键012(其它数字键无效)设置当前的计时器;按ESC键可以退出程序;F1键查看程序的帮助文件,其他键开始设置频率,Enter键确认输入。该系统的默认定时器为T0,工作方式Mode=0,频率Frq=1000,T0的初值通过value=119800/Frq算得。

程序运行后的界面如下:

       选择0145工作方式,在计数值为0,输出发生跳变后,程序会给予相应的提示(或是重装计数初值(05)或是给予GATE触发信号(14))。

 

程序的流程:

1.         Initial system;

2.         Get 8253 IO port;

3.         Print Menu;

4.         Get key;

5.         Switch(key) {

Case   Esc: Exit system; break;

Case   F1: Print help; break;

Case   Enter: Start Timer; break;

Case   UP/Down: modifier mode; break;

Case   0, 1, 2:  Modifier current timer; break;

Default: modifier current frequency;}

6. Goto 3

l       实验结果:

程序经过多次修改调试之后,运行良好,实验现象比较明显。

其中,方式2和方式3最容易,只需要选择好工作方式,输出波形都很稳定。CLK时钟信号和输出的OUT信号正确显示。

方式0和方式1时,可以看到OUT输出的是一个稳定的方波,每一个上升沿说明计数器工作结束一次。方波的占空比很大,输入的计数值变高,占空比就降低,方式1时变化比较明显。方式0不需要触发信号,GATE输入信号可以暂停计数。而方式1必须由GATE输入信号触发才能开始计数,计数中有GATE输入信号则重新计数而不是暂停计数。

方式4和方式5时,得到的波形是连续的负脉冲。两种方式都是只计数一次就停,且计数过程重新给计数值不影响当前计数,计数时GATE上升沿到来则计数器重新装入计数值,重新计数。计数结束后,方式4要重新给计数值才能再次计数,而方式5只要GATE又给触发信号就能再次工作。

 

 

l       实验小结:

在电路的设计中,因为实验箱上提供的脉冲频率太高,不利于观察定时器的输出波形,因此选用8253的定时器1作为分频器,其输出作为脉冲时钟供定时器0选用。

这一次实验感觉比前两次要好做,首先是电路的连接比较简单,不像前两次那样要接好多的线。考虑到82533个计数器,当其中一个不能用时,可以用另一个代替,程序设计中允许选择计数器,所以在电路的连接上,可以用的两个计数器都连接好了。除了方式2和方式3外都用了查询方式。因此用上了74LS244

计数器的6种工作方式验证都做完了,从中更深刻地认识8253定时计数器的结构和计数原理。对于这6种不同的工作方式,可以满足各种软件和硬件定时计数的要求。


附录:定时控制系统源代码:

#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <bios.h>
#include <conio.h>
unsigned char curr_timer=0;    /*Current working timer*/
unsigned int curr_frq=100;
unsigned int io_address=0x280;
#define CONTROLWD(i) (curr_timer<<6)|0x30|(i<<1)  /*cal the control word*/
union{   unsigned int b;
   unsigned char d[2];
  }count;
void inittimer(int i){
 outportb(io_address|0x03,CONTROLWD(i));
 outportb(io_address|curr_timer,count.d[0]);
 outportb(io_address|curr_timer,count.d[1]);
 }
unsigned char selecmenu(void);
/*the function is the special working mode*/
void spec_mode(int i) {
 unsigned char portst;
 inittimer(i);
 switch(i)
 { case 0: ;
   case 1: portst=0x01;break;
   case 4: ;
   case 5: portst=0x00;break;
 }
/* D0 is connect with out of timerX    */
 while(!kbhit()) {
  while(inportb(io_address|curr_timer)&0x01!=portst) ;
  gotoxy(1,15);
  cprintf("Init timer or Give the Gate signal");
  gotoxy(50,20);
  return ;
  }
}
void main(){
 unsigned char mode;
 clrscr();
 printf("input IO ADDRESS/n");
 scanf("%x%*c",io_address);
 while(1) {
 clrscr();
 mode=selecmenu();
 /*Exit the system*/
 if(mode>=6){
  clrscr();
  printf("Press any key to continue ...");
  getch();
  exit(1);}
 count.b=119318.0/curr_frq; /*cal the initvalue*/
 switch(mode)
 {case 0:spec_mode(0);break;
  case 1:spec_mode(1);break;
  case 2:inittimer(2);break;
  case 3:inittimer(3);break;
  case 4:spec_mode(4);break;
  case 5:spec_mode(5);break;
 }     /*end switch*/
   }  /*if the expection is false,the quit the while*/
}
void getfrq() /*modifier frequency*/
 {
 char ch=0;
 unsigned  frq=0;
 gotoxy(60,16);
 cprintf("      Hz");
 gotoxy(60,16);
 while(ch!=13)
 {
 ch=getch();
 if(ch-48>=0&&ch-48<=9)
  {frq=10*frq+ch-48;
  printf("%d",ch-48);
  }
 if(frq>6553)
  break;
 }
 curr_frq=(frq>0)?frq%65536:curr_frq;
 gotoxy(60,16);
 cprintf("%uHz",curr_frq);
 }
void help()
 {
 clrscr();
 printf(" /n/nThank you for using TPH_100 timer control system/n");
 printf(" Press Enter to start timerX with mode Y int fre Z/n");
 printf(" Init timer is timer 0 and Mode is mode 0 and frq=100Hz/n/n");
 printf(" OPERATOR AS:/n");
 printf(" Press direct key to select the mode/n");
 printf(" Press Digtal key 0,1,2 to set current timer/n");
 printf(" Press ESC key to quit system/n");
 printf(" Press any other key to input new frequency and press Enter to end/n");
 printf(" Press F1 to get help/n");
 printf("/n/nPress any key to continue.");
 getch();
 }
unsigned char selecmenu(){
 int i;
 int key;
 static unsigned char index=0;
 unsigned char curr_index; /*record curent index*/
 unsigned int flag=1;
static char *menu[]={ "-----Timer system Version 1.0-----",
  "      0---End AND Interrupt",
  "      1---Progarmmed Pluse",
  "      2---Frequency Function",
  "      3---Wave Fuction",
  "      4---Control  with Software",
  "      5---Control with Hardware",
  "      6---Quit system"};
 clrscr();
 for(i=0;i<8;i++){
 gotoxy(25,4+i);
 cprintf("%s",menu[i]);}
 gotoxy(1,21);
 printf("Press F1 get help/n");
 printf("Thank you for using Timer system/n");
 printf("Programme desigend:Y.Z.X/n");
 printf("2006.5/n");
 gotoxy(24,14);
 cprintf("The current timer is timer%d !",curr_timer); /*40*/
 while(flag){
 curr_index=index;
 gotoxy(20,5+curr_index);
 cprintf("---->");
 gotoxy(20,16);
 cprintf("Input the Initial Fre (DEC) like 0234 : %u Hz    ",curr_frq);
 gotoxy(60,16);
 key=bioskey(0);
 key=key&0xff?key&0xff:key>>8;
 switch(key)  {
   case 72: index=(curr_index==0?index=6:curr_index-1);break;
   case 80: index=(curr_index==6?index=0:curr_index+1);break;
   case 13: flag=0;  break;
   case 48: ;
   case 49: ;
   case 50: {gotoxy(50,14);
   curr_timer=key-48;
   printf("%d",curr_timer);
   gotoxy(50,20); break;     }
   case 27: exit(1);
   case 59: help();flag=0;break;
   default: getfrq();break;
   }
   gotoxy(20,5+curr_index);
   cprintf("      ");
   gotoxy(20,5+index);
   cprintf("---->");
  gotoxy(60,16);
 }
 return index;
}