⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timer.c

📁 支持三星原产的S3C24A0开发板
💻 C
📖 第 1 页 / 共 2 页
字号:
//=============================================================================
// File Name : Timer.c
// Function  : S3C2410 Watch-Dog and Timer
// Program   : Shin, On Pil (SOP)
// Date      : May 21, 2002
// Version   : 0.0
// History
//   0.0 : Programming start (February 27,2002) -> SOP
//=============================================================================
//=============================================================================
// File Name : Timer.c
// Function  : S3C24a0 Watch-Dog and PWM Timer
// Program   : Oh woo seok
// Date      : April 14, 2003
// Version   : 0.0
// History
//   0.0 : Programming start (April 14, 2003) 
//=============================================================================

#include <string.h>
#include "24a0addr.h"
#include "24a0lib.h"
#include "timer.h"
#include "def.h"


static volatile int dmaDone;
volatile int variable0,variable1,variable2,variable3,variable4;


//=========================================================================
//      SMDK24a0 TOUT configuration(GPCON_U:0x44800000)
//  GP23=PWM_TOUT3,GP22=PWM_TOUT2,GP21=PWM_TOUT1,GP20=PWM_TOUT0,
//  GP19=PWM_ECLK 

//
//Timer input clock frequency = PCLK/{prescaler value+1}/{divider value}
//{prescaler value} = 0 ~ 255   , {divider value} = 2,4,8,16
//
//  PWM Timer PWM_TOUT0/1/2/3/ECLK Test - 24a0
//=========================================================================


void * timer_func[][2]=
{
	(void *)Test_TimerInt,          	        "Timer Interrupt        ",
	(void *)Test_Timer,                    		"Timer Tout             ",
	(void *)Test_TimerDma,  	                "Timer DMA              ",
	0,0
};

void Ch7_PwmTimer_test(void)
{
	int i;
	
	Uart_Printf("Menu of Timer function\n");
	// Wait until memory stick is inserted.
	
	while(1) {
		TimerSubMessage();
		Uart_Printf("\nSelect(-1 to exit): ");
		i = Uart_GetIntNum();
		//Uart_Printf("IN:%d.\n\n", i);
		if(i==-1) break;
		
		if(i>=0 && (i<(sizeof(timer_func)/3)) ) 
	    	( (void (*)(void)) (timer_func[i][0]) )();	// execute selected function.
	}

}

void TimerSubMessage(void)
{
	int i;
	
	
	i=0;	
	Uart_Printf("\n\n");
	while(1)
	{   //display menu
	    Uart_Printf("%2d:%s",i,timer_func[i][1]);
	    i++;
	    if((int)(timer_func[i][0])==0)
	    {
			Uart_Printf("\n");
			break;
	    }
	    if((i%4)==0) Uart_Printf("\n");
	}
}


//=========================================================================
//      SMDK24a0 TOUT configuration(GPCON_U:0x44800000)
//  GP23=PWM_TOUT3,GP22=PWM_TOUT2,GP21=PWM_TOUT1,GP20=PWM_TOUT0,
//  GP19=PWM_ECLK 

//
//Timer input clock frequency = PCLK/{prescaler value+1}/{divider value}
//{prescaler value} = 0 ~ 255   , {divider value} = 2,4,8,16
//
//  PWM Timer PWM_TOUT0/1/2/3/ECLK Test - 24a0
//=========================================================================

#define GPCONU_ABAIL (TRUE)  // if wanna GPGONU set "FALSE"

