• Tiny4412中断之看门狗


      一:看门狗(WDT watch dog timer)

      看门狗其实是一个计数器,它的作用就是防止程序陷入死循环或者程序运行跑飞;看门狗是一个硬件,它的工作原理是,初始化给他一个值,它会过一段时间减一,直到这个数减为0,它将会产生一个中断信号或者reset信号,致使我们系统复位,而又时候我们不想让它过一会儿就重启又想预防死机,那么我们就可以在这个数减到快要接进0的时候,给它重新赋值;这样就不会触发reset信号,但当程序跑飞时机器死机时,它就会减到零,进行操作系统复位;

      具体看下图所示:输入时钟为PCLK(该时钟频率等于系统的主频),它经过两级分频(Prescaler和frequency division factor),最后将分频后的时钟作为该定时器的输入时钟,当计数器期满后可以产生中断或者复位信号。

      看门狗计数器公式如下:

      t_watchdog = 1/( PCLK / (Prescaler value + 1) / Division_factor )

      通过tiny4412用户手册我们可以找到看门狗的中断号为75(如下图):

      预分频器Prescaler及分频因子Division factor的值在WTCON(看门狗时钟控制寄存器)中设置,如下图:

      今天的程序是使用watchdog来实现led灯的闪烁,下面贴出代码:

     1 #ifndef __BUNFLY_H
     2 #define __BUNFLY_H
     3 
     4 #define ICCICR_CPU0        (*(volatile unsigned long *)0x10480000)
     5 #define ICCPMR_CPU0        (*(volatile unsigned long *)0x10480004)
     6 #define ICDDCR            (*(volatile unsigned long *)0x10490000)
     7 #define ICDIPR0_CPU0    (*(volatile unsigned long *)0x10490400)
     8 #define ICDIPTR0_CPU0    (*(volatile unsigned long *)0x10490800)
     9 #define ICDISER0_CPU0    (*(volatile unsigned long *)0x10490100)
    10 #define ICDSGIR            (*(volatile unsigned long *)0x10490f00)
    11 #define ICCEOIR_CPU0    (*(volatile unsigned long *)0x10480010)
    12 #define ICCIAR_CPU0        (*(volatile unsigned long *)0x1048000c)
    13 #define ICDIPR2_CPU0    (*(volatile unsigned long *)0x10490408)
    14 #define ICDIPTR2_CPU0    (*(volatile unsigned long *)0x10490808)
    15 #define ICDIPR3_CPU0    (*(volatile unsigned long *)0x1049040c)
    16 #define ICDIPTR3_CPU0    (*(volatile unsigned long *)0x1049080c)
    17 #define ICDIPR16_CPU0    (*(volatile unsigned long *)0x10490440)
    18 #define ICDIPTR16_CPU0    (*(volatile unsigned long *)0x10490840)
    19 #define ICDIPR18_CPU0    (*(volatile unsigned long *)0x10490448)
    20 #define ICDIPTR18_CPU0    (*(volatile unsigned long *)0x10490848)
    21 #define ICDISER2_CPU0    (*(volatile unsigned long *)0x10490108)
    22 
    23 #define WTCON             (*(volatile unsigned long *)0x10060000)
    24 #define WTDAT             (*(volatile unsigned long *)0x10060004)
    25 #define WTCNT             (*(volatile unsigned long *)0x10060008)
    26 #define WTCLRINT         (*(volatile unsigned long *)0x1006000C)
    27 
    28 #define EXT_INT43CON    (*(volatile unsigned long *)0x11000e0c)
    29 #define EXT_INT43_MASK    (*(volatile unsigned long *)0x11000f0c)
    30 #define EXT_INT43_PEND    (*(volatile unsigned long *)0x11000f4c)
    31 #define GPX3CON         (*(volatile unsigned long *)0x11000c60)
    32 
    33 #define GPM4CON    (*(volatile unsigned long *)0x110002e0)
    34 #define GPM4DAT (*(volatile unsigned long *)0x110002e4)
    35 
    36 #endif    //__BUNFLY_H
      1 #include "bunfly.h"
      2 
      3 void (*udelay)(int) = 0xc3e25f90;
      4 int (*printf)(char *, ...) = 0xc3e114d8;
      5 void enable_mmu();
      6 void init_table(unsigned long *addr);
      7 void memcpy(unsigned char *dest, unsigned char *src, int len);
      8 extern unsigned long  vector_start;
      9 void do_irq();
     10 void led_on();
     11 void led_off();
     12 
     13 int main()
     14 {    
     15     memcpy(0x70000000, vector_start, 0x1000);    
     16     enable_mmu();
     17 
     18     *(unsigned long *)0x47000000 = do_irq;
     19 
     20     //step 1: set cpu permit interrupt
     21     __asm__ __volatile__(
     22         "mrs r0, cpsr
    "
     23         "bic r0,r0, #0x80
    "
     24         "msr cpsr, r0
    "
     25         :::"r0"
     26     );
     27 
     28     //step 2: set GIC (cgi) enable
     29     ICCICR_CPU0 = 1; //中断总开关
     30     ICCPMR_CPU0 =0xff;//设置最低优先级(门槛)
     31     ICDDCR = 1; //本中断开关
     32     ICDIPR18_CPU0 = (100 << 24);//设置本中断优先级
     33     ICDIPTR18_CPU0 = (1 << 24);//选择指定的cpu进行中断处理
     34     ICDISER2_CPU0 = (1 << 11);//启用本中断
     35     
     36     //step 3: set watch dog timer
     37     WTCNT = 32768;
     38     WTDAT = 32768;
     39     WTCON = (1 << 2) | (3 << 3) | (1 << 5) | (95 << 8);
     40             
     41     printf("welcom back
    ");
     42 }
     43 
     44 void do_irq()
     45 {
     46     WTCLRINT = 0;//清中断
     47     printf("wang wang wang
    ");
     48     static int flags = 1;
     49     if(flags) {
     50         led_on();
     51         flags = 0;
     52     }
     53     else {
     54         led_off();
     55         flags = 1;
     56     }
     57 }
     58 
     59 void led_on()
     60 {
     61     GPM4CON &= ~0xffff;
     62     GPM4CON |= 0x1111;
     63     GPM4DAT &= ~0xf;
     64 }
     65 
     66 void led_off()
     67 {
     68 
     69     GPM4CON &= ~0xffff;
     70     GPM4CON |= 0x1111;
     71     GPM4DAT |= 0xf;
     72 }
     73 
     74 void memcpy(unsigned char *dest, unsigned char *src, int len)
     75 {
     76     int i = 0;
     77     for(i = 0; i < len; i++) {
     78         dest[i] = src[i];
     79     }
     80 }
     81 
     82 void enable_mmu()
     83 {
     84     /*构建表*/
     85     unsigned long addr = 0x50000000;
     86     init_table(addr);
     87     /*打开mmu*/
     88     unsigned long mmu = 0;
     89     mmu = 1 | (1 << 1) | (1 << 3) | (1 << 8);
     90     __asm__ __volatile__ (
     91         "mov r0, #3
    "
     92         "MCR p15, 0, r0, c3, c0, 0
    "//设置为管理员
     93         "MCR p15, 0, %0, c2, c0, 0
    "//设置表的地址
     94         "MCR p15, 0, %1, c1, c0, 0
    "//开启mmu
     95         :    
     96         :    "r" (addr), "r" (mmu)
     97         :
     98     );
     99 
    100 }
    101 
    102 __asm__(
    103 
    104 "vector: 
    "
    105 "    b reset
    "
    106 "    b und
    "
    107 "    b swi
    "
    108 "    b pre_abt
    "
    109 "    b data_abt
    "
    110 "    .word 0x0
    "
    111 "    b irq
    "
    112 "    b fiq
    "
    113 "reset:
    "
    114 "und:
    "
    115 "    mov sp, #0x47000000
    "
    116 "    stmdb sp!, {r0-r12, lr}
    "
    117 
    118 "    ldr r3, =0x47000004
    "
    119 "    ldr r2, [r3]
    "
    120 "    blx r2
    "
    121 
    122 "    mov sp, #0x47000000
    "
    123 "    ldmdb sp, {r0-r12, pc}^    
    "
    124 
    125 "swi:
    "
    126 "    mov sp, #0x47000000
    "
    127 "    stmdb sp!, {r0-r12, lr}^
    "
    128 
    129 "    mov sp, #0x47000000
    "
    130 "    ldmdb sp, {r0-r12, pc}^    
    "
    131 
    132 "pre_abt:
    "
    133 
    134 "data_abt:
    "
    135 "    mov sp, #0x47000000
    "
    136 "    sub lr, lr, #4
    "
    137 "    stmdb sp!, {r0-r12, lr}
    "
    138 
    139 "    ldr r3, =0x47000008
    "
    140 "    ldr r2, [r3]
    "
    141 "    blx r2
    "
    142 
    143 "    mov sp, #0x47000000
    "
    144 "    ldmdb sp, {r0-r12, pc}^    
    "
    145 "irq:
    "
    146 
    147 "    mov sp, #0x47000000
    "
    148 "    sub lr, lr, #4
    "
    149 "    stmdb sp!, {r0-r12, lr}
    "
    150 
    151 "    ldr r3, =0x47000000
    "
    152 "    ldr r2, [r3]
    "
    153 "    blx r2
    "
    154 
    155 "    mov sp, #0x47000000
    "
    156 "    ldmdb sp, {r0-r12, pc}^    
    "
    157 
    158 "fiq:
    "
    159 
    160     ".global vector_start
    "
    161 "vector_start: 
    "
    162     ".word vector 
     "
    163 
    164 );
    165 
    166 void init_table(unsigned long *addr)
    167 {
    168     unsigned long va = 0;
    169     unsigned long phys = 0;
    170 
    171     //0x40000000-0x80000000 -> 0x40000000-0x80000000    
    172     for(va = 0x40000000; va < 0x80000000; va += 0x100000) {
    173         phys = va;
    174         addr[va >> 20] = phys | 2;
    175     }
    176 
    177     //0x10000000-0x14000000 -> 0x10000000-0x140000000    
    178     for(va = 0x10000000; va < 0x14000000; va += 0x100000) {
    179         phys = va;
    180         addr[va >> 20] = phys | 2;
    181     }
    182     //0x10000000-0x14000000 -> 0x10000000-0x140000000    
    183     for(va = 0x0; va < 0x10000000; va += 0x100000) {
    184         phys = va + 0x70000000;
    185         addr[va >> 20] = phys | 2;
    186     }
    187             
    188 }
  • 相关阅读:
    C# comboBox实现省市两级联动(winform)
    Alter用法
    封装SQLHelper
    杨中科版C#射击游戏
    C# TXT文件导入至数据库
    C# 手机号码归属地查询
    C#中从数据库导出至txt
    解决C#中txt文档导入数据库时,中文显示乱码的问题
    第一篇博文与技术无关 纯瞎扯
    全国省市数据库
  • 原文地址:https://www.cnblogs.com/wenqiang/p/4781499.html
Copyright © 2020-2023  润新知