① 51单片机怎么实现计时
嘿嘿 还是让俺来帮你解决吧
1 关于定时器定时时间的计算问题:
如果使用的是12M晶振计算,指令周期1uS,定时器是加1计数器,即是对内部时钟即指令周期脉冲计数 每当1uS到时,计数器加1。
假设 定时器的初始值=X,则每到1uS 计数器的值就加1 ,则计数器值=X+1+1+...+1 值越来越大,最后达到FFFFH+1 就会产生溢出 结果计数器值回0(FFFFH+1=65536)
可以推出 定时时间=计数的1的个数×1uS=(65536—X )1 uS
结论: 定时时间跟初始值即时间常数X有关。
如果要定时0.5毫秒=500uS 根据定时时间公式 500=(65536—X )
即X=(65536-500) 一般把高8位送TH0 即 (65536-500)/256
把 (65536-500)%256即除上256后的余数 即低8位数送给TL0
每当定时时间到 计数器值都回0 必须重新送时间常数X
2每条指令的时间怎么算? 答复:
可以查指令表 每一条指令的执行时间的周期数 都是固定的 如 NOP 为一个机器周期
MOV R6,#200; 为2个机器周期
机器周期=12/晶振频率 如果晶振频率=12MHZ 则机器周期=1 uS
就可以知道 ; 执行NOP指令的执行时间为 1 uS
执行MOV R6,#200指令的执行时间为 2 uS
因此 是可以精确计算出指令的延时时间的
呵呵 就介绍这些吧 满意就 给加分吧
② 单片机如何计时
2个按钮分别接在2个中断口上,为单片机扩展一个数码管,2位还是4位看你需要显示多少了,或者使用6位,分别显示时,分,秒
程序是:单片机启动,初始化,循环等待
中断0中断,开始启动定时器,定时50毫秒,计数20次,计数的值为秒;
秒>60,则分+1,分>60,则时+1.
分别把时分秒数据送到数码管,数码管刷新
中断1中断,中断1服务子程序取消定时器中断,计时停止。
电路硬件:
1、at89c51
2、常开按钮(轻触开关)2只
3、共阴数码管,6只。
4、单片机最小系统必须的晶振1块,电容30pF,2只,复位电路需要的10u电解电容1只,电阻10K一只,开关1只,供电另计
因为外部器件不多,就直接用P2送数码管位码,没有扩展显示芯片。
③ 51单片机软件延时和定时器的区别
区别就是用单片机软件定时,CPU循环执行一小段延时程序,浪费CPU的精力,用定时器定时,CPU就可以干别的。
如果是程序延时的话,时间消耗在(延时程序+剩下的代码);计时器中断则相当于把延时程序交给定时器,此时CPU可以干别的事情,提高了效率。就类似于电脑打游戏时把图形处理任务交给显卡,CPU的压力就小。
单片机进中断后执行中断里的程序,比如你进定时中断,执行完后退出中断后做其他事,但定时还在计数,这样计数和做其他事情两不误。
你的程序中本来就没做其他事情,你的LED移动就是等待中断计数到10才操作的,LED动作的先决条件就是中断计数结束。
(3)单片机软计时扩展阅读
1、软件循环延时:采用循环语句,如for,while等,进行长时间的空操作,或者空语句。
优点:程序理解简易,入手快,新手必备武器。
缺点:时间精度不高,且占用单片机大量时间资源,引发其它子函数的不流畅(卡滞、迟钝),导致系统实时反应能力下降。
2、定时延时:采用定时器定时,如T0,T1;
优点:时间精度高,提高系统程序执行的高效性,不影响子函数的正常运行。
缺点:需占用1个定时器资源(可以复用),需良好程序构架支持,入手难。
个人建议:一旦学会定时器,就不应该再使用“循环延时”函数,采用定时器才是正道。如果对延时精度要求不高,建议使用结构体组成多个延时体。
④ 利用51单片机,4个数码管设计一个计时器,要求在数码管上显示的数据从0开始每1秒钟加1。
共阳数码管中断程序:
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[]=
{
0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x83,0xf8,
0x80,0x90,0x88,0x83,
0xc6,0xa1,0x86,0x8e};
uint num,a;
uchar ,shi,ge;
void init();
void delay(uint);
void display(uchar,ucharshi,ucharge);
uint fb();
uint fs();
uint fg();
void main()
{
init();
while(1)
{
display(fb(),fs(),fg());
}
}
void init()
{
num=0;
a=0;
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
void display(uchar,ucharshi,ucharge)
{
P1=0xfd;
P0=table[];
delay(1);
P1=0xfb;
P0=table[shi];
delay(1);
P1=0xf7;
P0=table[ge];
delay(1);
}
void timeoff() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65526-50000)%256;
a++;
if(a%20==0)
{
num++;
if(num==999)
{
num=0;
}
}
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
uint fb()
{
=num/100;
return ;
}
uint fs()
{
shi=num%100/10;
return shi;
}
uint fg()
{
ge =num%100%10;
return ge;
}
(4)单片机软计时扩展阅读
2个可编程定时/计数器·5个中断源,2个优先级(52有6个)
一个全双工串行通信口
外部数据存储器寻址空间为64kB
外部程序存储器寻址空间为64kB
逻辑操作位寻址功能·双列直插40PinDIP封装
单一+5V电源供电
CPU:由运算和控制逻辑组成,同时还包括中断系统和部分外部特殊功能寄存器;
RAM:用以存放可以读写的数据,如运算的中间结果、最终结果以及欲显示的数据;
ROM:用以存放程序、一些原始数据和表格;
I/O口:四个8位并行I/O口,既可用作输入,也可用作输出
T/C:两个定时/记数器,既可以工作在定时模式,也可以工作在记数模式;
五个中断源的中断控制系统;
一个全双工UART(通用异步接收发送器)的串行I/O口,用于实现单片机之间或单片机与微机之间的串行通信;
片内振荡器和时钟产生电路,石英晶体和微调电容需要外接。最佳振荡频率为6M—12M。
参考资料来源:网络-51单片机
⑤ 51单片机用软件定时来控制舵机,延时函数怎么写求解
延时可以用定时器来实现,也可以自己写延时函数。
这是51单片机定时器初始化示例程序。
TMOD = 0x10f; //GATE=0 01010001
//C/T=0--定时/计数器1工作于定时方式
//M1=1;M0=0--选择工作模式1,构成最大定时器
//T0:在此程序不使用
TL1 = 0x13; TH1 = 0x2C; //指定定时时间为50ms 65536-50/(11.0592/12)=11283=2C13h
EA = 1; //开总中断
TF1 = 0;
ET1 = 1; //开定时器中断
TR1 = 1; //开始计时
如果用延时函数,要精确计算时间。
这是精确定时1ms的程序,你可以参考一下。
void delay1ms(void)
{
unsigned char a,b,c;
for(c=1;c>0;c--)
for(b=142;b>0;b--)
for(a=2;a>0;a--);
}
⑥ 51单片机十秒简易计时器
因为楼主说,(不要太大面积修改)。
所以,就没有敢进行大面积的修改。
只简单的改改,未必能好用,仅供参考:
#include<reg51.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[] = {
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
sbit key1=P2^7;
sbit key2=P2^6;
sbit weiH=P3^0;
sbit weiM=P3^1;
sbit weiL=P3^2;
uint num=0,ge=0,shi=0,fen=0,k;
//num用来计数,ge为各位显示,shi为十位显示,fen为分钟显示
void delayms(uint xms) //i=xms即延时约xms毫秒
{
uint i,j;
for(i=xms;i>0;i--) for(j=110;j>0;j--);
}
uchar key1scan()
{
if(key1==0) {
delayms(10);
if(key1==0) {
while(!key1) showtime();//等待释放期间,也进行显示
return 1;
}
}
return 0;//添上了返回值
}
uchar key2scan()
{
if(key2==0) {
delayms(10);
if(key2==0) {
while(!key2) showtime();
return 1;
}
}
return 0;//添上了返回值
}
void showtime() //时间显示
{
//这里去掉了while(1) ,避免了死循环
P1=0xff; weiL=1; P1=table[ge]; delayms(5); weiL=0;//显示秒的个位
P1=0xff; weiM=1; P1=table[shi]; delayms(5); weiM=0;//显示秒的十位
P1=0xff; weiH=1; P1=table[fen]; delayms(5); weiH=0;//显示分钟,
}