加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

8254定时器的使用说明与解读

(2011-03-16 11:12:26)
标签:

定时器

8254

pwm

分类: 技术与学术

下面这段英文详细讲解了使用8254定时器产生PWM信号的方法(这块内容仅涉及如何用高级语言如CQBasic进行编程,并读写硬件的方法,但未涉及到MatlabC协同产生PWM的内容。这一点将在英文后另有叙述。)

参考:http://www.boondog.com/tutorials/2993pwm/2993pwm.htm

8254定时器几大主要功能,与本文内容关系较为密切的是第一、二项功能:第一项是产生PWM信号;第二项是生成方波信号:

  • create pulse-width-modulated (PWM) signals (e.g. for motor speed control)
  • generate +5 V square waves
  • count the number of times a switch toggles
  • count pulses from a motor wheel encoder disk
  • generate timed interrupts for analog-to-digital data acquisition
  • implement a PC-controlled oneshot timer
  • have a PC-controlled rate generator
  • have fine resolution (e.g. 0.1 microsecond) timing instead of imprecise for...next delay loops

 

    8254是可编程使用的,6种工作模式如下,其中第2和第3是经常使用的。

  • The 8254 is Programmable...

This is the real power and flexibility behind the 8254. Because the 8254 was meant to be a one-chip solution, Intel designed it with 6 programmable modes, by identifying the most common timing/counting needs. The 6 modes are described in detail in the 8254 data sheet. They are

  • Mode 0: Interrupt on terminal count
  • Mode 1: Hardware retriggable one-shot
  • Mode 2: Rate generator
  • Mode 3: Square wave mode
  • Mode 4: Software triggered mode
  • Mode 5: Hardware triggered strobe

 

本教程主要以模式3为例,解读8254的用法。
     This tutorial will demonstrate how to program the 8254 in Mode 3. The other modes are equally easy to implement. Mode 0 is commonly used to count pulses (0 to +5 V transition). like switch toggles or motor encoder disk rotations. Mode 1 is used to generate a periodic signal that goes from high (+5 V) to low (GND) at fixed time intervals. Mode 3 generates square waves at user-desired frequencies.

·         Programming

With 6 programmable modes, your 8254 Card can answer almost any timing or counting problem you can conceive. The 8254 data sheet provides details on how to implement each of mode. Before programming, you will need to understand some preliminaries.

I. Preliminaries

A. Reading and Writing of Bytes硬件的基本指令,不同的语言有所区别,比如下面QBasic写指令是用OUT,而Turbo C用的是outportb。我们在后面用到的是outp这一点需要特别注意!!!

You can use any compiler you like (e.g. Turbo C, Quick Basic, Pascal, Visual Basic (with a DLL), Borland C, Microsoft C++). that allows allows the writing and reading of bytes to a port address. For example in QBasic you use:

    OUT(portAddress, byteValue)
    byteValue = IN(portAddress)

OUT writes byteValue (0 to 255 decimal) to the address defined in portAddress and IN reads the value from portAddress and stores it in the variable byteValue.

In Turbo C you use:

    outportb(portAddress, byteValue)
    byteValue = inportb(portAddress)

to accomplish the same thing. outportb() and inportb() are defined in the conio.h header file, so you must to #include it in your Turbo C program. For this tutorial we will use Turbo C to highlight programming in DOS and easy enough to translate into other languages. 读写指令包含在conio.h头文件中,所以无论是用什么方式编程,都要包含这个头文件。

B. The Base Address对基地址的定义要特别小心,对于不同的硬件基地址是不同的。如果设置有误,不仅等不到正确的结果,而且有时还会引起很大的错误,如造成系统死机等。我们在后面用到的1711板卡的基地址是“0xc400”,通过板卡自带的Device Manager软件可以获得这方面信息。)

The Address Decoding section assigned your 8254 card with a unique address (608D). This is called the base address. Each counter also has an address:

    int baseAddress, counter0, counter1, counter2;
    baseAddress = 608; 

 counter0 = baseAddress;
 counter1 = baseAddress + 1;
 counter2 = baseAddress + 2;

one then does a outportb(counter0, counterValue) to write a value to counter0 or a counterValue = inportb(counter0) to read a value from counter0 . You do the same outportb() and inportb() if you need to select counter1 and counter2.


·         C. Control Register8254定时器的控制字寄存器。通过写这个寄存器的8位,可以控制寄存器的工作模式,定时器初值的读写方式等等。认真学习每一位的意义和用法!!特别是RW1RW0两位!!在后面实例中我们定义这两位为“11”,即先写低8[LSB],后写高8[MSB]。)

The 6 programmable modes mentioned before are invoked by writing a 8-bit value to the control register. This is done as follows:

 

    controlRegister = baseAddress + 3;

    outportb(controlRegister, controlWord);

 

where the variable controlWord is determined with the following chart (Figure 9)

  http://s13/middle/625c01d6g9e9172aff2dc&690

