加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

STC89C52单片机的定时器使用

(2012-06-16 19:35:42)
标签:

stc89c52单片机

 ////////////////////////////////////////////////////////////////////////
 实现功能:  配置定时器2的相关寄存器,使其实现定时器中断功能,然后根据中断
             的周期频率实现准确的时钟系统,在数码管上显示实现
 实验板型号:BS-XYD-C52
 实验名称:  定时器2实现时钟系统
 编写人:  谢应东
 编写日期:  2012-4-28     
/////////////////////////////////////////////////////////////////////////
#include<reg52.h>  
#define uchar unsigned char  //定义unsigned char 为 uchar
#define uint  unsigned int  //定义unsigned int 为 uint

uchar cTime_10ms_counter;  //中断次数计数单元
uchar cTime_1s_ok;    //判断是否为1s的变量
uchar uDis_buff[6];    //显示缓冲区,存放要显示的6个字符的段码值
uchar cTime[3];     //时、分、秒计数单元

#define Time_1s_Sign 100  //根据中断周期,判断是否到一秒的标志

sbit led=P1^0;
sbit Duan=P2^6;     //定义数码管的段选使能端
sbit Wei =P2^7;        //定义数码管的位选使能端

#define Digital_tube_Wei_Enable Wei=1;  //开启控制数码管的位选使能端
#define Digital_tube_Wei_Disable Wei=0;     //关闭控制数码管的位选使能端

#define Digital_tube_Duan_Enable Duan=1; //开启控制数码管的段选使能端
#define Digital_tube_Duan_Disable Duan=0; //关闭控制数码管的段选使能端

#define Digital_tube_Duan P0    //定义数码管数据端口

uchar code Dis_table[]=      //将BCD码转换成数码管扫描码的数组
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x00};
uchar code Dis_Position[]=  //定义数码管位选的数组
{0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
/////////////////////////////////////////////////////////////////////////

函数名称:毫秒延时函数
函数功能:实现毫秒级的延时
参数介绍:Delay_MS: 定义需要延时的毫秒的数值
          iNumber: 记录Delay_MS的数值,以for语句实现所要求的延时
    iValue: 要延时毫秒所要进行的循环数值,本数值为实际测得
返回值: 
注意事项:本实验是在所用晶振为12M的前提下实现的毫秒延时,本函数是通过循环的形
          式完成,所以如果改变了晶振的频率,请做相应的改变
/////////////////////////////////////////////////////////////////////////

void DelayMs(uint Delay_MS)
{
 uint iNumber,iValue;
 for(iNumber=0;iNumber<Delay_MS;iNumber++)    //用for语句实现单片机的延时
 {
     iValue=107;      //107这个数值是通过测定而得
     while(iValue--);
 }
}
/////////////////////////////////////////////////////////////////////////
函数名称:One_DigitalTube_display
函数功能:完成在实验板上数码管指定显示,即在特定的数码管上显示特定的数字,比
          在第一个数码管上显示0
参数介绍:cData:要显示的数字的BCD码数组
          cNumber:选择哪个数码管显示,即让某个特定数码管显示
返回值: 
注意事项:实验板上的数码管是共阴极的数码管,如果使用共阳极的数码管,请注意不
          要弄反了
/////////////////////////////////////////////////////////////////////////

void One_DigitalTube_display(uchar cData,uchar cNumber)

  Digital_tube_Duan_Enable;      //使能数码管的段选
  Digital_tube_Duan=Dis_table[cData];//输入所要显示的数值
  Digital_tube_Duan_Disable;      //关闭数码管的段选
 
  Digital_tube_Wei_Enable;      //使能数码管的位选
  Digital_tube_Duan=Dis_Position[cNumber]; //点亮特定的数码管的公共端
  Digital_tube_Wei_Disable;      //关闭数码管的位选
  DelayMs(1);         //调整时序,以实现稳定显示
}
/////////////////////////////////////////////////////////////////////////
函数名称:Time_to_disbuffer
函数功能:把要在数码管上显示的数值,进行取余、取整,即对数值进行分割,这样以
          便显示在分离的数码管
参数介绍:cNumber1: 记录时、分、秒计数单元数组的变量
    cNumber2:记录显示缓冲区数组的变量
