STM8S内部时钟切换问题解决

发布者:lcn18560863680最新更新时间:2019-12-05 来源: elecfans关键字:STM8S  内部时钟  切换问题 手机看文章 扫描二维码
随时随地手机看文章

/*

**********************************************************************************************************************************

* Name    : STM8S内部时钟切换问题解决

* Author  : MingMing

* Release : 2013/12/28

* Update  : 2013/12/29

* E-mail  : clint.wang@foxmail.com

**********************************************************************************************************************************

*/

    在使用STM8S105实现内部时钟切换的时候,发现时钟可以在HIS(内部高速时钟)和HSE(外部高速时钟)之间切换,而HSI(内部高速时钟)和LSI(内部低速时钟)之间的切换却不正常。当芯片上电或复位后芯片采用的是HSI/8作为主时钟源,这样我们可以将时钟源切换到外部时钟(16MHz)试试看。代码如下:

void Clock_Conversion (void)

{

  CLK_ECKR |= MASK_CLK_ECKR_HSEEN;     /* 打开外部高速时钟源 */  

  while(CLK_ECKR_HSERDY == 0);         /* 等待时钟源信号稳定,稳定后CLK_ECKR_HSERDY置位 */

  CLK_SWCR = MASK_CLK_SWCR_SWEN;       /* 转换使能,采用自动转换方式 */

  CLK_SWR  = MASTER_CLOCK_HSE;         /* 选择外部高速时钟源 */

  while(!(CLK_SWCR & 0x08));           /* 切换完成后,SWIF置位 */

}

    通过上面的代码,观察LED灯的闪烁频率,可以确定已经成功的把HSI内部时钟源切换到HSE外部时钟源。采用同样的方法我们试着去切换HSI内部高速时钟源到LSI内部低速时钟源,代码如下:


void Clock_Conversion (void)

{

  CLK_ICKR |= MASK_CLK_ICKR_LSIEN;     /* 打开内部低速时钟源 */  

  while(CLK_ICKR_LSIRDY == 0);         /* 等待时钟源信号稳定,稳定后CLK_ICKR_LSIRDY置位 */

  CLK_SWCR = MASK_CLK_SWCR_SWEN;       /* 转换使能,采用自动转换方式 */

  CLK_SWR  = MASTER_CLOCK_LSI;         /* 选择内部低速时钟源 */

  while(!(CLK_SWCR & 0x08));           /* 切换完成后,SWIF置位 */

}

    运行上面的代码,经过调试发现程序在while(!(CLK_SWCR & 0x08))处出现了死循环,SWIF未被置位。这就很奇怪了,代码第二句说明芯片的内部时钟源信号已经稳定,为什么切换不正常?貌似有一种无形的力量在限制着它。继续看芯片手册吧,在FLASH的章节中有一个Option byte(选项字节)的介绍。在选项字节中找到两块名字为OPT3和NOPT3的两处地址,OPT3和NOPT3的第四位控制着内部时钟的使能,终于这种无形的力量被找到了,那么开始想办法修改它吧。下面是关于LSI_EN的介绍:

    LSI_EN: Low speed internal clock enable

    0: LSI clock is not available as CPU clock source

    1: LSI clock is available as CPU clock source

    NLSI_EN: Low speed internal clock enable

    0: LSI clock is available as CPU clock source

    1: LSI clock is not available as CPU clock source

    上图为存储单元的地址映射,操作Option bytes相当于操作存储地址,那么我们就好好看看操作Flash需要哪些步骤,首先看看Flash的操作寄存器

    FLASH_CR2 :控制寄存器2

    OPT: 对选项字节进行写操作,该位可由软件来置位或清零。

    0: 对选项字节进行写操作被禁止

    1: 对选项字节进行写操作被使能

    FLASH_NCR2 :互补控制寄存器2

    NOPT: 对选项字节进行写操作,该位可由软件来置位或清零。

    0: 对选项字节进行写操作被使能

    1: 对选项字节进行写操作被禁止

    FLASH_DUKR :DATA EEPROM解除保护寄存器

    根据上面的分析,在主函数中编写我们的代码。


void main( void )

{

  do{

  FLASH_DUKR = 0xAE;               /* 写入第一个密钥 */

  asm("nop");

  FLASH_DUKR = 0x56;               /* 写入第二个密钥 */

  asm("nop");  

  }while(!(FLASH_IAPSR & 0x08));   /* 判断解锁是否成功,如果出现死循环,尝试先写入第二个密钥*/

  FLASH_CR2 = 0x80;                /* 解除OPT写保护 */

  FLASH_NCR2 = 0x7F;               /* 解除OPT写保护 */

  asm("nop"); 

  *((unsigned char*)0x4805) = 0x08;/* 对OPT3中LSI_EN置位 */

  *((unsigned char*)0x4806) = 0xF7;/* 对NOPT3中NLSI_EN清零 */

  asm("nop"); 

  Clock_Conversion ();             /* 转换时钟源到LSI内部低速时钟 */

•••••••••••••••••                  /* 其它模块代码省略 */

}

    看到这里我们已经成功了,这是通过代码修改OPT的方法,官方为我们提供的ST Toolset中STVP烧录工具可以对OPT修改。打开STVP,选择OPTION BYTE页,找到LSI_EN在下拉框中将LSI设置为available,点击Program current tab。烧录成功之后,程序中无需再加入上面的配置代码,只需在程序中调用时钟转换的函数即可。

关键字:STM8S  内部时钟  切换问题 引用地址:STM8S内部时钟切换问题解决

上一篇:STM8S存储器的读写操作
下一篇:STM8S开发环境搭建IAR For STM8

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved