OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4287|回复: 6

[XILINX] 有关ZYNQ的定时器中断问题

[复制链接]

19

主题

124

帖子

0

精华

高级会员

Rank: 4

积分
539
金钱
539
注册时间
2019-5-1
在线时间
79 小时
发表于 2022-5-21 14:33:28 | 显示全部楼层 |阅读模式
1金钱
我现在使用了CPU0的私有定时器做1ms的中断计数 ,想在开启一个定时器中断做10ms的中断计数 (不打算用1ms的定时器做计数累加),我在网上看介绍 cpu0和cpu1共用了一个全局定时器,我按照网上的代码测试了一下 映射到了cpu0上 发现之前的cpu0定时器没法正常工作(无法调到中断服务函数中了)  想请问一下怎么回事? 有没有什么其他办法可以cpu0上使用两个不同的定时器 进行计数?

最佳答案

查看完整内容[请看2#楼]

问题解决 我重复初始化了GIC
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

19

主题

124

帖子

0

精华

高级会员

Rank: 4

积分
539
金钱
539
注册时间
2019-5-1
在线时间
79 小时
 楼主| 发表于 2022-5-21 14:33:29 | 显示全部楼层
问题解决 我重复初始化了GIC
回复

使用道具 举报

19

主题

124

帖子

0

精华

高级会员

Rank: 4

积分
539
金钱
539
注册时间
2019-5-1
在线时间
79 小时
 楼主| 发表于 2022-5-21 14:36:34 | 显示全部楼层
#define GLOBAL_TIMER_LOAD_VALUE                                    0x3D08F
#define INTC_DEVICE_ID                                                XPAR_PS7_SCUGIC_0_DEVICE_ID
#define INTC_HANDLER                                                XScuGic_InterruptHandler
#define Global_Timer_INTR                       XPAR_GLOBAL_TMR_INTR
#define Global_Timer_Counter_Register0          XPAR_GLOBAL_TMR_BASEADDR+0x0U
#define Global_Timer_Counter_Register1          XPAR_GLOBAL_TMR_BASEADDR+0x4U
#define Global_Timer_Control_Register           XPAR_GLOBAL_TMR_BASEADDR+0x8U
#define Global_Timer_Interrupt_Status_Register  XPAR_GLOBAL_TMR_BASEADDR+0xCU
#define Comparator_Value_Register0              XPAR_GLOBAL_TMR_BASEADDR+0x10U
#define Comparator_Value_Register1              XPAR_GLOBAL_TMR_BASEADDR+0x14U
#define Auto_increment_Register                 XPAR_GLOBAL_TMR_BASEADDR+0x18U
#define Auto_Increment_Bit                      0x08U
#define IRQ_Enable_Bit                          0x04U
#define Comp_Enable_Bit                         0x02U
#define Timer_Enable_Bit                        0x01U

XScuGic   IntcInstancePtr;         /* The Instance of the Interrupt Controller Driver */
static void GlobalTimerIntrHandler();

/***************************************************************
  *  @brief:                        全局定时器的中断服务函数,完成IMU SPEED的采集
  *  @param:                         NULL
  *  @return:                        无
  *  @author:                       
  *  @data:                                2022.5.21
**************************************************************/
static void GlobalTimerIntrHandler()
{
    /*采集IMU及轮速计数据,对应函数为_ImuDataAcqireHandler及_SpeedSensorAcqireHandler*/
//    GN_TrigerEvent(GN_MODULE_CLOCK,GN_EVENT_IMUDATA_HANDLER,0,0);
    /*10ms读取一次IMU和轮速计数据*/
    if(g_running_ms%g_CountMs == 0)
        {
           s_SnapshotFlag = 1;
           GN_TrigerEvent(GN_MODULE_CLOCK,GN_EVENT_IMUDATA_HANDLER,0,0);
           /*采集IMU及轮速计数据,对应函数为_ImuDataAcqireHandler及_SpeedSensorAcqireHandler*/
           GN_TrigerEvent(GN_MODULE_CLOCK,GN_EVENT_SPEED_SENSOR_HANDLER,0,0);
        }
        return;
}
/***************************************************************
  *  @brief:                        对相应寄存器地址写操作
  *  @param:                         Reg_Addr:地址
  *                                          Reg_Val:赋值
  *  @return:                        无
  *  @author:                        贾粟
  *  @data:                                2022.5.21
**************************************************************/
void GN_Set_GlobalTimer_Reg(u32 Reg_Addr,u32 Reg_Val)
{
        Xil_Out32(Reg_Addr, Reg_Val);
}

/***************************************************************
  *  @brief:                        对相应寄存器地址写操作
  *  @param:                         Reg_Addr:地址
  *  @return:                        u32类型:该地址上的值
  *  @author:                       
  *  @data:                                2022.5.21
**************************************************************/
u32 GN_Get_GlobalTimer_Reg(u32 Reg_Addr)
{
        return Xil_In32(Reg_Addr);
}

/***************************************************************
  *  @brief:                        共享全局定时器的初始化
  *  @param:                         INTC *IntcInstancePtr
  *  @return:                        成功:0x00 失败:0x01
  *  @author:                       
  *  @data:                                2022.5.21
**************************************************************/

int SetupIntrSystem(XScuGic *IntcInstancePtr)
{
        int Status;
        XScuGic_Config *IntcConfig;
        /*
         * Initialize the interrupt controller driver so that it is ready to
         * use.
         */
        IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
        if (NULL == IntcConfig) {
                return XST_FAILURE;
        }
        Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
                                        IntcConfig->CpuBaseAddress);
        if (Status != XST_SUCCESS) {
                return XST_FAILURE;
        }
        /*
         * Initialize the  exception table
         */
        Xil_ExceptionInit();
        /*
         * Register the interrupt controller handler with the exception table
         */
        Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
                         (Xil_ExceptionHandler)INTC_HANDLER,
                         IntcInstancePtr);
        GN_Set_GlobalTimer_Reg(Global_Timer_Control_Register,0);//停止全局定时器
        GN_Set_GlobalTimer_Reg(Global_Timer_Counter_Register0,0);//清空计数器低32位
        GN_Set_GlobalTimer_Reg(Global_Timer_Counter_Register1,0);//清空计数器高32位
        GN_Set_GlobalTimer_Reg(Global_Timer_Interrupt_Status_Register,1);//清除中断标志位
        GN_Set_GlobalTimer_Reg(Comparator_Value_Register0,GLOBAL_TIMER_LOAD_VALUE);//加载比较器低32位
        GN_Set_GlobalTimer_Reg(Comparator_Value_Register1,0);//加载比较器高32位
        GN_Set_GlobalTimer_Reg(Auto_increment_Register,GLOBAL_TIMER_LOAD_VALUE);//加载递增寄存器数值
        Status = XScuGic_Connect(IntcInstancePtr, Global_Timer_INTR,
                                        (Xil_ExceptionHandler)GlobalTimerIntrHandler,
                                        0);//绑定全局定时器中断服务函数
        if (Status != XST_SUCCESS)
        {
                return Status;
        }
        XScuGic_InterruptMaptoCpu(IntcInstancePtr,0,Global_Timer_INTR);//将27号全局定时器中断映射到CPU0
        XScuGic_Enable(IntcInstancePtr, Global_Timer_INTR);//打开全局定时器中断(27号)
        Xil_ExceptionEnable();
        return XST_SUCCESS;
}

