利用定时/计数器T0从P1.0输出周期为1s的方波,让发光二极管以1Hz闪烁,设晶振频率为12MHz。
2021-01-20,51单片机学习笔记
代码(精简注释):
/*********************************************************
利用定时/计数器T0从P1.0输出周期为1s的方波,
让发光二极管以1HZ闪烁,设晶振频率为12MHz
**********************************************************/
#include <reg52.h>
unsigned char num;
sbit LED1=P1^0;
void main()
{
num=0;//初始化计数变量
EA=1;//打开特殊功能寄存器IE内的总开关EA
ET0=1;//打开特殊功能寄存器IE内的开关ET0
TMOD=0X01;//0000 0001
//低四位,GATE=0,C/T=0,M1M0=01;选用中断源T0,方式1,16位定时器
TH0=(65536-50000)/256;//初始化,装填初值
TL0=(65536-50000)%256;
TR0=1;//启动定时器
while(1)
{
if(num==20)
{
num=0;//中断函数每执行20次,初始化计数变量
LED1=~LED1;//取反
}
}//中断函数每执行20次,led1取反一次,20*50ms=1s,即led1以1s的间隔交替点亮熄灭
}
//中断函数 中断源:"定时/计数器0(T0)",代号1
void time0() interrupt 1
{
TH0=(65536-50000)/256;//初始化,装填初值60(8进制)
TL0=(65536-50000)%256;//初始化,装填初值176(8进制)
num++;//计数变量自增
/*方式1是对每一个机器周期进行计数,直到计满后,溢出,申请中断
这里是从15536(=65536-50000)位置开始计数,逐次加1,直到65535位置即将溢出,再加1,回到0
共50000次"加1",机器周期为1us时,每次加1耗时1us,全程耗时50ms*/
}
代码(详细注释):
/*********************************************************
利用定时/计数器T0从P1.0输出周期为1s的方波,
让发光二极管以1HZ闪烁,设晶振频率为12MHz
**********************************************************/
#include <reg52.h>
unsigned char num;
sbit LED1=P1^0;
void main()
{
num=0;//初始化计数变量
EA=1;//打开特殊功能寄存器IE内的总开关EA
ET0=1;//打开特殊功能寄存器IE内的开关ET0
TMOD=0X01;//0000 0001
/*
TMOD是定时/计数器的工作方式寄存器,
确定工作方式和功能。低四位用于T/C0,高四位用于T/C1。
自左向右:
高四位:[GATE|C/T|M1|M0]低四位:[GATE|C/T|M1|M0]
((这里选择T/C0,使用低四位,所以高四位设置0))‘0000 xxxx’
GATE:门控位。
GATE=0时,只要使TCON中的TR0或TR1为1,就可以启动定时/计数器(T/C)
工作。(其中:TR0对应T/C0;TR1对应T/C1)
GATA=1时,要满足两个条件,才能启动定时/计数器(T/C)工作:
1.使TR0或TR1为1。
2.同时外部中断引脚INT0/1也为高电平时。
(INT0对应T/C0;INT1对应T/C1)
((这里选择GATE=0,TR0=1))‘0000 0xxx’
C/T:定时/计数模式选择位。
C/T=0为定时模式;C/T=1为计数模式。
((这里选择C/T=0,定时模式))‘0000 00xx’
M1M0:工作方式设置位。
定时/计数器有四种工作方式,由M1M0进行设置。
M1M0=00,方式0,13位定时器/计数器
M1M0=01,方式1,16位定时器/计数器
M1M0=10,方式2,8位自动重装定时器/计数器
M1M0=11,方式3,T0分成两个独立的8位定时器/计数器,T1此方式停止计数
((这里选择M1M0=01,方式1))‘0000 0001’
*/
TH0=(65536-50000)/256;//初始化,装填初值,装填初值60(8进制)
TL0=(65536-50000)%256;//初始化,装填初值,装填初值176(8进制)
/*方式1(M1M0=01),定时器(C/T=0)模式
方式1的计数位数是16位,由TL0作为低8位,TH0作为高8位,组成了16位加1计数器
16位寄存器可以装填的范围是0~65535,共65536个数
65535(10)=1111 1111 1111 1111(2)=FFFF(16)=177777(8)
16位定时器0装初值的计算公式:
假设要计的个数是n,
TH0=(65536-n)/256;//高8位=差对256(2的8次方)求商
TL0=(65536-n)%256;//低8位=差对256(2的8次方)求余
*/
TR0=1;//启动定时器
/*TR0(TCON.4)T/C0运行控制位
TR0置1时,T/C0开始工作;TR0置0时,T/C0停止工作.TR0由软件置1或清0.
所以,用软件可控制定时/计数器的启动与停止.
*/
while(1)
{
if(num==20)
{
num=0;//中断函数每执行20次,初始化计数变量
LED1=~LED1;//取反
}
}//中断函数每执行20次,led1取反一次,20*50ms=1s,即led1以1s的间隔交替点亮熄灭
}
//中断函数 中断源:"定时/计数器0(T0)",代号1
/*5个中断源的代号分别是:
外部中断0(INT0)-->0
定时/计数器0(T0)-->1
外部中断1(INT1)-->2
定时/计数器1(T1)-->3
串行口-->4
它们的优先级从上到下由高到低递减*/
void time0() interrupt 1
{
TH0=(65536-50000)/256;//初始化,装填初值60(8进制)
TL0=(65536-50000)%256;//初始化,装填初值176(8进制)
num++;//计数变量自增
/*((这里要装填的个数为50000))
((fosc=12MHz,震荡周期=1/12um,机器周期=1us))
((50000*1us=50ms,单次执行延时50ms))
振荡周期:为单片机提供振荡源的周期(是指振荡源的两个相邻同方向峰值之间的时间)
机器周期:1个机器周期等于12个振荡周期
方式1是对每一个机器周期进行计数,直到计满后,溢出,申请中断
这里是从15536(=65536-50000)位置开始计数,逐次加1,直到65535位置即将溢出,再加1,回到0
共50000次"加1",机器周期为1us时,每次加1耗时1us,全程耗时50ms
*/
}
写在最后:
本文仅为个人学习笔记,诸多纰漏,欢迎斧正!