原创 STM8与汇编语言(13)--修改CPU的时钟

2010-6-13 09:44 3257 9 9 分类: MCU/ 嵌入式

                 STM8与汇编语言(13)--修改CPU的时钟<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


 


在有些单片机的应用系统中,并不需要CPU运行在多高的频率。在低频率下运行,芯片的功耗会大大下降。因此希望单片机能提供这个功能,STM8单片机确实有这个功能,并且修改也非常方便。


下面的实验程序首先将CPU的运行时钟设置在8MHZ,然后快速闪烁LED指示灯。接着,通过修改主时钟的分频系数和CPU时钟的分频系数,将CPU时钟频率设置在500KHZ,然后再慢速闪烁LED指示灯。通过观察LED指示灯的闪烁频率,可以看到,同样的循环代码,由于CPU时钟频率的改变,闪烁频率和时间长短都发生了变化。


同样还是利用ST的开发工具,生成一个汇编程序的框架,然后修改其中的main.asm,修改后的代码如下。


 


stm8/


 


       #include "mapping.inc"


       #include "STM8S<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />207C_S.INC"


 


; 定义堆栈空间的起始位置和结束位置


stack_start.w  EQU    $stack_segment_start


stack_end.w    EQU    $stack_segment_end


 


               segment 'rom'            ; 下面开始定义一个段,该段位于ROM


main.l                            ; 定义复位后的第一条指令的标号(即入口地址)


;


; 首先要初始化堆栈指针


        LDW     X,#stack_end         


        LDW     SP,X


                                                                        


        LD      A,#08


        LD      PD_DDR,A          ; PD3设置成输出


        LD      A,#08


        LD      PD_CR1,A          ; PD3设置成推挽输出


        LD      A,#00


        LD      PD_CR2,A         


                                  


        LD      A,#$E1


        LD      CLK_SWR,A         ;选择芯片内部的16MHZRC振荡器


                                                                                                                   ;为主时钟


                                                                                                                                           


                                  


MAIN_LOOP.L


;下面设置CPU时钟分频器,使得CPU时钟=主时钟


;通过发光二极管,可以看出,程序运行的速度确实明显提高了


        LD      A,#$08            


        LD      CLK_CKDIVR,A      ; 主时钟 = 16MHZ / 2


                                           ; CPU时钟 = 主时钟 = 8MHZ


 


        LD      A,#10             ; LED高速闪10


HIGH_SPEED.L                              


        PUSH    A                 ; 保存寄存器


        LD      A,#08          


        LD      PD_ODR,A          ; PD3的输出设置成1


        LD      A,#100


        CALL    DELAY_MS          ; 延时100MS


                                  


        LD      A,#00             ; 


        LD      PD_ODR,A          ; PD3的输出设置成0


        LD      A,#100


        CALL    DELAY_MS          ; 延时100MS


                                  


        POP     A                 ; 恢复寄存器


        DEC     A


        JRNE    HIGH_SPEED


                                  


;下面设置CPU时钟分频器,使得CPU时钟=主时钟/4


;通过发光二极管,可以看出,程序运行的速度确实明显下降了


        LD      A,#$1A            ;


        LD      CLK_CKDIVR,A      ; 主时钟 = 16MHZ / 8


                                                                ; CPU时钟 = 主时钟 / 4 = 500KHZ


 


        LD      A,#10             ; LED低速闪10


LOW_SPEED.L                               


        PUSH    A                 ; 保存寄存器


                                  


        LD      A,#08            


        LD      PD_ODR,A          ; PD3的输出设置成1


        LD      A,#100


        CALL    DELAY_MS          ; 延时100MS


 


        LD      A,#00             


        LD      PD_ODR,A          ; PD3的输出设置成0


        LD      A,#100


        CALL    DELAY_MS          ; 延时100MS


                                  


        POP     A                 ; 恢复寄存器


        DEC     A


        JRNE    LOW_SPEED


 


        JRA     MAIN_LOOP        


 


; 函数功能:延时


; 输入参数:寄存器A -- 要延时的毫秒数,这里假设CPU的主频为2MHZ


; 输出参数:无


; 值:无


;     注:无


DELAY_MS.L


        PUSH    A                ; 将入口参数保存到堆栈中


        LD      A,#250            ; 寄存器A<-250,作为下面的循环数 


DELAY_MS_1.L


        NOP                       ; 用空操作指令进行延时4T


        NOP


        NOP


        NOP


        NOP


        DEC     A                 ; 寄存器A<-A-1,本条指令执行之间为1T


        JRNE    DELAY_MS_1      ; 若不等于0,则循环,


                                         ; 本条指令执行时间为2T(跳时)或1T(不跳时)


POP     A                 ; 从堆栈中恢复入口参数


         DEC     A                 ; 将要延时的MS数-1 


         JRNE    DELAY_MS        ; 若不等于0,则循环


         RET                       ; 函数返回 


 


  interrupt NonHandledInterrupt


NonHandledInterrupt.l


         iret


 


; 下面定义中断向量表      


         segment 'vectit'


         dc.l {$82000000+main}                               ; reset


         dc.l {$82000000+NonHandledInterrupt}    ; trap


         dc.l {$82000000+NonHandledInterrupt}    ; irq0


         dc.l {$82000000+NonHandledInterrupt}    ; irq1


         dc.l {$82000000+NonHandledInterrupt}    ; irq2


         dc.l {$82000000+NonHandledInterrupt}    ; irq3


         dc.l {$82000000+NonHandledInterrupt}    ; irq4


         dc.l {$82000000+NonHandledInterrupt}    ; irq5


         dc.l {$82000000+NonHandledInterrupt}    ; irq6


         dc.l {$82000000+NonHandledInterrupt}    ; irq7


         dc.l {$82000000+NonHandledInterrupt}    ; irq8


         dc.l {$82000000+NonHandledInterrupt}    ; irq9


         dc.l {$82000000+NonHandledInterrupt}    ; irq10


         dc.l {$82000000+NonHandledInterrupt}    ; irq11


         dc.l {$82000000+NonHandledInterrupt}    ; irq12


         dc.l {$82000000+NonHandledInterrupt}    ; irq13


         dc.l {$82000000+NonHandledInterrupt}    ; irq14


         dc.l {$82000000+NonHandledInterrupt}    ; irq15


         dc.l {$82000000+NonHandledInterrupt}    ; irq16


         dc.l {$82000000+NonHandledInterrupt}    ; irq17


         dc.l {$82000000+NonHandledInterrupt}    ; irq18


         dc.l {$82000000+NonHandledInterrupt}    ; irq19


         dc.l {$82000000+NonHandledInterrupt}    ; irq20


         dc.l {$82000000+NonHandledInterrupt}    ; irq21


         dc.l {$82000000+NonHandledInterrupt}    ; irq22


         dc.l {$82000000+NonHandledInterrupt}    ; irq23


         dc.l {$82000000+NonHandledInterrupt}    ; irq24


         dc.l {$82000000+NonHandledInterrupt}    ; irq25


         dc.l {$82000000+NonHandledInterrupt}    ; irq26


         dc.l {$82000000+NonHandledInterrupt}    ; irq27


         dc.l {$82000000+NonHandledInterrupt}    ; irq28


         dc.l {$82000000+NonHandledInterrupt}    ; irq29


 


       end


 


 


                    2010-6-9

文章评论0条评论)

登录后参与讨论
我要评论
0
9
关闭 站长推荐上一条 /2 下一条