2440中使用看门狗定时器作为普通定时器

好吧,看s3c2440的看门狗看了好长时间,因为看门一般很少使用,所以我就想让看门狗作为一般的定时器来触发中断,简单一点,就做一个LED灯的定时闪烁。看了好多资料,百度、数据手册中英文版、学习板光盘资料。。。。。。确实是一个纠结的过程,但是最后懂了收获到的也是满满的快乐。

我要说的:

1、不能全相信手册,手册上说看门狗计时器作为一般定时器时,应使能中断并且禁止看门狗定时器。然而实践证明是不对的;应该使能中断并且使能看门狗定时器,同时禁止看门狗的复位功能。主程序中的rWTCON |= (1<<5)|(1<<2);就是见证。
2、清中断简单粗暴就行,不需要那么多的函数。

       rSRCPND = 0x1<<9;
       rSUBSRCPND = 0x1<<13;
       rINTPND = 0x1<<9;


以下贴出代码:

2440init.s

GET option.inc
	GET memcfg.inc
	GET 2440addr.inc

BIT_SELFREFRESH EQU	(1<<22)

;Pre-defined constants
USERMODE    EQU 	0x10
FIQMODE     EQU 	0x11
IRQMODE     EQU 	0x12
SVCMODE     EQU 	0x13
ABORTMODE   EQU 	0x17
UNDEFMODE   EQU 	0x1b
MODEMASK    EQU 	0x1f
NOINT       EQU 	0xc0

;The location of stacks
UserStack	EQU	(_STACK_BASEADDRESS-0x3800)	;0x33ff4800 ~
SVCStack	EQU	(_STACK_BASEADDRESS-0x2800)	;0x33ff5800 ~
UndefStack	EQU	(_STACK_BASEADDRESS-0x2400)	;0x33ff5c00 ~
AbortStack	EQU	(_STACK_BASEADDRESS-0x2000)	;0x33ff6000 ~
IRQStack	EQU	(_STACK_BASEADDRESS-0x1000)	;0x33ff7000 ~
FIQStack	EQU	(_STACK_BASEADDRESS-0x0)	;0x33ff8000 ~

;Check if tasm.exe(armasm -16 ...@ADS 1.0) is used.
	GBLL    THUMBCODE
	[ {CONFIG} = 16
THUMBCODE SETL  {TRUE}
	    CODE32
 		|
THUMBCODE SETL  {FALSE}
    ]

 		MACRO
	MOV_PC_LR
 		[ THUMBCODE
	    bx lr
 		|
	    mov	pc,lr
 		]
	MEND

 		MACRO
	MOVEQ_PC_LR
 		[ THUMBCODE
        bxeq lr
 		|
	    moveq pc,lr
 		]
	MEND
	

 		MACRO
$HandlerLabel HANDLER $HandleLabel

$HandlerLabel
	sub	sp,sp,#4	;decrement sp(to store jump address)
	stmfd	sp!,{r0}	;PUSH the work register to stack(lr does not push because it return to original address)
	ldr     r0,=$HandleLabel;load the address of HandleXXX to r0
	ldr     r0,[r0]	 ;load the contents(service routine start address) of HandleXXX
	str     r0,[sp,#4]      ;store the contents(ISR) of HandleXXX to stack
	ldmfd   sp!,{r0,pc}     ;POP the work register and pc(jump to ISR)
	MEND
	
	


	IMPORT  Main    ; The main entry of mon program

	AREA    Init,CODE,READONLY

	ENTRY
	
	EXPORT	__ENTRY
__ENTRY
ResetEntry
	;1)The code, which converts to Big-endian, should be in little endian code.
	;2)The following little endian code will be compiled in Big-Endian mode.
	;  The code byte order should be changed as the memory bus width.
	;3)The pseudo instruction,DCD can not be used here because the linker generates error.
	ASSERT	:DEF:ENDIAN_CHANGE
	[ ENDIAN_CHANGE
	    ASSERT  :DEF:ENTRY_BUS_WIDTH
	   

	    [ ENTRY_BUS_WIDTH=16
		andeq	r14,r7,r0,lsl #20   ;DCD 0x0007ea00
	    ]

	    [ ENTRY_BUS_WIDTH=8
		streq	r0,[r0,-r10,ror #1] ;DCD 0x070000ea
	    ]
	|
	    b	ResetHandler
    ]
	b	HandlerUndef	;handler for Undefined mode
	b	HandlerSWI	;handler for SWI interrupt
	b	HandlerPabort	;handler for PAbort
	b	HandlerDabort	;handler for DAbort
	b	.		;reserved
	b	HandlerIRQ	;handler for IRQ interrupt
	b	HandlerFIQ	;handler for FIQ interrupt

;@0x20
;	b	EnterPWDN	; Must be @0x20.

	
HandlerFIQ      HANDLER HandleFIQ
HandlerIRQ      HANDLER HandleIRQ
HandlerUndef    HANDLER HandleUndef
HandlerSWI      HANDLER HandleSWI
HandlerDabort   HANDLER HandleDabort
HandlerPabort   HANDLER HandlePabort

IsrIRQ
	sub	sp,sp,#4       ;reserved for PC
	stmfd	sp!,{r8-r9}

	ldr	r9,=INTOFFSET
	ldr	r9,[r9]
	ldr	r8,=HandleEINT0
	add	r8,r8,r9,lsl #2
	ldr	r8,[r8]
	str	r8,[sp,#8]
	ldmfd	sp!,{r8-r9,pc}


	LTORG

;=======
; ENTRY
;=======
ResetHandler
	ldr	r0,=WTCON       ;watch dog disable
	ldr	r1,=0x0
	str	r1,[r0]

	ldr	r0,=INTMSK
	ldr	r1,=0xffffffff  ;all interrupt disable
	str	r1,[r0]

	ldr	r0,=INTSUBMSK
	ldr	r1,=0x7fff		;all sub interrupt disable
	str	r1,[r0]

	

	;To reduce PLL lock time, adjust the LOCKTIME register.
	ldr	r0,=LOCKTIME
	ldr	r1,=0xffffff
	str	r1,[r0]

    [ PLL_ON_START
	; Added for confirm clock divide. for 2440.
	; Setting value Fclk:Hclk:Pclk
	ldr	r0,=CLKDIVN
	ldr	r1,=CLKDIV_VAL		; 0=1:1:1, 1=1:1:2, 2=1:2:2, 3=1:2:4, 4=1:4:4, 5=1:4:8, 6=1:3:3, 7=1:3:6.
	str	r1,[r0]

	;program has not been copied, so use these directly,
	[ CLKDIV_VAL>1 		; means Fclk:Hclk is not 1:1.
	mrc p15,0,r0,c1,c0,0
	orr r0,r0,#0xc0000000;R1_nF:OR:R1_iA
	mcr p15,0,r0,c1,c0,0
	|
	mrc p15,0,r0,c1,c0,0
	bic r0,r0,#0xc0000000;R1_iA:OR:R1_nF
	mcr p15,0,r0,c1,c0,0
	]
	
	;Configure UPLL
	ldr	r0,=UPLLCON
	ldr	r1,=((U_MDIV<<12)+(U_PDIV<<4)+U_SDIV)  
	str	r1,[r0]
	nop	; Caution: After UPLL setting, at least 7-clocks delay must be inserted for setting hardware be completed.
	nop
	nop
	nop
	nop
	nop
	nop
	;Configure MPLL
	ldr	r0,=MPLLCON
	ldr	r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV)  ;Fin=16.9344MHz
	str	r1,[r0]
    ]

	;Check if the boot is caused by the wake-up from SLEEP mode.




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;       When EINT0 is pressed,  Clear SDRAM 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; check if EIN0 button is pressed


1	bl	InitStacks


	

;===========================================================
  	; Setup IRQ handler
	ldr	r0,=HandleIRQ       ;This routine is needed
	ldr	r1,=IsrIRQ	  ;if there is not 'subs pc,lr,#4' at 0x18, 0x1c
	str	r1,[r0]




    [ :LNOT:THUMBCODE
 		bl	Main	;Do not use main() because ......
 		b	.
    ]

    [ THUMBCODE	 ;for start-up code for Thumb mode
 		orr	lr,pc,#1
 		bx	lr
 		CODE16
 		bl	Main	;Do not use main() because ......
 		b	.
		CODE32
    ]


;function initializing stacks
InitStacks
	;Do not use DRAM,such as stmfd,ldmfd......
	;SVCstack is initialized before
	;Under toolkit ver 2.5, 'msr cpsr,r1' can be used instead of 'msr cpsr_cxsf,r1'
	mrs	r0,cpsr
	bic	r0,r0,#MODEMASK
	orr	r1,r0,#UNDEFMODE|NOINT
	msr	cpsr_cxsf,r1		;UndefMode
	ldr	sp,=UndefStack		; UndefStack=0x33FF_5C00

	orr	r1,r0,#ABORTMODE|NOINT
	msr	cpsr_cxsf,r1		;AbortMode
	ldr	sp,=AbortStack		; AbortStack=0x33FF_6000

	orr	r1,r0,#IRQMODE|NOINT
	msr	cpsr_cxsf,r1		;IRQMode
	ldr	sp,=IRQStack		; IRQStack=0x33FF_7000

	orr	r1,r0,#FIQMODE|NOINT
	msr	cpsr_cxsf,r1		;FIQMode
	ldr	sp,=FIQStack		; FIQStack=0x33FF_8000

	bic	r0,r0,#MODEMASK|NOINT
	orr	r1,r0,#SVCMODE
	msr	cpsr_cxsf,r1		;SVCMode
	ldr	sp,=SVCStack		; SVCStack=0x33FF_5800

	;USER mode has not be initialized.

	mov	pc,lr
	;The LR register will not be valid if the current mode is not SVC mode.
	
;===========================================================







	
;=====================================================================
; Clock division test
; Assemble code, because VSYNC time is very short
;=====================================================================



	ALIGN

	AREA RamData, DATA, READWRITE

	^   _ISR_STARTADDRESS		; _ISR_STARTADDRESS=0x33FF_FF00
HandleReset 	#   4
HandleUndef 	#   4
HandleSWI		#   4
HandlePabort    #   4
HandleDabort    #   4
HandleReserved  #   4
HandleIRQ		#   4
HandleFIQ		#   4

;Do not use the label 'IntVectorTable',
;The value of IntVectorTable is different with the address you think it may be.
;IntVectorTable
;@0x33FF_FF20
HandleEINT0		#   4
HandleEINT1		#   4
HandleEINT2		#   4
HandleEINT3		#   4
HandleEINT4_7	#   4
HandleEINT8_23	#   4
HandleCAM		#   4		; Added for 2440.
HandleBATFLT	#   4
HandleTICK		#   4
HandleWDT		#   4
HandleTIMER0 	#   4
HandleTIMER1 	#   4
HandleTIMER2 	#   4
HandleTIMER3 	#   4
HandleTIMER4 	#   4
HandleUART2  	#   4
;@0x33FF_FF60
HandleLCD 		#   4
HandleDMA0		#   4
HandleDMA1		#   4
HandleDMA2		#   4
HandleDMA3		#   4
HandleMMC		#   4
HandleSPI0		#   4
HandleUART1		#   4
HandleNFCON		#   4		; Added for 2440.
HandleUSBD		#   4
HandleUSBH		#   4
HandleIIC		#   4
HandleUART0 	#   4
HandleSPI1 		#   4
HandleRTC 		#   4
HandleADC 		#   4
;@0x33FF_FFA0
	END
2440addr.h
#define _IRQ_BASEADDRESS 	0x33ffff00  
/*#define pISR_RESET	(*(unsigned *)(_IRQ_BASEADDRESS+0x0))
#define pISR_UNDEF		(*(unsigned *)(_IRQ_BASEADDRESS+0x4))
#define pISR_SWI		(*(unsigned *)(_IRQ_BASEADDRESS+0x8))
#define pISR_PABORT		(*(unsigned *)(_IRQ_BASEADDRESS+0xc))
#define pISR_DABORT		(*(unsigned *)(_IRQ_BASEADDRESS+0x10))
#define pISR_RESERVED	(*(unsigned *)(_IRQ_BASEADDRESS+0x14))
#define pISR_IRQ		(*(unsigned *)(_IRQ_BASEADDRESS+0x18))
#define pISR_FIQ		(*(unsigned *)(_IRQ_BASEADDRESS+0x1c))*/
#define pISR_WDT  (*(unsigned *)(_IRQ_BASEADDRESS+0x44))
#define U32 unsigned int
//GPBIO(使用GPB5)
#define rGPBCON    (*(unsigned *) 0x56000010) 
#define rGPBDAT   ( *(unsigned *) 0x56000014)
#define rGPBUP    ( *(unsigned *) 0x56000018)



//UART0
#define rUTRSTAT0   (*(volatile unsigned *)0x50000010)	//UART 0 Tx/Rx status
#define rULCON0     (*(volatile unsigned *)0x50000000)	//UART 0 Line control
#define rUCON0      (*(volatile unsigned *)0x50000004)	//UART 0 Control
#define rUFCON0     (*(volatile unsigned *)0x50000008)	//UART 0 FIFO control
#define rUBRDIV0    (*(volatile unsigned *)0x50000028)	//UART 0 Baud rate divisor
#define WrUTXH0(ch) (*(volatile unsigned char *)0x50000020)=(unsigned char)(ch)


//WDT
#define rWTCON  (*(volatile unsigned *)0x53000000)
#define rWTDAT  (*(volatile unsigned *)0x53000004)
#define rWTCNT  (*(volatile unsigned *)0x53000008)



//INTRRUPT
#define rSRCPND     (*(volatile unsigned *)0x4A000000)
#define rINTMOD     (*(volatile unsigned *)0x4A000004)
#define rINTMSK    (*(volatile unsigned *)0x4A000008)
#define rPRIORITY   (*(volatile unsigned *)0x4A00000c)
#define rINTPND     (*(volatile unsigned *)0x4A000010)
#define rINTOFFSET  (*(volatile unsigned *)0x4A000014)
#define rSUBSRCPND     (*(volatile unsigned *)0x4A000018)
#define rINTSUBMSK     (*(volatile unsigned *)0x4A00001C)



#define prescaler_value  127
#define clock_select     3
#define  BIT_WDT_AC97 (1<<9)
#define  BIT_WDT (1<<13)
#define  BIT_AC97 (1<<14)


#define	EnableIrq(bit)		rINTMSK &= ~(bit)
#define	DisableIrq(bit)		rINTMSK |= (bit)
#define	EnableSubIrq(bit)	rINTSUBMSK &= ~(bit)
#define	DisableSubIrq(bit)	rINTSUBMSK |= (bit)

main.c
#include "2440addr.h"
void delay(int a)
{
       int k;
       for(k=0;k<a;k++)
              ;
}

void __irq watchdog(void);
 
void Main(void)
{
    
	//GPB5设置为输出
	rGPBCON |= 0x400;
	rGPBCON &= 0xFFFFF7FF; 
	//GPB5设为灭状态
	rGPBDAT |= 0x20;
	//输出上拉
	rGPBUP  &=0xFDF;

    rWTCON = 0xf9<<8;                  //Prescaler = 249,Division = 16,时钟频率为12.5kHz
    
    rWTDAT = 40000;               //设置看门狗定时器超时时间为4秒(50÷12.5)
    rWTCNT = 40000;
    rWTCON |= (1<<5)|(1<<2);         //开启看门狗定时器中断
    rSRCPND = 0x1<<9;
    rSUBSRCPND = 0x1<<13;
    rINTPND = 0x1<<9;
    rINTSUBMSK = ~(0x1<<13);      //打开中断子屏蔽
    rINTMSK = ~(0x1<<9);                     //打开中断屏蔽
 
    pISR_WDT= (U32)watchdog;

    while(1) ;
       
}
void __irq watchdog(void)
{
      	rGPBDAT &=0xfdf;
		delay(6400000);
		 rGPBDAT |= 0x20;
       rSRCPND = 0x1<<9;
       rSUBSRCPND = 0x1<<13;
       rINTPND = 0x1<<9;
 
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值