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

« Previous Version 4 Next »

This experiment uses the HDMI display and timer counter function of the Plus1 7021 platform to introduce the basic programming method, which involves interrupt use. The Plus1 7021 system provides four general-purpose 16-bit count timers, timer0 to timer3. When the preset value is reached, the corresponding interrupt signal is generated by each timer。

The interrupt numbers assigned by the corresponding system are shown in the table below

 

Interrupt Number

Timer0

151

Timer1

152

Timer2

153

Timer3

154

The corresponding 32-bit registers are described in detail, please refer to the online technical documentation provided as follows:

10. General Purpose Timers

Here is a brief introduction to the meaning of related registers, as shown in the following table:

 

Control Register

Counting controller

Counting clock preprocessing controller

Counting value controller

 

 

 

 

 

 

 

Timer0

timer0_ctrl

bit[31:16]Reserved

bit[15:14] :Timer clock selection

0: System clock (default)

1: STC 90KHZ clock

bit13 :Operation method

0:Single operation (default)

1:Repeat the operation

bit12 : Reserved

bit11 :Switch control

0:Turn off the counter

1:Start counter

bit[10:0] :Reserved

timer0_reload

bit[31:16]Reserved

bit[15:0]

16-bit count preset value setting

 

 

timer0_cnt

bit[31:16]Reserved

bit[15:0]

16-bit count value

 

 

 

 

 

 

 

 

timer1

timer1_ctrl

bit[31:16]Reserved

bit[15:14] :Timer clock selection

0: System clock (default)

1: STC 90KHZ clock

bit13 :Operation method

0:Single operation (default)

1:重复操作

bit12 : Reserved

bit11 :开关控制

0:关闭计数器

1:启动计数器

bit[10:0] :Reserved

timer1_reload

bit[31:16]Reserved

bit[15:0]

16-bit count preset value setting

 

 

timer1_cnt

bit[31:16]Reserved

bit[15:0]

16-bit count value

 

 

 

 

 

 

timer2

timer2_ctrl

bit[31:6]Reserved

bit[5:2] :Timer clock selection

0: System clock (default)

1: STC 90KHZ clock

bit1 :Operation method

0:单次操作(default)

1:重复操作

bit1 : Reserved

bit0 :开关控制

0:关闭计数器

1:启动计数器

timer2_reload

bit[31:16]保留

bit[15:0]

16-bit count preset value setting

 

timer2_pres_val

bit[31:16]保留

bit[15:0]

16位计数时钟预值设置

 

timer2_cnt

bit[31:16]保留

bit[15:0]

16-bit count value

 

 

 

 

 

 

timer3

timer3_ctrl

bit[31:6]Reserved

bit[5:2] :Timer clock selection

0: System clock (default)

1: STC 90KHZ clock

bit1 :Operation method

0:单次操作(default)

1:重复操作

bit1 : Reserved

bit0 :开关控制

0:关闭计数器

1:启动计数器

timer3_reload

bit[31:16]保留

bit[15:0]

16-bit count preset value setting

 

timer3_pres_val

bit[31:16]保留

bit[15:0]

16位计数时钟预值设置

 

timer3_cnt

bit[31:16]保留

bit[15:0]

16-bit count value

 

安装目录 \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))

HDMI显示及定时器中断控制实验需要如下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();

disp_hdmi_init();

    timer_test_init();/*interrupt test api */

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

    while(1);

}

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

Step2: HDMI 显示初始化设置disp_hdmi_init(),如下:

void disp_hdmi_init()

{

    sp_disp_init();

    sp_enable_log_to_osd();

    sp_osd_draw_string("Display and Timer test...",240,50,20,113);

}

sp_enable_log_to_osd()的功能实现将串口调试信息printf()送到HDMI显示接口;

sp_osd_draw_string()的功能实现在HDMI显示画面的指定坐标位置显示ASCII字符

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

Step4: 最后调用系统中断管理函数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窗口,同时也送到HDMI终端显示。

 

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