编程题 设MCS-51单片机系统中晶振频率为12MHz,欲使用定时器/计数器1,采用方式1编写实现1秒定时时间的程

作者&投稿:望标 (若有异议请与网页底部的电邮联系)
设MCS-51单片机使用的晶振是12MHz,欲使用定时器/计数器1实现50ms定时中断.~

不管使用什么工作方式都是可以完成的,这个取决于你设置的定时/计数器的初值。下面使用方式一和方式二来分别说明。
一、使用方式一:
晶振频率为12MHz,机器周期为1us,50ms时间需要计数50000次,故计数器初值为(65536-50000),65536是因为方式一中,定时/计数器的最大值为65536(2^16),当然写程序时不一定非要这么计算,因为定时/计数器是溢出产生中断,也就是从最大加1就溢出,最大加1就是等于0的,只要计数个数加上初值等于0就溢出了,也就产生中断了。由于题目上给的是TH1、TL1,所以,设置的时候必须设置定时/计数器T1。故TMOD = 0x10,TCON中只需要设置TR1为1,故TCON = 0x40,IE需要设置ET0和EA为1,故IE = 0x88。
C语言程序:
#include
void main (void)
{
TMOD = 0x10;
TH1 = (-50000>>8);
TL1 = -50000;
TCON = 0x40;
IE = 0x88;
while(1);
}

void T1_int (void) interrupt 3
{
TH1 = (-50000>>8);
TL1 = -50000;
}

汇编程序如下:
ORG 0000H
AJMP MAIN
ORG 001BH
AJMP T1INT
ORG 0100H
MAIN:
MOV TMOD, #10H
MOV TH1, #HIGH(-50000)
MOV TL1, #LOW(-50000)
MOV TCON, #40H
MOV IE, #88H
AJMP $
T1INT:
PUSH ACC
MOV TH1, #HIGH(-50000)
MOV TL1, #LOW(-50000)
POP ACC
RETI
二、使用方式二:
由于方式二最大计数值只能是256,显然装不下50000,故可以选一个比较小的计数值,做多次循环就可以做到。选用计数个数为200,那么循环250次就可以了。
C语言程序:
#include
void main (void)
{
TMOD = 0x20;
TH1 = -200;
TL1 = -200;
TCON = 0x40;
IE = 0x88;
while(1);
}

void T1_int (void) interrupt 3
{
static unsigned char i = 0;
if (++i >= 250)
i = 0; //如果等于250次,说明50ms时间到了
}

汇编语言:
ORG 0000H
AJMP MAIN
ORG 001BH
AJMP T1INT
ORG 0100H
MAIN:
MOV TMOD, #20H
MOV TH1, #-200
MOV TL1, #-200
MOV R1, #250
MOV TCON, #40H
MOV IE, #88H
AJMP $
T1INT:
PUSH ACC
DJNZ R1, OUT
MOV R1, #250
OUT: POP ACC
RETI

晶振是12MHz,所以机器周期T=1μs
需定时,C//T=0
30ms/1μs=30000
因为30000>8192,需选择方式1,M1M0=01
TMOD=0000 0001B
计数初值为:
65536-30000=35536=8AD0H
所以
TH0=6AH,TL0=0D0H
因为开放总中断和T0中断,IE=10000010B

TCON=0001 0000B;启动T0,TR0就是TCON中的控制位,也可用位操作指令直接将TR0置1
程序见“做而论道”给的程序。

采用12Mhz晶振的51单片机,软件如下(调试通过)

#include <reg52.h>

#define PERIODH (65536l-50000l)/0X100 //设50ms中断1次TH1初值
#define PERIODL (65536l-50000l)%0X100 //设50ms中断1次TL1初值
//如果需要极精确的延时,应根据实际编译后的产生的汇编指令,扣除掉中断响应中重装所占用的时间

unsigned int count;//延时时间变量

