蜂鸟E203系列——定时器中断设计

时间:2022-07-22
本文章向大家介绍蜂鸟E203系列——定时器中断设计,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

原理图

LED 原理图如下图所示,连接GPIO19,GPIO21,GPIO22。

源码

// See LICENSE for license details.

#include <stdio.h>
#include <stdlib.h>
#include "platform.h"
#include <string.h>
#include "plic/plic_driver.h"
#include "encoding.h"
#include <unistd.h>
#include "stdatomic.h"

//计时器中断处理函数
void handle_m_time_interrupt(){

  clear_csr(mie, MIE_MTIE);

  // Reset the timer for 3s in the future.
  // This also clears the existing timer interrupt.

  volatile uint64_t * mtime       = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIME);
  volatile uint64_t * mtimecmp    = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIMECMP);
  uint64_t now = *mtime;
  uint64_t then = now + 1 * RTC_FREQ;
  *mtimecmp = then;


  GPIO_REG(GPIO_OUTPUT_VAL) ^= (0x1 << RED_LED_GPIO_OFFSET);
  GPIO_REG(GPIO_OUTPUT_VAL) ^= (0x1 << GREEN_LED_GPIO_OFFSET);
  GPIO_REG(GPIO_OUTPUT_VAL) ^= (0x1 << BLUE_LED_GPIO_OFFSET);

  // Re-enable the timer interrupt.
  set_csr(mie, MIE_MTIE);

}


//计时器初始化

void setup_mtime (){

    // Set the machine timer to go off in 3 seconds.
    // The
    volatile uint64_t * mtime       = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIME);
    volatile uint64_t * mtimecmp    = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIMECMP);
    uint64_t now = *mtime;
    uint64_t then = now + 10 * RTC_FREQ;
    *mtimecmp = then;

}

int main(int argc, char **argv)
{

//关闭GPIO的输入使能
  GPIO_REG(GPIO_INPUT_EN)    &= ~((0x1<< RED_LED_GPIO_OFFSET) | (0x1<< GREEN_LED_GPIO_OFFSET) | (0x1 << BLUE_LED_GPIO_OFFSET)) ;

  //打开GPIO的输出使能:三个颜色的LED灯
  GPIO_REG(GPIO_OUTPUT_EN)   |=  ((0x1<< RED_LED_GPIO_OFFSET)| (0x1<< GREEN_LED_GPIO_OFFSET) | (0x1 << BLUE_LED_GPIO_OFFSET)) ;


  //设置GPIO的输出值
  GPIO_REG(GPIO_OUTPUT_VAL)  |=   (0x1 << RED_LED_GPIO_OFFSET) ;
  GPIO_REG(GPIO_OUTPUT_VAL)  |=   (0x1 << GREEN_LED_GPIO_OFFSET) ;
  GPIO_REG(GPIO_OUTPUT_VAL)  |=   (0x1 << BLUE_LED_GPIO_OFFSET) ;



//关闭计时器中断局部使能
  clear_csr(mie, MIE_MTIE);

//计时器初始化
  setup_mtime();

  //打开计时器中断局部使能
  set_csr(mie, MIE_MTIE);
  //打开中断的全局使能
  set_csr(mstatus, MSTATUS_MIE);



  return 0;

}

实验结果

每间隔 1 秒,可以看到 LED 灯闪烁一次。