/***************************************************************
  *  @brief:                        启动全局定时器
  *  @param:                         无
  *  @return:                        成功:0x00 失败:0x01
  *  @author:                       
  *  @data:                                2022.5.21
**************************************************************/
int StartUpGlobalTimer()
{

        if ( (SetupIntrSystem(&IntcInstancePtr)) )
        {
                return XST_FAILURE;
        }
        GN_Set_GlobalTimer_Reg(Global_Timer_Control_Register,//启动全局定时器
                                Auto_Increment_Bit|IRQ_Enable_Bit|Comp_Enable_Bit|Timer_Enable_Bit);
        return XST_SUCCESS;
}
回复

使用道具 举报

19

主题

124

帖子

0

精华

高级会员

Rank: 4

积分
539
金钱
539
注册时间
2019-5-1
在线时间
79 小时
 楼主| 发表于 2022-5-21 14:37:05 | 显示全部楼层
爱吃栗子的栗子 发表于 2022-5-21 14:36
#define GLOBAL_TIMER_LOAD_VALUE                                    0x3D08F
#define INTC_DEVICE_ID                                                XPAR_PS7_SCUGIC_0 ...

全局定时器的初始化和中断服务函数
回复

使用道具 举报

13

主题

202

帖子

0

精华

高级会员

Rank: 4

积分
527
金钱
527
注册时间
2012-10-27
在线时间
65 小时
发表于 2022-5-21 15:43:18 | 显示全部楼层
本帖最后由 arm51avr 于 2022-5-21 15:47 编辑

