8254的三种读出方式

8254的三种读出方式,第1张

RL,RLo=01 :仅读/写一个低字节,RL:RLo=10:仅读/写一个高字节RL,RLo=11 :读/写2个字节,先是低字节,后是高字节。

8253芯片是Intel公司为了解决微型机系统设计中的时间控制问题而开发的可编程定时器/计数器,主要用于早期的IBM PC/XT微型机中。8254是8253的改进型,两者兼容。

我来试试吧,用汇编语言编写:

ORG 0

JMP MAIN

MAIN:SETB P10

ACALL DELAY

CLR P10

ACALL DELAY

JMP MAIN

DELAY:MOV R1,#10 ;500ms的延时子程序

MOV TMOD,#1 ;定时器0方式1

AGAIN:MOV TL0,#LOW(65536-50000) ;装载计数初值的低位

MOV TH0,#HIGH(65536-50000) ;装载计数初值的高位

SETB TR0 ;启动

LOOP1:JBC TF0,LOOP2 ;查询并清除溢出位

JMP LOOP1

LOOP2:DJNZ R1,AGAIN

CLR TR0

RET

END

刚才我拿51的测试板编译了一下,下载后可以正常运行,你直接拷贝应该就能用,嘻嘻

8253具有3个独立的16位计数器,6种不同的工作方式。计数寄存器用来寄存计数初值,计数工作单元为16位减1计数器,它的初值便是计数寄存器内容,计数单元对CLK脉冲计数,每出现一个CLK脉冲,计数器减1,当减为零时,通过OUT输出指示信号表明计数单元已为零。当作为定时器工作时,每当计数单元为零时,计数寄存器内容会自动重新装入 计数单元,而且CLK输入是均匀的脉冲序列,于是OUT输出频率是降低了的(相对于CLK信号频率)脉冲序列。

当作为计数器工作时,表明只关心在CLK端出现(代表事件)的脉冲个数,当CLK端出现了规定个数的脉冲时,OUT输出一个脉冲信号。

8253在PC系列微机系统中,在如下三个方面得到了应用:

(1)计数器0作为系统计时器

用计数器0产生时钟信号的系统计时器。系统主要利用它完成日时钟计数。

计数器0的CLKo输人为1.1931816MHz方波,工作于方式3,计数初值为0(即65536),输出信号OUTo接到中断控制器8259A的IRQo作为中断请求输入线,OUT0输出的方波脉冲序列频率为Fout0=11931816MHz/65536=182Hz

即计数器0中断频率为每秒18.2次,计满1h需要中断65520次(1826060=65520)。24h需中断1573040次(001800BOH)。每次中断总是对低位字加1,当低位字计满为0时高位字加1。当高位字计到0018H,低位字计到00BOH时,表示计满24h,双字复位清0。

(2)计数器1作为动态存储器定时刷新控制

计数器1的CLK1接11931816MHz的方波脉冲,工作于方式2,计数初值为18(0012H),OUTl输出的负脉冲脉宽为1÷11931816MHz=838ns,其周期为18÷11931816MHz= 1508 us,即每隔1508us产生一个正脉冲,作为DMAC8237A的0通道的请求信号DREQ0,定时地对系统的动态存储器芯片进行一次刷新 *** 作。

(3)计数器2作为扬声器音频发生器

计数器2用于为系统机箱内的扬声器发声提供音频信号。系统利用扬声器发声进行提示和故障报警。另外,还可对计数器2重新进行初始化,用于乐曲演奏等。

8255方式0是基本输入/输出方式,A、B、C三个口中任何一个口都可提供简单的输入和输出 *** 作,不需要应答联络信号,即可用于无条件传送的场合,也可以用作查询方式传送。当采用查询方式传送时,原则上可用A、B和C三个口的任一位充当查询信号,但通常都是选用C口充当查询信号,这和C口的编程有关。通常把C口的4位(高4位或低4位)规定为输出口,用以输出一些控制信号,把C口的另4位规定为输人口,用以输入外设的状态。

方式1是一种选通输人偷出方式,A口和B口均可工作在这种方式。方式1可作为查询式传送方式,此时握手联络信号,C口要用6位(分成两个3位)分别作为A口和B口的应答联络信号。方式1也可用作中断方式,此时要写对应的C口的按位置位字,打开中断。

方式2是A口独有的双向传送方式,一般使用中断传送方式。

还有8254的本人还没有学到,请不要见怪,我就尽我所能帮你,还有不足的,小弟在这里说对不起了,

你看过汇编吗?与汇编的格式是一样的。具体就是先开中断允许标志位(IE里面对应的各个位)在设定TMOD工作方式。下一步就是设定初始值了(TH、TL)。设置完这些就可以开定时器了。写中断中段函数是是需要另加interrupt 加上一个常数(比如是定时器0就在后面加上1)。我用89S52芯片编过一个定时器程序你参考一下,希望对你有一点帮助。

//功能:感应外界温度并用数码管显示

//时间:2005年6月20日

//设计人:

#include<reg52h>

#define uchar unsigned char

sbit ad0809_oe=P1^0; //定义各个位

sbit ad0809_start=P1^1;

sbit ad0809_ale=P1^2;

sbit ls595_rclk=P1^3;

sbit ad0809_eoc=P1^5;

sbit ls595_oe=P1^4;

sbit ls595_ser=P3^0;

sbit ls595_srclr=P3^1;

