7.1 - 定时器之中断控制LED实验
文章目录
- 1 实验任务
- 2 系统框图
- 3 软件设计
1 实验任务
本实验任务是通过CPU私有定时器的中断,每 200ms 控制一次PS LED灯的亮灭。
2 系统框图
3 软件设计
注意事项:
- 定时器中断在收到中断后,只需清除中断状态,无需禁用中断、启动中断操作。
/***************************** Include Files ********************************/
#include <stdio.h>
#include "xparameters.h"
#include "xgpiops.h"
#include "xscutimer.h"
#include "xscugic.h"
#include "xil_exception.h"
#include "xstatus.h"
/************************** Constant Definitions ****************************/
#define GPIO_DEVICE_ID XPAR_XGPIOPS_0_DEVICE_ID
#define TIMER_DEVICE_ID XPAR_XSCUTIMER_0_DEVICE_ID
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
#define TIMER_INTR_ID XPAR_SCUTIMER_INTR
#define PS_LED0_GPIO_PIN 0
#define TIMER_LOAD_VALUE XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ / 2
/**************************** Type Definitions ******************************/
/***************** Macros (Inline Functions) Definitions ********************/
/************************** Function Prototypes *****************************/
int GpioInit(XGpioPs* GpioInstPtr);
int TimerInit(XScuTimer* TimerInstPtr);
int SetupIntrSystem(XScuGic* IntcInstPtr, XScuTimer* TimerInstPtr, u16 TimerIntrId);
void TimerIntrHandler(void *CallBackRef);
/************************** Variable Definitions ****************************/
XGpioPs GpioInst;
XScuTimer TimerInst;
XScuGic IntcInst;
u32 TimeOut = 0;
/****************************************************************************/
int GpioInit(XGpioPs* GpioInstPtr)
{
//
int Status;
XGpioPs_Config* GpioPsConfigPtr;
//
GpioPsConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
Status = XGpioPs_CfgInitialize(GpioInstPtr, GpioPsConfigPtr, GpioPsConfigPtr->BaseAddr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
// 设置输出
XGpioPs_SetDirectionPin(GpioInstPtr, PS_LED0_GPIO_PIN, 1);
// 使能输出
XGpioPs_SetOutputEnablePin(GpioInstPtr, PS_LED0_GPIO_PIN, 1);
//
return XST_SUCCESS;
}
int TimerInit(XScuTimer* TimerInstPtr)
{
//
int Status;
XScuTimer_Config* TimerConfigPtr;
//
TimerConfigPtr = XScuTimer_LookupConfig(TIMER_DEVICE_ID);
Status = XScuTimer_CfgInitialize(TimerInstPtr, TimerConfigPtr, TimerConfigPtr->BaseAddr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
// 自动加载
XScuTimer_EnableAutoReload(TimerInstPtr);
// 加载初值
XScuTimer_LoadTimer(TimerInstPtr, TIMER_LOAD_VALUE);
// 使能中断
XScuTimer_EnableInterrupt(TimerInstPtr);
//
return XST_SUCCESS;
}
int SetupIntrSystem(XScuGic* IntcInstPtr, XScuTimer* TimerInstPtr, u16 TimerIntrId)
{
//
int Status;
XScuGic_Config* IntcConfigPtr;
// step1. 初始化中断控制器GIC
IntcConfigPtr= XScuGic_LookupConfig(INTC_DEVICE_ID);
if (NULL == IntcConfigPtr) {
return XST_FAILURE;
}
Status = XScuGic_CfgInitialize(IntcInstPtr, IntcConfigPtr, IntcConfigPtr->CpuBaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
// step2. 在处理器中初始化异常处理功能
Xil_ExceptionInit();
// step3. 在处理器中为IRQ中断异常注册处理程序
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler, IntcInstPtr);
// step4. 在处理器中使能IRQ中断异常
Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
// step5. 在GIC中为外设注册中断处理程序
Status = XScuGic_Connect(IntcInstPtr, TimerIntrId, (Xil_ExceptionHandler)TimerIntrHandler, (void *)TimerInstPtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
// step6. 在GIC中设置外设中断的优先级和触发类型
// XScuGic_SetPriorityTriggerType();
// step7. 在GIC中使能外设中断
XScuGic_Enable(IntcInstPtr, TimerIntrId);
//
return XST_SUCCESS;
}
void TimerIntrHandler(void *CallBackRef)
{
//
XScuTimer* TimerInstPtr = (XScuTimer*)CallBackRef;
//
if (XScuTimer_IsExpired(TimerInstPtr))
{
XScuTimer_ClearInterruptStatus(TimerInstPtr);
printf("Timer is timeout.\n");
TimeOut = 1;
}
//
return;
}
int main()
{
//
int Status;
u32 LedValue;
//
printf("Timter Interrupt Control LED Test\n");
//
Status = GpioInit(&GpioInst);
if (Status == XST_FAILURE) {
printf("GPIO Init Failed.\n");
}
//
Status = TimerInit(&TimerInst);
if (Status == XST_FAILURE) {
printf("Timer Init Failed.\n");
}
//
Status = SetupIntrSystem(&IntcInst, &TimerInst, TIMER_INTR_ID);
if (Status == XST_FAILURE) {
printf("Setup Interrupt System Failed.\n");
}
// 启动定时器
XScuTimer_Start(&TimerInst);
//
while(1)
{
if(TimeOut==1)
{
LedValue = ~XGpioPs_ReadPin(&GpioInst, PS_LED0_GPIO_PIN);
XGpioPs_WritePin(&GpioInst, PS_LED0_GPIO_PIN, LedValue);
TimeOut = 0;
}
}
//
return 0;
}