From Figure 9 we can see that the control word is an 8-bit binary number. There are 5 steps to calculate the proper control word number:

Step 1: Chose one counter (SC1 and SC0)
Step 2: Chose method to load (RW1 and RW0)
Step 3: Chose programming mode (M2, M1 and M0)
Step 4: Chose binary or BCD number (BCD).
Step 5: Convert the final binary word into decimal

Example: Suppose you want to make counter 0 a binary counter that generates square waves, and uses LSB and MSB read/write loading. What is the proper control word?

 http://s6/middle/625c01d6g9e91784b2de5&690 

 

Figure 10 shows the answer. From Step 1, SC1 and SC0 both are 0 if you want to use counter 0. Step 2 say that LSB and MSB are both loaded. For square wave generation, you use Mode 3 and Step 3 says that M2,M1,M0 = 011. Step 4 makes BCD = 0 to have a binary counter. Thus the resulting binary number is 00110110 or, 54 decimal. Thus you would load the control register with controlWord with 54:

10110
    controlRegister = baseAddress + 3;
    outportb(controlRegister, 54); 

    上面一条指令是写控制字寄存器,设定counter0工作于模式3。其中“54”是十进制,转化为二进制是“00110110”,即写入的控制字。

D. LSB and MSB(低8位和高8位的概念,不明白的好好看看!!

All 3 counters are 16-bits.  A byte is 8-bits long, hence each timer is 2-bytes.  This means that each counter can have values ranging from:
     0000000000000000 (16 zeros) to 1111111111111111 (16 ones) in binary, or 0 to 65535 decimal.  ISA is an 8-bit data bus and can read or write only one byte at a time.  Thus to read or write a 16-bit value, you must do so one byte at a time.
The lower and higher 8-bit numbers are called least and most-significant bytes (LSB, MSB) respectively. For example, to load counter0 with 38370 decimal, the LSB is 226 decimal, and its MSB is 149 decimal (Figure 11).
http://s16/middle/625c01d6g9e9191f15b4f&690

The control word's RW1 and RW0 setting tells the 8254 that you will read or write 16-bit byte values with the LSB first followed by  the MSB.  In code you would do the following

    outportb(counter0, 226); 
       outportb(counter0, 149); 
先写第八位,再写高八位。这一点也要特别注意!!!

There might be cases where you only want to read or write the LSB or MSB.  You would then choose the respective RW1 and RW0 values from Figure 9.

E. Counter Reading and/or Writing

By reading the counter value you can determine how many pulses it has received.  Rather than counting upwardly (0,1,2..., 65535), the 8254's counters by default, count downwardly (65535, 65534...,0).  In many of the programming modes, the counter will wrap around and start at 65535 once it has reached 0.

You can give a counter a preset value to start counting down from by writing this value to it.  For example in the code above, counter0 starts counting down from 38370.

 

For timed applications, using a 1.0 MHz oscillator, each count takes 1 microseconds (usec).  Thus the preset value takes the same number of usec needed to reach 0.  Thus 38370 would take 38370 usec. 

 

You now may know see the significance of using the 74HC393. By changing jumper positions you can easily drive the counter with a different frequency.  Thus we have:

     Frequency    time/count
     1.0  MHz      1 usec
     500  KHz      2 usec
     250  KHz      4 usec
     125  KHz      8 usec
     62.5 KHz       16 usec

II. The Code

With the preliminaries out of the way, 3sqwave.c . is a short Turbo C program that allows the user to select a counter and frequency to generate square waves. A useful application of this code is to drive a stepper motor. Many dedicated stepper motor chips (such as Allegro Microsystems 5804) require a square wave, thus you can extend the code to run a stepper motor.

The program begins by defining crystalValue with 1.0 MHz.  Further down, baseAddress is given the 8254 card address 608 decimal and is used to assign addresses to the counters and control register.

Each counter is then configured in Mode 3 (square wave) as a binary counter with LSB and MSB loading. This makes the control word 54, 118 and 182 decimal (see Figure 9).

During program execution the user is then promped to select a counter (0, 1 or 2) and its gate, (gateNumber) is then assigned.

The user is then asked to enter a frequency.  The appropriate calculations are performed to load the counter's preset value counterValue.  The gate can be toggled so that the user can stop or start the squave wave at any time.  Also, the user can change the squave wave frequency at any time during program execution.

As you can see programming the 8254 is not very complicated. The 8254's other modes can be programmed similarly.

 

Final Words

This tutorial provides a solution to many timing and counting needs required in PC interfacing.  By building the 8254 circuit on an ISA card, one can have a very powerful, flexible and high resolution timer. 

Program mode 3 was illustrated to demonstrate the 8254 card's squave wave generating ability.  In the near future, source code for other modes will be added. Other soon to come tutorials will illustrate the 8254 forL


1.        (Available 06/14/99) A motor speed control using pulse-width-modulation

2.        Counting motor revolutions

3.        Stepper motor application

4.         Running servo motor

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有