私有定时器计时控制LED
#include "stdio.h"
#include "xparameters.h"
#include "xgpiops.h"
#include "sleep.h"
#include "key_debounce.h"
#include "xil_io.h"
#include "xscutimer.h"
#include "xscugic.h"
#define GPIO_DEVICE_ID XPAR_XGPIOPS_0_DEVICE_ID
#define EMIO_PLUSE 54
#define LED_STATE_REG KEY_DEBOUNCE_S00_AXI_SLV_REG4_OFFSET
#define BASEADDR XPAR_KEY_DEBOUNCE_0_S00_AXI_BASEADDR
#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
//3.000003000003000003000003000003
#define TIMER_LOAD_VALUE1 0xEE719B //47
#define TIMER_LOAD_VALUE2 0xF42400 //48
#define TIMER_LOAD_VALUE3 0xF93A15 //49
#define TIMER_LOAD_VALUE4 0xFE502A //50
#define TIMER_LOAD_VALUE5 0x1036640 //51
#define TIMER_LOAD_VALUE6 0x1087C55 //52
#define TIMER_LOAD_VALUE7 0x10D962A //53
#define TIMER_LOAD_VALUE8 0x112A880 //54
#define TIMER_LOAD_VALUE_delay 0X8235
XScuTimer TimerInstance; /* Cortex A9 Scu Private Timer Instance */
XScuGic IntcInstance; /* Interrupt Controller Instance */
XGpioPs Gpio;
unsigned char CODE;
static int sig=1;
const u32 laser_code_order9 [128] =
{
45287, 49655, 50361, 50190, 54521, 46008, 51577, 46729,
46331, 48459, 47016, 47245, 54064, 50434, 52660, 46788,
52524, 53759, 45839, 50722, 48553, 50247, 49753, 51975,
49427, 46920, 46122, 50532, 45380, 54616, 46387, 51935,
48516, 47945, 53267, 48974, 50494, 51328, 48726, 53550,
50950, 50472, 46616, 48099, 49123, 48535, 53627, 53116,
50397, 54028, 54560, 51709, 51916, 52014, 45572, 45628,
52963, 51291, 52088, 48611, 49808, 45742, 46844, 45972,
50817, 52430, 45494, 47756, 49163, 54159, 53382, 50776,
47321, 48762, 52715, 49562, 45361, 49504, 50228, 47110,
52812, 51425, 46769, 49466, 53002, 49582, 48669, 51498,
49105, 49712, 45684, 46901, 49334, 48423, 46578, 54180,
53324, 49733, 54085, 48230, 45325, 45610, 47548, 49066,
51612, 50513, 48118, 50683, 52353, 53021, 53743, 46219,
54253, 46159, 53227, 48706, 48819, 46978, 50549, 53667,
46371, 50263, 52925, 47510, 47965, 51880, 52945, 53418
};
const u32 laser_code_order10 [128] ={
50605, 45818, 47888, 52109, 47796, 50795, 47870, 50073,
51007, 54502, 48802, 51309, 50836, 52221, 49029, 48023,
45307, 49637, 49050, 45894, 45456, 47147, 45858, 51195,
48496, 53588, 47643, 49200, 45799, 52885, 51270, 47926,
53249, 48858, 53154, 48154, 46558, 51441, 52507, 46047,
45077, 49903, 54710, 45476, 46749, 49525, 53894, 50456,
49486, 52277, 51766, 52375, 48211, 46238, 51081, 54275,
52032, 52165, 50321, 51384, 48686, 54462, 51824, 48002,
48896, 52907, 47339, 45117, 52679, 53970, 51994, 52126,
48269, 52185, 47168, 45399, 49921, 50702, 45098, 46255,
50852, 48287, 47812, 54386, 49258, 50931, 47433, 53342,
48572, 46446, 46673, 49373, 51745, 53192, 52639, 48782,
49353, 47491, 51366, 50035, 53857, 50417, 53095, 47090,
51251, 53683, 46275, 53799, 51026, 52051, 51954, 52242,
53703, 53778, 46086, 48441, 52318, 45513, 47698, 48593,
45704, 49979, 50301, 46863, 50378, 52336, 49962, 54405
};
const u32 laser_code_order11 [128] ={
48251, 45990, 45779, 53931, 51899, 49998, 52850, 50664,
53722, 46292, 54291, 49447, 46596, 54445, 51518, 52733,
46634, 53496, 53284, 50967, 46427, 47206, 51462, 45019,
49543, 46199, 47774, 53056, 46808, 46995, 53989, 47282,
50094, 46884, 48344, 52619, 45952, 50757, 50891, 49240,
49883, 52828, 54215, 45934, 51804, 48175, 49314, 54197,
52488, 51632, 51159, 47262, 53952, 48990, 51102, 51347,
46066, 53474, 51594, 49864, 49410, 48043, 47072, 49087,
54579, 47984, 47528, 50644, 48401, 53646, 47454, 48933,
50284, 52146, 52450, 54046, 46539, 47378, 51785, 48135,
46653, 53609, 45266, 52792, 52981, 47299, 52469, 51688,
54120, 46957, 53398, 46029, 45722, 54367, 51672, 52601,
51651, 54313, 53515, 53303, 46503, 45001, 49181, 53875,
54595, 50909, 53838, 48630, 47566, 45193, 46482, 47907,
48364, 47585, 53170, 54633, 49847, 54331, 54481, 49390,
51727, 54654, 47739, 46826, 47851, 50132, 49277, 50111
};
const u32 laser_code_order12 [128] ={
47834, 52261, 52411, 48952, 51556, 46466, 50152, 45592,
51539, 45173, 50627, 47395, 47131, 52564, 48877, 49771,
53818, 54009, 45209, 53077, 53363, 46523, 45420, 46940,
48650, 54236, 49696, 45041, 48079, 52298, 45666, 52772,
54673, 47720, 51061, 53135, 53912, 46103, 53038, 47415,
51178, 52697, 51841, 45440, 45342, 46179, 49599, 49677,
50057, 50740, 45551, 48384, 50342, 49294, 50986, 52754,
53534, 52068, 54141, 47680, 45875, 46694, 49218, 46313,
47186, 47036, 47472, 47053, 53211, 47359, 45648, 50169,
45760, 54351, 49144, 49789, 47663, 51121, 51216, 45133,
49943, 48193, 52543, 49828, 53437, 50568, 51043, 53572,
45532, 46142, 47605, 48328, 45060, 54104, 46406, 54691,
52582, 48746, 51234, 50208, 51139, 47224, 45248, 48839,
54541, 45231, 47625, 52203, 49620, 45154, 48479, 50874,
46712, 52866, 50016, 48916, 52394, 46351, 53456, 50588,
45915, 51860, 48306, 54426, 51479, 48059, 51405, 49010
};
/*void mio_init()
{
XGpioPs_Config *ConfigPtr;
XGpioPs Gpio;
ConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
//查找配置表
XGpioPs_CfgInitialize(&Gpio,ConfigPtr,ConfigPtr->BaseAddr);
//初始化GPIO驱动
XGpioPs_SetDirectionPin(&Gpio,EMIO_PLUSE,1);
//设置脉冲引脚方向为输出
XGpioPs_SetOutputEnablePin(&Gpio,EMIO_PLUSE,1);
//打开脉冲引脚使能
}*/
void TimerIntrHandler(void *CallBackRef)
{
XScuTimer *TimerInstancePtr = (XScuTimer *) CallBackRef;
if (XScuTimer_IsExpired(TimerInstancePtr)) {
XScuTimer_ClearInterruptStatus(TimerInstancePtr);
sig=0;
}
}
void TimerSetupIntrSystem(XScuGic *IntcInstancePtr,
XScuTimer *TimerInstancePtr, u16 TimerIntrId)
{
XScuGic_Config *IntcConfig;
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,IntcConfig->CpuBaseAddress);
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
IntcInstancePtr);
XScuGic_Connect(IntcInstancePtr, TimerIntrId,
(Xil_ExceptionHandler)TimerIntrHandler,
(void *)TimerInstancePtr);
XScuGic_Enable(IntcInstancePtr, TimerIntrId);
XScuTimer_EnableInterrupt(TimerInstancePtr);
Xil_ExceptionEnable();
}
void sig_gen(XScuTimer * TimerInstancePtr)
{
XGpioPs Gpio;
XGpioPs_Config *ConfigPtr;
ConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
//查找配置表
XGpioPs_CfgInitialize(&Gpio,ConfigPtr,ConfigPtr->BaseAddr);
//初始化GPIO驱动
XGpioPs_SetDirectionPin(&Gpio,EMIO_PLUSE,1);
//设置脉冲引脚方向为输出
XGpioPs_SetOutputEnablePin(&Gpio,EMIO_PLUSE,1);
//打开脉冲引脚使能
CODE=~KEY_DEBOUNCE_mReadReg(BASEADDR, LED_STATE_REG)&0X0f;
//读取4个led上的引脚数据
printf("CODE=%d\n",CODE);
while(1)
{
CODE=~KEY_DEBOUNCE_mReadReg(BASEADDR, LED_STATE_REG)&0X0F;
{
u16 i=0;
switch (CODE)
{
case 0X01:
XScuTimer_LoadTimer(TimerInstancePtr, TIMER_LOAD_VALUE1);
XScuTimer_Start(&TimerInstance);
while(sig){
}
sig=1;
printf("CODE_1_1=%d\n",CODE);
printf("CODE_1_2=%d\n",CODE);
XGpioPs_WritePin(&Gpio,EMIO_PLUSE,1);
printf("CODE_1_T_out1_3=%d\n",CODE);
XScuTimer_LoadTimer(TimerInstancePtr, TIMER_LOAD_VALUE_delay);
XScuTimer_Start(&TimerInstance);
while(sig){
}
sig=1;
XGpioPs_WritePin(&Gpio,EMIO_PLUSE,0);
CODE=~KEY_DEBOUNCE_mReadReg(BASEADDR, LED_STATE_REG)&0X0F;
printf("CODE_1_T_out0=%d\n",CODE);
if(CODE!=1)
{
break;
}
break;
case 0X02:
XScuTimer_LoadTimer(TimerInstancePtr, TIMER_LOAD_VALUE2);
XScuTimer_Start(&TimerInstance);
while(sig){
}
sig=1;
XGpioPs_WritePin(&Gpio,EMIO_PLUSE,1);
XScuTimer_LoadTimer(TimerInstancePtr, TIMER_LOAD_VALUE_delay);
XScuTimer_Start(&TimerInstance);
while(sig){
}
sig=1;
XGpioPs_WritePin(&Gpio,EMIO_PLUSE,0);
CODE=~KEY_DEBOUNCE_mReadReg(BASEADDR, LED_STATE_REG)&0X0F;
printf("CODE_2_T=%d\n",CODE);
if(CODE!=1)
{
break;
}
break;
case 0X03:
XScuTimer_LoadTimer(TimerInstancePtr, TIMER_LOAD_VALUE3);
XScuTimer_Start(&TimerInstance);
while(sig){
}
sig=1;
XGpioPs_WritePin(&Gpio,EMIO_PLUSE,1);
XScuTimer_LoadTimer(TimerInstancePtr, TIMER_LOAD_VALUE_delay);
XScuTimer_Start(&TimerInstance);
while(sig){
}
sig=1;
XGpioPs_WritePin(&Gpio,EMIO_PLUSE,0);
CODE=~KEY_DEBOUNCE_mReadReg(BASEADDR, LED_STATE_REG)&0X0F;
printf("CODE_3_T=%d\n",CODE);
if(CODE!=1)
{
break;
}
break;
case 0X04:
XScuTimer_LoadTimer(TimerInstancePtr, TIMER_LOAD_VALUE4);
XScuTimer_Start(&TimerInstance);
while(sig){
}
sig=1;
XGpioPs_WritePin(&Gpio,EMIO_PLUSE,1);
XScuTimer_LoadTimer(TimerInstancePtr, TIMER_LOAD_VALUE_delay);
XScuTimer_Start(&TimerInstance);
while(sig){
}
sig=1;
XGpioPs_WritePin(&Gpio,EMIO_PLUSE,0);
CODE=~KEY_DEBOUNCE_mReadReg(BASEADDR, LED_STATE_REG)&0X0F;
printf("CODE_4_T=%d\n",CODE);
if(CODE!=1)
{
break;
}
break;
case 0X05:
XScuTimer_LoadTimer(TimerInstancePtr, TIMER_LOAD_VALUE5);
XScuTimer_Start(&TimerInstance);
while(sig){
}
sig=1;
XGpioPs_WritePin(&Gpio,EMIO_PLUSE,1);
XScuTimer_LoadTimer(TimerInstancePtr, TIMER_LOAD_VALUE_delay);
XScuTimer_Start(&TimerInstance);
while(sig){
}
sig=1;
XGpioPs_WritePin(&Gpio,EMIO_PLUSE,0);
CODE=~KEY_DEBOUNCE_mReadReg(BASEADDR, LED_STATE_REG)&0X0F;
printf("CODE_5_T=%d\n",CODE);
if(CODE!=1)
{
break;
}
break;
case 0X06:
XScuTimer_LoadTimer(TimerInstancePtr, TIMER_LOAD_VALUE6);
XScuTimer_Start(&TimerInstance);
while(sig){
}
sig=1;
XGpioPs_WritePin(&Gpio,EMIO_PLUSE,1);
XScuTimer_LoadTimer(TimerInstancePtr, TIMER_LOAD_VALUE_delay);
XScuTimer_Start(&TimerInstance);
while(sig){
}
sig=1;
XGpioPs_WritePin(&Gpio,EMIO_PLUSE,0);
CODE=~KEY_DEBOUNCE_mReadReg(BASEADDR, LED_STATE_REG)&0X0F;
printf("CODE_6_T=%d\n",CODE);
if(CODE!=1)
{
break;
}
break;
case 0X07:
XScuTimer_LoadTimer(TimerInstancePtr, TIMER_LOAD_VALUE7);
XScuTimer_Start(&TimerInstance);
while(sig){
}
sig=1;
XGpioPs_WritePin(&Gpio,EMIO_PLUSE,1);
XScuTimer_LoadTimer(TimerInstancePtr, TIMER_LOAD_VALUE_delay);
XScuTimer_Start(&TimerInstance);
while(sig){
}
sig=1;
XGpioPs_WritePin(&Gpio,EMIO_PLUSE,0);
CODE=~KEY_DEBOUNCE_mReadReg(BASEADDR, LED_STATE_REG)&0X0F;
printf("CODE_7_T=%d\n",CODE);
if(CODE!=1)
{
break;
}
break;
case 0X08:
XScuTimer_LoadTimer(TimerInstancePtr, TIMER_LOAD_VALUE8);
XScuTimer_Start(&TimerInstance);
while(sig){
}
sig=1;
XGpioPs_WritePin(&Gpio,EMIO_PLUSE,1);
XScuTimer_LoadTimer(TimerInstancePtr, TIMER_LOAD_VALUE_delay);
XScuTimer_Start(&TimerInstance);
while(sig){
}
sig=1;
XGpioPs_WritePin(&Gpio,EMIO_PLUSE,0);
CODE=~KEY_DEBOUNCE_mReadReg(BASEADDR, LED_STATE_REG)&0X0F;
printf("CODE_8_T=%d\n",CODE);
if(CODE!=1)
{
break;
}
break;
case 0X09:
for (i = 0; i < 127; ++i)
{
XScuTimer_LoadTimer(TimerInstancePtr, laser_code_order9[i]*1000/3);
XScuTimer_Start(TimerInstancePtr);
while(sig){
}
sig=1;
XGpioPs_WritePin(&Gpio,EMIO_PLUSE,1);
XScuTimer_LoadTimer(TimerInstancePtr, TIMER_LOAD_VALUE_delay);
XScuTimer_Start(&TimerInstance);
while(sig){
}
sig=1;
XGpioPs_WritePin(&Gpio,EMIO_PLUSE,0);
CODE=~KEY_DEBOUNCE_mReadReg(BASEADDR, LED_STATE_REG)&0X0F;
printf("9_CODE=%d\n",CODE);
if(CODE!=0X09)
{
break;
}
}
case 0X0A:
for (i = 0; i < 127; ++i)
{
XScuTimer_LoadTimer(TimerInstancePtr, laser_code_order10[i]*1000/3);
XScuTimer_Start(TimerInstancePtr);
while(sig){
}
sig=1;
XGpioPs_WritePin(&Gpio,EMIO_PLUSE,1);
XScuTimer_LoadTimer(TimerInstancePtr, TIMER_LOAD_VALUE_delay);
XScuTimer_Start(&TimerInstance);
while(sig){
}
sig=1;
XGpioPs_WritePin(&Gpio,EMIO_PLUSE,0);
CODE=~KEY_DEBOUNCE_mReadReg(BASEADDR, LED_STATE_REG)&0X0F;
printf("10_CODE=%d\n",CODE);
if(CODE!=0X0A)
{
break;
}
}
case 0X0B:
for (i = 0; i < 127; ++i)
{
XScuTimer_LoadTimer(TimerInstancePtr, laser_code_order11[i]*1000/3);
XScuTimer_Start(TimerInstancePtr);
while(sig){
}
sig=1;
XGpioPs_WritePin(&Gpio,EMIO_PLUSE,1);
XScuTimer_LoadTimer(TimerInstancePtr, TIMER_LOAD_VALUE_delay);
XScuTimer_Start(&TimerInstance);
while(sig){
}
sig=1;
XGpioPs_WritePin(&Gpio,EMIO_PLUSE,0);
CODE=~KEY_DEBOUNCE_mReadReg(BASEADDR, LED_STATE_REG)&0X0F;
printf("11_CODE=%d\n",CODE);
if(CODE!=0X0B)
{
break;
}
}
case 0X0C:
for (i = 0; i < 127; ++i)
{
XScuTimer_LoadTimer(TimerInstancePtr, laser_code_order12[i]*1000/3);
XScuTimer_Start(TimerInstancePtr);
while(sig){
}
sig=1;
XGpioPs_WritePin(&Gpio,EMIO_PLUSE,1);
XScuTimer_LoadTimer(TimerInstancePtr, TIMER_LOAD_VALUE_delay);
XScuTimer_Start(&TimerInstance);
while(sig){
}
sig=1;
XGpioPs_WritePin(&Gpio,EMIO_PLUSE,0);
CODE=~KEY_DEBOUNCE_mReadReg(BASEADDR, LED_STATE_REG)&0X0F;
printf("12_CODE=%d\n",CODE);
if(CODE!=0X0C)
{
break;
}
}
default: break;
}
}
}
}
void timer_init(XScuGic *IntcInstancePtr, XScuTimer * TimerInstancePtr,
u16 TimerDeviceId, u16 TimerIntrId)
{
XScuTimer_Config *ConfigPtr;
ConfigPtr = XScuTimer_LookupConfig(TimerDeviceId);
XScuTimer_CfgInitialize(TimerInstancePtr, ConfigPtr,
ConfigPtr->BaseAddr);
TimerSetupIntrSystem(IntcInstancePtr,
TimerInstancePtr, TimerIntrId);
XScuTimer_EnableAutoReload(TimerInstancePtr);
//XScuTimer_LoadTimer(TimerInstancePtr, TIMER_LOAD_VALUE2);
sig_gen(TimerInstancePtr);
}
int main()
{
//mio_init();
timer_init(&IntcInstance, &TimerInstance,TIMER_DEVICE_ID, TIMER_IRPT_INTR);
//XScuTimer_Start(&TimerInstance);
return 0;
}
定时器可以不在cpu的干预下运行
用sleep()函数的缺点是会消耗cpu的资源,cpu在延时的时候就干不了其他的事情,只能等着等延时完成。如果延时交给定时器来完成,cpu就可以去做其他的事情。
学习:如何使用ARM内部的定时器

每个处理器有它们私有的32位定时器和32位的看门狗定时器。2个处理器共用1个总的64位的定时器。这些定时器的时钟都是由 1/2 的cpu的时钟来进行驱动。
cpu频率一般为666.6666Mhz 则定时器频率为333.333Mhz 在计算的时候要进行换算。
私有定时器:常规的计时计数,包括输出pwm的波形这样的一个功能,
看门狗定时器:实现监控,监视的功能。比如程序死机了,或者是跑飞了,看门狗可以使我们的程序重启,重新开始运行,让我们的程序恢复到一个正常的状态。
系统级上还有
24位的看门狗定时器 时钟频率为cpu的 1/4 或 1/6
三重定时器:16位,时钟频率为cpu的 1/4 或 1/6 。可以对信号的脉冲宽度进行计数(可以来自MIO引脚或PL)。有些外设,像红外遥控是根据脉冲宽度的时间来去判断它是逻辑0还是逻辑1的,就可以通过三重定时器来判断是逻辑0还是逻辑1,并且三重定时器可以不受CPU的干预的情况下自己独立运行,从而节省cpu的资源。

这些定时器都可以触发中断控制器进行中断。
本次实验要完成功能:通过CPU的私有定时器来去触发中断,从而来控制引脚让其输出高低电平

CPU私有的定时器和看门狗定时器共有的特性:
1.当达到0的时候产生中断。其实定时器在工作的时候我们需要给一个预装载的值,可以是1000也可以是其他的数。定时器运行的时候值慢慢减小,到0的时候产生中断,通知我们的CPU计时完成。
2.有8位的预分频用以使能来更好的控制中断周期。因为它的时钟的驱动频率就是1/2的系统时钟,系统时钟的频率还是比较快的,如果想降低它的频率的话可以通过这个预分频来对其进行分频从而降低它的频率。
3.可以配置成单次的模式或者是自动装载(重复)的模式。(就是给它一个预装载的值,计时到0之后就结束了,还是说再重新进行一个装载)。
4.可以给它配置一个初始的值,

Timer Load:装载值,慢慢递减
Timer Counter:当前递减到多少

系统的看门狗定时器 SWDT,可以在系统发生错误的时候,产生复位信号让程序重启。与AWDT:私有的定时器不同的是,SWDT的时钟可以来自于外部的设备或者PL然后提供提供复位信号到外部设备或PL
(UG585 timer)在文档中还有各自定时器的使用指南。

实验 每隔200MS产生中断,通过GPIO控制PS部分的led灯每200MS进行亮灭
使用定时器不需要再做额外配置,只需要在SDK当中通过C语言额外使能定时器即可。




1000/333.3333=3ns
200ms/3ns=666_666_00 因为从0开始 要-1 最后是 0X3F94067 延时200MS所需要的值




定时器中断初始化和串口中断其实大同小异

定时器模板:
1.先对定时器进行初始化
2.中断初始化
3.reload模式和装载计数器的值
4.开启定时器

浙公网安备 33010602011771号