ZYNQ 定时器中断

REVIEW

关于ZYNQ中断:

ZYNQ PS_GPIO中断-优快云博客

ZYNQ AXI_GPIO_INT-优快云博客

1. 今日摸鱼任务

实现私有定时器中断控制EDA扩展版上8个led亮灭效果

(私有定时器中断 + AXI_GPIO)

小梅哥教材:

03_【裸机教程】基于C编程的Zynq裸机程序设计与应用教程v2.4.5.pdf

第六章 定时器中断(没用串口)

开发板上 CPU 的时钟频率为 666MHz
定时器时钟频率为 CPU 时钟频率的一半,即 333MHz

2. Block Design

本次使用 axi_gpio的写入功能

ARM 的私有定时器默认是开启的,不需要配置

3. SDK

AXI_GPIO SCU_GIC
ZYNQ AXI_GPIO_INT-优快云博客
SCU_TIMER.h

#ifndef ACZ702_LIB_SCU_TIMER_H_
#define ACZ702_LIB_SCU_TIMER_H_

#include "xscutimer.h"
#include <stdint.h>

extern uint8_t Tick_Flag;

XScuTimer ScuTimer;
#define    CPU_CLK_HZ    XPAR_PS7_CORTEXA9_0_CPU_CLK_FREQ_HZ    //CPU时钟频率(单位Hz)

void ScuTimer_Int_Init(double Load_Val);
void ScuTimer_IRQ_Handler(void *CallBackRef);

#endif /* ACZ702_LIB_SCU_TIMER_H_ */
 

SCU_TIMER.c

/**
  *****************************************************************************
  *                         私有定时器应用库
  *****************************************************************************
  *
  * @File   : SCU_TIMER.c
  * @By     : Sun
  * @Version: V0.5
  * @Date   : 2022 / 05 / 30
  * @Shop    : https://xiaomeige.taobao.com/
  *
  *****************************************************************************
**/
#include "SCU_TIMER.h"
#include "SCU_GIC.h"
#include "xparameters.h"
XScuTimer ScuTimer;        //私有定时器

uint8_t Tick_Flag = 0 ;


void ScuTimer_IRQ_Handler(void *CallBackRef)
{
    /* ↓↓↓用户处理↓↓↓ */
    Tick_Flag = 1;

    /* ↑↑↑结束处理↑↑↑ */
    XScuTimer_ClearInterruptStatus(&ScuTimer);
}


/**
  *****************************************************
  * @brief    初始化私有定时器
  * @param    Time_us        定时器中断触发时间,单位为us
  * @usage    ScuTimer_Int_Init(20);    //初始化私有定时器,每20us触发一次
  * @tag    本函数开启私有定时器,并进行周期性中断,要停止私有定时器可使用XScuTimer_Stop(&ScuTimer);
  *****************************************************
**/
void ScuTimer_Int_Init(double Time_us)
{
    uint32_t Load_Val;
    //定时器初始化
    XScuTimer_Config *Config;
    Config = XScuTimer_LookupConfig(XPAR_XSCUTIMER_0_DEVICE_ID);
    XScuTimer_CfgInitialize(&ScuTimer, Config,Config->BaseAddr);

    //将us转换为定时器装载值
    Load_Val = ((float)CPU_CLK_HZ / 2 / 1000000 * Time_us) - 1;

    //四舍五入,使结果更精准
    if(((uint32_t)(CPU_CLK_HZ / 2 / 100000 * Time_us))%10 >=5 )
        Load_Val++;

    //设置自动装载值和自动装载模式
    XScuTimer_LoadTimer(&ScuTimer, Load_Val);
    XScuTimer_EnableAutoReload(&ScuTimer);

    //链接到中断控制器
    Set_ScuGic_Link(XPAR_SCUTIMER_INTR, 0xA8,Rising_Edge_Sensitive,ScuTimer_IRQ_Handler,(void *)&ScuTimer);

    //使能定时器中断
    XScuTimer_EnableInterrupt(&ScuTimer);

    //开启计数器
    XScuTimer_Start(&ScuTimer);
}

main.c

/*
 * main.c
 *
 *  Created on: 2024年10月24日
 *      Author: Administrator
 */


//系统头文件
#include <stdio.h>
#include <stdint.h>

//Xilinx头文件
#include "xgpiops.h"
#include "xparameters.h"

#include "AXI_GPIO.h"
#include "SCU_GIC.h"
#include "SCU_TIMER.h"


#define GPIO_0_ID XPAR_AXI_GPIO_0_DEVICE_ID


int main(void)
{
    uint32_t Tick_Cnt = 0;
    //初始化通用中断控制器
    ScuGic_Init();
    //初始化私有定时器,每 1s 触发一次
    ScuTimer_Int_Init(500000);
    //初始化AXI GPIO0
    AXI_GPIO_Init(&AXI_GPIO0,GPIO_0_ID);
    //设置i/o
    AXI_GPIO_Set_Channel(&AXI_GPIO0, XGPIO_IR_CH1_MASK, 0x00, 0);

    while(1)
    {
        //Tick 标志由私有定时器中断控制,中断服务函数在SCU_TIMER.c 中
        if(Tick_Flag)
            {
                Tick_Flag = 0;//全局计数函数

                if(Tick_Cnt > 7)
                {
                    Tick_Cnt = 0;
                    AXI_GPIO_Set_Channel(&AXI_GPIO0, XGPIO_IR_CH1_MASK, 0, 0);
                }
                else
                {
                    AXI_GPIO_SetPin(&AXI_GPIO0, XGPIO_IR_CH1_MASK, Tick_Cnt, 1);
                    Tick_Cnt++;
                }
            }
    }
    return 0;
}
 

4. 效果

EDA扩展板上,8个LED依次点亮、全灭,循环。

摸鱼结束哩~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值