void timer1() interrupt 3 using 1
{//定时器每0.05秒一次中断

TH1 = PERIODH;
TL1 = PERIODL;

if(count)
{//计数未到0,则保持定时器运行,计数器-1
count--;
}
else
{//计数到0,关定时器
TR1 =0; //stop timer 1
}

}

//以秒为基本定时单位的子程序
void Delay1S(unsigned char x)
{
TH1 =PERIODH;
TL1 =PERIODL;
TR1 = 1;//此时定时开始

count = 20*x;//因50ms中断1次,故乘20
while(count);
}

main()
{
TMOD = 0X10;//方式1
EA = 1;//总中断允许
ET1 = 1;//定时器1中断允许

while(1)
{
Delay1S(1);//延时1秒
Delay1S(2);//延时2秒
Delay1S(3);//延时3秒
Delay1S(4);//延时4秒

}
}

Delay1S函数是调用时才开始计时,根据需要的定时长度到时停止计时。如果定时精度要求不高,可以不用在中段服务程序中关闭定时器,每次调用误差也就在50ms。
可以用KEIL仿真看一下实际时间

#include <reg51.h>
unsigned char i;
void main()
{
TMOD=0x10;
TH1=0x3c;
TL1=0xb0;
EA=1;
ET1=1;
TR1=1;

while(1)
{
if(i==20)
{
i=0;
//下面写你要处理的的其他程序,你只要了定时1s。
}
}
}

void a(void) interrupt 3
{
unsigned char i;
TH1=0x3c;
TL1=0xb0;
i++;
}

12Mhz的51单片机,经过12分频后为1MHz,则一个指令周期为1/1Mhz = 1us.
则定时50ms为 0xffff - 0x3cb0,即65535 - 15535 = 50000us = 50ms,则20次的定时:20×50ms=1s。

明白了吗?怪简单的问题……

祝你顺利哦!

这个太简单了,给你个方法,你自己弄吧,不会多看看书。
1 使能定时器
2 使能定时器中断
3 编写中断程序
我估计你是觉得1秒的时间,定时器达不到,你可以在中断里面再自己写个计数,或者开启计数器2,这样两两相乘,时间就能到1秒钟了。
要做到精确的定时,就要用计数器2,然后在Keil里可以看到时间,再对定时器进行微调就好了。

void sheding()
{
TMOD=0x10;//定时器/计数器工作方式寄存器的设定
TH1=(65536-50000)/256;
TL1=(65536-50000)%265;
//定时器/计数器控制寄存器设定
EA=1; //全局中断允许位
ET1=1; //打开定时器/计数器1
TR1=1;
}
void zhongduan() interrupt 3
{
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
k++;
if(k==20)
{
k=0;
shu++;
if(shu==86400)
shu=0;
}
}

#include <reg51.h>
unsigned int num ;
void InitTimer1(void)
{
TMOD = 0x10;
TH1 = 0x3C; //50ms定时
TL1 = 0x0B0;
EA = 1;
ET1 = 1;
TR1 = 1;
}

void main(void)
{
InitTimer1();
}

void Timer1Interrupt(void) interrupt 3
{
TH1 = 0x3C;
TL1 = 0x0B0;
num++;
if(num==20){ ;} //1S时间到。
}


安塞县17320586013: 设mcs - 51单片机中,晶振频率为12mhz,编程实现使p1.0和p1.1分别输出周期为2ms和5 -
向珊抵克: ORG 0000H LJMP MAIN ORG 000BH LJMP T0ISR ORG 0030H MAIN: MOV TMOD,#01H MOV TH0,#HIGH(65536-250) MOV TL0,#LOW(65536-250) SETB TR0 SETB ET0 SETB EA MOV R2,#0 SJMP $ T0ISR: CLR TR0 MOV TH0,#HIGH(65536-250) MOV TL0,#LOW(65536-250) SETB TR0 CPL P1.1 INC R2 CJNE R2,#4,T0E CPL P1.0 MOV R2,#0 T0E: RETI END

