查看: 786|回复: 0

[经验] 米尔MYD-C7Z020开发板试用6---定时器中断

[复制链接]
  • TA的每日心情
    开心
    2020-7-25 10:37
  • 签到天数: 40 天

    连续签到: 1 天

    [LV.5]常住居民I

    发表于 2019-11-24 14:57:33 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 武器哈12 于 2019-11-24 15:10 编辑

    一起来看看实验结果:       

       
        定时器在嵌入式中非常常用,学习定时器是歇息任何一款芯片或者开发板的必经之路。
        在 ZYNQ 嵌入式系统中,定时器的资源是非常丰富的,每个 Cortex-A9 处理器都有各自独立的 32 位私有定时器和 32 位看门狗定时器,这两个 CPU 同时共享一个 64 位的全局定时器(GT)。下图是ZYNQ定时器的系统框图:
    1.JPG
        从图中可以看出PS中具有看门狗定时器(SWDT)和两个 TTC(Triple Timer Counters)以及私有定时器(CPU Private Timer)。其中私有定时器较为常用,这次实验使用私有定时器来产生中断500ms,控制EMIO连接的LED闪烁,并同时控制串口输出消息。
        私有定时器的时钟频率为 CPU 时钟频率的一半,可以在ZYNQ IP核定制的时候设置,一般ARM 的工作时钟频率为 666.666Mhz,则私有定时器的时钟频率为 333.333Mhz。私有定时器的特性如下:
    1、32 位计数器,当计数器递减至 0 后产生中断;
    2、8 位预分频计数器,可以更好的控制中断周期;
    3、可以配置单次定时或者自动重载模式;
    4、通过配置起始计数值来设置定时时间。
        我们在helloword工程的基础上建立工程,因为这个工程包含了最基本的ZYNQ IP核定制,再此基础上修改可以少走弯路,节省大家的开发时间。
        在ZYNQ IP定制中修改如下,增加一个EMIO口即可:
    2.JPG 3.JPG
        修改好后原理图中多出一个关键,如上边右图所示。
       添加管脚约束如下:
    • set_property PACKAGE_PIN U13 [get_ports {mygpio_tri_io[0]}]
    • set_property IOSTANDARD LVCMOS33 [get_ports {mygpio_tri_io[0]}]
       编译综合,生成bit文件。打开SDK,编写软件代码如下:


    • #include "xparameters.h"
    • #include "xscutimer.h"
    • #include "xscugic.h"
    • #include "xgpiops.h"
    • #include "xil_exception.h"
    • #include "xil_printf.h"
    • #define TIMER_DEVICE_ID     XPAR_XSCUTIMER_0_DEVICE_ID   //定时器ID
    • #define INTC_DEVICE_ID      XPAR_SCUGIC_SINGLE_DEVICE_ID //中断ID
    • #define TIMER_IRPT_INTR     XPAR_SCUTIMER_INTR           //定时器中断ID
    • #define GPIO_DEVICE_ID      XPAR_XGPIOPS_0_DEVICE_ID     //宏定义 GPIO_PS ID
    • #define MIO_LED             54                           //led连接到 MIO0
    • //私有定时器的时钟频率 = CPU时钟频率/2 = 333MHz
    • //0.5s闪烁一次,0.5*1000_000_000/(1000/333) - 1 = 166499999
    • #define TIMER_LOAD_VALUE    166499999                    //定时器装载值
    • XScuGic Intc;               //中断控制器驱动程序实例
    • XScuTimer Timer;            //定时器驱动程序实例
    • XGpioPs Gpio;               //GPIO设备的驱动程序实例
    • //MIO引脚初始化
    • int mio_init(XGpioPs *mio_ptr)
    • {
    •     int status;
    •     XGpioPs_Config *mio_cfg_ptr;
    •     mio_cfg_ptr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
    •     status = XGpioPs_CfgInitialize(mio_ptr, mio_cfg_ptr,mio_cfg_ptr->BaseAddr);
    •     XGpioPs_SetDirectionPin(&Gpio, MIO_LED, 1);//设置指定引脚的方向: 0 输入, 1 输出
    •     XGpioPs_SetOutputEnablePin(&Gpio, MIO_LED, 1);//使能指定引脚输出: 0 禁止输出使能, 1 使能输出
    •     return XST_SUCCESS;
    • }
    • //定时器初始化程序
    • int timer_init(XScuTimer *timer_ptr)
    • {
    •     int status;
    •     //私有定时器初始化
    •     XScuTimer_Config *timer_cfg_ptr;
    •     timer_cfg_ptr = XScuTimer_LookupConfig(TIMER_DEVICE_ID);
    •     if (NULL == timer_cfg_ptr)
    •         return XST_FAILURE;
    •     status = XScuTimer_CfgInitialize(timer_ptr, timer_cfg_ptr,timer_cfg_ptr->BaseAddr);
    •     if (status != XST_SUCCESS)
    •         return XST_FAILURE;
    •     XScuTimer_LoadTimer(timer_ptr, TIMER_LOAD_VALUE); // 加载计数周期
    •     XScuTimer_EnableAutoReload(timer_ptr);            // 设置自动装载模式
    •     return XST_SUCCESS;
    • }
    • //定时器中断处理程序
    • void timer_intr_handler(void *CallBackRef)
    • {
    •     //LED状态,用于控制LED灯状态翻转
    •     static int led_state = 0;
    • static int times = 1;
    •     XScuTimer *timer_ptr = (XScuTimer *) CallBackRef;
    •     if(led_state == 0)
    •         led_state = 1;
    •     else
    •         led_state = 0;
    •     XGpioPs_WritePin(&Gpio, MIO_LED,led_state); //向指定引脚写入数据: 0 或 1
    • xil_printf("米尔科技 定时器中断测试 timer:%d \r\n",times++);
    •     XScuTimer_ClearInterruptStatus(timer_ptr); //清除定时器中断标志
    • }
    • //定时器中断初始化
    • void timer_intr_init(XScuGic *intc_ptr,XScuTimer *timer_ptr)
    • {
    •     //初始化中断控制器
    •     XScuGic_Config *intc_cfg_ptr;
    •     intc_cfg_ptr = XScuGic_LookupConfig(INTC_DEVICE_ID);
    •     XScuGic_CfgInitialize(intc_ptr, intc_cfg_ptr,
    •             intc_cfg_ptr->CpuBaseAddress);
    •     //设置并打开中断异常处理功能
    •     Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
    •             (Xil_ExceptionHandler)XScuGic_InterruptHandler, intc_ptr);
    •     Xil_ExceptionEnable();
    •     //设置定时器中断
    •     XScuGic_Connect(intc_ptr, TIMER_IRPT_INTR,
    •           (Xil_ExceptionHandler)timer_intr_handler, (void *)timer_ptr);
    •     XScuGic_Enable(intc_ptr, TIMER_IRPT_INTR); //使能GIC中的定时器中断
    •     XScuTimer_EnableInterrupt(timer_ptr);      //使能定时器中断
    • }
    • int main()
    • {
    •     int status;
    •     xil_printf("SCU Timer Interrupt Test \r\n");
    •     mio_init(&Gpio);                 //MIO引脚初始化
    •     status = timer_init(&Timer);     //定时器初始化
    •     if (status != XST_SUCCESS) {
    •         xil_printf("Timer Initial Failed\r\n");
    •         return XST_FAILURE;
    •     }
    •     timer_intr_init(&Intc,&Timer);   //定时器中断初始化
    •     XScuTimer_Start(&Timer);         //启动定时器
    •     while(1);
    •     return 0;
    • }
    附上我的工程:


    MYiRtest1.zip (4.16 MB, 下载次数: 5, 售价: 1 与非币)
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-4-18 11:17 , Processed in 0.117662 second(s), 17 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.