No7 蓝桥杯单片机实践之定时器的应用

1 回顾:

程序编写结构还是中断函数结构的写法,只是由于定时器涉及的寄存器较多,中断初始条件函数中条件也就随之增多。

void  函数名()

{

主要写一些初始化变量。(基本的就是3.1~3.5所涉及的寄存器的初值条件设定)

}

void  函数名() interrupt  中断号

{

就是写时间到后执行什么。(但是为了中断的实时性,有时只写只写中断状态的标志,紧急事件用另一个函数来写,后续实践篇代码有讲)

}

别忘了还要查看对应的中断号

涉及的寄存器要查看手册,通常会涉及到:

高低位寄存器

TMOD寄存器

中断寄存器

TCON寄存器

2 实践

2.1 任务

2.2 思路

涉及的模块:

这里涉及到了LED操作,故HC138接到4通道,才能是控制LED灯的,只有L1和L8两个灯,可以用sbit标出来,可读性比较强。

用到了定时,故定时的结构需要写出来。

在定时结构中,题目要求是Time0,查询资料手册,涉及的寄存器有如下,并写入代码: 

L1灯单位是0.5秒,L8单位是5秒,两者成一个倍数关系,故只需要一个初值即可,以0.5秒为初值,但一个定时器运行完依次最多为65535us,即65.532ms,

                                              需要0.5s即500ms即500000us,

故可以每次计时50000us,定时器运行10次,就到达了0.5s, 定时器运行100次,就到达了5秒。

按照之前所提的公式: TH0 = (65535 - 50000) / 256;
                                     TL0 =  (65535 - 50000) % 256;

void Init_Time0()
{
  TMOD = 0x01;
  TH0 = (65535 - 50000) / 256;
  TL0 = (65535 - 50000) % 256;
  TR0 = 1;
  EA = 1;
  ET0 = 1;

}

然后在中断服务函数上判断是否到达0.5s,到达了进行L1操作

在进一步判断是否到达5s,到达了进行L8操作。

2.3 完整代码:

这里解释以下:

(1)判断定时器运行10次和100次可以用一个变量累加来判断。然后取余操作判断是否达到了每一个10次,当达到100次时,变量清零重计数

(2)在中断中L1和L8的闪烁操作用的是取反:

为什么可以这样呢?中断程序是这样的,刚刚提到定时器运行10次才到达0.5s,默认L1初始为1,即不点亮,当定时器运行了10次才能到达0.5s,注意在这十次中,每一次,都进入了中断服务函数,但是执行到了count++后就不再执行下去,因为没满足if条件,故这段时间L1一直是熄灭的,熄灭时间为(0~9次),刚好10次,0.5秒。当执行第十次时,满足第一个if条件,到达0.5s,那么L1取反为0,点亮。在第11到第19次中,同样,每一次,都进入了中断服务函数,但是执行到了count++后就不再执行下去,因为没满足if条件,故在这段时间内L1一直=0,即L1一直是点亮状态,这段点亮持续了多久呢?(第10次到第19次),刚好10次,故点亮了0.5s。直到第20次,又满足了第一个if条件,L1取反为1,熄灭。

这就是在中断中可以用取反来表示LED闪烁的原因。

#include "stc15f2k60s2.h"

sbit L1 = P0^0;
sbit L8 = P0^7;

void selectHC138(unsigned int n)
{
  switch(n)
  {
    case 0:
      P2 = (P2 & 0x1f) | 0x00;  break;
   	case 1: 
			P2 = (P2 & 0x1f) | 0x20;  break; 
		case 2:
			P2 = (P2 & 0x1f) | 0x40;  break; 
		case 3: 
			P2 = (P2 & 0x1f) | 0x60;  break; 
		case 4:
			P2 = (P2 & 0x1f) | 0x80;  break; 
		case 5:
			P2 = (P2 & 0x1f) | 0xa0;  break; 
		case 6:
			P2 = (P2 & 0x1f) | 0xc0;  break; 
		case 7:
			P2 = (P2 & 0x1f) | 0xe0;  break;
  }
}

void Init_Time0()
{
  TMOD = 0x01;
  TH0 = (65535 - 50000) / 256;
  TL0 = (65535 - 50000) % 256;
  TR0 = 1;
  EA = 1;
  ET0 = 1;
}

unsigned char count = 0;
void Time0() interrupt 1
{

  TH0 = (65535 - 50000) / 256;
  TL0 = (65535 - 50000) % 256;
  count ++;
  if (count % 10 == 0)
  {
    L1 = ~L1;

  }
  if (count %100 == 0)
  {
    L8 = ~L8;
    count = 0;
  }
  
}



void close()   //关闭外设
{
  selectHC138(5);
  P0 = 0x00;
  selectHC138(4);
  P0 = 0xff;  
}

void main()
{
  close();
  Init_Time0();
  selectHC138(4);
  while(1)
  {
    
  }
}

3 进阶版实践

3.1 任务

3.2 思路

这里涉及到多种模块:

定时器 :故定时器结构得写下来

数码管计时: 故要数码管得动态变化:数码管内容表(0~F,-) 数码管函数(包括内容和位置),数码管显示函数(显示什么内容),延时函数,HC138选择通道。

