2440中使用看门狗定时器作为普通定时器
来源:互联网 发布:2012年西部决赛数据 编辑:程序博客网 时间:2024/05/22 00:32
好吧,看s3c2440的看门狗看了好长时间,因为看门一般很少使用,所以我就想让看门狗作为一般的定时器来触发中断,简单一点,就做一个LED灯的定时闪烁。看了好多资料,百度、数据手册中英文版、学习板光盘资料。。。。。。确实是一个纠结的过程,但是最后懂了收获到的也是满满的快乐。
我要说的:
1、不能全相信手册,手册上说看门狗计时器作为一般定时器时,应使能中断并且禁止看门狗定时器。然而实践证明是不对的;应该使能中断并且使能看门狗定时器,同时禁止看门狗的复位功能。主程序中的rWTCON |= (1<<5)|(1<<2);就是见证。
2、清中断简单粗暴就行,不需要那么多的函数。
rSRCPND = 0x1<<9; rSUBSRCPND = 0x1<<13; rINTPND = 0x1<<9;
2440init.s
GET option.incGET memcfg.incGET 2440addr.incBIT_SELFREFRESH EQU(1<<22);Pre-defined constantsUSERMODE EQU 0x10FIQMODE EQU 0x11IRQMODE EQU 0x12SVCMODE EQU 0x13ABORTMODE EQU 0x17UNDEFMODE EQU 0x1bMODEMASK EQU 0x1fNOINT EQU 0xc0;The location of stacksUserStackEQU(_STACK_BASEADDRESS-0x3800);0x33ff4800 ~SVCStackEQU(_STACK_BASEADDRESS-0x2800);0x33ff5800 ~UndefStackEQU(_STACK_BASEADDRESS-0x2400);0x33ff5c00 ~AbortStackEQU(_STACK_BASEADDRESS-0x2000);0x33ff6000 ~IRQStackEQU(_STACK_BASEADDRESS-0x1000);0x33ff7000 ~FIQStackEQU(_STACK_BASEADDRESS-0x0);0x33ff8000 ~;Check if tasm.exe(armasm -16 ...@ADS 1.0) is used.GBLL THUMBCODE[ {CONFIG} = 16THUMBCODE SETL {TRUE} CODE32 |THUMBCODE SETL {FALSE} ] MACROMOV_PC_LR [ THUMBCODE bx lr | movpc,lr ]MEND MACROMOVEQ_PC_LR [ THUMBCODE bxeq lr | moveq pc,lr ]MEND MACRO$HandlerLabel HANDLER $HandleLabel$HandlerLabelsubsp,sp,#4;decrement sp(to store jump address)stmfdsp!,{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 r0ldr r0,[r0] ;load the contents(service routine start address) of HandleXXXstr r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stackldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)MENDIMPORT Main ; The main entry of mon programAREA Init,CODE,READONLYENTRYEXPORT__ENTRY__ENTRYResetEntry;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=16andeqr14,r7,r0,lsl #20 ;DCD 0x0007ea00 ] [ ENTRY_BUS_WIDTH=8streqr0,[r0,-r10,ror #1] ;DCD 0x070000ea ]| bResetHandler ]bHandlerUndef;handler for Undefined modebHandlerSWI;handler for SWI interruptbHandlerPabort;handler for PAbortbHandlerDabort;handler for DAbortb.;reservedbHandlerIRQ;handler for IRQ interruptbHandlerFIQ;handler for FIQ interrupt;@0x20;bEnterPWDN; Must be @0x20.HandlerFIQ HANDLER HandleFIQHandlerIRQ HANDLER HandleIRQHandlerUndef HANDLER HandleUndefHandlerSWI HANDLER HandleSWIHandlerDabort HANDLER HandleDabortHandlerPabort HANDLER HandlePabortIsrIRQsubsp,sp,#4 ;reserved for PCstmfdsp!,{r8-r9}ldrr9,=INTOFFSETldrr9,[r9]ldrr8,=HandleEINT0addr8,r8,r9,lsl #2ldrr8,[r8]strr8,[sp,#8]ldmfdsp!,{r8-r9,pc}LTORG;=======; ENTRY;=======ResetHandlerldrr0,=WTCON ;watch dog disableldrr1,=0x0strr1,[r0]ldrr0,=INTMSKldrr1,=0xffffffff ;all interrupt disablestrr1,[r0]ldrr0,=INTSUBMSKldrr1,=0x7fff;all sub interrupt disablestrr1,[r0];To reduce PLL lock time, adjust the LOCKTIME register.ldrr0,=LOCKTIMEldrr1,=0xffffffstrr1,[r0] [ PLL_ON_START; Added for confirm clock divide. for 2440.; Setting value Fclk:Hclk:Pclkldrr0,=CLKDIVNldrr1,=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.strr1,[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,0orr r0,r0,#0xc0000000;R1_nF:OR:R1_iAmcr p15,0,r0,c1,c0,0|mrc p15,0,r0,c1,c0,0bic r0,r0,#0xc0000000;R1_iA:OR:R1_nFmcr p15,0,r0,c1,c0,0];Configure UPLLldrr0,=UPLLCONldrr1,=((U_MDIV<<12)+(U_PDIV<<4)+U_SDIV) strr1,[r0]nop; Caution: After UPLL setting, at least 7-clocks delay must be inserted for setting hardware be completed.nopnopnopnopnopnop;Configure MPLLldrr0,=MPLLCONldrr1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV) ;Fin=16.9344MHzstrr1,[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 pressed1blInitStacks;=========================================================== ; Setup IRQ handlerldrr0,=HandleIRQ ;This routine is neededldrr1,=IsrIRQ ;if there is not 'subs pc,lr,#4' at 0x18, 0x1cstrr1,[r0] [ :LNOT:THUMBCODE blMain;Do not use main() because ...... b. ] [ THUMBCODE ;for start-up code for Thumb mode orrlr,pc,#1 bxlr CODE16 blMain;Do not use main() because ...... b.CODE32 ];function initializing stacksInitStacks;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'mrsr0,cpsrbicr0,r0,#MODEMASKorrr1,r0,#UNDEFMODE|NOINTmsrcpsr_cxsf,r1;UndefModeldrsp,=UndefStack; UndefStack=0x33FF_5C00orrr1,r0,#ABORTMODE|NOINTmsrcpsr_cxsf,r1;AbortModeldrsp,=AbortStack; AbortStack=0x33FF_6000orrr1,r0,#IRQMODE|NOINTmsrcpsr_cxsf,r1;IRQModeldrsp,=IRQStack; IRQStack=0x33FF_7000orrr1,r0,#FIQMODE|NOINTmsrcpsr_cxsf,r1;FIQModeldrsp,=FIQStack; FIQStack=0x33FF_8000bicr0,r0,#MODEMASK|NOINTorrr1,r0,#SVCMODEmsrcpsr_cxsf,r1;SVCModeldrsp,=SVCStack; SVCStack=0x33FF_5800;USER mode has not be initialized.movpc,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;=====================================================================ALIGNAREA RamData, DATA, READWRITE^ _ISR_STARTADDRESS; _ISR_STARTADDRESS=0x33FF_FF00HandleReset # 4HandleUndef # 4HandleSWI# 4HandlePabort # 4HandleDabort # 4HandleReserved # 4HandleIRQ# 4HandleFIQ# 4;Do not use the label 'IntVectorTable',;The value of IntVectorTable is different with the address you think it may be.;IntVectorTable;@0x33FF_FF20HandleEINT0# 4HandleEINT1# 4HandleEINT2# 4HandleEINT3# 4HandleEINT4_7# 4HandleEINT8_23# 4HandleCAM# 4; Added for 2440.HandleBATFLT# 4HandleTICK# 4HandleWDT# 4HandleTIMER0 # 4HandleTIMER1 # 4HandleTIMER2 # 4HandleTIMER3 # 4HandleTIMER4 # 4HandleUART2 # 4;@0x33FF_FF60HandleLCD # 4HandleDMA0# 4HandleDMA1# 4HandleDMA2# 4HandleDMA3# 4HandleMMC# 4HandleSPI0# 4HandleUART1# 4HandleNFCON# 4; Added for 2440.HandleUSBD# 4HandleUSBH# 4HandleIIC# 4HandleUART0 # 4HandleSPI1 # 4HandleRTC # 4HandleADC # 4;@0x33FF_FFA0END2440addr.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)#defineEnableIrq(bit)rINTMSK &= ~(bit)#defineDisableIrq(bit)rINTMSK |= (bit)#defineEnableSubIrq(bit)rINTSUBMSK &= ~(bit)#defineDisableSubIrq(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 0
- 2440中使用看门狗定时器作为普通定时器
- s3c2440看门狗定时器作为普通定时器应用的补充说明
- 看门狗定时器
- 看门狗定时器
- at91sam7x之看门狗定时器使用
- S3C2440看门狗定时器
- AT89S52的看门狗定时器
- S3C2440看门狗定时器
- S5PC100看门狗定时器
- ARM看门狗定时器设置
- 【转载】DSP看门狗定时器
- 9.0 看门狗定时器WDT
- MSP430--看门狗定时器
- s3c2440看门狗定时器
- 看门狗定时器学习笔记
- 看门狗定时器WDT
- 【记录】看门狗定时器基础
- 定时器,看门狗&RTC
- js笔记(5)
- FPGA笔记 连续赋值,阻塞赋值,非阻塞赋值
- 生活杂记
- NSURLConection的使用
- 制作Mini2440内核
- 2440中使用看门狗定时器作为普通定时器
- win8.1系统如何提升账户管理员权限,继而系统永久激活
- Memory Model(java语言规范17.4章节)
- HTML常用标签
- 定风波·三月七日(苏轼)
- 编程心得03
- tbnet编译
- 165,TOM猫源代码
- BC #68 (div.2) A