如何使用定时器延迟功能及ISR实现LED的闪烁

LEDs

357人已加入

描述

  在我们之前的Nuvoton 微控制器教程中,我们使用了一个基本的 LED 闪烁程序作为入门指南,并将 GPIO 接口作为连接触觉开关的输入。通过该教程,我们完全了解如何配置 Keil 项目并设置编程 N76E003 Nuvoton 微控制器的环境。是时候使用微控制器单元的内部外围设备了,并通过使用N76E003的内置定时器进一步移动一点。在本教程中,我们将学习如何使用定时器延迟功能以及定时器 ISR(中断服务程序)并闪烁两个单独的 LED。

  硬件设置和要求

  由于本项目的要求是学习Timer ISR 和 timer delay 函数,我们将使用两个 LED,其中一个在 while 循环中使用 timer delay 闪烁,另一个在 ISR 函数中闪烁。

  由于 N76E003 开发板中提供了 LED,因此该项目需要一个额外的 LED 和限流电阻来限制 LED 电流。我们需要的组件 -

  LED的任何颜色

  100R电阻

  更不用说,除了上述组件,我们还需要基于N76E003 微控制器的开发板以及Nu-Link 编程器。此外,还需要面包板和连接线来连接所有组件。

  LED与Nuvoton N76E003接口的电路图

  正如我们在下面的示意图中看到的,测试 LED 在开发板内部可用,它连接在端口 1.4 上。一个额外的 LED 连接到端口 1.5。电阻 R3 用于限制 LED 电流。在最左侧,显示了编程接口连接。

定时器

  Nuvoton N76E003 上的定时器引脚

  N76E003的引脚图如下图所示——

定时器

  正如我们所看到的,每个引脚都有不同的规格,每个引脚都可以用于多种用途。但是,用作 LED 输出引脚的引脚 1.5 将失去 PWM 和其他功能。但是,这不是问题,因为该项目不需要其他功能。

  选择引脚 1.5 作为输出和引脚 1.6 作为输入的原因是因为 GND 和 VDD 引脚最近可用,以便于连接。但是,在这个微控制器的 20 个引脚中,有 18 个引脚可以用作 GPIO 引脚,任何其他 GPIO 引脚都可以用于输出和输入相关用途,除了引脚 2.0 专用于复位输入,不能用作输出。所有 GPIO 引脚都可以在下面描述的模式下进行配置。

定时器

  根据数据表,PxM1.n 和 PxM2.n是两个寄存器,用于确定 I/O 端口的控制操作。由于我们使用的是 LED,并且我们需要该引脚作为通用输出引脚,因此我们将使用准双向模式作为引脚。

  Nuvoton N76E003 中的定时器寄存器

  对于任何微控制器单元来说,定时器都是很重要的。微控制器带有一个内置的定时器外设。nuvoton N76E003 还配备了16 位定时器外设。然而,每个定时器用于不同的目的,在使用任何定时器接口之前,了解定时器是很重要的。

  新唐N76E003中的时间类型

  定时器 0 和 1:

  这两个定时器 timer0 和 timer1 与 8051 定时器相同。这两个定时器可用作通用定时器或计数器。这两个定时器以四种模式运行。在模式 0中,这些定时器将在 13 位定时器/计数器模式下运行。在模式 1中,这两个定时器的分辨率位将为 16 位。在模式 2中,定时器配置为具有 8 位分辨率的自动重载模式。在模式 3中,定时器 1 暂停,定时器 0 可同时用作计数器和定时器。

  在这四种模式中,大多数情况下使用模式 1。这两个定时器可以在固定或预分频模式(Fys / 12)下使用 Fsys(系统频率)。它也可以由外部时钟源提供时钟。

  定时器 2:

  定时器 2 也是一个 16 位定时器,主要用于波形捕捉。它还使用系统时钟,并且可以通过使用 8 个不同的比例来划分时钟频率,从而在不同的应用中使用。它也可以用于比较模式或产生 PWM。

  与 Timer 0 和 Timer 1 一样,Timer 2 可以在自动重载模式下使用。

  定时器 3:

  定时器 3 也用作 16 位定时器,用作 UART 的波特率时钟源。它还具有自动重新加载功能。如果应用程序需要 UART 通信,请务必将此定时器仅用于串行通信 (UART)。在这种情况下,由于计时器设置中的冲突过程,建议不要将此计时器用于其他目的。

  看门狗定时器:

  看门狗定时器可用作标准的 6 位定时器,但不用于此目的。看门狗定时器用作通用定时器适用于微控制器大部分处于空闲模式的低功耗应用。

  看门狗定时器,顾名思义,总是检查微控制器是否正常工作。在微控制器挂起或停止的情况下,WDT(看门狗定时器)会自动复位微控制器,确保微控制器在连续的代码流中运行,而不会出现卡住、挂起或停止的情况。

  自唤醒定时器:

  这是另一个定时器外设,它提供与看门狗定时器相同的专用定时过程。当微控制器在低功耗模式下运行时,此定时器会定期唤醒系统。

  此定时器外设可在内部使用或使用外部外设将微控制器从睡眠模式唤醒。对于这个项目,我们将使用 Timer 1 和 Timer 2。

为定时器编程 Nuvoton N76E003 微控制器

将引脚设置为输出:

让我们先从输出部分开始。我们使用了两个 LED,一个是板载 LED,命名为 Test,连接到 P1.4 端口,一个外部 LED 连接到引脚 P1.5。

因此,这两个引脚配置为输出引脚,以使用以下代码片段连接这两个 LED。

 

#define Test_LED P14 
#define LED1 P15

 

这两个引脚在设置函数中设置为准双向引脚。

 

无效设置(无效){
                P14_准模式;
                P15_准模式;
                }

 

  设置定时器功能:

  在设置功能中,需要配置定时器 2 以获得所需的输出。为此,我们将 T2MOD 寄存器设置为 1/128 时钟分频因子,并在自动重载延迟模式下使用它。这是T2MOD寄存器的概述-

定时器

  T2MOD 寄存器的第 4、5 和 6 位设置定时器 2 时钟分频器,第 7 位设置自动重载模式。这是使用以下行完成的 -

 

TIMER2_DIV_128;
TIMER2_Auto_Reload_Delay_Mode;

 

这两行在Function_define.h文件中定义为

 

#define TIMER2_DIV_128 T2MOD|=0x50; T2MOD&=0xDF
#define TIMER2_Auto_Reload_Delay_Mode T2CON&=~SET_BIT0; T2MOD|=SET_BIT7; T2MOD|=SET_BIT3

 

现在,这些行设置了 Timer 2 ISR 所需的时序值。

 

RCMP2L = TIMER_DIV128_VALUE_100ms;
RCMP2H = TIMER_DIV128_VALUE_100ms>>8;

 

在 Function_define.h 文件中进一步定义为-

 

TIMER_DIV128_VALUE_100ms 65536-12500 //12500*128/16000000 = 100 ms

 

因此,16000000 是 16 Mhz 的晶振频率,它设置了 100 ms 的时间延迟。

下面两行将清空 Timer 2 Low 和 High 字节。

 

TL2 = 0; 
TH2 = 0;

 

最后,下面的代码将启用定时器 2 中断并启动定时器 2。

 

设置_ET2;// 启用 Timer2 中断
设置_EA;
设置_TR2;// Timer2 运行

 

完整的设置功能可以在下面的代码中看到 -

 

无效设置(无效){ 
P14_Quasi_Mode; 
P15_准模式;
TIMER2_DIV_128;
TIMER2_Auto_Reload_Delay_Mode;
RCMP2L = TIMER_DIV128_VALUE_100ms;
RCMP2H = TIMER_DIV128_VALUE_100ms>>8;
TL2 = 0; 
TH2 = 0; 
设置_ET2;// 启用 Timer2 中断
set_EA; 
设置_TR2;// Timer2 运行
}

 

定时器 2 ISR 功能:

Timer 2 ISR 功能可以在下面的代码中看到。

 

void Timer2_ISR (void) 中断 5 
{ 
                  clr_TF2; //清除 Timer2 中断标志
                  ​​ LED1 = ~LED1; // LED1 切换,连接在 P1.5;   
}

 

Clr_TF2将清除定时器 2 中断标志​​,并且每当调用 ISR 函数时 LED 将被切换。由于中断设置为 100 ms,LED 将以 100 ms 的时间间隔闪烁。

主函数和while循环:

一个硬件,如果连接电源并且工作正常,那么它应该连续输出并且应用程序永远不会停止。它无限次地做同样的事情。来了函数while循环。while 循环内的应用程序无限运行。首先,调用 setup 函数。

 

设置(); 
而(1){                         
                        Test_LED = 0; 
                        Timer1_Delay10ms(100); 
                        测试_LED = 1;
                        Timer1_Delay10ms(100); 
  } 
}

 

上面的 while 循环根据 Timer 1 延迟使 LED 闪烁。该值设置为 1 秒。

定时器 1 在板支持包中提供的 delay.c 文件中配置。

 

无效 Timer1_Delay10ms(UINT32 u32CNT){ 
    clr_T1M; //T1M=0, Timer1 时钟 = Fsys/12 TMOD |= 0x10; //Timer1为16位模式                                                                                                                                       
set_TR1; //启动 Timer1                                                                                                                                                                         
    while (u32CNT != 0) {
        TL1 = LOBYTE(TIMER_DIV12_VALUE_10ms); //在 "Function_define.h" "TIMER VALUE" 中找到定义
        TH1 = HIBYTE(TIMER_DIV12_VALUE_10ms); 
        而(TF1!= 1);//检查Timer1超时标志
        clr_TF1; 
        u32CNT——;
    } 
    clr_TR1; //停止定时器
1 }

 

  在上述函数中,定时器 1 的时钟在 16 位模式下设置为 Fsys/12。计时器启动并计算 10 毫秒间隔的滴答时间,然后停止。由于定时器配置为 100 次Timer1_Delay10ms(100);它得到 10 毫秒 x 100 = 1 秒的时间。

  闪烁代码和验证定时器功能的输出

  编译时的代码(如下所示)返回 0 个警告和 0 个错误,我使用 Keil 中的默认刷新方法对其进行了刷新。闪烁后,LED 按照编程定义的定时器延迟闪烁。

定时器
 

#include "N76E003.h"
#include "SFR_Macro.h"
#include "函数定义.h"
#include "Common.h"
#include "延迟.h"
#define Test_LED P14
#define LED1 P15
/************************************************************************************************************
* Timer2 中断子程序
************************************************************************************************************/
void Timer2_ISR (void) 中断 5
{
clr_TF2; //清除Timer2中断标志
LED1 = ~LED1;
// LED1 切换,连接在 P1.5;
}
无效设置(无效);
无效的主要(无效){
设置();
而(1){
测试_LED = 0;
Timer1_Delay10ms(100);
测试_LED = 1;
Timer1_Delay10ms(100);
}
}
//这是应用程序运行前的设置文件
无效设置(无效){
P14_准模式;
P15_准模式;
TIMER2_DIV_128;
TIMER2_Auto_Reload_Delay_Mode;
RCMP2L = TIMER_DIV128_VALUE_100ms;
RCMP2H = TIMER_DIV128_VALUE_100ms>>8;
TL2 = 0;
TH2 = 0;
设置_ET2;// 启用 Timer2 中断
设置_EA;
设置_TR2;// Timer2 运行
}

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分