Microcomputer Interface Experiment 4: Programmable Timer/Counter 8254

1. The purpose of the experiment

Grasp the basic working principle and programming method of 8254, use an oscilloscope to observe waveforms in different ways. (Note: There is no oscilloscope, so use the blinking of the LED light to observe)

2. Experimental principle and content

Insert picture description here

Three, programming tips

Insert picture description here

Four, circuit wiring diagram

Experiment 1:
Insert picture description here
Experiment 2:
Insert picture description here

Five, program design flow chart

Experiment 1:
Insert picture description here
Experiment 2:
Insert picture description here

Six, some explanation

  1. In Experiment 1, after each reading, simply judge whether it is the same as the last time, because it may be that the counter has not decreased by 1 during this reading.
  2. In experiment 2, because two square waves with different frequencies are to be output, and the LED lights are to be flickered in time, three counters are needed.

Seven, program source code

Experiment 1:

stack segment stack
    db 200 dup(0)
stack ends

data segment
      ZERO equ 280h
      ONE equ 281h
      CTRL equ 283h
data ends

code segment
      assume cs:code,ds:data,ss:stack

      newline MACRO   ;回车换行
        push ax
        push dx
        mov ah,02h
        mov dl,0ah
        int 21h
        mov ah,02h
        mov dl,0dh
        int 21h
        pop dx
        pop ax
      ENDM

      dispchar MACRO x    ;输出单个字符并换行
        push dx
        push ax
        newline
        mov ah,02h
        mov dl,x
        int 21h
        pop ax
        pop dx
      ENDM

      put_data MACRO x, y  ;x为端口,y为数据
        push ax
        push dx
        mov al, y
        mov dx, x
        out dx, al
        pop dx
        pop ax
      ENDM

   main:mov ax,data
        mov ds,ax
        mov ax, stack
        mov ss, ax
        put_data CTRL, 00010000b  ;计数器0工作在方式0下,只读写低8位,二进制计数码
        put_data ZERO, 0fh   ;写入计数器初值15,开始计数
  again:mov dx, ZERO
        in al, dx   ;读取通道0数据
        and al, 0fh;  读取低四位
        mov dl, al
        cmp bl, dl
        jz again   ;本次读出的数值与上次一样,说明还没有手动输入脉冲,继续读取,直到本次读取 的数据与上次不一样
        mov bl, dl  ;本次与上次不一样
        cmp dl, 9  ;判断是否小于9
        ja disp_
        add dl, 30h
        dispchar dl   ;显示0-9的一个数
        jmp again
  disp_:add dl, 37h
        dispchar dl    ;显示A-F中的一个数
        jmp again
        mov ah,4ch
        int 21h
code ends
     end main

Experiment 2:

stack segment stack
    db 200 dup(0)
stack ends

data segment
      ZERO equ 280h
      ONE equ 281h
      TWO equ 282h
      CTRL equ 283h
      
data ends

code segment
      assume cs:code,ds:data,ss:stack
      
      put_data MACRO x, y  ;x为端口 y为数据
        push ax
        push dx
        mov al, y
        mov dx, x
        out dx, al
        pop dx
        pop ax
      ENDM

;分析:连接时钟频率为1MHz,周期为1us,要求输出的1Hz的信号周期为1,分频系数为1e6,but8254最大计数为65536
;又因为1e6 = 1000 * 1000,所以通道0和通道1分别把信号1000分频即可

   main:mov ax,data
        mov ds,ax
        mov ax, stack
        mov ss, ax
        put_data CTRL, 00110111b  ;计数器0工作在方式3,读写16,BCD计数码
        put_data ZERO, 00   ;写入计数器初值1000
        put_data ZERO, 10h  ;先写低8位再写高80001 0000 0000 0000
        put_data CTRL, 01110110b  ;计数器1工作在方式3,读写16,二进制数码
        put_data ONE, 0e8h
        put_data ONE, 03h   ;写入计数器初值1000,开始计数,out0端为高电平,接LED灯,LED灯亮
        put_data CTRL 10110111b    ;计数器2工作在方式3下,读写16位,BCD计数码
        put_data TWO 02      ;写入计数初值2,输出两个端口,out1端口输出频率是out2端口2
        put_data TWO 00h
        mov ah, 4ch
        int 21h
code ends
     end main

Guess you like

Origin blog.csdn.net/Cyril_KI/article/details/110678076