Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

本实验利用Plus1 7021自带的定时计数器介绍基本编程方法,涉及到中断使用, Plus17021系统提供4个通用的16位计数定时器timer0到timer3; 每个计数定时器都支持计数到预设值时产生相应的中断信号。

对应系统分配的中断号如下表所示

 

中断号

Timer0

151

Timer1

152

Timer2

153

Timer3

154

对应的32位寄存器详细介绍,请参考我们提供的文档QAC628_regfile.pdf, 如下

这里简单介绍相关寄存器的含义,如下表所示:

 

控制寄存器

计数预值控制器

计数时钟预处理控制器

计数值控制器

 

 

 

 

 

 

 

Timer0

timer0_ctrl

bit[31:16]保留

bit[15:14] :计数时钟选择

0: 系统时钟(default)

1: STC 90KHZ 时钟

bit13 :操作方式

0:单次操作(default)

1:重复操作

bit12 : 保留

bit11 :开关控制

0:关闭计数器

1:启动计数器

bit[10:0] :保留

timer0_reload

bit[31:16]保留

bit[15:0]

16位计数预值设置

 

 

timer0_cnt

bit[31:16]保留

bit[15:0]

16位计数值

 

 

 

 

 

 

 

 

timer1

timer1_ctrl

bit[31:16]保留

bit[15:14] :计数时钟选择

0: 系统时钟(default)

1: STC 90KHZ 时钟

bit13 :操作方式

0:单次操作(default)

1:重复操作

bit12 : 保留

bit11 :开关控制

0:关闭计数器

1:启动计数器

bit[10:0] :保留

timer1_reload

bit[31:16]保留

bit[15:0]

16位计数预值设置

 

 

timer1_cnt

bit[31:16]保留

bit[15:0]

16位计数值

 

 

 

 

 

 

timer2

timer2_ctrl

bit[31:6]保留

bit[5:2] :计数时钟选择

0: 系统时钟(default)

1: STC 90KHZ 时钟

bit1 :操作方式

0:单次操作(default)

1:重复操作

bit1 : 保留

bit0 :开关控制

0:关闭计数器

1:启动计数器

timer2_reload

bit[31:16]保留

bit[15:0]

16位计数预值设置

 

timer2_pres_val

bit[31:16]保留

bit[15:0]

16位计数时钟预值设置

 

timer2_cnt

bit[31:16]保留

bit[15:0]

16位计数值

 

 

 

 

 

 

timer3

timer3_ctrl

bit[31:6]保留

bit[5:2] :计数时钟选择

0: 系统时钟(default)

1: STC 90KHZ 时钟

bit1 :操作方式

0:单次操作(default)

1:重复操作

bit1 : 保留

bit0 :开关控制

0:关闭计数器

1:启动计数器

timer3_reload

bit[31:16]保留

bit[15:0]

16位计数预值设置

 

timer3_pres_val

bit[31:16]保留

bit[15:0]

16位计数时钟预值设置

 

timer3_cnt

bit[31:16]保留

bit[15:0]

16位计数值

 

安装目录 \SP7021\workspace\sp7021\include 文件夹下的regmap_q628.h定义了这四个寄存器,如下图红色:

regmap_q628.h

struct stc_regs {

    unsigned int stc_15_0;       // 12.0

    unsigned int stc_31_16;      // 12.1

    unsigned int stc_64;         // 12.2

    unsigned int stc_divisor;    // 12.3

    unsigned int rtc_15_0;       // 12.4

    unsigned int rtc_23_16;      // 12.5

    unsigned int rtc_divisor;    // 12.6

    unsigned int stc_config;     // 12.7

    unsigned int timer0_ctrl;    // 12.8

    unsigned int timer0_cnt;     // 12.9

    unsigned int timer1_ctrl;    // 12.10

    unsigned int timer1_cnt;     // 12.11

    unsigned int timerw_ctrl;    // 12.12

    unsigned int timerw_cnt;     // 12.13

    unsigned int stc_47_32;      // 12.14

    unsigned int stc_63_48;      // 12.15

    unsigned int timer2_ctl;     // 12.16

    unsigned int timer2_pres_val;// 12.17

    unsigned int timer2_reload;  // 12.18

    unsigned int timer2_cnt;     // 12.19

    unsigned int timer3_ctl;     // 12.20

    unsigned int timer3_pres_val;// 12.21

    unsigned int timer3_reload;  // 12.22

    unsigned int timer3_cnt;     // 12.23

    unsigned int stcl_0;         // 12.24

    unsigned int stcl_1;         // 12.25

    unsigned int stcl_2;         // 12.26

    unsigned int atc_0;          // 12.27

    unsigned int atc_1;          // 12.28

    unsigned int atc_2;          // 12.29

    unsigned int timer0_reload;  // 12.30

    unsigned int timer1_reload;  // 12.31

};

#define STC_REG     ((volatile struct stc_regs *)RF_GRP(12, 0))

定时器控制实验需要如下3个文件,如下:

1) 安装目录 \SP7021\workspace\sp7021\ 文件夹下的main.c

2) 安装目录 \SP7021\workspace\sp7021\testapi\util 文件夹下的timer.c

3) 安装目录 \SP7021\workspace\sp7021\ include\util文件夹下的timer.h

main.c

int main(void)

{

    printf("Build @%s, %s\n", __DATE__, __TIME__);

    hw_init();

    sys_init();

    timer_test_init();/*interrupt test api */

    sp_interrupt_setup(); /* interrupt manager module init */

    while(1);

}

首先时系统及硬件初始化:hw_init();sys_init();

然后时调用timer.c中定义的计数定时器初始化函数timer_test_init();

最后调用系统中断管理函数sp_interrupt_setup();

上面的4个函数只有timer_test_init()是由用户根据应用需求编写,其它都是系统提供。

timer_test_init() 的函数体实现在timer.c中,负责计数定时器timer3进行初始化工作,包含计数时钟的选择,定时值设置,定时器中断配置及对应的中断处理函数操作。

 timer.c

#include "common_all.h"

#include "cache.h"

#include "sp_interrupt.h"

#define TIMER3_TICKS        (90 - 1)        /* 1s */

#define TIMER3_CONFIG_STC   (1 << 2)    /* src: stc */

#define TIMER3_RELOAD       (1 << 1)    /* timer3 auto reload */

#define TIMER3_RUN          (1 << 0)    /* timer3 run */

#define TIMER3_STOP         (0 << 0)    /* timer3 stop */

#define TIMER3_INT  (154)

static unsigned int g_repeat_cnt = 0;

void timer3_interrupt_control_mask(int enable)

static void timer3_isr_cfg()

void timer3_callback(void)

void timer_test_init()

timer.c提供实现定时器控制实验的4个方法函数及宏定义,分别讲解如下:

 void timer3_interrupt_control_mask(int enable)

{

    if (enable != 0) {

        /* enable timer3 interrupt */

        hal_interrupt_unmask(TIMER3_INT);

    } else {

        hal_interrupt_mask(TIMER3_INT);

    }

}

用来控制计数定时器3中断的开与关;enable为0时关闭中断,为1时开启中断

static void timer3_isr_cfg() 

{

    printf("[CFG] Timer3\n");

    STC_REG->timer3_ctl = TIMER3_CONFIG_STC | TIMER3_RELOAD;

    STC_REG->timer3_pres_val = 999;

    STC_REG->timer3_reload = TIMER3_TICKS;

    STC_REG->timer3_cnt = TIMER3_TICKS;

    hal_interrupt_configure(TIMER3_INT, 0, 1);

    timer3_interrupt_control_mask(1);

    STC_REG->timer3_ctl |= TIMER3_RUN;

}

实现计数定时器每1秒产生1次中断,相关配置工作如下:

1)    STC_REG->timer3_ctl = TIMER3_CONFIG_STC | TIMER3_RELOAD;

计时钟选择STC 90KHZ 时钟;操作方式为重复操作

2)    STC_REG->timer3_pres_val = 999;

   计数时钟预处理设置为999,表示每收到1000个STC 90KHZ时钟,timer3 才计数1次;

3)    STC_REG->timer3_reload = TIMER3_TICKS;

计数预值设置为89, 表示timer3 计数90次后,重新开始计数

4)    STC_REG->timer3_cnt = TIMER3_TICKS;

计数初值设置为89,因为计数器是 UP to DOWN 的方式,即从初值计数到0完成1次操作;

5)    hal_interrupt_configure(TIMER3_INT, 0, 1);

这是系统提供的中断设置函数,共有3个参数需要设置,如下:

     void hal_interrupt_configure(int vector, int level, int up)

     int vector :中断号,系统分配指定,每个定时器都有自己专门的中断号:

time0的中断号是151

time1的中断号是152

time2的中断号是153

time3的中断号是154

     int level :中断信号触发方式

0:边沿触发

1:电平触发

     int  up    :中断信号极性方式

0:负极性(负边沿或负电平)

1:正极性(正边沿或正电平)

6)    timer3_interrupt_control_mask(1);

    开启计数定时器3中断

7)    STC_REG->timer3_ctl |= TIMER3_RUN;

    启动计数定时器3,计数开始

void timer3_callback(void)

{

    printf("@Timer3[%d]\n", ++g_repeat_cnt);

}

是对应的中断处理函数操作,将中断的次数显示在IDE 环境的Terminal窗口,如图所示。

 

void timer_test_init()

{

    static interrupt_operation timer3_opt;

    memcpy(timer3_opt.dev_name, "Timer3", strlen("Timer3"));

    timer3_opt.vector = TIMER3_INT;

    timer3_opt.device_config = timer3_isr_cfg;

    timer3_opt.interrupt_handler = timer3_callback;

    interrupt_register(&timer3_opt);

}

是中断初始化操作,完成中断函数的注册,包含上面定义的3个函数的调用

 

timer.h

#ifndef __TIMER_H__

#define __TIMER_H__

void timer_test_init();

#endif // __TIMER_H__

timer.c 中的函数被其它文件中的函数调用时,需要在timer.h中申明

在Plus1 IDE环境中compile后,下载到平台运行,在terminal窗口看到如下信息

  • No labels