历史上的今天
今天是:2024年12月05日(星期四)
2019年12月05日 | STM8S内部时钟切换问题解决
2019-12-05 来源:elecfans
/*
**********************************************************************************************************************************
* 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存储器的读写操作
史海拾趣
|
一个好梦机电路及制作方法介绍 做梦机是每个人都乐意组装和试验的制作,它也是很有用的。它的功能是产生松驰的催眠讯号,有助你晚上好好地睡上一觉。 我们认为睡眠是一个休息的时间,可是大多数人的晚上是在紧张的状态下渡过的,以至没法 ...… 查看全部问答> |
|
NRF24L01无线数传模块(13RMB为人民服务) http://store.taobao.com/shop/view_shop.htm?shop_id=59240360… 查看全部问答> |
|
操作2440,提取一幅图片的C数组形式放到程序里,程序在RAM里面可以跑,程序下载到NAND FLASH里面LCD显示图片乱的,只有局部正确?请高手帮忙分析原因… 查看全部问答> |
|
我的STM32 是利用ST官方的Mass_Storage修改的 端点1是IN 端点2是OUT 这两个端点都是批量传输端点 安装驱动后 我用Bus Hound 5向其发送数据 STM32能顺利接收 void EP2_OUT_Callback(void) { &nbs ...… 查看全部问答> |
|
我在速查表收集了DOS命令列表,对于386时代的人来说,一般人是接触不到计算机的,DOS命令是同计算机操作系统唯一交流的系统工具,在WINDOWS大行其道的今天,只有网管和黑客们还在孜孜不倦地研究它,DOS命令渐渐被人遗忘了,令人眼花缭乱的WINDOWS可 ...… 查看全部问答> |
|
针对目前磁场矢量测量动态响应慢、 功耗过高等问题, 进行研究基于MS P 4 3 0单片机的高性能固态三轴磁探仪。磁敏器件采用动态响应快、 抗干扰能力强的固态磁传感器 S E N - L ; 数据采集模块采用低功耗 P N I 1 1 0 9 6 芯片, 并通过 S P ...… 查看全部问答> |
|
MSP430是超低功耗16位单片机,越来越受到电子工程师亲睐并得到广泛应用。C程序直观,可读性好,易于移植和维护,已被很多单片机编程人员所采用。MSP430集成开发环境(如IAR Embedded Workbench和AQ430)都集成了C编译器和C语言级调试器C—SPY。但是C ...… 查看全部问答> |




