GNU ARM汇编--(十)s3c2440的RTC

来源:互联网 发布:ubuntu 宽带测速 编辑:程序博客网 时间:2024/06/06 13:56

http://blog.csdn.net/dndxhej/article/details/7727489


RTC


概述
    在系统电源关掉时RTC可以在备份电池的支持下来工作.RTC可以使用STRB/LDRB指令传输8bit的BCD值到CPU.数据包括秒,分,时,日期,天,月和年.RTC工作在外部32.768KHz的晶振下,而且有报警功能.


属性
    BCD:秒,分,时,日期,天,月和年
    闰年产生器
    报警功能:报警中断  从power-off模式唤醒
    独立的电源管脚(RTCVDD)
    为RTOS kernel time tick支持毫秒级的tick.


闰年产生器
    闰年产生器通过BCDDATA,BCDMON和BCDYEAR来决定每个月最后一天的日期.一个8bit的计数器只能表示两个BCD码,所以无法决定'00'年是否是闰年.举个例子,它不能区分1900和2000.为了解决这个问题,s3c2440的RTC模块在硬件逻辑上支持闰年是2000.1900不是闰年而2000时闰年.因此s3c2440的00表示2000,而不是1900.


READ/WRITE REGISTERS
    为了写BCD寄存器,RTCCON寄存器的第0位必须置高.为了显示秒,分,时,日期,月和年,CPU从BCDSEC,BCDMIN,BCDHOUR,BCDDAY,BCDDATE,BCDMON和BCDYEAR寄存器中读数据.然而,在读取多个寄存器时,可能会有1秒的偏移.比如,当user读数据的时候,假设结果是2059(Year),12(Month),31(Date),23(Hour)和59(Minute).当user读BCDSEC寄存器,值的范围是1--59s,到这没有问题,但是,如果这个值是0s,由于刚才提到的那一s的偏移,年月日时分就会变为2060(year),1(Month),1(Date),0(Hour)和0(Minute).在这种情况下,如果BCDSEC是0 user应该重读各个寄存器.


BACKUP BATTERY OPERATION
    RTC由备份电池驱动,及时系统电源断了,备份电池可以通过RTCVDD管脚向RTC模块供电.当系统关闭,CPU和RTC逻辑之间的接口是封闭的,备份电池只是驱动晶振电路和BCD计数器来减少电源消耗.


ALARM FUNCTION
    在power-off模式或者正常操作模式下,RTC可以在一个指定的时间产生一个报警信号.在正常操作模式下,报警中断(INT_RTC)是激活的.在power-off模式,电源管理唤醒信号(PMWKUP)和INT_RTC都是激活的.RTC报警寄存器(RTCALM)决定是否开启报警状态和报警时间的设置.


TICK TIME INTERRUPT
    RTC的tick time用于中断请求.TICNT寄存器有中断使能位和中断的计数值.当tick time中断产生计数值为0.中断的周期:
Period = (n+1)/128 second
n:Tick time count value(1~127)


REAL TIME CLOCK SPECIAL REGISTERS
RTCCON
    RTCCON控制4个bits,比如RTCEN控制BCD寄存器的读写使能,CLKSEL,CNTSEL和CLKRST是用于测试的.
    RTCEN bit控制CPU与RTC之间的所有接口,所以在系统重启后应该在RTC控制程序中将其设为1来使能数据的读写.在电源关闭前,RTCEN应该清0来防止对RTC寄存器的不经意的写入.
Register          Address             R/W          Description       Reset Value
RTCCON   0x57000040(L)/0x57000043(B)  R/W      RTC control register     0x0


RTCCON            Bit            Description               Initial State
RTCEN             [0]            RTC控制使能                   0
注意:所有的RTC寄存器都要以字节为单位来访问,可以用STRB和LDRB汇编指令或者char类型的指针.


TICNT
Register          Address                   R/W               Description             Reset Value
TICNT      0x57000044(L)/0x57000047(B)     R/W(by byte)     Tick time count register     0x0


TICNT              BIT                     Description           Initial State
TICK INT ENABLE    [7]                 tick time 中断使能             0
TICK TIME COUNT    [6:0]               tick time 计数值(1~127)       000000


