📄 timer.c
字号:
/*
*********************************************************
* Copyright (c)
* All rights reserved.
*
* 文件名称:Timer.c
* 文件标识:
* 摘 要:本文件是对Timer and Watch-dog进行初始化和操作。
* 当前版本:1.0
* 作 者:刘征
* 完成日期:2005.4.3
*
* 取代版本:
* 作 者:
* 完成日期:
*********************************************************
*/
/*
*********************************************************
* 头文件
*********************************************************
*/
#include <string.h>
#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
#include "timer.h"
/*
*********************************************************
* 变量
*********************************************************
*/
/* Structure Define for DMA Special Registers */
typedef struct tagDMA
{
volatile U32 DISRC; //0x0
volatile U32 DISRCC; //0x4
volatile U32 DIDST; //0x8
volatile U32 DIDSTC; //0xc
volatile U32 DCON; //0x10
volatile U32 DSTAT; //0x14
volatile U32 DCSRC; //0x18
volatile U32 DCDST; //0x1c
volatile U32 DMASKTRIG; //0x20
}DMA;
static volatile int dmaDone,variable0,variable1,variable2,variable3,variable4;
int TestMode,j;
volatile int isWdtInt;
/*
*********************************************************
* 函数
*********************************************************
*/
/******************** PWM Timer Normal Operation Test ********************/
void Test_TimerNormal(void)
{
int save_B,save_G,save_H,save_PB,save_PG,save_PH,save_MI;
char key;
/* Save Current Register related to PWM Port */
//Save Current GPB, G, H Configure Registers
save_B = rGPBCON;
save_G = rGPGCON;
save_H = rGPHCON;
//Save Pull-Up Disable Register
save_PB = rGPBUP;
save_PG = rGPGUP;
save_PH = rGPHUP;
//Save Miscellaneous Control Register
save_MI = rMISCCR;
/* Setting Port related to PWM */
// PortB
rGPBUP = rGPBUP & ~(0x1f) | 0x1f; //GPB[4:0] Pull Up
rGPBCON = rGPBCON & ~(0x3ff) | 0x2 | 0x2 << 2 | 0x2 << 4 | 0x2 << 6 | 0x2 << 8; //TCKL0, TOUT[3:0]
// PortG
rGPGUP = rGPGUP & ~(0x800) | 0x800; //GPG11 Pull Up
rGPGCON = rGPGCON & ~(0xc00000) | 0xc00000; //TCLK1
// PortH
rGPHUP = rGPHUP & ~(0x200) | 0x200; //GPH9 Pull Up
rGPHCON = rGPHCON & ~(0x3<<18) | (0x2<<18); //CLKOUT0
// Miscellaneous Control Register
rMISCCR = rMISCCR & ~(0xf0) | 0x40; //Select PCLK with CLKOUT0
Uart_Printf("[Select Timer Test Setting]\n");
Uart_Printf("a. Prescaler 1, 0: 0, Dead zone Disable, MUX 4~0: 1/2, (H/L)duty 50 \nb. Prescaler 1, 0: 8, Dead zone Enable, MUX 4~0: 1/16, (H/L)duty 50 \nc. (H/L)duty 0, TCNT =< TCMP, Inverter On\nd. TCLK0, TCLK1 Input Divider Test\n");
Uart_Printf("Select [a ~ d]: \n");
key = Uart_Getch();
Uart_Printf("%c\n\n",key);
/* Timer Configuration Reg.0, 1(TCFG0, TCFG1) Setting */
switch(key)
{
case 'a':
rTCFG0 = rTCFG0 & ~(0xffffff) | 0x00000; //Dead zone=0, Prescaler1=0, Prescaler0=0
rTCFG1 = 0x0; //All Interrupt, MUX 4 ~ 0: 1/2
Uart_Printf("Prescaler1=0, Prescaler0=0, Dead Zone Disable, MUX 4 ~ 0: 1/2, Duty 50% \n");
break;
case 'b':
rTCFG0 = rTCFG0 & ~(0xffffff) | (0xc8)<<16 | (0x7)<<8 | (0x7); //Dead zone=0, Prescaler1=7, Prescaler0=7
rTCFG1 = rTCFG1 & ~(0xffffff) | (0x3)<<16 | (0x3)<<12 | (0x3)<<8 | (0x3)<<4 | (0x3); //All Interrupt, MUX 4 ~ 0: 1/16
Uart_Printf("Prescaler1=8, Prescaler0=8, Dead zone=200 Enable, MUX 4 ~ 0: 1/16, duty = 50%, Consider Dead zone effect\n");
break;
case 'c':
rTCFG0 = rTCFG0 & 0x0; //Dead zone=0, Prescaler1=0, Prescaler0=0
rTCFG1 = rTCFG1 & 0x0; //All Interrupt, MUX 4 ~ 0: 1/2
Uart_Printf("(H/L)Duty 0, TCNT =< TCMP, Inverter On\n");
break;
case 'd':
rTCFG0 = rTCFG0 & ~(0xffffff) | 0x00000; //Dead zone=0, Prescaler1=0, Prescaler0=0
rTCFG1 = rTCFG1 & ~(0xffffff) | 0x4 | 0x4 << 4 | 0x4 << 8 | 0x4 << 12 | 0x4 << 16; //All Interrupt, MUX 4 ~ 0: 1/2
Uart_Printf("TCLK0, TCLK1 Input Divider Test(if TCLK0, TCLK1=25.4MHZ)\n");
break;
default:
rGPBCON = save_B;
rGPGCON = save_G;
rGPHCON = save_H;
rGPBUP = save_PB;
rGPGUP = save_PG;
rGPHUP = save_PH;
rMISCCR = save_MI;
return;
}
//(1/(PCLK/(Prescaler+1)/divider) * count(Max 65535) = Timer clock (Frequency)
//(1/(50.8MHz/1/2)) * 2000 = 0.0787 msec ( 12.7 KHz)
//(1/(50.8MHz/1/2)) * 4000 = 0.1575 msec ( 6.35 KHz)
//(1/(50.8MHz/1/2)) * 5000 = 0.1969 msec ( 5.080 KHz)
//(1/(50.8MHz/1/2)) * 10000 = 0.3937 msec ( 2.54 KHz)
//(1/(50.8MHz/8/16)) * 2000 = 5.039 msec ( 198.45 Hz)
//(1/(50.8MHz/8/16)) * 4000 = 10.079 msec ( 99.216 KHz)
//(1/(50.8MHz/8/16)) * 5000 = 12.598 msec ( 79.38 Hz)
//(1/(50.8MHz/8/16)) * 10000 = 25.197 msec ( 39.687 Hz)
rTCNTB0 = 2000;
rTCNTB1 = 4000;
rTCNTB2 = 5000;
rTCNTB3 = 10000;
rTCMPB0 = 2000 - 1000; //(H/L)duty 50%
rTCMPB1 = 4000 - 2000;
rTCMPB2 = 5000 - 2500;
rTCMPB3 = 10000 - 5000;
rTCON = rTCON & ~(0xffffff) | 0x1<<1 | 0x1<<9 | 0x1<<13 | 0x1<<17 | 0x1<<21 ; //Manual update
switch(key)
{
case 'a':
rTCON = rTCON & ~(0xffffff) | 0x599909; //Auto reload, Inverter off, No operation, Start, Dead zone Disable
break;
case 'b':
rTCNTB0 = rTCNTB0 & ~(0xffff) | 500; //(1/(50.8MHz/8/16)) * 500 = 1.273 msec ( 793.8 Hz)
rTCMPB0 = 500 - 250; //(H/L)duty 50%
rTCON = rTCON & ~(0xffffff) | 0x6aaa0a; //Auto reload, Inverter off, Manual update, Stop, Dead zone Disable
rTCON = rTCON & ~(0xffffff) | 0x599909| (0x1) << 4; //Auto reload, Inverter off, No operation, Start, Dead zone Enable
break;
case 'c':
rTCNTB0 = rTCNTB0 & ~(0xffff) | 1000;
rTCMPB0 = 1000;
rTCNTB1 = rTCNTB1 & ~(0xffff) | 1000;
rTCMPB1 = 1000;
rTCNTB2 = rTCNTB2 & ~(0xffff) | 1000;
rTCMPB2 = 1000;
rTCNTB3 = rTCNTB3 & ~(0xffff) | 1000;
rTCMPB3 = 1000;
rTCON = rTCON & ~(0xffffff) | 0x1 << 1 | 0x1 << 9 | 0x1 << 13 | 0x1 << 17 | 0x1 << 21; //Auto reload disable, Inverter off, Manual update, Stop, Dead zone Disable
rTCON = rTCON & ~(0xffffff) | 0x1 | 0x1 << 2 | 0x1 <<8 | 0x1 << 10| 0x1 << 12 | 0x1 << 14 | 0x1 << 16 | 0x1 << 18| 0x1 << 20; //Auto reload enable, Inverter On, No Operation, Start, Dead zone Disable
Uart_Printf("rTCNTB0 = Dec:%d, rTCNTO0 = Dec:%d, rTCMPB0 = Dec:%d\n",rTCNTB0, rTCNTO0, rTCMPB0);
break;
case 'd':
rTCON = rTCON & ~(0xffffff) | 0x599909; //Auto reload, Inverter off, No operation, Start, Dead zone Disable
break;
default:
break;
}
if(key=='a' && (PCLK==(203200000/4)))
{
Uart_Printf("PCLK 50.8MHz, Timer TOUT0 : 0.0787 msec ( 12.70 KHz)\n");
Uart_Printf("PCLK 50.8MHz, Timer TOUT1 : 0.1575 msec ( 6.35 KHz)\n");
Uart_Printf("PCLK 50.8MHz, Timer TOUT2 : 0.1969 msec ( 5.08 KHz)\n");
Uart_Printf("PCLK 50.8MHz, Timer TOUT3 : 0.3937 msec ( 2.54 KHz)\n");
}
else if(key=='b' && (PCLK==(203200000/4)))
{
Uart_Printf("PCLK 50.8MHz, Timer TOUT0 : 1.273 msec (793.8 KHz)\n");
Uart_Printf("PCLK 50.8MHz, Timer TOUT1 : /TOUT0 \n");
Uart_Printf("PCLK 50.8MHz, Timer TOUT2 : 13.6094 msec ( 73.478 Hz)\n");
Uart_Printf("PCLK 50.8MHz, Timer TOUT3 : 27.2189 msec ( 36.739 Hz)\n");
}
else if(key=='d' && (PCLK==(203200000/4)))
{
Uart_Printf("then Timer TOUT 0 : 0.0787 msec ( 12.70 KHz)\n");
Uart_Printf("then Timer TOUT 1 : 0.1575 msec ( 6.35 KHz)\n");
Uart_Printf("then Timer TOUT 2 : 0.1969 msec ( 5.08 KHz)\n");
Uart_Printf("then Timer TOUT 3 : 0.3937 msec ( 2.54 KHz)\n");
}
Uart_Printf("\nProbe PCLK.\n");
Uart_Printf("Probe TOUT0.\n");
Uart_Printf("Probe TOUT1.\n");
Uart_Printf("Probe TOUT2.\n");
Uart_Printf("Probe TOUT3.\n");
Uart_Printf("\nCheck PWM (Pulse Width Modulation) Output\n");
Uart_Printf("Press any key.\n");
Uart_Getch();
/* Stop Timer0, 1, 2, 3, 4 */
rTCON = 0x0; //One-shot, Inverter off, No operation, Dead zone disable, Stop Timer
rGPBCON = save_B;
rGPGCON = save_G;
rGPHCON = save_H;
rGPBUP = save_PB;
rGPGUP = save_PG;
rGPHUP = save_PH;
rMISCCR = save_MI;
}
/******************** Timer Interrupt 0/1/2/3/4 test ********************/
void Test_TimerInt(void)
{
variable0 = 0;variable1 = 0;variable2 = 0;variable3 = 0;variable4 = 0;
/* Timer0,1,2,3,4 Interrupt service is available */
rINTMSK = ~(BIT_TIMER4 | BIT_TIMER3 | BIT_TIMER2 | BIT_TIMER1 | BIT_TIMER0);
// Uart_Printf("rINTMSK (After) = 0x%8x <= Timer4,3,2,1 Bit[14:10]\n",rINTMSK);
/* Timer0,1,2,3,4 Interrupt Service Routine Entry Point Determine */
pISR_TIMER0 = (int)Timer0Done;
pISR_TIMER1 = (int)Timer1Done;
pISR_TIMER2 = (int)Timer2Done;
pISR_TIMER3 = (int)Timer3Done;
pISR_TIMER4 = (int)Timer4Done;
Uart_Printf("\n[Timer 0,1,2,3,4 Interrupt Test]\n\n");
rTCFG0 = rTCFG0 & ~(0xffffff) | 0xff | 0xff<<8; //Dead zone=0,Prescaler1=255(0x0f),Prescaler0=255(0x0f)
rTCFG1 =rTCFG1 & ~(0xffffff) | 0x001233; //All interrupt,Mux4=1/2,Mux3=1/4,Mux2=1/8,Mux1=1/16,Mux0=1/16
rTCNTB0 = 30000;
rTCNTB1 = 30000;
rTCNTB2 = 30000;
rTCNTB3 = 30000;
rTCNTB4 = 30000;
rTCMPB0 = 15000;
rTCMPB1 = 15000;
rTCMPB2 = 15000;
rTCMPB3 = 15000;
rTCON = rTCON & ~(0xffffff) | 0x1<<1 | 0x1<<9 | 0x1<<13 | 0x1<<17 | 0x1<<21 ; //Manual update
rTCON = rTCON & ~(0xffffff) | 0x1 | 0x1<<3 ; //Timer 0 Start, Auto-reload
rTCON = rTCON | 0x1<<8 | 0x1<<11 ; //Timer 1 Start, Auto-reload
rTCON = rTCON | 0x1<<12 | 0x1<<15 ; //Timer 2 Start, Auto-reload
rTCON = rTCON | 0x1<<16 | 0x1<<19 ; //Timer 3 Start, Auto-reload
rTCON = rTCON | 0x1<<20 | 0x1<<22 ; //Timer 4 Start, Auto-reload
//Auto reload,Inverter off,No operation,Dead zone disable,Start
while(1)
{
if(variable4 == 8)
break;
}
//Delay(1); //To compensate timer error(<1 tick period)
rTCON = 0x0; //Stop Timers
if(variable4==8 && variable3==4 && variable2==2 && variable1==1 && variable0==1)
{
Uart_Printf("Timer 0,1,2,3,4 Auto-reload Interrupt Test => OK!\n");
}
else
{
Uart_Printf("Timer 0,1,2,3,4 Auto-reload Interrupt Test => Fail............\n");
}
Uart_Printf("Timer0: %d (=1)\nTimer1: %d (=1)\nTimer2: %d (=2)\nTimer3: %d (=4)\nTimer4: %d (=8)\n",
variable0,variable1,variable2,variable3,variable4);
/* Timer0,1,2,3,4 Interrupt Service is masked */
rINTMSK |= (BIT_TIMER4 | BIT_TIMER3 | BIT_TIMER2 | BIT_TIMER1 | BIT_TIMER0);
Uart_Printf("Press any key\n");
while(!Uart_Getch()); //Key board press check
}
/****** Timer Interrupt Request ******/
void __irq Timer0Done(void)
{
rSRCPND = BIT_TIMER0; //Clear pending bit
rINTPND = BIT_TIMER0;
// rINTPND; //Prevent an double interrupt pending
variable0++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -