• 用看门狗定时器做计时器,计算程序耗时,超声波测距,FL2440


    开发板:FL2440

    核心芯片:S3C2440(ARM9)

    超声波模块:HC-SR04

    超声波模块工作原理:共四个脚,VCC接5V,GND接地,Trig脚接芯片通过IO传出的高电平(持续时间不低于10微秒),之后Echo脚输出一段时间高电平,高电平持续时间即为超声波发出到接收到回波的间隔时间。

    主要是为了使用看门狗定时器来作计时器,来计算Echo脚返回的高电平持续时间,要将复位使能与中断使能关闭,然后给“狗”最大数值,持续一段时间后,用最大数值减去当前数值,就可得到消耗的数值,再乘以“狗”每次减数的时间间隔(通过设定预分频与分频因子来确定),就是消耗的时间。

    试验期间出现的重要错误:程序自动run后,消耗时间总是0,而采用AXD单步执行则可以得出正确数值——解决方法:将“狗”的每次递减的时间间隔加大。

    下面来程序:

    2440init.s

      1 ;=========================================
      2 ; NAME: 2440INIT.S
      3 ; DESC: C start up codes
      4 ;       Configure memory, ISR ,stacks
      5 ;    Initialize C-variables
      6 ; HISTORY:
      7 ; 2002.02.25:kwtark: ver 0.0
      8 ; 2002.03.20:purnnamu: Add some functions for testing STOP,Sleep mode
      9 ; 2003.03.14:DonGo: Modified for 2440.
     10 ;=========================================
     11 
     12     GET option.inc
     13     GET memcfg.inc
     14     GET 2440addr.inc
     15 
     16 BIT_SELFREFRESH EQU    (1<<22)
     17 
     18 ;Pre-defined constants
     19 USERMODE    EQU     0x10
     20 FIQMODE     EQU     0x11
     21 IRQMODE     EQU     0x12
     22 SVCMODE     EQU     0x13
     23 ABORTMODE   EQU     0x17
     24 UNDEFMODE   EQU     0x1b
     25 MODEMASK    EQU     0x1f
     26 NOINT       EQU     0xc0
     27 
     28 ;The location of stacks
     29 UserStack    EQU    (_STACK_BASEADDRESS-0x3800)    ;0x33ff4800 ~
     30 SVCStack    EQU    (_STACK_BASEADDRESS-0x2800)    ;0x33ff5800 ~
     31 UndefStack    EQU    (_STACK_BASEADDRESS-0x2400)    ;0x33ff5c00 ~
     32 AbortStack    EQU    (_STACK_BASEADDRESS-0x2000)    ;0x33ff6000 ~
     33 IRQStack    EQU    (_STACK_BASEADDRESS-0x1000)    ;0x33ff7000 ~
     34 FIQStack    EQU    (_STACK_BASEADDRESS-0x0)    ;0x33ff8000 ~
     35 
     36 ;Check if tasm.exe(armasm -16 ...@ADS 1.0) is used.
     37     GBLL    THUMBCODE
     38     [ {CONFIG} = 16
     39 THUMBCODE SETL  {TRUE}
     40         CODE32
     41          |
     42 THUMBCODE SETL  {FALSE}
     43     ]
     44 
     45          MACRO
     46     MOV_PC_LR
     47          [ THUMBCODE
     48         bx lr
     49          |
     50         mov    pc,lr
     51          ]
     52     MEND
     53 
     54          MACRO
     55     MOVEQ_PC_LR
     56          [ THUMBCODE
     57         bxeq lr
     58          |
     59         moveq pc,lr
     60          ]
     61     MEND
     62     
     63 
     64          MACRO
     65 $HandlerLabel HANDLER $HandleLabel
     66 
     67 $HandlerLabel
     68     sub    sp,sp,#4    ;decrement sp(to store jump address)
     69     stmfd    sp!,{r0}    ;PUSH the work register to stack(lr does not push because it return to original address)
     70     ldr     r0,=$HandleLabel;load the address of HandleXXX to r0
     71     ldr     r0,[r0]     ;load the contents(service routine start address) of HandleXXX
     72     str     r0,[sp,#4]      ;store the contents(ISR) of HandleXXX to stack
     73     ldmfd   sp!,{r0,pc}     ;POP the work register and pc(jump to ISR)
     74     MEND
     75     
     76     
     77 
     78 
     79     IMPORT  Main    ; The main entry of mon program
     80 
     81     AREA    Init,CODE,READONLY
     82 
     83     ENTRY
     84     
     85     EXPORT    __ENTRY
     86 __ENTRY
     87 ResetEntry
     88     ;1)The code, which converts to Big-endian, should be in little endian code.
     89     ;2)The following little endian code will be compiled in Big-Endian mode.
     90     ;  The code byte order should be changed as the memory bus width.
     91     ;3)The pseudo instruction,DCD can not be used here because the linker generates error.
     92     ASSERT    :DEF:ENDIAN_CHANGE
     93     [ ENDIAN_CHANGE
     94         ASSERT  :DEF:ENTRY_BUS_WIDTH
     95        
     96 
     97         [ ENTRY_BUS_WIDTH=16
     98         andeq    r14,r7,r0,lsl #20   ;DCD 0x0007ea00
     99         ]
    100 
    101         [ ENTRY_BUS_WIDTH=8
    102         streq    r0,[r0,-r10,ror #1] ;DCD 0x070000ea
    103         ]
    104     |
    105         b    ResetHandler
    106     ]
    107     b    HandlerUndef    ;handler for Undefined mode
    108     b    HandlerSWI    ;handler for SWI interrupt
    109     b    HandlerPabort    ;handler for PAbort
    110     b    HandlerDabort    ;handler for DAbort
    111     b    .        ;reserved
    112     b    HandlerIRQ    ;handler for IRQ interrupt
    113     b    HandlerFIQ    ;handler for FIQ interrupt
    114 
    115 ;@0x20
    116 ;    b    EnterPWDN    ; Must be @0x20.
    117 
    118     
    119 HandlerFIQ      HANDLER HandleFIQ
    120 HandlerIRQ      HANDLER HandleIRQ
    121 HandlerUndef    HANDLER HandleUndef
    122 HandlerSWI      HANDLER HandleSWI
    123 HandlerDabort   HANDLER HandleDabort
    124 HandlerPabort   HANDLER HandlePabort
    125 
    126 IsrIRQ
    127     sub    sp,sp,#4       ;reserved for PC
    128     stmfd    sp!,{r8-r9}
    129 
    130     ldr    r9,=INTOFFSET
    131     ldr    r9,[r9]
    132     ldr    r8,=HandleEINT0
    133     add    r8,r8,r9,lsl #2
    134     ldr    r8,[r8]
    135     str    r8,[sp,#8]
    136     ldmfd    sp!,{r8-r9,pc}
    137 
    138 
    139     LTORG
    140 
    141 ;=======
    142 ; ENTRY
    143 ;=======
    144 ResetHandler
    145     ldr    r0,=WTCON       ;watch dog disable
    146     ldr    r1,=0x0
    147     str    r1,[r0]
    148 
    149     ldr    r0,=INTMSK
    150     ldr    r1,=0xffffffff  ;all interrupt disable
    151     str    r1,[r0]
    152 
    153     ldr    r0,=INTSUBMSK
    154     ldr    r1,=0x7fff        ;all sub interrupt disable
    155     str    r1,[r0]
    156 
    157     
    158 
    159     ;To reduce PLL lock time, adjust the LOCKTIME register.
    160     ldr    r0,=LOCKTIME
    161     ldr    r1,=0xffffff
    162     str    r1,[r0]
    163 
    164     [ PLL_ON_START
    165     ; Added for confirm clock divide. for 2440.
    166     ; Setting value Fclk:Hclk:Pclk
    167     ldr    r0,=CLKDIVN
    168     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.
    169     str    r1,[r0]
    170 
    171     ;program has not been copied, so use these directly,
    172     [ CLKDIV_VAL>1         ; means Fclk:Hclk is not 1:1.
    173     mrc p15,0,r0,c1,c0,0
    174     orr r0,r0,#0xc0000000;R1_nF:OR:R1_iA
    175     mcr p15,0,r0,c1,c0,0
    176     |
    177     mrc p15,0,r0,c1,c0,0
    178     bic r0,r0,#0xc0000000;R1_iA:OR:R1_nF
    179     mcr p15,0,r0,c1,c0,0
    180     ]
    181     
    182     ;Configure UPLL
    183     ldr    r0,=UPLLCON
    184     ldr    r1,=((U_MDIV<<12)+(U_PDIV<<4)+U_SDIV)  
    185     str    r1,[r0]
    186     nop    ; Caution: After UPLL setting, at least 7-clocks delay must be inserted for setting hardware be completed.
    187     nop
    188     nop
    189     nop
    190     nop
    191     nop
    192     nop
    193     ;Configure MPLL
    194     ldr    r0,=MPLLCON
    195     ldr    r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV)  ;Fin=16.9344MHz
    196     str    r1,[r0]
    197     ]
    198 
    199     ;Check if the boot is caused by the wake-up from SLEEP mode.
    200 
    201 
    202 
    203 
    204 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    205 ;;;;;;;;;;;;;       When EINT0 is pressed,  Clear SDRAM 
    206 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    207 ; check if EIN0 button is pressed
    208 
    209 
    210 1    bl    InitStacks
    211 
    212 
    213     
    214 
    215 ;===========================================================
    216       ; Setup IRQ handler
    217     ldr    r0,=HandleIRQ       ;This routine is needed
    218     ldr    r1,=IsrIRQ      ;if there is not 'subs pc,lr,#4' at 0x18, 0x1c
    219     str    r1,[r0]
    220 
    221 
    222 
    223 
    224     [ :LNOT:THUMBCODE
    225          bl    Main    ;Do not use main() because ......
    226          b    .
    227     ]
    228 
    229     [ THUMBCODE     ;for start-up code for Thumb mode
    230          orr    lr,pc,#1
    231          bx    lr
    232          CODE16
    233          bl    Main    ;Do not use main() because ......
    234          b    .
    235         CODE32
    236     ]
    237 
    238 
    239 ;function initializing stacks
    240 InitStacks
    241     ;Do not use DRAM,such as stmfd,ldmfd......
    242     ;SVCstack is initialized before
    243     ;Under toolkit ver 2.5, 'msr cpsr,r1' can be used instead of 'msr cpsr_cxsf,r1'
    244     mrs    r0,cpsr
    245     bic    r0,r0,#MODEMASK
    246     orr    r1,r0,#UNDEFMODE|NOINT
    247     msr    cpsr_cxsf,r1        ;UndefMode
    248     ldr    sp,=UndefStack        ; UndefStack=0x33FF_5C00
    249 
    250     orr    r1,r0,#ABORTMODE|NOINT
    251     msr    cpsr_cxsf,r1        ;AbortMode
    252     ldr    sp,=AbortStack        ; AbortStack=0x33FF_6000
    253 
    254     orr    r1,r0,#IRQMODE|NOINT
    255     msr    cpsr_cxsf,r1        ;IRQMode
    256     ldr    sp,=IRQStack        ; IRQStack=0x33FF_7000
    257 
    258     orr    r1,r0,#FIQMODE|NOINT
    259     msr    cpsr_cxsf,r1        ;FIQMode
    260     ldr    sp,=FIQStack        ; FIQStack=0x33FF_8000
    261 
    262     bic    r0,r0,#MODEMASK|NOINT
    263     orr    r1,r0,#SVCMODE
    264     msr    cpsr_cxsf,r1        ;SVCMode
    265     ldr    sp,=SVCStack        ; SVCStack=0x33FF_5800
    266 
    267     ;USER mode has not be initialized.
    268 
    269     mov    pc,lr
    270     ;The LR register will not be valid if the current mode is not SVC mode.
    271     
    272 ;===========================================================
    273 
    274 
    275 
    276 
    277 
    278 
    279 
    280     
    281 ;=====================================================================
    282 ; Clock division test
    283 ; Assemble code, because VSYNC time is very short
    284 ;=====================================================================
    285 
    286 
    287 
    288     ALIGN
    289 
    290     AREA RamData, DATA, READWRITE
    291 
    292     ^   _ISR_STARTADDRESS        ; _ISR_STARTADDRESS=0x33FF_FF00
    293 HandleReset     #   4
    294 HandleUndef     #   4
    295 HandleSWI        #   4
    296 HandlePabort    #   4
    297 HandleDabort    #   4
    298 HandleReserved  #   4
    299 HandleIRQ        #   4
    300 HandleFIQ        #   4
    301 
    302 ;Do not use the label 'IntVectorTable',
    303 ;The value of IntVectorTable is different with the address you think it may be.
    304 ;IntVectorTable
    305 ;@0x33FF_FF20
    306 HandleEINT0        #   4
    307 HandleEINT1        #   4
    308 HandleEINT2        #   4
    309 HandleEINT3        #   4
    310 HandleEINT4_7    #   4
    311 HandleEINT8_23    #   4
    312 HandleCAM        #   4        ; Added for 2440.
    313 HandleBATFLT    #   4
    314 HandleTICK        #   4
    315 HandleWDT        #   4
    316 HandleTIMER0     #   4
    317 HandleTIMER1     #   4
    318 HandleTIMER2     #   4
    319 HandleTIMER3     #   4
    320 HandleTIMER4     #   4
    321 HandleUART2      #   4
    322 ;@0x33FF_FF60
    323 HandleLCD         #   4
    324 HandleDMA0        #   4
    325 HandleDMA1        #   4
    326 HandleDMA2        #   4
    327 HandleDMA3        #   4
    328 HandleMMC        #   4
    329 HandleSPI0        #   4
    330 HandleUART1        #   4
    331 HandleNFCON        #   4        ; Added for 2440.
    332 HandleUSBD        #   4
    333 HandleUSBH        #   4
    334 HandleIIC        #   4
    335 HandleUART0     #   4
    336 HandleSPI1         #   4
    337 HandleRTC         #   4
    338 HandleADC         #   4
    339 ;@0x33FF_FFA0
    340     END

    2440addr.h

     1 //ISR
     2 
     3 //_ISR_STARTADDRESS    EQU 0x33ffff00
     4 #define _IRQ_BASEADDRESS     0x33ffff00  
     5 /*#define pISR_RESET    (*(unsigned *)(_IRQ_BASEADDRESS+0x0))
     6 #define pISR_UNDEF        (*(unsigned *)(_IRQ_BASEADDRESS+0x4))
     7 #define pISR_SWI        (*(unsigned *)(_IRQ_BASEADDRESS+0x8))
     8 #define pISR_PABORT        (*(unsigned *)(_IRQ_BASEADDRESS+0xc))
     9 #define pISR_DABORT        (*(unsigned *)(_IRQ_BASEADDRESS+0x10))
    10 #define pISR_RESERVED    (*(unsigned *)(_IRQ_BASEADDRESS+0x14))
    11 #define pISR_IRQ        (*(unsigned *)(_IRQ_BASEADDRESS+0x18))
    12 #define pISR_FIQ        (*(unsigned *)(_IRQ_BASEADDRESS+0x1c))*/
    13 #define pISR_WDT  (*(unsigned *)(_IRQ_BASEADDRESS+0x44))
    14 
    15 
    16 //UART0
    17 #define rUTRSTAT0   (*(volatile unsigned *)0x50000010)    //UART 0 Tx/Rx status
    18 #define rULCON0     (*(volatile unsigned *)0x50000000)    //UART 0 Line control
    19 #define rUCON0      (*(volatile unsigned *)0x50000004)    //UART 0 Control
    20 #define rUFCON0     (*(volatile unsigned *)0x50000008)    //UART 0 FIFO control
    21 #define rUBRDIV0    (*(volatile unsigned *)0x50000028)    //UART 0 Baud rate divisor
    22 #define WrUTXH0(ch) (*(volatile unsigned char *)0x50000020)=(unsigned char)(ch)
    23 
    24 
    25 //WDT
    26 #define rWTCON  (*(volatile unsigned *)0x53000000)
    27 #define rWTDAT  (*(volatile unsigned *)0x53000004)
    28 #define rWTCNT  (*(volatile unsigned *)0x53000008)
    29 
    30 
    31 
    32 //INTRRUPT
    33 #define rSRCPND     (*(volatile unsigned *)0x4A000000)
    34 #define rINTMOD     (*(volatile unsigned *)0x4A000004)
    35 #define rINTMSK    (*(volatile unsigned *)0x4A000008)
    36 #define rPRIORITY   (*(volatile unsigned *)0x4A00000c)
    37 #define rINTPND     (*(volatile unsigned *)0x4A000010)
    38 #define rINTOFFSET  (*(volatile unsigned *)0x4A000014)
    39 #define rSUBSRCPND     (*(volatile unsigned *)0x4A000018)
    40 #define rINTSUBMSK     (*(volatile unsigned *)0x4A00001C)
    41 
    42 //gpio
    43 #define GPBCON (*(volatile unsigned *)0x56000010) 
    44 #define GPBDAT (*(volatile unsigned *)0x56000014) 
    45 #define GPBUP (*(volatile unsigned *)0x56000018)
    46 
    47 #define GPECON (*(volatile unsigned *)0x56000040) 
    48 #define GPEDAT (*(volatile unsigned *)0x56000044) 
    49 #define GPEUP (*(volatile unsigned *)0x56000048)
    50 
    51 #define GPGCON (*(volatile unsigned *)0x56000060) 
    52 #define GPGDAT (*(volatile unsigned *)0x56000064) 
    53 #define GPGUP (*(volatile unsigned *)0x56000068)
    54 
    55 #define uchar unsigned char
    56 #define uint unsigned int
    57 
    58 #define prescaler_value  0
    59 #define clock_select     2
    60 #define  BIT_WDT_AC97 (1<<9)
    61 #define  BIT_WDT (1<<13)
    62 
    63 
    64 #define    EnableIrq(bit)        rINTMSK &= ~(bit)
    65 #define    DisableIrq(bit)        rINTMSK |= (bit)
    66 #define    EnableSubIrq(bit)    rINTSUBMSK &= ~(bit)
    67 #define    DisableSubIrq(bit)    rINTSUBMSK |= (bit)

    uart.c

     1 #include <stdarg.h>
     2 #include "2440addr.h"
     3 
     4 void Uart_Init(int baud)
     5 {
     6     int i;
     7     rUFCON0 = 0x0;   //UART channel 0 FIFO control register, FIFO disable
     8   
     9  
    10 //UART0
    11     rULCON0 = 0x3;   //Line control register : Normal,No parity,1 stop,8 bits
    12      //    [10]       [9]     [8]        [7]        [6]      [5]         [4]           [3:2]        [1:0]
    13      // Clock Sel,  Tx Int,  Rx Int, Rx Time Out, Rx err, Loop-back, Send break,  Transmit Mode, Receive Mode
    14      //     0          1       0    ,     0          1        0           0     ,       01          01
    15      //   PCLK       Level    Pulse    Disable    Generate  Normal      Normal        Interrupt or Polling
    16     rUCON0  = 0x805;   // Control register
    17     rUBRDIV0=( (int)(50000000/16./baud+0.5) -1 );   //Baud rate divisior register 0
    18 //UART1
    19 
    20     for(i=0;i<100;i++);
    21 }
    22 
    23 
    24     
    25 //=====================================================================
    26 void Uart_SendByte(int data)
    27 {
    28    
    29         if(data=='\n')
    30         {
    31             while(!(rUTRSTAT0 & 0x2));
    32            // Delay(1);                 //because the slow response of hyper_terminal 
    33             WrUTXH0('\r');
    34         }
    35         while(!(rUTRSTAT0 & 0x2));   //Wait until THR is empty.
    36       //  Delay(1);
    37         WrUTXH0(data);
    38   
    39    
    40 }               
    41 
    42 //====================================================================
    43 void Uart_SendString(char *pt)
    44 {
    45     while(*pt)
    46         Uart_SendByte(*pt++);
    47 }
    48 
    49 //=====================================================================
    50 //If you don't use vsprintf(), the code size is reduced very much.
    51 void Uart_Printf(char *fmt,...)
    52 {
    53     va_list ap;
    54     char str[255];
    55 
    56     va_start(ap,fmt);
    57     vsprintf(str,fmt,ap);
    58     Uart_SendString(str);
    59     va_end(ap);
    60 }

    main.c

      1 #include "2440addr.h"
      2 
      3 void watchdog_test(void) ;
      4 extern void Uart_Printf(char *fmt,...);
      5 extern void Uart_Init(int baud);
      6 void ClearPending(int bit);
      7 void ClearSubPending(int bit);
      8 __irq void  watchdog_isr(void);
      9 
     10 /*-----------------------全局变量定义------------------------*/
     11 unsigned f_ucSencondNo;        //看门运行计数器
     12 
     13 void Delay(int x)  
     14 {
     15      int k,j;
     16      while(x--)
     17      {
     18          for (k=0;k<=100;k++)
     19              for(j=0;j<=100;j++);
     20              
     21      }
     22 }
     23 
     24 void init(void)
     25 {
     26     GPBCON = 0x1dd7fc;    // GPB5,GPB6,GPB8,GPB10设置为输出
     27     GPBDAT = ((1<<5)|(1<<6)|(1<<8)|(1<<10));    //使LED全灭
     28     GPBDAT&=0xffe;        //关闭蜂鸣器
     29     GPBUP = 1; 
     30     
     31       
     32     GPECON &= ~((1<<25)|(1<<27)|(1<<26));
     33     GPECON |= (1<<24);
     34     GPEUP &= ~(1<<12);
     35     
     36     GPGCON &= ~(3<<4);
     37     
     38     rWTCON &= ~(1<<2);//关闭中断
     39     
     40 }
     41 
     42 int control_on(void)
     43 {    
     44     GPEDAT |= (1<<12);
     45     GPBDAT &= ~(1<<8);
     46     return 0;
     47 }
     48 
     49 
     50 
     51 int control_off(void)
     52 {
     53     GPEDAT &= ~(1<<12);
     54     GPBDAT |= (1<<8);
     55     return 0;
     56 }
     57 
     58 void count_start(void)
     59 {
     60     //看门狗时间间隔1.28微秒 
     61     rWTDAT=0xffff;
     62     rWTCNT=0xffff;
     63     rWTCON |= (1<<5);     //打开WDT定时器
     64 }
     65 
     66 
     67 long count_stop(void)
     68 {
     69     long i=0;
     70     rWTCON &= ~(1<<5); //关闭定时器,计时结束
     71     i=0xffff-rWTCNT;
     72     return i*259;
     73     
     74     
     75 }
     76 
     77 void Main(void)
     78 { 
     79     Uart_Init(115200); 
     80     init();
     81     Uart_Printf("\nwatchdog test is beginning\n");   
     82     watchdog_test();
     83 }
     84 
     85 void watchdog_test(void) 
     86 {
     87     long time,distance;
     88     while(1)
     89     {
     90         time=0;
     91         distance=0;
     92         
     93         rWTCON=((prescaler_value<<8)|(clock_select<<3));    //设置预分频数和除数因数  
     94         
     95         control_on();
     96         Delay(2);
     97         control_off();
     98         
     99         while(!(GPGDAT & (0x0004)));
    100         count_start();
    101         while(GPGDAT & (0x0004));
    102         time=count_stop();
    103         distance=time/58;//得到厘米
    104 
    105         Delay(50);
    106         
    107         Uart_Printf("time is %d\n",time);
    108         Uart_Printf("distance is %d\n",distance);
    109     }
    110 }
    111   
  • 相关阅读:
    记录下Cookie与Session
    宝塔部署 springboot 项目遇到的 一些bug处理方案
    [IDEA] [SpringBoot] 项目所写的内容不能同步到编译出的文件中
    cookie和session的区别
    JVM类加载
    线程与线程池
    子父类继承相关(static)
    界面控件开发包DevExpress 9月正式发布v21.1.6
    Delphi开发工具DevExpress VCL全新发布v21.1.5
    强大的Visual Studio插件CodeRush v21.1.7已正式发布
  • 原文地址:https://www.cnblogs.com/wuqi1003/p/2745744.html
Copyright © 2020-2023  润新知