uchar nn,mm;

uchar code tab[]={0x81,0xcf,0x92,0x86,0xcc,0xa4,0xa0,0x8f,0x80,0x84};

send(uchar); //声明函数

AD(uchar);

void display(uchar);

void init();

//普通口输入数据

send(uchar shu) //普通口串行输入

{

unsigned char i,k;

k=0x01;

for(i=0;i<8;i++)

{

if(k==(k&shu)) //判断每位上是否为1

ls595_ser=1;

else

ls595_ser=0;

k<<=1; //左移一位

ls595_srclr=0; //输入一个上升沿讲数送入595中

ls595_srclr=1;

}

}

//595显示子程序

void display(uchar du)

{

uchar ge,shi,flge; //ge拆字后个位的存放处shi拆字后十位的存放处flge ℃的存放处

shi=tab[du/10]; //拆字

send(shi); //给595送数

ge=tab[du%10];

send(ge);

flge=0xb1;

send(flge);

ls595_rclk=0; //上升沿送出数据

ls595_rclk=1;

}

//初始化程序

void init() //初始化AD、定时器

{

ad0809_start=0; //Start管教上升沿将AD内部寄存器清零

ad0809_start=1;

ad0809_ale=1; //ALE高电平选择通道

nn=0;

mm=0;

TMOD=0x01; //定时器初始化

//IE=0x82;

EA=1;

ET0=1;

TCON=0x00;

TL0=(65536-50000)%256; //定时50ms

TH0=(65536-50000)/256;

}

AD(uchar wen)

{

// unsigned char tt=0;

// ad0809_ale=1; //选择通道

ad0809_start=1;

ad0809_start=0; //start下降沿启动转换信号

while(ad0809_eoc==0); //判断转换是否结束

ad0809_oe=1; //转换结束送出转换数据

wen=P2;

return (wen);

}

//中断服务程序

void tiam0() interrupt 1 using 1 //中断服务程序

{

TL0=(65536-50000)%256; //定时50ms

TH0=(65536-50000)/256;

nn++;

if(nn==10) //05秒M加一

{

mm++;

nn=0;

}

}

//主程序

void main()

{

unsigned char bb,aa,cc; //bb=计算后得到温度,aa=AD输出数据

unsigned char wen; //wen存放转换的得到的数据

init();

// wen=17;

ls595_oe=0;

cc=0;

TR0=1;

while(1)

{

aa=AD(wen);

// ad0809_oe=0;

aa=~aa;

bb=aa/4;

if(mm==2)

{

mm=0;

cc=bb;

}

display(cc); //调用显示子程序

}

}

/---------------

文件名称: PWMC

功能 :单片机脉冲方式产生PWM信号

----------------/

#include <reg52h> // 引用标准库的头文件

#include <absacch>

#include <stdioh>

#define uchar unsigned char

#define uint unsigned int

#define COUNT0 XBYTE [0X0000] // 8254计数器0寄存器地址

#define COUNT1 XBYTE [0X0200] // 8254计数器1寄存器地址

#define COUNT2 XBYTE [0X0400] // 8254计数器2寄存器地址

#define COMWORD XBYTE [0X0600] // 8254控制寄存器地址

/

函数名称: SIGNAL(SIG_OUTPUT_COMPARE1A)

功能 :定时器0中断子程序

入口参数:无

返回值 :无

/

void time0_int () interrupt 1 using 1

{

TR0=0; // 关闭T0

TH0=-(20000/256);

TL0=-(20000%256); //重置20ms计数值

/--------------用8254计数器发送第一路的PWM信号-----------/

COMWORD=0x30; //1MHz时钟作为计数时钟,计数1000次后实现1ms高电平

COUNT0=0xE0;

COUNT1=0x03;

/--------------用8254发送第二路的PWM信号----------------/

COMWORD=0x70; //1MHz时钟作为计数时钟,计数2000次后实现2ms高电平

COUNT0=0xD0;

COUNT1=0x07;

/-------------用8254发送第三路的PWM信号----------------/

COMWORD=0xB0;//1MHz时钟作为计数时钟,计数3000次后实现32ms高电平

COUNT0=0xB0;

COUNT1=0x0B;

TR0=1; //启动T0

}

//主函数

void main ()

{

EA=1; // 开CPU总中断

ET0=1; // 开T0定时器中断

TMOD=0x01; // 开定时器中断

TH0=-(20000/256); //20ms定时器计数初值

TL0=-(20000%256);

/--------------向8254控制寄存器选择计数器0,并对其赋值0-----------------/

COMWORD=0x30;

COUNT0=0; //赋低位字节

COUNT0=0; //赋高位字节

/---------------向8254控制寄存器选择计数器1,并对其赋值0------------------/

COMWORD=0x70;

COUNT0=0; //赋低位字节

COUNT0=0; //赋高位字节

/---------------向8254控制寄存器选择计数器2,并对其赋值0-----------------/

COMWORD=0xB0;

COUNT0=0; //赋低位字节

COUNT0=0; //赋高位字节

TR0=1; //启动定时器0

While (1); //无限次循环

}

以上就是关于8254的三种读出方式全部的内容,包括:8254的三种读出方式、单片机定时器应用实验程序、8254计数时,外部进来的第一个脉冲怎么处理等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zz/9497901.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-29
下一篇 2023-04-29

发表评论

登录后才能评论

评论列表(0条)

保存