独立按键的使用:跳帽接到对应位置。由于只用了两个独立按键,可用sbit表示出来,要写个独立按键函数,判断是否按下。

这里主要的核心是定时器怎么设置:

题目要求设计秒表,分—秒—毫秒。

最小单位为50ms,即数码管最后两位每加1代表每加50ms,即01=50ms,02=100ms。

又1s= 1000ms  ,最小单位为50ms,故数码管最后两位加到20就为1s,秒的两个位置(s位)+1,且数码管最后两位(ms位)清零。

同理,1min=60s,当秒位加到60,清零,min位+1。

数码管显示动态显示对应的位置,由于分—秒—毫秒都是各占两位,如用除和区域可得到各自的十位和个位。

3.3完整代码

注意:     

TR0 = ~TR0;     //表停止计时

#include "stc15f2k60s2.h"
sbit S4 = P3^3;
sbit S5 = P3^2;

void selectHC138(unsigned int n)
{
  switch(n)
  {
    case 0:
      P2 = (P2 & 0x1f) | 0x00;  break;
    case 1: 
			P2 = (P2 & 0x1f) | 0x20;  break; 
		case 2:
			P2 = (P2 & 0x1f) | 0x40;  break; 
		case 3: 
			P2 = (P2 & 0x1f) | 0x60;  break; 
		case 4:
			P2 = (P2 & 0x1f) | 0x80;  break; 
		case 5:
			P2 = (P2 & 0x1f) | 0xa0;  break; 
		case 6:
			P2 = (P2 & 0x1f) | 0xc0;  break; 
		case 7:
			P2 = (P2 & 0x1f) | 0xe0;  break;
  }
}

void Delay(unsigned char t)
{
  while(t--);
}

code unsigned char SMG_Table[] = 
{
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0x88, //A
0x83, //b
0xc6, //C
0xa1, //d
0x86, //E
0x8e,  //F
0xbf  //-
};

unsigned char t_min = 0;
unsigned char t_s = 0;
unsigned char t_ms = 0;
//==============================Timer============
void InitTime0()
{
  TMOD = 0x01;
  TH0 = (65535-50000) / 256;
  TL0 = (65535-50000) % 256;
  TR0 = 1;
  ET0 = 1;
  EA = 1;
}

void Time0() interrupt 1
{
  TH0 = (65535-50000) / 256;
  TL0 = (65535-50000) % 256;
  t_ms++;
  if (t_ms == 20)
  {
    t_s++;
    t_ms = 0;
    if (t_s == 60)
    {
      t_min++;
      t_s = 0;
    }
  }
  if (t_min == 99)
  {
    t_ms = 0;
    t_s = 0;
    t_min = 0;
  }
}
//==============================================

void showSMG(unsigned char position, unsigned char number)
{
  selectHC138(6);
  P0 = 0x01 << position;
  selectHC138(7); 
  P0 = SMG_Table[number];
}

void SMGDisplay()
{
  showSMG(0,t_min/10);
  Delay(500);
  showSMG(1,t_min%10);
  Delay(500);
  showSMG(2,16);
  Delay(500);
  showSMG(3,t_s/10);
  Delay(500);
  showSMG(4,t_s%10);
  Delay(500);
  showSMG(5,16);
  Delay(500);
  showSMG(6,t_ms/10);
  Delay(500);
  showSMG(7,t_ms%10);
  Delay(500);
}

//void SMGDelay(unsigned char t)
//{
//  while(t--)
//  {
//    
//  }
//}

void Key()
{
  if(S4 == 0)  //stop
  {
    Delay(50);
    if(S4 == 0)
    {
      TR0 = ~TR0;     //停止计时
      while(S4 == 0)
      {
        SMGDisplay();       
      }
    }
  }
  if(S5 == 0)  // clear to 0
  {
    Delay(50);
    if(S5 == 0)
    {
      t_ms = 0;
      t_s = 0;
      t_min = 0;
      while(S5 == 0)
      {
        SMGDisplay();       
      }
    }
  }
}

void close()
{
  selectHC138(5);
  P0 = 0x00;
  selectHC138(4);
  P0 = 0xff; 
}

void main()
{
  close();
  InitTime0();
  while(1)
  {
    SMGDisplay();
    Key();
  }
}

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-14 07:16:04       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-14 07:16:04       106 阅读
  3. 在Django里面运行非项目文件

    2024-03-14 07:16:04       87 阅读
  4. Python语言-面向对象

    2024-03-14 07:16:04       96 阅读

热门阅读

  1. 信号和槽1

    2024-03-14 07:16:04       38 阅读
  2. sql server 生成本月日期的临时表

    2024-03-14 07:16:04       43 阅读
  3. RocketMQ的两种消费模式

    2024-03-14 07:16:04       37 阅读
  4. 逻辑回归吧

    2024-03-14 07:16:04       40 阅读
  5. 使用链表的优先级队列

    2024-03-14 07:16:04       41 阅读
  6. qt+ffmpeg 实现音视频播放(一)

    2024-03-14 07:16:04       38 阅读
  7. Qt如何保证控件调用时候的线程安全

    2024-03-14 07:16:04       40 阅读
  8. 22.5 RabbitMQ

    2024-03-14 07:16:04       36 阅读