程序中断(2)
这一部分是基于基于ZYNQ-7000开发板的调试系列(4)继续展开的,主要的部分是需要两个定时器开启中断开始。这一部分主要是需要使用TTC,完成2组流水灯的同时工作,两组的频率也不一致。
[参考自ZYNQ7000 TRM (Page.245-249)]
TTC可以完成的工作比较多,其实TTC的使用是可以控制GPIO的占空比。这个的最简单的使用例程就是做一个呼吸灯。但是需要使用到PL的PWM,这里就先不涉及这一部分的内容了。
[参考自ZYNQ进阶之路8–PS端实现EMIO TTC PWM输出(与PL端PWM联合使用)]
1. 修改Block
1. 修改ZYNQ7 Processing System
其实这里主要就是需要把TTC0和TTC1打开,这里提供的EMIO是可以向外输出波形的,这里可以并不需要,所以这里可以不用向外提供接口。具体的Diagram图大概是这个样子的。
然后这里就没有其他需要修改的部分了,这里生成Bitstream即可。
2. 编写PS程序
这一部分的程序编写其实和上一部分几乎是一致的,和上一部分最大的不同就是TTC的使能和控制。
其中,引入必须引入的库:
#include "xttcps.h"
然后是关于TTC的函数:
- 初始化
XTtcPs_Config *XTtcPs_LookupConfig(
u16 DeviceId
);
s32 XTtcPs_CfgInitialize(
XTtcPs *InstancePtr,
XTtcPs_Config * ConfigPtr,
u32 EffectiveAddr
);
- 定时器配置
s32 XTtcPs_SetOptions(
XTtcPs *InstancePtr,
u32 Options
); //关于TTC的模式配置
void XTtcPs_CalcIntervalFromFreq(
XTtcPs *InstancePtr,
u32 Freq,
XInterval *Interval,
u8 *Prescaler
); //通过用户给定的频率计算分频和间隔的数值,并赋值到指定的地址上
void XTtcPs_SetInterval(
XTtcPs *InstancePtr;
XInterval interval
); // 该函数实质上就是往寄存器里写入值
void XTtcPs_SetPrescaler(
XTtcPs *InstancePtr,
u8 PrescalerValue
); // 该函数按照指定的分频向寄存器内写入值
void XTtcPs_EnableInterrupts(
XTtcPs *InstancePtr,
u32 InterruptMask
); // 该函数实质上就是往寄存器里写入值,使能TTC中断
定时器开始
XTtcPs_Start(
XTtcPs *InstancePtr
); // 该函数实质上就是往寄存器里写入值,开始计数
中断内函数
u32 XTtcPs_GetInterruptStatus(
XTtcPs *InstancePtr
); // 检测是否已经触发了中断
void XTtcPs_ClearInterruptStatus(
XTtcPs *InstancePtr,
u32 statusEvent
); // 如果触发中断,该部分解除中断
其余部分和上一部分几乎一致。程序如下:
#include "xparameters.h"
#include "xgpio.h"
#include "xgpiops.h"
#include "xttcps.h"
#include "xstatus.h"
#include "xscugic.h"
#include "xil_exception.h"
#define PS_GIC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
#define LEDG1_INTR_ID XPAR_XTTCPS_0_INTR
#define LEDG2_INTR_ID XPAR_XTTCPS_3_INTR
#define LED1_INTR_DEVICE_ID XPAR_XTTCPS_0_DEVICE_ID
#define LED2_INTR_DEVICE_ID XPAR_XTTCPS_3_DEVICE_ID
#define LED1_FREQ_HZ 2
#define LED2_FREQ_HZ 3
#define PL_GPIO_DEVICE_ID XPAR_GPIO_0_DEVICE_ID
#define PS_GPIO_DEVICE_ID XPAR_XGPIOPS_0_DEVICE_ID
#define PL_LED_CHANNEL 1
#define PL_KEY_CHANNEL 2
#define PS_BANK XGPIOPS_BANK0
#define PL_LED0 0x01
#define PL_LED1 0x02
#define PL_LED2 0x04
#define PL_LED3 0x08
#define PL_LED4 0x10
#define PS_LED0 0x09
#define PS_LED1 0x00
typedef struct {
u32 OutputHz; /* Output frequency */
XInterval Interval; /* Interval value */
u8 Prescaler; /* Prescaler value */
u16 Options; /* Option settings */
} TmrCntrSetup;
volatile u8 led_status = 0x00;
volatile u8 state1;
volatile u8 state2;
volatile u8 plLed;
volatile u8 psLed;
XGpio plGpio;
XGpioPs psGpio;
XTtcPs psTimer1;
XTtcPs psTimer2;
XScuGic psGic;
static TmrCntrSetup timer1Setup = {
LED1_FREQ_HZ, 0, 0, 0};
static TmrCntrSetup timer2Setup = {
LED2_FREQ_HZ, 0,