返回值: 
注意事项:无
/////////////////////////////////////////////////////////////////////////
void Time_to_disbuffer()
{
 uchar cNumber1,cNumber2=0;
 for(cNumber1=0;cNumber1<=2;cNumber1++)
 {
  uDis_buff[cNumber2++]=cTime[cNumber1]/10;   //对cTime的数值取整,即
                                              //就是取cTime的十位
  uDis_buff[cNumber2++]=cTime[cNumber1]; //对cTime的数值取余,即
                                              //就是取cTime的个位
 }
}
/////////////////////////////////////////////////////////////////////////
函数名称:Init_time2
函数功能:配置定时器2,配置的模式是定时器1采用16位定时器模式,在定时器1的输入
          数值寄存器输入特定的数值,使其每次中断的周期为10ms,同时允许定时器1
          中断,并打开总中断
参数介绍:无
返回值: 
注意事项:无
/////////////////////////////////////////////////////////////////////////
void Init_time1(void)
    
  TH2=(65535-10000)/256;  
  TL2=(65535-10000)%6;  //定时器0的,写入数值寄存器的低8位
    EA=1;             //总中断打开
  ET2=1;            //定时器T0允许中断
  TR2=1;            //定时器T0开始工作
}
/////////////////////////////////////////////////////////////////////////

函数名称:Timer_Display
函数功能:把显示缓冲区的数值显示在数码管上
参数介绍:cNumber:记录for语句的循环次数
返回值: 
注意事项:无
/////////////////////////////////////////////////////////////////////////
void Timer_Display()
{
   uchar cNumber;
   for(cNumber=0;cNumber<6;cNumber++)
   {
     One_DigitalTube_display(uDis_buff[cNumber],cNumber);
  if(cNumber==1|cNumber==3)
  {
   Digital_tube_Duan_Enable;      //使能数码管的段选
         Digital_tube_Duan=0x80;             //输入所要显示的数值
         Digital_tube_Duan_Disable;      //关闭数码管的段选
 
         Digital_tube_Wei_Enable;     //使能数码管的位选
         Digital_tube_Duan=Dis_Position[cNumber]; //点亮特定的数码管的公共端
         Digital_tube_Wei_Disable;     //关闭数码管的位选
   DelayMs(1);
  }
   }
}
/////////////////////////////////////////////////////////////////////////

函数名称:main
函数功能:利用定时器2中断,实现准确的时钟系统,然后在数码管上显示实现
参数介绍:无
返回值: 
注意事项:无
/////////////////////////////////////////////////////////////////////////
void main()
{
    Init_time1();     //初始化定时器1
    cTime[0]=23,cTime[1]=58,cTime[2]=58;    
 Time_to_disbuffer();        //把预设时间送入显示缓冲区    
 while(1)
 {
  if(cTime_1s_ok)       //判断是否到1秒了
  {
   cTime_1s_ok=0;
   if(++cTime[2]>=60)     //每次自加一,同时判断是否到1分钟
   {
    cTime[2]=0;
    if(++cTime[1]>=60)    //每次自加一,同时判断是否到1小时了
    {
     cTime[1]=0;
     if(++cTime[0]>=24) //每次自加一,同时判断是否到24点了
     {
      cTime[0]=0;
     }
    }
   }
   Time_to_disbuffer();   //新调整好的时间送入显示缓冲区
  }
  Timer_Display();      //更新显示内容
 }
}
/////////////////////////////////////////////////////////////////////////

函数名称:Interrupt_handler_time2
函数功能:重新给寄存器TH2和TL2赋值,判断是否到达一秒,如果到一秒了,把相应的
          变量赋予正值,以方便其他的程序编写
参数介绍:无
返回值: 
注意事项:无
/////////////////////////////////////////////////////////////////////////
void Interrupt_handler_time2(void) interrupt 5
{
 TF2=0;
  TH2=(65535-10000)/256;//定时10毫秒
 TL2=(65535-10000)%6;
 cTime_10ms_counter++;
 if(cTime_10ms_counter==Time_1s_Sign) //判断是否到达一秒
 {
  cTime_10ms_counter=0;
  cTime_1s_ok=1; 
 }
}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有