实验简介
定时器配置实现LED亮灭,流水灯效果,蜂鸣器是否发声,继电器是否吸附,数码管示值,数字秒表。
实验原理图
实验原理
声明:实验原理部分来自普中51单片机攻略和《“蓝桥杯”全国软件和信息技术专业人才大赛(电子类)实训指导书》
-
定时器介绍:定时计数器可以用于精确事件定时。IAP15F2K61S2 单片机内部集成了 3 个 16 位的定时/计数器 T0、 T1 和 T2,其核心部件是一个加法计数器( TH 和 TL),对输入脉冲进行计数。若计数脉冲来自系统时钟,则为定时器方式;若计数脉冲来自 T0( P34)、 T1( P35)或 T2( P31)引脚,则为计数器方式。 -
知识补充:学习定时器需要了解CPU 时序的有关知识。 振荡周期: 为单片机提供定时信号的振荡源的周期(晶振周期或外加振荡周期) 。机器周期:即CPU周期,完成一个基本操作所需要的时间。机器周期=1/单片机的内部时钟频率。内部时钟频率是外部时钟的 12 分频 ,也就是说当外部晶振的频率输入到单片机里面的时候要进行 12分频。1 个机器周期含12 个振荡周期。指令周期:完成 1 条指令所占用的全部时间,它以机器周期为单位。外接晶振为 12MHz 时,振荡周期=1/12us;机器周期=1us;指令周期=1~4us;可知工作在定时模式时最高单次定时时间约为65535*1us=65ms < 100ms,也就是说单次定时无法达到0.1s,这点在后面的综合模块中会用到 -
特殊功能寄存器介绍:TMOD是定时/计数器的工作方式寄存器, 确定工作方式和功能; TCON是控制寄存器, 控制 T0、 T1 的启动和停止及设置溢出标志。
- 工作方式寄存器 TMOD。
工作方式寄存器 TMOD 用于设置定时/计数器的工作方式,低四位 用于 T0, 高四位 用于 T1。GATE 是门控位,GATE = ,软件使 TR0 或 TR1 为 1,能启动定时/计数器工作。GATE = 1,软件使 TR0 或 TR1 为 1,再使外部中断引脚 INT0/1 也为高电平时, 才能启动定时/计数器工作。C/T :定时/计数模式选择位。 C/T =0 为定时模式;C/T =1 为计数模式。M1M0 :定时/计数器 T0 和 T1 具有四种工作方式,由特殊功能寄存器 TMOD 中的 M1 和 M0 位决定,具体工作方式设置,下图示。
其中我们特别解释一下,方式 1 的计数位数是 16 位, 由 TL0 作为低 8 位, TH0 作为高 8 位, 组成了16 位加 1 计数器。 门控位 GATE = 0 ,经过非门反相,再经过或门输出为1,此时仅由 TR0 控制与门的开启, 与门输出 1 时, 控制开关接通, 计数开始;而门控位 GATE = 1 ,我们类比可以分析出,此时与门的开启由外中断引脚信号和 TR0 共同控制,由此解释了上述工作方式寄存器 TMOD中门控位GATE的相关赋值方式。方式1其结构图如下所示:
- 控制寄存器 TCON
TCON 的低 4 位用于控制外部中断,可以去《蓝桥杯CT107D单片机竞赛板》:中断模块查看。TCON 的高 4 位用于控制定时/计数器的启动和中断申请。TF1 :T1 溢出中断请求标志位。 T1 计数溢出时由硬件自动置 TF1为 1。CPU 响应中断后 TF1 由硬件自动清 0。 T1 工作时, CPU 可随时查询 TF1 的状态。 所以, TF1 可用作查询测试的标志。这点我们会在后面的综合应用中使用到,TF1 也可以用软件置 1 或清 0, 同硬件置 1 或清 0 的效果一样。TR1 :T1 运行控制位。TR1 = 1,定时器1工作,TR1 = 0,定时器停止工作。TR1 由软件置 1 或清 0。TF0 ,和TR0 用法类似于定时器1。
- 定时器配置:①TMOD
设置定时器模式 ,确定 T0 和 T1 的工作方式。②根据所要定时的时间计算初值 ,并将其写入THx,TLx中,例如外部晶振12MHZ,定时1ms,每次获取输入脉冲,即经历了一个机器周期1us时间,1ms/1us=1000。计数 1000 个,对于方式1为16位的定时/计数器,由于计数器到65535 再加 1 才会溢出,故初值=65535-1000+1=64536=FC18H,所以初值即为 THx=0XFC,TLx=0X18。③若 使用中断,则对 EA 赋值,开放 定时器中断④启动 定时器的运行控制位TRx
实验程序
定时器0控制LED隔 1 秒闪烁
#ifndef _CONFIG_H
#define _CONFIG_H
#include <STC15F2K60S2.H>
#define uchar unsigned char
#define uint unsigned int
#endif
#include "config.h"
uchar uled = 0;
void close_peripheral()
{
P2 = (P2 & 0x1f) | 0x80;
P0 = 0xff;
P2 = (P2 & 0x1f) | 0xa0;
P0 = 0xaf;
P2 &= 0x1f;
}
void Timer0Init()
{
AUXR &= 0x7F;
TMOD &= 0xF0;
TMOD |= 0x01;
TL0 = 0x18;
TH0 = 0xFC;
TF0 = 0;
TR0 = 1;
ET0=1;
EA=1;
}
void main()
{
close_peripheral();
Timer0Init();
while(1);
}
void timer0() interrupt 1
{
static uint i;
TL0 = 0x18;
TH0 = 0xFC;
i++;
if (1000 == i)
{
i = 0;
uled ^= 1;
P2 = (P2 & 0x1f) | 0x80;
P0 = ~uled;
P2 &= 0x1f;
}
}
定时器0控制蜂鸣器和继电器
main.c代码主要改变部分
void timer0() interrupt 1
{
static uint i;
TL0 = 0x18;
TH0 = 0xFC;
i++;
if (1000 == i)
{
i = 0;
uled ^= 0x50;
P2 = (P2 & 0x1f) | 0xa0;
P0 = ~uled;
P2 &= 0x1f;
}
}
定时器1实现流水灯效果
#ifndef _CONFIG_H
#define _CONFIG_H
#include <STC15F2K60S2.H>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#endif
#include "config.h"
uchar time = 0;
void Timer1Init(void)
{
AUXR &= 0xBF;
TMOD &= 0x0F;
TMOD |= 0x10;
TL1 = 0xB0;
TH1 = 0x3C;
TF1 = 0;
TR1 = 1;
ET1 = 1;
EA = 1;
}
void main()
{
uchar data1 = 0xfe;
Timer1Init();
while(1)
{
P2 = (P2 & 0x1f) | 0x80;
P0 = data1;
P2 &= 0x1f;
if (time >= 10)
{
time = 0;
data1 = (data1 << 1) | 0x01;
if(0xff == data1)
data1 = 0xfe;
}
}
}
void timer1() interrupt 3
{
time++;
TL1 = 0xB0;
TH1 = 0x3C;
}
定时器0每2ms对S7进行扫描,按下则n值加1,数码管显示
#ifndef _CONFIG_H
#define _CONFIG_H
#include <STC15F2K60S2.H>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
void Delay20ms();
#endif
#include "config.h"
sbit S7 = P3^0;
uchar dspcom = 0;
uchar dspbuf[8];
uchar n = 0;
uchar tab[] = {
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};
void close_peripheral()
{
P2 = (P2 & 0x1f) | 0x80;
P0 = 0xff;
P2 = (P2 & 0x1f) | 0xa0;
P0 = 0xaf;
P2 &= 0x1f;
}
void Timer0Init(void)
{
AUXR &= 0x7F;
TMOD &= 0xF0;
TMOD |= 0x01;
TL0 = 0x30;
TH0 = 0xF8;
TF0 = 0;
TR0 = 1;
ET0 = 1;
EA = 1;
}
void display()
{
P2 = (P2 & 0x1f) | 0xe0;
P0 = 0xff;
P2 = (P2 & 0x1f) | 0xc0;
P0 = 1 << dspcom;
P2 = (P2 & 0x1f) | 0xe0;
P0 = ~tab[dspbuf[dspcom]];
P2 &= 0x1f;
if (++dspcom == 8)
{
dspcom = 0;
}
}
void main()
{
close_peripheral();
Timer0Init();
while(1)
{
if (0 == S7)
{
Delay20ms();
if (0 == S7)
{
n++;
dspbuf[0] = n / 10;
dspbuf[1] = n % 10;
if (n >= 100)
n = 0;
}
while(!S7);
}
}
}
void timer0() interrupt 1
{
TL0 = 0x30;
TH0 = 0xF8;
display();
}
void Delay20ms()
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 1;
j = 234;
k = 113;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
定时器1实现数字秒表–使用定时器1查询
注意:该实验与下一个实验区别可以观察Timer1Init()函数,以及TF1的使用
#ifndef _CONFIG_H
#define _CONFIG_H
#include <STC15F2K60S2.H>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
void Delay20ms();
#endif
#include "config.h"
uchar dspcom = 0;
uchar dspbuf[8];
uint cnt;
uchar sec, min;
uchar tab[] = {
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};
void close_peripheral()
{
P2 = (P2 & 0x1f) | 0x80;
P0 = 0xff;
P2 = (P2 & 0x1f) | 0xa0;
P0 = 0xaf;
P2 &= 0x1f;
}
void Timer1Init(void)
{
AUXR &= 0xBF;
TMOD &= 0x0F;
TMOD |= 0x10;
TL1 = 0x30;
TH1 = 0xF8;
TR1 = 1;
}
void data_proc()
{
dspbuf[0] = 16;
dspbuf[1] = 16;
dspbuf[2] = 16;
dspbuf[3] = 16;
dspbuf[4] = min / 10;
dspbuf[5] = min % 10;
dspbuf[6] = sec / 10;
dspbuf[7] = sec % 10;
}
void display()
{
P2 = (P2 & 0x1f) | 0xe0;
P0 = 0xff;
P2 = (P2 & 0x1f) | 0xc0;
P0 = 1 << dspcom;
P2 = (P2 & 0x1f) | 0xe0;
P0 = ~tab[dspbuf[dspcom]];
P2 &= 0x1f;
if (++dspcom == 8)
{
dspcom = 0;
}
}
void main()
{
close_peripheral();
Timer1Init();
while(1)
{
if (TF1)
{
data_proc();
display();
cnt++;
TF1 = 0;
TL1 = 0x30;
TH1 = 0xF8;
if (cnt >= 500)
{
cnt = 0;
sec++;
if (sec >= 60)
{
sec = 0;
min++;
if (min >=60)
min = 0;
}
}
}
}
}
定时器1实现数字秒表
#ifndef _CONFIG_H
#define _CONFIG_H
#include <STC15F2K60S2.H>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#endif
#include "config.h"
uchar dspcom = 0;
uchar dspbuf[8];
uint cnt;
uchar sec, min;
uchar tab[] = {
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};
void close_peripheral()
{
P2 = (P2 & 0x1f) | 0x80;
P0 = 0xff;
P2 = (P2 & 0x1f) | 0xa0;
P0 = 0xaf;
P2 &= 0x1f;
}
void Timer1Init(void)
{
AUXR &= 0xBF;
TMOD &= 0x0F;
TMOD |= 0x10;
TL1 = 0x18;
TH1 = 0xFC;
TR1 = 1;
ET1 = 1;
EA = 1;
}
void data_proc()
{
dspbuf[0] = min / 10;
dspbuf[1] = min % 10;
dspbuf[2] = sec / 10;
dspbuf[3] = sec % 10;
dspbuf[4] = 16;
dspbuf[5] = cnt / 100;
dspbuf[6] = cnt / 10 % 10;
dspbuf[7] = cnt % 10;
}
void display()
{
P2 = (P2 & 0x1f) | 0xe0;
P0 = 0xff;
P2 = (P2 & 0x1f) | 0xc0;
P0 = 1 << dspcom;
P2 = (P2 & 0x1f) | 0xe0;
P0 = ~tab[dspbuf[dspcom]];
P2 &= 0x1f;
if (++dspcom == 8)
{
dspcom = 0;
}
}
void main()
{
close_peripheral();
Timer1Init();
while(1);
}
void timer1() interrupt 3
{
data_proc();
display();
cnt++;
TL1 = 0x18;
TH1 = 0xFC;
if (cnt >= 1000)
{
cnt = 0;
sec++;
if (sec >= 60)
{
sec = 0;
min++;
if (min >=60)
min = 0;
}
}
}
定时器1实现00-00-00型数字时钟
#ifndef _CONFIG_H
#define _CONFIG_H
#include <STC15F2K60S2.H>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#endif
#include "config.h"
uchar dspcom = 0;
uchar dspbuf[8];
uint cnt;
uchar sec, min, h;
uchar tab[] = {
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};
void close_peripheral()
{
P2 = (P2 & 0x1f) | 0x80;
P0 = 0xff;
P2 = (P2 & 0x1f) | 0xa0;
P0 = 0xaf;
P2 &= 0x1f;
}
void Timer1Init(void)
{
AUXR &= 0xBF;
TMOD &= 0x0F;
TMOD |= 0x10;
TL1 = 0x18;
TH1 = 0xFC;
TR1 = 1;
ET1 = 1;
EA = 1;
}
void data_proc()
{
dspbuf[0] = h / 10;
dspbuf[1] = h % 10;
dspbuf[2] = 17;
dspbuf[3] = min / 10;
dspbuf[4] = min % 10;
dspbuf[5] = 17;
dspbuf[6] = sec / 10;
dspbuf[7] = sec % 10;
}
void display()
{
P2 = (P2 & 0x1f) | 0xe0;
P0 = 0xff;
P2 = (P2 & 0x1f) | 0xc0;
P0 = 1 << dspcom;
P2 = (P2 & 0x1f) | 0xe0;
P0 = ~tab[dspbuf[dspcom]];
P2 &= 0x1f;
if (++dspcom == 8)
{
dspcom = 0;
}
}
void main()
{
close_peripheral();
Timer1Init();
while(1);
}
void timer1() interrupt 3
{
data_proc();
display();
cnt++;
TL1 = 0x18;
TH1 = 0xFC;
if (cnt >= 1000)
{
cnt = 0;
sec++;
if (sec >= 60)
{
sec = 0;
min++;
if (min >=60)
{
min = 0;
h++;
if (h >= 24)
h = 0;
}
}
}
}
定时器1设定1分钟闹钟,数码管显示时间,S7停止计数,S6开始计数
#ifndef _CONFIG_H
#define _CONFIG_H
#include <STC15F2K60S2.H>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
void Delay10ms();
#endif
#include "config.h"
sbit S6 = P3^1;
sbit S7 = P3^0;
uchar dspcom = 0;
uchar dspbuf[8];
uint cnt;
uchar sec, min;
uchar tab[] = {
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};
void close_peripheral()
{
P2 = (P2 & 0x1f) | 0x80;
P0 = 0xff;
P2 = (P2 & 0x1f) | 0xa0;
P0 = 0xaf;
P2 &= 0x1f;
}
void Timer1Init(void)
{
AUXR &= 0xBF;
TMOD &= 0x0F;
TMOD |= 0x10;
TL1 = 0x18;
TH1 = 0xFC;
TR1 = 0;
ET1 = 1;
EA = 1;
}
void data_proc()
{
dspbuf[0] = 16;
dspbuf[1] = 16;
dspbuf[2] = 16;
dspbuf[3] = 16;
dspbuf[4] = 16;
dspbuf[5] = 16;
dspbuf[6] = sec / 10;
dspbuf[7] = sec % 10;
}
void display()
{
P2 = (P2 & 0x1f) | 0xe0;
P0 = 0xff;
P2 = (P2 & 0x1f) | 0xc0;
P0 = 1 << dspcom;
P2 = (P2 & 0x1f) | 0xe0;
P0 = ~tab[dspbuf[dspcom]];
P2 &= 0x1f;
if (++dspcom == 8)
{
dspcom = 0;
}
}
void main()
{
close_peripheral();
Timer1Init();
while(1)
{
if (0 == S6)
{
Delay10ms();
if (0 == S6)
TR1 = 1;
while(!S6);
}
if (0 == S7)
{
Delay10ms();
if (0 == S7)
{
TR1 = 0;
sec = 0;
P2 = (P2 & 0x1f) | 0xa0;
P0 = 0xaf;
P2 &= 0x1f;
}
while(!S7);
}
}
}
void timer1() interrupt 3
{
data_proc();
display();
cnt++;
TL1 = 0x18;
TH1 = 0xFC;
if (cnt >= 1000)
{
cnt = 0;
sec++;
if (sec >= 60)
{
P2 = (P2 & 0x1f) | 0xa0;
P0 = 0x5f;
P2 &= 0x1f;
TR1 = 0;
sec = 0;
}
}
}
void Delay10ms()
{
unsigned char i, j;
i = 117;
j = 184;
do
{
while (--j);
} while (--i);
}
|