安塞县17320586013: 设MCS - 51的单片机时钟频率为12Mhz请编写程序在P1.7脚输出周期为1s,脉宽为1ms的脉 -
向珊抵克: #include<reg51.h> #define uchar unsigned char sbit pluse=P1^7; void delay(int a) { uchar i; while(a--)for(i=0;i<120;i++); } main() { while(1){pluse=1;delay(1);pluse=0;delay(999);} }

安塞县17320586013: 设MCS - 51单片机主频为12MHZ,编写一个延时10秒的程序 -
向珊抵克: void timer0() interrupt 1 { uchar count; TH0 = (65536-50000)/256; TL0 = (65536-50000)%6; count++; if(count == 20) { count = 0; sec++; if(sec == 100) { sec = 0; } } }

安塞县17320586013: 设MCS - 51单片机的晶振频率为12MHZ,使用定时器1工作方式1中断方式在P1输出周期为100ms的方波 -
向珊抵克: ;ORG 0000HSJMP STARTORG 0001BHMOV TH1, #(65536 - 50000) / 256MOV TL1, #LOW(65536 - 50000)CPL P1.0RETI START:MOV TMOD, #10HMOV TH1, #(65536 - 50000) / 256MOV TL1, #LOW(65536 - 50000)SETB TR1MOV IE, #88HSJMP $END

安塞县17320586013: 请教几道单片机编程题目,谢谢帮助!!!!!!! -
向珊抵克: 1、编程,将8031单片机片内RAM 20H至2FH单元中的数据顺序移到50H至5FH单元中.ORG 0000HMOV R0,#20HMOV R1,#50HMOV R7,#10H L00P: MOV A,@R0MOV @R1,AINC R0INC R1DJNZ R7,LOOPEND 2、编程,将8031单...

安塞县17320586013: 单片机编程设计一按键和LED发光二极管MCS - 51单片机最小工作系统,并编写 -
向珊抵克: ORG 0000H LJMP MAIN ORG 0030HMAIN: CLR EAMOV SP,#5FH CLR P1.0 LOOP: JB P1.3,LOOP ;键未按下等待 JNB P1.3,$ ;键未抬起等待 CPL P1.0 ;LED取反,按键切换 SJMP LOOP END

安塞县17320586013: 设MCS - 51单片机的晶振频率为12MHZ,试编写10ms的延时程序(要求误差不超过0.003ms). -
向珊抵克: 我们用汇编语言写单片机延时10ms的程序(用的是12MHz晶振的 MCS-51),可以编写下面的程序来实现: MOV R5,#5 ① D1: MOV R6,#4 ② D2: MOV R7,#248 ③ DJNZ R7,$ ④ DJNZ R6,D2 ⑤ DJNZ R5,D1 ⑥ RET ⑦ 这个延时程序共有七条指...

安塞县17320586013: 利用mcs - 51单片机指令系统设计一段交通灯轮流点亮的程序 -
向珊抵克: 参考程序, 具体留言商议.ORG 0000HLJMP MAINORG 0100H MAIN:MOV SP,#60H ; LCALL DIR ;调用日期、时间显示子程序 LOOP:MOV P1,#0FFHLJMP TESTLCALL ROAD1 ;路口1的车直行时各路口灯亮情况LCALL DLY30s ;...

安塞县17320586013: 4. 用中断的方法有单片机P1.0每秒产生一个机器周期的正脉冲. 求程序 MCS - 51 -
向珊抵克: 假设晶振是12MHZ的,你用16位的定时器0,定时100ms,这样,在中断程序里面,设置一个计数的寄存器,记够10次后对p1.0口进行一次置位和清0操作,至于定时器怎么初始化和赋初值,自己从书上找.在写程序的时候一定要事先说明晶振是多少,这样才可以你程序里的计数器初值对应起来.

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网