51单片机利用for语句嵌套实现简单的延时1s功能解说和视频教程
51单片机利用for语句嵌套实现简单的延时1s功能
名词解释:
(1)时钟周期。定义为时钟频率的倒数,本例使用12MHz的时钟频率,它的时钟周期大约就是1/12μs。
(2)机器周期。单片机的基本操作周期,STC89C51系列的单片机来说,一个机器周期由12个时钟周期组成,也就是1μs。
(3)指令周期。指的是单片机执行一条指令需要的时间,一个指令周期需要1~4个机器周期。一个for循环需要8个指令周期。
假设单片机采用了12MHz的时钟频率,利用for语句嵌套实现简单的延时1s功能。
unsigned int i;
Unsigned char j; //定义两个循环变量i、j
for (i = 1000; i > 0; i--) //外层循环1000次
for (j = 124; j > 0; j--) ; //内层循环124次
内层循环代码含义:
在12MHz的时钟频率下,for循环124次所消耗的时间ntime是:
ntime= 124次 × 8个指令周期 × 1μs = 992μs
也就是内循环延时大概为1ms。
外层循环代码含义:
外层循环又将内层循环重复1000次:
for (i = 1000; i > 0; i--) //外层循环1000次
那么,全部执行完成花费的总时间T大约是:
T = 1000 × ( ntime + 8 × 1 ) = 1000 ms=1s,基本上达到延时1s的功能。这个延时程序中外层循环的变量是多少,整个for嵌套语句就延时大约多少毫秒,在以后的应用当中,会经常用到这个程序进行不需要精确时间的延时。
比如,要实现2s的延时,就把i=1000修改为i=2000就可以了。
视频教程如下:
视频教程
单片机的功能确实多,做一个秒表应该怎么写程序呢?
单片机也有中断功能,它也会中断单片机主程序正常运行。今天设计的秒表是利用单片机内部资源——定时/计数器中断,前面讲过延时1秒(s),是让单片机空耗一段时间,并且延时时间不是精确的,但是定时器中断获得时间单位就比较精确,精确程度与单片机外接晶振质量有关。
常见的单片机单片机一共有5个中断,即外部中断0、外部中断1、定时/计数中断0、定时/计数中断1、串口中断。
一、制作一个秒表
1.电路
2.程序设计
#include<reg52.h>//头文件
#define uchar unsigned char//宏定义
#define uint unsigned int
uchar table []={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//共阴数码管数组
uchar num,num1,shi,ge;//定义变量
void delay(uchar a)//延时函数
{
uint i,j;
for(j=a;j>0;j--)
for(i=110;i>0;i--);
}
void display(uchar shi,uchar ge)//显示函数
{
P0=table[shi];
P1=0XFE;//1111 1110选中数码管第一位
delay(5);
P0=table[ge];
P1=0XFd;//1111 1101选中数码管第二位
delay(5);
}
void t0init()//初始化
{
TMOD=0X01;//0000 0001//定时器0工作方式1
TH0=0X3C;//装入初值,50毫秒
TL0=0XB0;//装入初值
EA=1;//打开总中断开关
ET0=1;//打开定时器0中断开关
TR0=1;//启动定时器0
}
void main()//主函数
{
t0init();
while(1)//无限循环
{
display(shi,ge);
}
}
void timer0()interrupt 1 //中断函数
{
TH0=0X3C;//装入初值
TL0=0XB0;//装入初值
num++;//变量累加
if(num==20)//1秒
{
num=0;
num1++;
shi=num1/10;//取十位
ge=num1%10;//取个位
if(num1==60)
{
num1=0;
}
}
}
3.程序解释
(1)采用定时器中断必要的语句。
TMOD=0X01;
TMOD是选择定时器工作方式。0X01是定时/计数中断0工作方式1,如果是0X10是定时/计数1工作方式1。
TH0=0X3C;//装入初值
TL0=0XB0;//装入初值
如果单片机外接晶振是12M,它的时钟周期是1/12μs(微妙),12个时钟周期是一个机器周期即1μs,定时/计数0工作方式1,最大值能定时65536μs(2的16次方),约等于65ms。如果需要定时50ms,也就是计数不是从0开始,而是从15536(65536-50000)开始,15536(十进制)换算为16进制为3CB0,即“TH0=0X3C;TL0=0XB0;”,需要计时1s,只需程序中断20次。
EA=1;//打开总中断开关
EA是总开关,好比总电闸。
ET0=1;//打开定时器0中断开关。它是定时器0的开关,好比客厅总电源开关。
TR0=1;//启动定时器0。启动定时器0好比客厅的吊灯开关。
以上语句需要写在主函数中,或者作为函数,在主函数中调用。
(2)void display(uchar shi,uchar ge)//显示函数显示部分用函数形式体现,在主函数循环调用。
(3)中断函数
既然中断产生了,那么中断以后做什么?
void timer0()interrupt 1 //中断函数
{
做什么工作;
}
“timer0”自己起的名字,代表定时/计数0中断,“interrupt”不能写错,关键是它后面的数字千万也不能搞错。需要注意,采用工作方式1,需要在中断函数中重新装入初值。
中断源与序号


相关问答
单片机 怎么设置LED点阵亮的时间长度?要设置LED点阵亮的时间长度,可以通过控制单片机的IO口输出信号来实现。首先,需要确定所使用的单片机型号和开发环境,然后编写相应的程序代码。在程序中,可以...
keil软件调试 延时 时间的详细步骤?mS级带参数延时子程序voiddelay_ms(uintz)//延时子程序{uintx,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}上面这个程...
c语言控制一个led亮两秒,灭一秒?while(1){LEDON;Delay(2000);//延时2SLEDOFF;Delay(1000);//延时1S}程序大体就是这个样子。while(1){LEDON;Dela...
单片机 代码编程时如何嵌入汇编语言?Keil软件设置Keil工程建立好以后进行工程的汇编语言混编设置软件编写51单片机12MHZ晶振延时1S为例汇编程序写在#pragmaasm·······//写汇编语...
51 单片机 c语言编程led灯1,3,5,7和2,4,6,8交替闪烁?假设你的8个LED是通过低电平来点亮,即LED负极连接P口,正极连接电源:1.当1,3,5,7亮时,我们的P2口状态以二进制表示应该是10101010,也就是0xAA,程序应该写成...
如何用PLC编辑暂停 程序 ?1.编程思路:编程之前首先需要弄清楚动作的具体要求,实现的先后顺序。在动作运行过程中,总避免不了实现启动、暂停的功能,而暂停设置即使整个过程停止在当前运...
急求无源蜂鸣器的驱动 程序 , 单片机 是51的?无源蜂鸣器驱动,只需定时将管脚2端电平取反即可如让其响1S,频率约500HZ,可用软延时uinti;for(i=0;i{P1^0=~P1^0;delay_ms(1);}如果想长时间响...
单片机 怎么从矩阵键盘中提取一个按键来实现“按一下键切换一个LED灯亮”?可以啊,可以根据按键时间的长短,和高低电平来实现。比如,长按1s为高电平是一个功能,长按2s是另一个功能。步骤为:先读取某个io口的值,若为高电平(if按...可...
51 单片机程序 ?你这不是都已经把程序写出来了吗?!平铺直叙就是最好的程序。你的要求写成计算机认识的语句就是程序。假定p1口的0--7对应你说的D1__D8,电平高点亮。#inclu...
单片机 8个LED灯随机闪烁怎么做?方法:1:设定一个变量i,可以从0到3循环的变化2:检测一个经过消抖处理的按键,按一下,i+13:当i值为各个值时,执行相应的花样。流水灯参考程序#include...方...