打印
[KungFu8位 MCU]

T0定时器中断模式实验

[复制链接]
6563|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
硬件说明
本实验运用到两个模块,一个是单片机内部功能模块,定时器0(T0),另
一个是数码管显示模块。数码管具体特性在此之前已经讲解过,在此不作敷述,
T0属于内部模块,不需进行接线操作。

程序设计说明
T0是一个8位的定时/计数器,当T0寄存器值加到255时,再加1,则会产生溢
出,T0寄存器的值返回到0开始重新计数。
使用T0定时器,只需配置OPTR一个寄存器,其各个位如图4.1所示。在此重
点讲解定时器0的分频器使用,例如我们采用8M频率,T0工作在定时模式下为每
个机器周期加1,则定时器每次加1的时间是(1/8M)*4=0.5us。如果此时将预分
频器分频比设置成64分频,那么定时器每次加1的时间就是0.5us*64=32us。如果
我们需要一个5MS的定时,那么我们需要156个这样的计数。此时我们即可将T0
寄存器初始值设为100,当T0数值加到256时正好是156个计数,这样便会产生一
个5MS的定时。200个5MS这样的定时就是1S的时间。当T0用于定时中断功能时,
关于OPTR寄存器的说明如下:
1、配置T0CS = 0,使其工作于定时模式。
2、 PS<2:0>位用来设置T0预分频器分频比,如需要进行64分频,则PS0 = 1,
PS1 = 0,PS2 = 1。
其它位按照上电默认配置即可。


#include<KF8F312.h>
/*********************宏定义****************************/
#define uchar unsigned char
#define uint unsigned int
/*********************宏定义结束****************************/
/**********************全局变量*****************************/
uchar const Arr_num[] = {0X3F,
0X06,
0X5B,
0X4F,
0X66,
0X6D,
0X7D,
0X07,
0X7F,
0X6F
}; //共阴接法,数码管显示笔形码
uchar Unit, Decade, Hundred, Thousand; //定义个十百千位
uchar time_1s; //定时计数器
/**********************全局变量结束*************************/
/************************
* 函数名 :Delay_200us
* 函数功能:短时间延时
* 入口参数:无
* 返回 :无
************************/
void Delay_200us()
{
uchar i = 60;
while(--i);
}
/************************
* 函数名 :Init_fun
* 函数功能:初始化函数
* 入口参数:无
* 返回 :无
************************/
void Init_fun(void)
{
OSCCTL = 0x60; // 设置为8M
/*****端口初始化********/
TR0 = 0x08; //设置P03端口为输入
TR1 = 0x00; //设置P1端口为输出
TR2 = 0x00; //设置P2端口为输出
P0 = 0;
P1 = 0;
P2 = 0;
/****初始化定时器0*****/
OPTR = 0x05; //定时器0,分频为1:64,现在晶振为8M,一条指令为
0.5us(1/(8M/4)=0.5us ),则经过32us,计数1
T0 = 0x64; //设定定时5MS, 0X64=100D 即计数156后为256溢
出产生中断,而156*32=4992 约为5000us=5ms
INTCTL = 0XA0; //使能总中断AIE、使能T0中断T0IE、清T0中断标志
位T0IF
}

void main()
{
uchar i;
Unit = 0;
Decade = 0;
Hundred = 0;
Thousand = 0;
time_1s = 0;
Init_fun(); //初始化
while(1)
{
for(i = 0; i < 100; i++)
{
P2 = 0XE0; //打开数码管的个位
P1 = Arr_num[Unit];
Delay_200us();
P1 = 0;
P2 = 0XF0; //消影
P2 = 0XD0; //打开数码管的十位
P1 = Arr_num[Decade];
Delay_200us();
P1 = 0;
P2 = 0XF0; //消影
P2 = 0XB0; //打开数码管的百位
P1 = Arr_num[Hundred];
Delay_200us();
P1 = 0;
P2 = 0XF0; //消影
P2 = 0X70; //打开数码管的千位
P1 = Arr_num[Thousand];
Delay_200us();
P1 = 0;
P2 = 0XF0; //消影
}
}
}
//中断函数
void int_fun() __interrupt
{
if(T0IF)
{
T0IF = 0; //清零中断标志
T0 = 0x64; //T0重新赋值
if(time_1s++ >= 200) //判断是否达到1s记时 5ms*200
= 1s
{
time_1s = 0; //清零计数器
Unit++; //个位相加
if(Unit == 10)
{
Unit = 0;
Decade++; //十位相加
if(Decade == 10)
{
Decade = 0;
Hundred++; //百位相加
if(Hundred == 10)
{
Hundred = 0;
Thousand++; //千位相加
if(Thousand == 10)
{
Thousand = 0;
}
}
}
}
}











使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

85

主题

473

帖子

2

粉丝