可否将“之前的定时器”定时器初始化以及中断服务程序发上来?

我大致看了下代码,貌似没有找到中断优先级的配置代码?两个定时器的优先级是怎么设置的?

有没有可能程序卡在了GlobalTimerIntrHandler()中断服务例程里?
回复

使用道具 举报

19

主题

124

帖子

0

精华

高级会员

Rank: 4

积分
539
金钱
539
注册时间
2019-5-1
在线时间
79 小时
 楼主| 发表于 2022-5-23 21:39:04 | 显示全部楼层
arm51avr 发表于 2022-5-21 15:43
可否将“之前的定时器”定时器初始化以及中断服务程序发上来?

我大致看了下代码,貌似没有找到中断优先 ...

#define TIMER_DEVICE_ID                XPAR_XSCUTIMER_0_DEVICE_ID
#define INTC_DEVICE_ID                XPAR_SCUGIC_SINGLE_DEVICE_ID
#define TIMER_IRPT_INTR                XPAR_SCUTIMER_INTR
// (249_999 + 1)/ 333*1000_000 = 0.0007s  0.7ms
#define TIMER_LOAD_VALUE        0x3D08F//0x927BF_300M//0x3D08F_500M////0x249EF//0x493DF//0x927BF//0x11E1A2FF//0x000249EF

XScuGic Intc;                         //GIC
static XScuTimer Timer;                        //timer half of CPU clock
unsigned int TimerCnt = 0;                //timer count
static void _setupTimerIrtSystem(XScuGic *GicInstancePtr, XScuTimer *TimerInstancePtr, u16 TimerIntrId);
static void TimerIntrHandler(void *CallBackRef);



/*定时器中断初始化*/
static void _setupTimerIrtSystem(XScuGic *GicInstancePtr, XScuTimer *TimerInstancePtr, u16 TimerIntrId)
{
        XScuGic_Config *IntcConfig; //GIC config
        Xil_ExceptionInit();

        //initialize the GIC
        IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
        XScuGic_CfgInitialize(GicInstancePtr, IntcConfig,
                                        IntcConfig->CpuBaseAddress);

        // 设置并打开中断异常处理功能
        Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
                        (Xil_ExceptionHandler)XScuGic_InterruptHandler,
                                GicInstancePtr);

        // 设置定时器中断
        XScuGic_Connect(GicInstancePtr, TimerIntrId,
                                        (Xil_ExceptionHandler)TimerIntrHandler,
                                        (void *)TimerInstancePtr);

        // 使能GTC中的定时器中断
        XScuGic_Enable(GicInstancePtr, TimerIntrId);

//        XScuGic_SetPriorityTriggerType(GicInstancePtr,TimerIntrId,0xf0,0x2);

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



        //Enable interrupts in the Processor.
        Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
}

/*定时器中断处理函数*/
static void _timer0IsrHandler(void)
{
        if( g_SysReadyFlag )
        {
                GN_TrigerEvent( GN_MODULE_DEV, GN_EVENT_FPGA_INT, 0, 0 );
//                GN_Prints(0x80, "helloword\r\n");

        }
}


static void TimerIntrHandler(void *CallBackRef)
{
        //XScuTimer_Stop(&Timer);
        XScuTimer *TimerInstancePtr = (XScuTimer *) CallBackRef;

        _timer0IsrHandler();
        //XScuTimer_ClearInterruptStatus(TimerInstancePtr);
        //XScuTimer_Start(&Timer);
}


/***************************************************************
  *  @brief:        定时器的初始化
  *  @param:         void
  *  @return:        无
  *  @note:               
  *  @data:                2022.5.21
**************************************************************/
void timerIrtEnable(void)
{
        // 私有定时器初始化  私有定时器的时钟频率等于 CPU 时钟频率的一半,因此私有定时器的时钟频率约为 333Mhz
        XScuTimer_Config *TMRConfigPtr;     //timer config

        //timer initialisation
        TMRConfigPtr = XScuTimer_LookupConfig(TIMER_DEVICE_ID);
        XScuTimer_CfgInitialize(&Timer, TMRConfigPtr,TMRConfigPtr->BaseAddr);
        XScuTimer_SelfTest(&Timer);

        // 设置定时器中断
        _setupTimerIrtSystem(&Intc, &Timer, TIMER_IRPT_INTR);

        //load the timer
        XScuTimer_LoadTimer(&Timer, TIMER_LOAD_VALUE);                // 加载计数周期 定时器在运行时,初始值为定时器的装载值,当定时器的装载值递减至 0 后,产生中断
        XScuTimer_EnableAutoReload(&Timer);                                        // 设置自动装载模式

        // 启动定时器
        XScuTimer_Start(&Timer);


}
回复