RTCALM
RTCALM决定alarm使能和alarm时间.在power-off模式下RTCALM寄存器通过INT_RTC和PWMKUP产生报警信号,而在正常模式下只通过INT_RTC.


Register                     Address                      R/W           Description      Reset Value
RTCALM             0x57000050(L)/0x57000053(B)         R/W(by type)   RTC报警控制寄存器     0x0


RTCALM            Bit                            Description                       Initial State
ALMEN             [6]                            报警总开关                          0
YEAREN            [5]                            Year报警开关                        0
MONREN            [4]                            Month报警开关                       0
DATEEN            [3]                            Date报警开关                        0
HOUREN            [2]                            Hour报警开关                        0
MINEN             [1]                            Minute报警开关                      0
SECEN             [0]                            Second报警开关                      0


ALMSEC
设置Second报警的具体秒数
ALMMIN
设置Minute报警的具体分钟数
ALMHOUR
设置Hour报警的具体小时数
ALMDATE
设置Date报警的具体日期
ALMMON
设置Mon报警的具体月份
ALMYEAR
设置Year报警的具体年份


BCDSEC BCDMIN BCDHOUR BCDDATE BCDMON BCDYEAR

用BCD码表示的秒 分 时 日期 月份 年


给出报警中断的rtc汇编和c代码如下,在报警中断时是调用PWM的蜂鸣器来做闹钟的:

start.S:

[cpp] view plaincopyprint?
  1. /* 
  2. watchdog timer with disable reset 
  3. copyleft@  dndxhej@gmail.com 
  4. */  
  5.   
  6. .equ   NOINT, 0xc0  
  7.   
  8. .equ    GPBCON, 0x56000010      @led  
  9. .equ    GPBDAT, 0x56000014      @led  
  10. .equ   GPBUP,        0x56000018    @led  
  11. .equ    GPFCON, 0x56000050      @interrupt config  
  12. .equ    EINTMASK, 0x560000a4  
  13. .equ    EXTINT0,  0x56000088  
  14. .equ    EXTINT1,  0x5600008c  
  15. .equ    EXTINT2,  0x56000090  
  16. .equ    INTMSK,  0x4A000008  
  17. .equ   EINTPEND,     0x560000a8  
  18.   
  19. .equ    SUBSRCPND,  0x4a000018   
  20. .equ    INTSUBMSK,  0x4a00001c  
  21.   
  22.   
  23.   
  24. .equ   SRCPND,   0X4A000000  
  25. .equ   INTPND,   0X4A000010  
  26.   
  27.   
  28. .equ    GPHCON, 0x56000070  
  29. .equ    GPHDAT, 0x56000074  
  30.   
  31. .equ GPB5_out,  (1<<(5*2))    
  32. .equ GPB6_out,  (1<<(6*2))    
  33. .equ GPB7_out,  (1<<(7*2))    
  34. .equ GPB8_out,  (1<<(8*2))    
  35.         
  36. .equ GPBVALUE,    (GPB5_out | GPB6_out | GPB7_out | GPB8_out)    
  37.   
  38. .equ    LOCKTIME, 0x4c000000  
  39. .equ    MPLLCON, 0x4c000004  
  40. .equ    UPLLCON, 0x4c000008  
  41. .equ    M_MDIV, 92  
  42. .equ   M_PDIV, 1  
  43. .equ    M_SDIV, 1  
  44. .equ    U_MDIV, 56  
  45. .equ   U_PDIV, 2  
  46. .equ    U_SDIV, 2  
  47.   
  48. .equ    CLKDIVN, 0x4c000014  
  49. .equ    DIVN_UPLL, 0  
  50. .equ    HDIVN,  1  
  51. .equ    PDIVN,  1    @FCLK : HCLK : PCLK = 1:2:4  
  52.   
  53.   
  54. .equ    WTCON,  0x53000000  
  55. .equ    Pre_scaler,  249  
  56. .equ    wd_timer,   1  
  57. .equ    clock_select,   00   @316  
  58. .equ    int_gen,    1     @开中断  
  59. .equ    reset_enable,   0  @关掉重启信号  
  60.   
  61. .equ    WTDAT,0x53000004  
  62. .equ    Count_reload,50000    @定时器定为2S PCLK = 100M   PCLK/(Pre_scaler+1)/clock_select = 100M/(249+1)/16=25k   50000/25k=2s  
  63.   
  64. .equ    WTCNT,0x53000008  
  65. .equ    Count,50000  
  66.   
  67.   
  68. .equ    TCFG0,0x51000000  
  69. .equ    Prescaler1,0x00   @[15:8]Timer234  
  70. .equ    Prescaler0,249   @[7:0]Timer01  
  71.   
  72. .equ    TCFG1,0x51000004  
  73. .equ    DMA_MODE,0x0        @[23:20]no dma channal  
  74. .equ    MUX0,0x2            @[3:0]   1/8  
  75. @定时器输入时钟周期 = PCLK/(prescaler + 1)/(divider value)  
  76. @clk = 100M/(249+1)/8=25k  
  77.   
  78. .equ    TCON,0x51000008  
  79. .equ    DZ_eable,0    @[4]关闭死区的操作  
  80. .equ    auto_reload,1    @[3]auto_reload  
  81. .equ    inverter,1  @[2]打开电平反转  
  82. .equ    man_update,1   @[1]手动更新  
  83. .equ   clear_man_update,0  
  84. .equ    start,1 @[0]开始  
  85. .equ    stop,0      @[0]停止  
  86.   
  87. .equ    TCNTB0,0x5100000c         
  88. .equ    TCMPB0,0x51000010  
  89.   
  90. .equ    TCNTO0,0x51000014  
  91.   
  92.   
  93. .equ    ULCON0, 0x50000000  
  94. .equ    IR_MODE,    0x0   @[6]正常模式  
  95. .equ    Parity_Mode,    0x0 @[5:3]无校验位  
  96. .equ    Num_of_stop_bit,  0x0  @[2]一个停止位  
  97. .equ    Word_length,    0b11    @[1:0]8个数据位  
  98.   
  99. .equ    UCON0,  0x50000004  
  100. .equ    FCLK_Div,   0   @[15:12]  时钟源选择用PCLK,所以这里用默认值  
  101. .equ    Clk_select, 0b00    @[11:10] 时钟源选择使用PCLK  
  102. .equ    Tx_Int_Type, 1  @[9]  中断请求类型为Level  
  103. .equ    Rx_Int_Type, 0 @1  @[8]  中断请求类型为Level  
  104. .equ    Rx_Timeout, 0  @[7]  
  105. .equ    Rx_Error_Stat_Int, 1 @[6]  
  106. .equ    Loopback_Mode, 0 @[5]  正常模式  
  107. .equ    Break_Sig,  0 @[4] 不发送终止信号  
  108. .equ    Tx_Mode,    0b01 @[3:2]  中断请求或轮循模式  
  109. .equ    Rx_Mode,    0b01 @[1:0]  中断请求或轮循模式  
  110.   
  111. .equ    UFCON0, 0x50000008  
  112. .equ    Tx_FIFO_Trig_Level, 0b00 @[7:6]  
  113. .equ    Rx_FIFO_Trig_Level, 0b00 @[5:4]  
  114. .equ    Tx_FIFO_Reset,  0b0 @[2]  
  115. .equ    Rx_FIFO_Reset,  0b0 @[1]  
  116. .equ    FIFO_Enable,    0b0 @[0] 非FIFO模式  
  117.   
  118. .equ    UMCON0, 0x5000000C    @这个寄存器可以不管的  
  119. .equ    UTRSTAT0,   0x50000010  
  120. .equ    UERSTAT0,   0x50000014  
  121. .equ    UFSTAT0,    0x50000018  
  122. .equ    UMSTAT0,    0x5000001C  
  123. .equ    UTXH0,      0x50000020   @(L 小端)  
  124. .equ    URXH0,      0x50000024   @(L 小端)  
  125.   
  126. .equ     UBRDIV0,    0x50000028  
  127. .equ     UBRDIV,    0x35   @PCLK=400M/4=100M   UBRDIV = (int)(100M/115200/16) - 1 = 53 = 0x35  
  128.   
  129.   
  130. .equ    BCDMIN,0x57000074  
  131.   
  132. .equ    BCDSEC,0x57000070  
  133.   
  134. //.global Buzzer_Freq_Set   
  135.   
  136. .global _start  
  137. _start:     b   reset  
  138.         ldr     pc, _undefined_instruction  
  139.         ldr     pc, _software_interrupt  
  140.         ldr pc, _prefetch_abort  
  141.         ldr pc, _data_abort  
  142.         ldr pc, _not_used  
  143.         @b  irq  
  144.         ldr     pc, _irq  
  145.         ldr     pc, _fiq  
  146.   
  147.   
  148.   
  149. _undefined_instruction:     .word undefined_instruction  
  150. _software_interrupt:        .word software_interrupt  
  151. _prefetch_abort:        .word prefetch_abort  
  152. _data_abort:            .word data_abort  
  153. _not_used:          .word not_used  
  154. _irq:               .word irq  
  155. _fiq:               .word fiq  
  156.   
  157. .balignl 16,0xdeadbeef  
  158.   
  159. reset:  
  160.   
  161.   
  162.     ldr     r3, =WTCON  
  163.     mov r4, #0x0                       
  164.     str r4, [r3]    @ disable watchdog      
  165.   
  166.     ldr r0, =GPBCON  
  167.     ldr r1, =0x15400     @这个时候暂不配置GPB0为TOUT0  
  168.     str r1, [r0]  
  169.   
  170.     ldr r2, =GPBDAT  
  171.     ldr r1, =0x160  
  172.     str r1, [r2]  
  173.   
  174.     bl clock_setup  
  175.     bl uart_init  
  176.     bl delay  
  177.   
  178.   
  179.     msr cpsr_c, #0xd2 @进入中断模式  
  180.     ldr sp, =3072 @中断模式的栈指针定义  
  181.   
  182.     msr cpsr_c, #0xd3 @进入系统模式  
  183.     ldr sp, =4096 @设置系统模式的栈指针  
  184.   
  185. @--------------------------------------------  
  186.   
  187.     ldr r0, =GPBUP  
  188.     ldr r1, =0x03f0    
  189.     str r1, [r0]        
  190.      
  191.     ldr r0, =GPFCON  
  192.     ldr r1, =0x2ea@0x2      
  193.     str r1, [r0]    
  194.   
  195.     ldr r0, =EXTINT0  
  196.     @ldr    r1, =0x8f888@0x0@0x8f888      @~(7|(7<<4)|(7<<8)|(7<<16))   //低电平触发中断  
  197.     ldr r1, =0xafaaa@0x0@0x8f888      //下降沿触发中断  
  198.     str r1, [r0]    
  199.   
  200.     ldr r0, =EINTPEND  
  201.     ldr r1, =0xf0@0b10000  
  202.     str r1, [r0]    
  203.   
  204.     ldr r0, =EINTMASK  
  205.     ldr r1, =0x00@0b00000  
  206.     str r1, [r0]    
  207.   
  208.   
  209.   
  210.     ldr r0, =SRCPND  
  211.     ldr r1, =0x3ff | (1<<30) @0x1@0b11111  
  212.     str r1, [r0]    
  213.   
  214.     ldr r0, =SUBSRCPND  
  215.     ldr r1, =0x1<<13  
  216.     str r1, [r0]    
  217.   
  218.     ldr r0, =INTPND  
  219.     ldr r1, =0x3ff | (1<<30) @0x1@0b11111  
  220.     str r1, [r0]    
  221.   
  222.     ldr r0, =INTSUBMSK  
  223.     ldr r1, =0x0<<13  
  224.     str r1, [r0]    
  225.   
  226.     ldr r0, =INTMSK  
  227.     ldr r1, =0x1ffff000@0b00000  
  228.     str r1, [r0]    
  229.   
  230.     MRS r1, cpsr  
  231.     BIC r1, r1, #0x80  
  232.     MSR cpsr_c, r1  
  233.   
  234.   
  235.     bl     main  
  236.   
  237. irq:  
  238.     sub     lr,lr,#4  
  239.     stmfd   sp!,{r0-r12,lr}  
  240.   
  241.   
  242.     bl irq_isr  
  243.     ldmfd  sp!,{r0-r12,pc}^   
  244.   
  245.   
  246. irq_isr:  
  247.   
  248.     ldr r2, =GPBDAT  
  249.     ldr r1, =0x0e0  
  250.     str r1, [r2]  
  251.   
  252.     ldr r3,=0xffffff  
  253.   
  254. delay2:  
  255.     sub r3,r3,#1  
  256.   
  257.     cmp r3,#0x0  
  258.   
  259.     bne delay2  
  260.   
  261.     //这上面的延时必须要,否则蜂鸣器的声音有问题   
  262.          ldr r0,=EINTPEND  
  263.          ldr r1,=0xf0  
  264.          str r1,[r0]   
  265.   
  266.     ldr r0, =SRCPND  
  267.     ldr r1, =0x3ff | (1<<30) @0b11111  
  268.     str r1, [r0]    
  269.   
  270.     ldr r0, =SUBSRCPND  
  271.     ldr r1, =0x1<<13  
  272.     str r1, [r0]    
  273.   
  274.     ldr r0, =INTPND  
  275.     ldr r1, =0x3ff | (1<<30) @0b11111  
  276.     str r1, [r0]    
  277.   
  278.   
  279.   
  280.     ldr r2, =GPBCON  
  281.     ldr r1,[r2]  
  282.     ldr r1,[r1]  
  283.     //ldr   r1, =0x15400   
  284.     bic r1,r1,#0x3  
  285.     orr r1,r1,#0x2  
  286.     str r1,[r2]  
  287.   
  288.     ldr r2, =GPBDAT  
  289.     ldr r1, =0x1a0  
  290.     str r1, [r2]  
  291.   
  292.     ldr r1,=TCFG0  
  293.     ldr r2,=(Prescaler0<<0)  
  294.     str r2, [r1]  
  295.   
  296.     ldr r1,=TCFG1  
  297.     ldr r2,=(DMA_MODE<<20) | (MUX0<<0)  
  298.     str r2, [r1]  
  299.   
  300. //  ldr r3,[r0]   
  301. //  str r3,[r2]   
  302.   
  303.   
  304.   
  305.     //mov  r2, r0   
  306.   
  307.     ldr r1,=TCNTB0  
  308.     ldr r2,=10  
  309.     str r2, [r1]        //r0就是c调用汇编的传递参数   
  310.       
  311.     //mov  r0,r0,LSR #2   
  312.   
  313.     ldr r1,=TCMPB0  
  314.     ldr r2,=2  
  315.     str r2, [r1]  
  316.   
  317.   
  318.   
  319.     ldr r1,=TCON  
  320.     ldr r2,=(DZ_eable<<4) | (auto_reload<<3) | (inverter<<2) | (man_update<<1) | (start<<0)  
  321.     str r2, [r1]  
  322.   
  323.     ldr r1,=TCON  
  324.     ldr r2,=(DZ_eable<<4) | (auto_reload<<3) | (inverter<<2) | (clear_man_update<<1) | (start<<0)  
  325.     str r2, [r1]  
  326.   
  327.     ldr r2, =GPBDAT  
  328.     ldr r1, =0x1a0  
  329.     str r1, [r2]  
  330.   
  331.   
  332.   
  333.   
  334.   
  335.     mov pc,lr  
  336.   
  337.   
  338. delay:  
  339.       
  340.     ldr r3,=0xffffff  
  341.   
  342. delay1:  
  343.     sub r3,r3,#1  
  344.   
  345.     cmp r3,#0x0  
  346.   
  347.     bne delay1  
  348.   
  349.     mov pc,lr  
  350.   
  351.   
  352. clock_setup:  
  353.   
  354.     ldr r0,=LOCKTIME  
  355.     ldr r1,=0xffffffff  
  356.     str r1, [r0]  
  357.   
  358.     ldr r0,=CLKDIVN  
  359.     ldr r1,=(DIVN_UPLL<<3) | (HDIVN<<1) | (PDIVN<<0)  
  360.     str r1, [r0]  
  361.   
  362.     ldr r0,=UPLLCON  
  363.     ldr r1,=(U_MDIV<<12) | (U_PDIV<<4) | (U_SDIV<<0)   @Fin=12M  UPLL=48M  
  364.     str r1, [r0]  
  365.     nop  
  366.     nop  
  367.     nop  
  368.     nop  
  369.     nop  
  370.     nop  
  371.     nop  
  372.     ldr r0,=MPLLCON  
  373.     ldr r1,=(M_MDIV<<12) | (M_PDIV<<4) | (M_SDIV<<0)    @Fin=12M  FCLK=400M  
  374.     str r1, [r0]  
  375.   
  376.   
  377.   
  378.     mov pc,lr  
  379.   
  380.   
  381. uart_init:  
  382.     ldr r0,=GPHCON  
  383.     ldr r1,=0x2aaaa     @配置GPIO复用规则为串口  
  384.     str r1, [r0]  
  385.   
  386.     ldr r0,=ULCON0  
  387.     ldr r1,=(IR_MODE<<6) | (Parity_Mode<<3) | (Num_of_stop_bit<<2) | (Word_length<<0)    @  
  388.     str r1, [r0]  
  389.   
  390.     ldr r0,=UCON0  
  391.     ldr r1,=(FCLK_Div<<12) | (Clk_select<<10) | (Tx_Int_Type<<9) | (Rx_Int_Type<<8) | (Rx_Timeout<<7) | (Rx_Error_Stat_Int<<6) |(Loopback_Mode<<5) | (Break_Sig<<4) | (Tx_Mode<<2) | (Rx_Mode<<0)  
  392.     str r1, [r0]  
  393.   
  394.     ldr r0,=UFCON0  
  395.     ldr r1,=(Tx_FIFO_Trig_Level<<6) | (Rx_FIFO_Trig_Level<<4) | (Tx_FIFO_Reset<<2) | (Rx_FIFO_Reset<<1) | (FIFO_Enable<<0)    @  
  396.     str r1, [r0]  
  397.   
  398.     ldr r0,=UBRDIV0  
  399.     ldr r1,=(UBRDIV<<0)  
  400.     str r1, [r0]  
  401.   
  402.         mov pc,lr  
  403.   
  404. /* 
  405. Buzzer_Freq_Set: 
  406.  
  407.     //ldr   r0, =GPBCON 
  408.     //ldr   r1, =0x15400     @这个时候暂不配置GPB0为TOUT0,这时候只是配置GPB0为TOUT0 
  409.     //str   r1, [r0] 
  410.  
  411.  
  412.  
  413.     ldr r2, =GPBCON 
  414.     ldr r1,[r2] 
  415.     ldr r1,[r1] 
  416.     //ldr   r1, =0x15400 
  417.     bic r1,r1,#0x3 
  418.     orr r1,r1,#0x2 
  419.     str r1,[r2] 
  420.  
  421.     ldr r2, =GPBDAT 
  422.     ldr r1, =0x1a0 
  423.     str r1, [r2] 
  424.  
  425.     ldr r1,=TCFG0 
  426.     ldr r2,=(Prescaler0<<0) 
  427.     str r2, [r1] 
  428.  
  429.     ldr r1,=TCFG1 
  430.     ldr r2,=(DMA_MODE<<20) | (MUX0<<0) 
  431.     str r2, [r1] 
  432.  
  433. //  ldr r3,[r0] 
  434. //  str r3,[r2] 
  435.  
  436.  
  437.  
  438.     //mov  r2, r0 
  439.  
  440.     ldr r1,=TCNTB0 
  441.     ldr r2,=10 
  442.     str r2, [r1]        //r0就是c调用汇编的传递参数 
  443.      
  444.     //mov  r0,r0,LSR #2 
  445.  
  446.     ldr r1,=TCMPB0 
  447.     ldr r2,=2 
  448.     str r2, [r1] 
  449.  
  450.  
  451.  
  452.     ldr r1,=TCON 
  453.     ldr r2,=(DZ_eable<<4) | (auto_reload<<3) | (inverter<<2) | (man_update<<1) | (start<<0) 
  454.     str r2, [r1] 
  455.  
  456.     ldr r1,=TCON 
  457.     ldr r2,=(DZ_eable<<4) | (auto_reload<<3) | (inverter<<2) | (clear_man_update<<1) | (start<<0) 
  458.     str r2, [r1] 
  459.  
  460.     ldr r2, =GPBDAT 
  461.     ldr r1, =0x1a0 
  462.     str r1, [r2] 
  463.  
  464.     mov pc,lr 
  465. */  
  466. main:  
  467.   
  468.     ldr r2, =GPBDAT  
  469.     ldr r1, =0x1a0  
  470.     str r1, [r2]  
  471.     bl delay  
  472.   
  473.     //ldr r1,=TCON   
  474.     //ldr r2,=(DZ_eable<<4) | (auto_reload<<3) | (inverter<<2) | (man_update<<1) | (stop<<0)  
  475.     //str r2, [r1]   
  476.   
  477. /* 
  478.     ldr r2, =GPBCON 
  479.     ldr r1,[r2] 
  480.     ldr r1,[r1] 
  481.     //ldr   r1, =0x15400 
  482.     bic r1,r1,#0x3 
  483.     orr r1,r1,#0x2 
  484.     str r1,[r2] 
  485.  
  486.  
  487.  
  488.     ldr r0,=TCFG0 
  489.     ldr r1,=(Prescaler0<<0) 
  490.     str r1, [r0] 
  491.  
  492.     ldr r0,=TCFG1 
  493.     ldr r1,=(DMA_MODE<<20) | (MUX0<<0) 
  494.     str r1, [r0] 
  495.  
  496.  
  497.     ldr r0,=TCNTB0 
  498.     ldr r1,=10 
  499.     str r1, [r0] 
  500.  
  501.     ldr r0,=TCMPB0 
  502.     ldr r1,=2 
  503.     str r1, [r0] 
  504.  
  505.  
  506.  
  507.     ldr r0,=TCON 
  508.     ldr r1,=(DZ_eable<<4) | (auto_reload<<3) | (inverter<<2) | (man_update<<1) | (start<<0) 
  509.     str r1, [r0] 
  510.  
  511.     ldr r0,=TCON 
  512.     ldr r1,=(DZ_eable<<4) | (auto_reload<<3) | (inverter<<2) | (clear_man_update<<1) | (start<<0) 
  513.     str r1, [r0] 
  514.  
  515. */  
  516.   
  517.   
  518.                             
  519.                
  520.   
  521.   
  522.   
  523.        ldr lr, =loop    
  524.  // ldr pc, _rtc_uart_test   
  525. //_rtc_uart_test:   .word rtc_uart_test   
  526.     bl rtc_uart_test  
  527.   
  528.     ldr r2, =GPBDAT  
  529.     ldr r1, =0x1c0  
  530.     str r1, [r2]  
  531.     bl delay  
  532. loop:  
  533.     ldr r2, =BCDSEC   @BCDMIN  
  534.     ldr r1,[r2]  
  535.     cmp     r1, #0x06  
  536.         bleq     ledon  
  537.       
  538.       
  539.         b loop                                               @ 死循环  
  540.   
  541. ledon:  
  542.     ldr r2, =GPBDAT  
  543.     ldr r1, =0x160  
  544.     str r1, [r2]  
  545.   
  546.     ldr r3,=0xffffff  
  547.   
  548. delay3:  
  549.     sub r3,r3,#1  
  550.   
  551.     cmp r3,#0x0  
  552.   
  553.     bne delay3  
  554.     mov pc,lr  
  555.   
  556.   
  557.   
  558. undefined_instruction:  
  559.             nop  
  560. software_interrupt:  
  561.             nop  
  562. prefetch_abort:   
  563.             nop  
  564. data_abort:  
  565.             nop  
  566. not_used:  
  567.             nop  
  568. fiq:  
  569.             nop  

rtc_uart_test.s:

[cpp] view plaincopyprint?
  1. #include <stdarg.h>   
  2. #include <string.h>   
  3. #include <stdlib.h>   
  4. #include <stdio.h>   
  5. #include <ctype.h>   
  6.   
  7. #include "rtc_uart_test.h"   
  8. extern void Buzzer_Freq_Set(int freq);  
  9. //extern void Buzzer_Freq_Set( void );   
  10. char uart_GetByte(void)  
  11. {  
  12.         while(!(rUTRSTAT0 & 0x1));   //Wait until THR is empty.  
  13.             return RdURXH0();  
  14. }  
  15.   
  16.   
  17. void uart_GetString(char *pt)  
  18. {  
  19.     while(*pt)  
  20.         uart_GetByte();  
  21. }  
  22.   
  23.   
  24. void uart_SendByte(int data)  
  25. {  
  26.       
  27.         if(data=='\n')  
  28.         {  
  29.             while(!(rUTRSTAT0 & 0x2));  
  30.             WrUTXH0('\r');  
  31.         }  
  32.         while(!(rUTRSTAT0 & 0x2));   //Wait until THR is empty.  
  33.         WrUTXH0(data);  
  34.   
  35. }                 
  36.   
  37. //====================================================================  
  38. void uart_SendString(char *pt)  
  39. {  
  40.     while(*pt)  
  41.            uart_SendByte(*pt++);  
  42. }  
  43.   
  44. void uart_Printf(char *fmt,...)  
  45. {  
  46.     va_list ap;  
  47.     char string[256];  
  48.   
  49.     va_start(ap,fmt);  
  50.     //vsprintf(string,fmt,ap);   
  51.     uart_SendString(string);  
  52.     va_end(ap);  
  53. }  
  54.   
  55. void uart_test(void)  
  56. {  
  57.       
  58.     char str[20] = "\nhello world\n";  
  59.     int a = 97;  
  60.     //while(1)   
  61.     //  uart_SendByte(a);      
  62.     uart_SendString(str);  
  63.     char s = uart_GetByte();  
  64.     //if(s == 'a')   
  65.     if(s == 97)  
  66.         rGPBDAT = 0x1c0;  
  67.     //uart_SendByte(a);   
  68.     //uart_SendByte(97);   
  69.     //uart_SendByte('a');   
  70.     uart_SendByte((int)s);  
  71.     uart_SendByte((int)'s');  
  72. }  
  73.   
  74.   
  75. void rtc_uart_test(void)  
  76. {  
  77.     rRTCCON = 0x1;  
  78.     rTICNT = 0x0;  
  79.     rRTCALM = 0x42;  
  80.       
  81.   
  82.   
  83.     rBCDYEAR = 0x10 ;         
  84.     rBCDMON  = 0x11 ;         
  85.     rBCDDATE = 0x07 ;         
  86.     rBCDDAY  = 0x05 ;         
  87.     rBCDHOUR = 0x12 ;         
  88.     rBCDMIN  = 0x03 ;             
  89.     rBCDSEC  = 0x00 ;         
  90.   
  91.     rALMMIN = 0x04;  
  92.     uart_SendString("begin\n");  
  93.     //uart_Printf("year:%d\n",rBCDYEAR);   
  94. }  
  95.   
  96.   
  97. void pwm_uart_test(void)  
  98. {  
  99.     int freq = 10;  
  100.     int i;  
  101.     for(i=0; i<100;i++)  
  102.     uart_SendString("app\n");  
  103.     //Buzzer_Freq_Set( freq ) ;   
  104.     //Buzzer_Freq_Set(  ) ;   
  105.     //uart_test();   
  106.     uart_SendString("start\n");  
  107. /* 
  108.     int i; 
  109.     for(i=0;i<1000;i++) 
  110.         uart_SendString("wait\n"); 
  111.     while( 1 ) 
  112.     { 
  113.         char key = uart_GetByte(); 
  114.         uart_SendByte(key); 
  115.         if( key == 'a' || key == 'A' ) 
  116.         { 
  117.             if( freq < 2000 )  //lci  20000 
  118.                 freq += 10 ; 
  119.                 uart_SendByte('a'); 
  120.             Buzzer_Freq_Set( freq ) ; 
  121.         } 
  122.  
  123.         if( key == 'b' || key == 'B' ) 
  124.         { 
  125.             if( freq > 11 ) 
  126.                 freq -= 10 ; 
  127.                 uart_SendByte('b'); 
  128.             Buzzer_Freq_Set( freq ) ; 
  129.         } 
  130.          
  131.         //uart_SendString( "\tFreq = %d\n", freq ) ; 
  132.         //if( key == ESC_KEY ) 
  133.         //{ 
  134.         //  Buzzer_Stop() ; 
  135.         //  return ; 
  136.         //} 
  137.  
  138.     } 
  139.  
  140. */  
  141. }  

在调这个过程中,因为RTCCON中的CLKRST最初被我置为1,导致时间根本不走,为了查这个问题,专门通过led显示来判断这个时间是不是不走:

ldr r2, =BCDSEC   @BCDMIN
ldr r1,[r2]
cmp     r1, #0x06
    bleq     ledon

通过这里的判断,可以明确时间有被设进去,可是时间不走.经过google,才确定是寄存器的设置问题.


到此,rtc的闹钟也实现了功能.明天就用这个做闹钟吧~~


0 0