原创 STM8与汇编语言(14)--切换时钟源

2010-6-11 09:58 3844 8 8 分类: MCU/ 嵌入式

                 STM8与汇编语言(14)--切换时钟源<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


 


STM8单片机的时钟源,即可以选内部的,也可以选外部的,在系统运行过程中,可以很方便地切换。


下面的实验程序首先将主时钟源切换到外部的晶体振荡器上,振荡频率为8MHZ,然后,然后快速闪烁LED指示灯。接着,将主时钟源又切换到内部的振荡器上,振荡频率为2MHZ,然后再慢速闪烁LED指示灯。通过观察LED指示灯的闪烁频率,可以看到,同样的循环代码,由于主时钟源的改变的改变,闪烁频率和时间长短都发生了变化。


同样还是利用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,#$01


        LD      CLK_ECKR,A        ; 允许外部高速振荡器工作


WAIT_HSE_READY.L


        LD      A,CLK_ECKR


        AND     A,#$02


        JREQ    WAIT_HSE_READY    ; 等待外部高速振荡器准备好


                   


; 注意:经过上述切换后,主时钟从HSI/82MHZ)切换到HSE8MHZ         


;         


MAIN_LOOP.L


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


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


        LD      A,#$02


        LD      CLK_SWCR,A        ; SWEN <- 1


         


        LD      A,#$B4   


        LD      CLK_SWR,A         ; 选择芯片外部的高速振荡器为主时钟


WAIT_CLK_SWITCH_1.L


        LD      A,CLK_SWCR


        AND     A,#$08


        JREQ    WAIT_CLK_SWITCH_1 ; 等待切换成功


         


        LD      A,#$00            ; 清除切换标志


        LD      CLK_SWCR,A


 


        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的输出设置成1


        LD      A,#100


        CALL    DELAY_MS          ; 延时100MS


                                  


        POP     A                 ; 恢复寄存器


        DEC     A


        JRNE    HIGH_SPEED


                                  


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


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


        LD      A,#$02


        LD      CLK_SWCR,A        ; SWEN <- 1


         


        LD      A,#$E1            ; 选择HSI为主时钟源


        LD      CLK_SWR,A        


WAIT_CLK_SWITCH_2.L


        LD      A,CLK_SWCR


        AND     A,#$08


        JREQ    WAIT_CLK_SWITCH_2 ; 等待切换成功


         


        LD      A,#$00            ; 清除切换标志


        LD      CLK_SWCR,A


; 注意:经过上述切换后,主时钟从HSE8MHZ)切换到HSI/82MHZ         


 


        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的输出设置成1


        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-11


 

文章评论0条评论)

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