使用道具 举报

19

主题

124

帖子

0

精华

高级会员

Rank: 4

积分
539
金钱
539
注册时间
2019-5-1
在线时间
79 小时
 楼主| 发表于 2022-5-23 21:39:25 | 显示全部楼层
#define TIMER_DEVICE_ID                XPAR_XSCUTIMER_0_DEVICE_ID
#define INTC_DEVICE_ID                XPAR_SCUGIC_SINGLE_DEVICE_ID
#define TIMER_IRPT_INTR                XPAR_SCUTIMER_INTR
// (249_999 + 1)/ 333*1000_000 = 0.0007s  0.7ms
#define TIMER_LOAD_VALUE        0x3D08F//0x927BF_300M//0x3D08F_500M////0x249EF//0x493DF//0x927BF//0x11E1A2FF//0x000249EF

XScuGic Intc;                         //GIC
static XScuTimer Timer;                        //timer half of CPU clock
unsigned int TimerCnt = 0;                //timer count
static void _setupTimerIrtSystem(XScuGic *GicInstancePtr, XScuTimer *TimerInstancePtr, u16 TimerIntrId);
static void TimerIntrHandler(void *CallBackRef);



/*定时器中断初始化*/
static void _setupTimerIrtSystem(XScuGic *GicInstancePtr, XScuTimer *TimerInstancePtr, u16 TimerIntrId)
{
        XScuGic_Config *IntcConfig; //GIC config
        Xil_ExceptionInit();

        //initialize the GIC
        IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
        XScuGic_CfgInitialize(GicInstancePtr, IntcConfig,
                                        IntcConfig->CpuBaseAddress);

        // 设置并打开中断异常处理功能
        Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
                        (Xil_ExceptionHandler)XScuGic_InterruptHandler,
                                GicInstancePtr);

        // 设置定时器中断
        XScuGic_Connect(GicInstancePtr, TimerIntrId,
                                        (Xil_ExceptionHandler)TimerIntrHandler,
                                        (void *)TimerInstancePtr);

        // 使能GTC中的定时器中断
        XScuGic_Enable(GicInstancePtr, TimerIntrId);

//        XScuGic_SetPriorityTriggerType(GicInstancePtr,TimerIntrId,0xf0,0x2);

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



        //Enable interrupts in the Processor.
        Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
}

/*定时器中断处理函数*/
static void _timer0IsrHandler(void)
{
        if( g_SysReadyFlag )
        {
                GN_TrigerEvent( GN_MODULE_DEV, GN_EVENT_FPGA_INT, 0, 0 );
//                GN_Prints(0x80, "helloword\r\n");

        }
}


static void TimerIntrHandler(void *CallBackRef)
{
        //XScuTimer_Stop(&Timer);
        XScuTimer *TimerInstancePtr = (XScuTimer *) CallBackRef;

        _timer0IsrHandler();
        //XScuTimer_ClearInterruptStatus(TimerInstancePtr);
        //XScuTimer_Start(&Timer);
}


/***************************************************************
  *  @brief:        定时器的初始化
  *  @param:         void
  *  @return:        无
  *  @note:               
  *  @data:                2022.5.21
**************************************************************/
void timerIrtEnable(void)
{
        // 私有定时器初始化  私有定时器的时钟频率等于 CPU 时钟频率的一半,因此私有定时器的时钟频率约为 333Mhz
        XScuTimer_Config *TMRConfigPtr;     //timer config

        //timer initialisation
        TMRConfigPtr = XScuTimer_LookupConfig(TIMER_DEVICE_ID);
        XScuTimer_CfgInitialize(&Timer, TMRConfigPtr,TMRConfigPtr->BaseAddr);
        XScuTimer_SelfTest(&Timer);

        // 设置定时器中断
        _setupTimerIrtSystem(&Intc, &Timer, TIMER_IRPT_INTR);

        //load the timer
        XScuTimer_LoadTimer(&Timer, TIMER_LOAD_VALUE);                // 加载计数周期 定时器在运行时,初始值为定时器的装载值,当定时器的装载值递减至 0 后,产生中断
        XScuTimer_EnableAutoReload(&Timer);                                        // 设置自动装载模式

        // 启动定时器
        XScuTimer_Start(&Timer);


}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-23 13:03

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表