void Test_Timer(void)
{
    int save_GPCON_U, save_GPCON_L,save_GPDAT, save_rGPUP;
    int Deadzone_test_flag= 0, PWM50_test_flag=0, Inverton_test_flag=0;
	char key;
	
    
    Uart_Printf("[ PWM_TOUT 0,1,2,3 Test ]\n\n");    
    //Uart_Printf("= Current Port Setting List =\n");
    //Uart_Printf("rGPCON_U = 0x%8x,   rGPDAT = 0x%8x,   rGPUP= 0x%8x \n" ,rGPCON_U,rGPDAT,rGPUP);

    save_GPCON_L= rGPCON_L;
    save_GPCON_U= rGPCON_U;	
    save_GPDAT= rGPDAT;
    save_rGPUP= rGPPU;    

    // controls PCLK into PWMTIMER block 0 :disable, 1:enable
    rCLKCON = rCLKCON & ~(0x100) | 0x100;
    // IO port pull up control register : 0=enable, 1=disable   
    //rGPPU= rGPPU & ~(0x00f80000) | 0x00f80000;

    // IO port configuration register relative to TIMER
#if GPCONU_ABAIL
    	rGPCON_U = 0x2aa;
#else
    	rGPCON_L = 0xffc;
#endif

    rGPPU = 0x0;	
    // check the buffer writing, correctly
    //Uart_Printf("= Changed Port Setting List =\n");    
    //Uart_Printf("rGPCON_U = 0x%8x,   rGPDAT = 0x%8x,   rGPUP= 0x%8x \n" ,rGPCON_L,rGPDAT,rGPPU);


LABEL:

    Uart_Printf("[ Select Timer Clock ]\n");
    Uart_Printf("[  prescaler0 | prescaler1 | divider\n");
    Uart_Printf("a.       0                 0             1/2 \n");
    Uart_Printf("b.       0                 0             1/4 \n");
    Uart_Printf("c.       0                 0             1/8 \n");
    Uart_Printf("d.       0                 0             1/16 \n");
//    Uart_Printf("e.       0                 0             TCLK0 \n"); // not implemented in GPIO
    Uart_Printf("f.     255              255           1/2 \n");
    Uart_Printf("g.    255              255           1/4 \n");
    Uart_Printf("h.    255              255           1/8 \n"); 
    Uart_Printf("i.     255              255           1/16 \n");
//    Uart_Printf("j.     255              255           TCLK1 \n"); // // not implemented in GPIO	
    Uart_Printf("k.       0                 0             1/2 (Dead-zone value=40 \n");
    Uart_Printf("l.       0                 0             1/2 (PWM 50% \n");
    Uart_Printf("m.     0                 0             1/2 (Invert on.off \n");
		
    Uart_Printf("\nSelect the function to test : ");
    key = Uart_Getch();
    Uart_Printf("%c\n\n",key);    

    switch(key)
    {
	 case 'a'://All Interrupt, MUX 4 ~ 0 : 1/2 //Dead zone=1,Prescaler1=0,Prescaler0=0	
            rTCFG0 = rTCFG0 & ~(0xffffff) | 0x10000;     
            rTCFG1 = 0x0; 
            break;
	 case 'b'://All Interrupt, MUX 4 ~ 0 : 1/4 //Dead zone=1,Prescaler1=0,Prescaler0=0	
            rTCFG0 = rTCFG0 & ~(0xffffff) | 0x10000;     
            rTCFG1 = 0x1111; 
            break;
	 case 'c'://All Interrupt, MUX 4 ~ 0 : 1/8 //Dead zone=1,Prescaler1=0,Prescaler0=0	
            rTCFG0 = rTCFG0 & ~(0xffffff) | 0x10000;     
            rTCFG1 = 0x2222; 
            break;
	 case 'd'://All Interrupt, MUX 4 ~ 0 : 1/16 //Dead zone=1,Prescaler1=0,Prescaler0=0	
            rTCFG0 = rTCFG0 & ~(0xffffff) | 0x10000;     
            rTCFG1 = 0x3333; 
            break;
//	 case 'e'://All Interrupt, MUX 4 ~ 0 : TCLK0 //Dead zone=1,Prescaler1=0,Prescaler0=0	
//            rTCFG0 = rTCFG0 & ~(0xffffff) | 0x10000;     
//            rTCFG1 = 0x4444; 
//            break;
	 case 'f'://All Interrupt, MUX 4 ~ 0 : 1/2 //Dead zone=1,Prescaler1=255,Prescaler0=255	
            rTCFG0 = rTCFG0 & ~(0xffffff) | 0x1ffff;     
            rTCFG1 = 0x0; 
            break;
	 case 'g'://All Interrupt, MUX 4 ~ 0 : 1/4 //Dead zone=1,Prescaler1=255,Prescaler0=255	
            rTCFG0 = rTCFG0 & ~(0xffffff) | 0x1ffff;     
            rTCFG1 = 0x1111; 
            break;
	 case 'h'://All Interrupt, MUX 4 ~ 0 : 1/8 //Dead zone=1,Prescaler1=255,Prescaler0=255	
            rTCFG0 = rTCFG0 & ~(0xffffff) | 0x1ffff;     
            rTCFG1 = 0x2222; 
            break;
	 case 'i'://All Interrupt, MUX 4 ~ 0 : 1/16 //Dead zone=1,Prescaler1=255,Prescaler0=255	
            rTCFG0 = rTCFG0 & ~(0xffffff) | 0x1ffff;     
            rTCFG1 = 0x3333; 
            break;
//	case 'j'://All Interrupt, MUX 4 ~ 0 : TCLK1 //Dead zone=1,Prescaler1=255,Prescaler0=255	
//            rTCFG0 = rTCFG0 & ~(0xffffff) | 0x1ffff;     
//            rTCFG1 = 0x4444; 
//            break;
	 case 'k'://All Interrupt, MUX 1 ~ 0 : 1/2 //Dead zone=40,Prescaler1=0,Prescaler0=0	
            rTCFG0 = rTCFG0 & ~(0xffffff) | 0x280000;     
            rTCFG1 = 0x0; 
            Deadzone_test_flag = 1;			
            break;
	 case 'l'://All Interrupt, MUX 1 ~ 0 : 1/2 //Dead zone=1,Prescaler1=0,Prescaler0=0, PWM50%	
            rTCFG0 = rTCFG0 & ~(0xffffff) | 0x280000;     
            rTCFG1 = 0x0; 
            PWM50_test_flag = 1;			
            break;
	 case 'm'://All Interrupt, MUX 4 ~ 0 : 1/2 //Dead zone=1,Prescaler1=0,Prescaler0=0, Invert ON
            rTCFG0 = rTCFG0 & ~(0xffffff) | 0x280000;     
            rTCFG1 = 0x0; 
            Inverton_test_flag = 1;			
            break;
  			
        default:
	    rTCON   = 0x0;		
           rGPCON_U  = save_GPCON_U;
           rGPCON_L = save_GPCON_L;
	    rGPDAT 	= save_GPDAT;
	    rGPPU 	= save_rGPUP;    			
           return;
    }

////////////////////////////////////////////////////////////////////////////////////  
// Step1>> write the rTCNTBn and rTCMPBn
//(1/(PCLK/(Prescaler+1)/divider) * count(Max 65535) = Timer clock (Frequency)
////////////////////////////////////////////////////////////////////////////////////  

    rTCNTB0 = rTCNTB0 & ~(0xffff) | 2000;       //(1/(50MHz/69/2))  *  2000 =  5.5200 msec (181.159  Hz)
                                                //(1/(50.7MHz/69/2))*  2000 =  5.4437 msec (183.698  Hz)
                                                //(1/(50MHz/1/2))   *  2000 =  0.0800 msec ( 12.500 KHz)
                                                //(1/(50.7MHz/1/2)) *  2000 =  0.0788 msec ( 12.690 KHz)
    rTCNTB1 = rTCNTB1 & ~(0xffff) | 4000;       //(0.0000027600003) *  4000 = 11.0400 msec ( 90.579  Hz)
                                                //(0.0000027218935) *  4000 = 10.8875 msec ( 91.848  Hz)
                                                //(0.00000004)      *  4000 =  0.1600 msec (  6.250 KHz)
                                                //(0.0000000394477) *  4000 =  0.1577 msec (  6.337 KHz)
    rTCNTB2 = rTCNTB2 & ~(0xffff) | 5000;       //(0.0000027600003) *  5000 = 13.8000 msec ( 72.463  Hz)
                                                //(0.0000027218935) *  5000 = 13.6094 msec ( 73.478  Hz)
                                                //(0.00000004)      *  5000 =  0.2000 msec (  5.000 KHz)
                                                //(0.0000000394477) *  5000 =  0.1972 msec (  5.070 KHz)
    rTCNTB3 = rTCNTB3 & ~(0xffff) | 10000;      //(0.0000027600003) * 10000 = 27.6000 msec ( 36.231  Hz)
                                                //(0.0000027218935) * 10000 = 27.2189 msec ( 36.739  Hz)
                                                //(0.00000004)      * 10000 =  0.4000 msec (  2.500 KHz)
                                                //(0.0000000394477) * 10000 =  0.3944 msec (  2.535 KHz)


   //Uart_Printf("rTCNTB0=%d |rTCNTB1=%d |rTCNTB2=%d | rTCNTB3=%d \n",rTCNTB0,rTCNTB1,rTCNTB2,rTCNTB3);

   if(PWM50_test_flag ==1 ){
       rTCMPB0 =  2000;     rTCMPB1 =  4000;    rTCMPB2 =  5000;    rTCMPB3 = 10000;
	PWM50_test_flag = 0;
   }else{ 
       rTCMPB0 =  2000 - 1000;    rTCMPB1 =  4000 - 2000;    rTCMPB2 =  5000 - 2500;    rTCMPB3 = 10000-5000;
   }

   //Uart_Printf("rTCMPB0=%d |rTCMPB1=%d |rTCMPB2=%d | rTCMPB3=%d \n",rTCMPB0,rTCMPB1,rTCMPB2,rTCMPB3);


////////////////////////////////////////////////////////////////////////////////////
//	Step2.>> Set the manual update bit[TCON] of the corresponging timer. it is recommended to configure
//	   the inverter on/off bit
////////////////////////////////////////////////////////////////////////////////////
    //Uart_Printf("rTCON  = 0x%6x (Before)  <= Timer control register.\n",rTCON); 

     // [22:20] [19:16] [15:12] [11:8] [7:4] [3:0]
     //   110     1010   1010    1010   0000  1010
    if(Deadzone_test_flag == 1)
       rTCON   = rTCON & ~(0xffffff) | 0x6aaa1a;  //Auto reload, Inverter off, Manual update, Stop, Dead zone enable
    else 
       rTCON   = rTCON & ~(0xffffff) | 0x6aaa0a;  //Auto reload, Inverter off, Manual update, Stop, Dead zone disable
    
    if(Inverton_test_flag == 1) rTCON |= 0x44404;
	
    //Uart_Printf("rTCON  = 0x%6x (After)   <= Timer control register.(0x6aaa0a)\n",rTCON);
	

////////////////////////////////////////////////////////////////////////////////////
// Step3>> set start bit of corresponding timer to start the timer
//  (at the same time, clear the manual update bit)
 ////////////////////////////////////////////////////////////////////////////////////
    
     // [22:20] [19:16] [15:12] [11:8] [7:4] [3:0]
     //   101     1001   1001    1001   0000  1001
    if(Deadzone_test_flag == 1){
        //Auto reload, Inverter off, No operation, Timer0&1 Start, Dead zone enable
        rTCON   = rTCON & ~(0xffffff) | 0x099919;  
	 Deadzone_test_flag=0;
    	}
    else{
       if(Inverton_test_flag ==1){
          rTCON   = rTCON & ~(0xffffff) | 0x5ddd0d; // inverter on
          Inverton_test_flag = 0;
      	}
	 //Auto reload, Inverter off, No operation, Start, Dead zone disable
        rTCON   = rTCON & ~(0xffffff) | 0x599909;  
    }

    Uart_Printf("rTCON  = 0x%6x (After)   <= Timer control register.(0x599909)\n\n",rTCON);
    Uart_Printf("rGPGONU  = 0x%8x (After)   <= Timer control register.(0x599909)\n\n",rGPCON_U);	
    //Uart_Printf("\n");
    Uart_Printf("Probing PWM TOUT0,1,2,3 and ECLK, respectively TP20,19,18,17,16 \n");                                                           
    Uart_Printf("\nCheck PWM (Pulse Width Modulation) Output\n");
    Uart_Printf("Press any key to exit.\n");
    Uart_Printf("\n\n");

    Uart_Getch();   

    goto LABEL;
////////////////////////////////////////////////////////////////////////////////////
// Step4 >> Stop timer
////////////////////////////////////////////////////////////////////////////////////	 
    rTCON   = 0x0;      //One-shot, Inverter off, No operation, Dead zone disable, Stop
    //Uart_Printf("rTCNTB0=0x%6x|rTCNTB1=0x%6x|rTCNTB2=0x%6x|rTCNTB3=0x%6x\n",rTCNTB0,rTCNTB1,rTCNTB2,rTCNTB3);
    //Uart_Printf("rTCMPB0=0x%6x|rTCMPB2=0x%6x|rTCMPB2=0x%6x|rTCMPB3=0x%6x\n",rTCMPB0,rTCMPB1,rTCMPB2,rTCMPB3);
    //Uart_Printf("rTCON  = 0x%6x   <= Timer control register.(0x0)\n",rTCON);
     rGPCON_U  = save_GPCON_U;
     rGPCON_L = save_GPCON_L;	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -