一、实验目的 1.理解单片机的定时/计数原理,掌握定时/计数程序的编写方法。
2.掌握定时/计数器在定时、计数方面的应用。
3.学会使用 PROTEUS 中 VSM 虚拟示波器观察波形。
二、实验任务 1.基本任务
(1)利用单片机定时器/计数器设计一个秒表,由 P0 口连接 LED 灯,采用 BCD 码
显示,发光二极管亮表示 1,暗则表示 0,计满 100s 后从头开始,依次循环。利用一只
按键控制秒表的启、停。请在 Proteus 中画出电路原理图,并编写程序仿真实现上述功
能。
(2) 用单片机内部的 T0 或 T1 定时,实现:在 P1.7 引脚上输出一个矩形波,该矩
形波的宽度为 500ms,周期为 1.5s。请在 Proteus 中画出电路原理图,并编写程序仿真
实现上述功能。在 Proteus 中用虚拟示波器观察该矩形波。
#include //包含 51 标准文件头
#define uchar unsigned char
#define uint unsigned char
uchar dat=0; //定义 BCD 计数单元(范围: 0~99)
uchar i; //定义循环变量
int cnt=0;
sbit key=P1^0; //定义按键
/*---------------------- T0 初始化子函数 -----------------------*/
void Timer0Init(void) //50毫秒@12.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xB0; //设置定时初值
TH0 = 0x3C; //设置定时初值
TF0 = 0; //清除TF0标志
EA = 1; //全局中断使能
ET0 = 1; //定时器0中断使能
}
/*---------------------- T1 初始化子函数 -----------------------*/
void Timer1Init(void) //50毫秒@12.000MHz
{
AUXR &= 0xBF; //定时器时钟12T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0xB0; //设置定时初值
TH1 = 0x3C; //设置定时初值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
EA = 1; //全局中断使能
ET1 = 1; //定时器1中断使能
}
/*-------------------- T0 中断服务子函数 -----------------------*/
void Timer0_int(void) interrupt 1 //T0 中断服务子程序
{
i++;
if(i==10) //计时 1S
{
i = 0;
dat++;
if(dat==100) //计时到 100S 时,又从 0 开始
{
dat = 0;
}
}
}
/*-------------------- T1 中断服务子函数 -----------------------*/
void Timer1_isr (void) interrupt 3
{
cnt++;
if(cnt==10)
P17=!P17;
else if(cnt==30)
{
cnt=0;
P17=!P17;
}
}
/*----------------------- 启动子函数 ---------------------------*/
void Start(void) //启动定时函数
{
if(key==0) //判断按键按下
{
TR0=1; //定时器0开始计时
}
else
{
TR0=0; //定时器0结束计时
}
}
/*-------------------- BCD 码转换子函数 ------------------------*/
int decimal_bcd_code(int decimal) //十进制转BCD码
{
int sum = 0, i; //i计数变量,sum返回的BCD码
for ( i = 0; decimal > 0; i++)
{
sum |= ((decimal % 10 ) << ( 4*i));
decimal /= 10;
}
return sum;
}
/*-------------------------- 主函数 ---------------------------*/
void main(void)
{
Timer0Init(); //T0 初始化
Timer1Init(); //T1 初始化
while(1)
{
Start(); // 启动定时
P0 = ~(decimal_bcd_code(dat)); //送 LED 显示
}
}