STM8的C语言编程(11)-- 切换时钟源
- 格式:doc
- 大小:15.50 KB
- 文档页数:3
第八章STM8S207时钟编程及其实例本章介绍STM8S207 的时钟编程。
STM8S207 时钟控制器功能强大而灵活易用,允许程序运行中将主时钟从一个时钟源切换到另一个时钟源,而且同一个时钟源可以任意更改分频系数。
8.1 STM8 时钟控制简介时钟控制器功能强大而且灵活易用。
其目的在于使用户在获得最好性能的同时,亦能保证消耗的功率最低。
用户可独立地管理各个时钟源,并将它们分配到CPU 或各个外设。
主时钟和CPU 时钟均带有预分频器。
具有安全可靠的无故障时钟切换机制,可在程序运行中将主时钟从一个时钟源切换到另一个时钟源。
抗电磁干扰时钟配置寄存器为了避免由电磁干扰造成的对应用程序误写操作或系统挂起,大多数关键的时钟配置寄存器都有一个互补寄存器与之相对应。
系统将会自动检测这些关键寄存器与其互补寄存器之间是否匹配。
如果不匹配,则产生一个EMS 复位,从而使应用程序恢复到正常操作。
详情请参见时钟寄存器描述。
1、主时钟源介绍下面4种时钟源可用做主时钟1、1-24MHz 高速外部晶振(HSE)2、最大24MHz 高速外部时钟信号3、16MHz 高速内部RC 振荡器(HSI)4、128KHz 低速内部RC(LSI)所以总的来说可以分为三种时钟源,HSE、HSI、LSI2、时钟树,如下图所示由上图可以发现,作为f_cpu 的时钟源可以来源于f_hse、f_hsi 经过HSIDIV分频后的时钟、f_lsi 这三个时钟源。
而选择开关在CKM[7:0]中。
由此事实上可以作为f_master 的时钟源频率有:外部HSE 24MHz内部高速HSI 16MHz、2 分频的8MHz、4 分频的4MHz、8 分频的2MHz(复位默认时钟源)内部低速LSI 128KHz上面得到的频率是f_master 的频率,然后f_master 还可以通过CPUDIV 来分频后提供f_cpu 的时钟,CPUDIV 可以为1、2、4、8、16、32、64、128 分频,最终得到是CPU 的时钟频率f_cpu。
如何在C语言中转换时间如何在C语言中转换时间本文是店铺搜索整理的关于介绍了在C语言中转换时间的基本方法,分别是mktime()函数和localtime()函数的使用,供参考阅读,希望对大家有所帮助!想了解更多相关信息请持续关注我们店铺!C语言mktime()函数:将时间转换成经过的秒数头文件:#include <time.h>定义函数:time_t mktime(strcut tm * timeptr);函数说明:mktime()用来将参数timeptr 所指的tm 结构数据转换成从公元1970 年1 月1 日0 时0 分0 秒算起至今的UTC 时间所经过的秒数。
返回值:返回经过的秒数。
范例:用time()取得时间(秒数), 利用localtime() 转换成struct tm 再利用mktine()将structtm 转换成原来的秒数。
#include <time.h>main(){time_t timep;strcut tm *p;time(&timep);printf("time() : %d \n", timep);p = localtime(&timep);timep = mktime(p);printf("time()->localtime()->mktime():%d\n", timep);}执行结果:time():974943297 time()->localtime()->mktime():974943297 C语言localtime()函数:获取当前时间和日期并转换为本地时间头文件:#include <time.h>定义函数:struct tm *localtime(const time_t * timep);函数说明:localtime()将参数timep 所指的time_t 结构中的`信息转换成真实世界所使用的时间日期表示方法,然后将结果由结构tm 返回。
手动开关手动开关没有自动切换为直接的但它提供给用户的切换事件时间的精确控制。
参照图20中的流程图。
1。
写使用系统时钟开关选择目标时钟源的8位值寄存器(clk_swr)。
然后swbsy位是由硬件,和目标源振荡器开始。
古老的时钟源继续驱动CPU和外设。
2。
该软件具有等到目标时钟源准备(稳定的)。
这是在clk_swcr寄存器和快捷旗由中断如果swien位设置显示。
3。
最终软件的作用是设置,在所选择的时间,在clk_swcr的赛文点寄存器来执行开关。
在手动和自动切换模式,旧的系统时钟源不会自动关闭的情况下是由其他模块(LSI混凝土可用于例如独立的看门狗驱动)。
时钟源可以关机使用在内部时钟寄存器的位(clk_ickcr)和外部时钟寄存器(clk_eckcr)。
如果时钟开关不因任何原因的工作,软件可以通过清除swbsy标志复位电流开关操作。
这将恢复clk_swr注册到其以前的内容(旧的系统时钟)。
注意:在清理swbsy标志具有复位时钟主开关的程序,应用程序必须等到后产生新的主时钟切换请求之前有一段至少两个时钟周期。
9.7周门控时钟(PCG)外周时钟门控(PCG)模式选择性地启用或禁用系统时钟(SYSCLK)连接到外围设备在运行或慢速模式的任何时间来优化功耗。
设备复位后,所有的外设时钟被禁用。
唯一的一点是在复位状态是默认启用pcken27因为它用于启动。
软件已被正确地写入关掉ROM Bootloader执行后的时钟。
您可以启用时钟的任何外围设置在clk_pckenrx周围门控时钟寄存器的相应pcken点。
●使周围,首先使在clk_pckenr相应的pcken点寄存器然后设置使点周围的外围控制寄存器。
●禁用适当的外围,先禁用在周边的适当位控制寄存器,然后停止相应的时钟。
注:蜂鸣器,RTC和液晶显示器是由不同的SYSCLK特定的时钟,使他们继续运行,即使时钟门控的外设寄存器是断言。
9.8时钟安全系统(CSS)9.8.1时钟安全系统对HSE时钟安全系统(CSS)监控HSE晶体时钟源故障时安全作为系统时钟。
如何分配变量到指定的地址举例:unsigned char temp_A@0x00; //定义无符号变量temp_A,强制其地址为0x00 unsigned char temp_B@0x100; //定义无符号变量temp_B,强制其地址为0x100@tiny unsigned char temp_C; //定义无符号变量temp_C,由编译器自动在地址小于0x100的RAM中为其分配一个地址@near unsigned char temp_D; //定义无符号变量temp_D,由编译器自动在地址大于0xFF 的RAM中为其分配一个地址另外也可以采用伪指令"pragma"将函数或者变量定义到指定的section中,例如:#pragma section [name] // 将下面定义的未初始化变量定义到.name section中Unsigned char data1;Unsigned int data2;……(任何需要定义在.name section中的变量)……#pragma section [] // 返回到正常的section.注意:pragma伪指令可以用来定位函数,初始化变量或者未初始化变量。
这三者用不同的括号区分。
(name):代码[name] :未初始化变量{name}:初始化变量如何在COSMIC C文件中使用汇编语言在COSMIC C文件中使用汇编语言常见的方法有如下两种:使用#asm …#endasm组合格式或_asm("…"); 单行格式。
举例1:unsigned char temp_A;Void func1(void){...#asmPUSH ALD A,(X)LD _temp_A,APOP A#endasm...}注:在C嵌汇编环境下使用全局变量,要在该全局变量名称前加下划线"_"。
举例2:Void func1(void){..._asm("rim");_asm("nop");...}如何观察RAM/FLASH/EEPROM的最终分配情况在Project->settings->linker选项页中,将Category选为Output,再勾选Generate Map File。
一时钟管理1 恢复相关的时钟寄存器到默认值void CLK_DeInit()2 启用或关闭外部高速振荡器(HSE)void CLK_HSECmd(FunctionState NewState)启用CLK_HSECmd(ENABLE)关闭CLK_HSECmd(DISABLE)3启用或关闭内部高速振荡器(HSI)void CLK_HSICmd(FunctionState NewState)启用CLK_HSICmd(ENABLE)关闭CLK_HSICmd(DISABLE)4启用或关闭内部低速振荡器(LSI)void CLK_LSICmd(FunctionState NewState)关闭CLK_LSICmd(DISABLE);启用CLK_LSICmd(ENABLE);5 启用或关闭时钟输出功能void CLK_CCOCmd(FunctionState NewState)关闭CLK_CCOCmd(DISABLE);启用CLK_CCOCmd(ENABLE);6 启用或关闭时钟切换void CLK_ClockSwitchCmd(FunctionState NewState)关闭CLK_ClockSwitchCmd(DISABLE);启用CLK_ClockSwitchCmd(ENABLE);7 启用或关闭快速唤醒void CLK_FastHaltWakeUpCmd(FunctionState NewState)关闭CLK_FastHaltWakeUpCmd(DISABLE);启用CLK_FastHaltWakeUpCmd(ENABLE);8 启用或关闭活跃停机模式下的电压调节器CLK_SlowActiveHaltWakeUpCmd(FunctionState NewState)关闭CLK_SlowActiveHaltWakeUpCmd(DISABLE);启用CLK_SlowActiveHaltWakeUpCmd(ENABLE);9 启用或关闭指定的时钟中断CLK_PeripheralClockConfig(CLK_IT_TypeDef CLK_IT, FunctionState NewState)参数1:I2C 参数2:ENABLECLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, ENABLE);参数1:SPI 参数2:ENABLECLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, ENABLE);参数1:UART1 参数2:ENABLECLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, ENABLE);参数1:UART2 参数2:ENABLECLK_PeripheralClockConfig(CLK_PERIPHERAL_UART2, ENABLE);参数1:UART3 参数2:ENABLECLK_PeripheralClockConfig(CLK_PERIPHERAL_UART3, ENABLE);参数1:TIMER1 参数2:ENABLECLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, ENABLE);参数1:TIMER2 参数2:ENABLECLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, ENABLE);参数1:TIMER3 参数2:ENABLECLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER3, ENABLE);参数1:TIMER4 参数2:ENABLECLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, ENABLE);参数1:TIMER5 参数2:ENABLECLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER5, ENABLE);参数1:TIMER6 参数2:ENABLECLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER6, ENABLE);参数1:AWU 参数2:ENABLECLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, ENABLE);参数1:ADC 参数2:ENABLECLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, ENABLE);参数1:CAN 参数2:ENABLECLK_PeripheralClockConfig(CLK_PERIPHERAL_CAN, ENABLE);10 系统时钟切换配置CLK_ClockSwitchConfig(CLK_SwitchMode_TypeDef CLK_SwitchMode, CLK_Source_TypeDef CLK_NewClock,FunctionState ITState, CLK_CurrentClockState_TypeDef CLK_CurrentClockState)参数1:手动切换参数2:内部高速振荡器参数3:关闭参数4:继续启用ErrorStatus clk_return_status;clk_return_status = CLK_ClockSwitchConfig(CLK_SWITCHMODE_MANUAL, CLK_SOURCE_HSI, ENABLE, CLK_CURRENTCLOCKSTATE_ENABLE);参数1:自动切换参数2:内部低速振荡器参数3:关闭参数4:关闭ErrorStatus clk_return_status;clk_return_status = CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_LSI, DISABLE, CLK_CURRENTCLOCKSTATE_DISABLE);参数1:自动切换参数2:外部高速振荡器参数3:关闭参数4:关闭ErrorStatus clk_return_status;clk_return_status = CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSE, DISABLE, CLK_CURRENTCLOCKSTATE_DISABLE);11 配置内部高速振荡器(HSI)的分频器void CLK_HSIPrescalerConfig(CLK_Prescaler_TypeDef HSIPrescaler)1分频CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);2分频CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV2);4分频CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV4);8分频CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8);12 配置时钟输出脚(CCO)的时钟源Void CLK_CCOConfig(CLK_Output_TypeDef CLK_CCO)参数1:内部高速振荡器/分频值CLK_CCOConfig(CLK_OUTPUT_HSI);参数1:内部低速振荡器CLK_CCOConfig(CLK_OUTPUT_LSI);参数1:外部高速振荡器CLK_CCOConfig(CLK_OUTPUT_HSE);参数1:CPU时钟1分频CLK_CCOConfig(CLK_OUTPUT_CPU);参数1:CPU时钟2分频CLK_CCOConfig(CLK_OUTPUT_CPUDIV2);参数1:CPU时钟4分频CLK_CCOConfig(CLK_OUTPUT_CPUDIV4);参数1:CPU时钟8分频CLK_CCOConfig(CLK_OUTPUT_CPUDIV8);参数1:CPU时钟16分频CLK_CCOConfig(CLK_OUTPUT_CPUDIV16);参数1:CPU时钟32分频CLK_CCOConfig(CLK_OUTPUT_CPUDIV32);参数1:CPU时钟64分频CLK_CCOConfig(CLK_OUTPUT_CPUDIV64);参数1:fHSI CLK_CCOConfig(CLK_OUTPUT_HSIRC);参数1:fMASTER CLK_CCOConfig(CLK_OUTPUT_MASTER);参数1:其它/fCPU CLK_CCOConfig(CLK_OUTPUT_OTHERS);13 启用或关闭指定的外设时钟Void CLK_PeripheralClockConfig(CLK_Peripheral_TypeDef CLK_Peripheral,FunctionalState NewState)参数1:时钟安全系统检测标志参数2:启用CLK_ITConfig(CLK_IT_CSSD, ENABLE);参数1:时钟切换中断标志参数2:关闭CLK_ITConfig(CLK_IT_SWIF, DISABLE);14 配置系统时钟分频器Void CLK_SYSCLKConfig(CLK_Prescaler_TypeDef CLK_Prescale)参数1:内部高速振荡器1分频CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV1);参数1:内部高速振荡器2分频CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV2);参数1:内部高速振荡器4分频CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV4);参数1:内部高速振荡器8分频CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV8);参数1:CPU时钟1分频CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);参数1:CPU时钟2分频CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV2);参数1:CPU时钟4分频CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV4);参数1:CPU时钟8分频CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV8);参数1:CPU时钟16分频CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV16);参数1:CPU时钟32分频CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV32);参数1:CPU时钟64分频CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV64);参数1:CPU时钟128分频CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV128);15 配置SWIM时钟分频器void CLK_SWIMConfig(CLK_SWIMDivider_TypeDef CLK_SWIMDivider)参数1:2分频CLK_SWIMConfig(CLK_SWIMDIVIDER_2);参数1:不分频CLK_SWIMConfig(CLK_SWIMDIVIDER_OTHER); 16配置CAN时钟频率Void CLK_CANConfig((CLK_CANDivider_TypeDef CLK_CANDivider)参数1:时钟频率=HSE/1 CLK_CANConfig(CLK_CANDIVIDER_1);参数1:时钟频率=HSE/2 CLK_CANConfig(CLK_CANDIVIDER_2);参数1:时钟频率=HSE/3 CLK_CANConfig(CLK_CANDIVIDER_3);参数1:时钟频率=HSE/4 CLK_CANConfig(CLK_CANDIVIDER_4);参数1:时钟频率=HSE/5 CLK_CANConfig(CLK_CANDIVIDER_5);参数1:时钟频率=HSE/6 CLK_CANConfig(CLK_CANDIVIDER_6);参数1:时钟频率=HSE/7 CLK_CANConfig(CLK_CANDIVIDER_7);参数1:时钟频率=HSE/8 CLK_CANConfig(CLK_CANDIVIDER_8);17 启用时钟安全系统Void CLK_ClockSercuritySystemEnable(void)18 清除时钟切换忙标志Void CLK_SYSCLKEmergencyClear(void)19 修正内部高速振荡器频率Void CLK_AdjustHSICalibrationValue(CLK_HSITrimValue_TypeDef CLK_HSITrimValue)参数1:校准值为0 CLK_AdjustHSICalibrationValue(CLK_HSITRIMVALUE_0);参数1:校准值为1 CLK_AdjustHSICalibrationValue(CLK_HSITRIMVALUE_1);参数1:校准值为2 CLK_AdjustHSICalibrationValue(CLK_HSITRIMVALUE_2);参数1:校准值为3 CLK_AdjustHSICalibrationValue(CLK_HSITRIMVALUE_3);参数1:校准值为4 CLK_AdjustHSICalibrationValue(CLK_HSITRIMVALUE_4);参数1:校准值为5 CLK_AdjustHSICalibrationValue(CLK_HSITRIMVALUE_5);参数1:校准值为6 CLK_AdjustHSICalibrationValue(CLK_HSITRIMVALUE_6);参数1:校准值为7 CLK_AdjustHSICalibrationValue(CLK_HSITRIMVALUE_7);20 获得系统时钟频率u32 CLK_GetClockFreq()21 获得系统时钟源CLK_GetSYSCLKSource(void)22 获得时钟标志状态CLK_GetFlagStatus(CLK_FLAG_TypeDef CLK_FLAG)参数1:内部低速振荡器就绪标志位CLK_GetFlagStatus(CLK_FLAG_LSIRDY);参数1:内部高速振荡器就绪标志位CLK_GetFlagStatus(CLK_FLAG_HSIRDY);参数1:外部高速振荡器就绪标志位CLK_GetFlagStatus(CLK_FLAG_HSERDY);参数1:时钟切换中断标志位CLK_GetFlagStatus(CLK_FLAG_SWIF);参数1:时钟切换忙标志位CCLK_GetFlagStatus(CLK_FLAG_SWBSY);参数1:时钟安全系统检测标志位CLK_GetFlagStatus(CLK_FLAG_CSSD);参数1:辅助振荡器开关状态位CLK_GetFlagStatus(CLK_FLAG_AUX);参数1:时钟输出忙标志位CLK_GetFlagStatus(CLK_FLAG_CCOBSY);参数1:时钟输出就绪标志位CLK_GetFlagStatus(CLK_FLAG_CCORDY);23 获得时钟中断标志状态CLK_GetITStatus(CLK_IT_TypeDef CLK_IT)参数1:时钟安全系统监测标志CLK_GetITStatus(CLK_IT_CSSD);参数1:时钟切换中断标志CLK_GetITStatus(CLK_IT_SWIF);24 清除中断标志状态Void CLK_ClearITPendingBit(CLK_IT_ TypeDef CLK_IT);参数1:时钟安全系统检测标志CLK_ClearITPendingBit(CLK_IT_CSSD);参数1:时钟切换终端标志CLK_ClearITPendingBit(CLK_IT_SWIF);。
课程设计内容与要求课程设计目的:1、巩固和加深对单片机原理知识的理解和运用。
2、进一步提高学生综合运用所学知识的能力。
3、培养学生综合分析问题、发现问题和解决问题的能力基本要求:1)显示时间和日期2)可设置多个闹钟3)可以调整时间扩展功能:1)按键复用共有六个按键,每个按键在不同模式下有不同的功能。
2)秒表功能进入秒表界面后,再按一下就秒表开始计时,再按一下秒表停止。
3)省电模式在每天00:00会自动进入省电模式,8个数码管会自动关闭,到5:00时会自动退出省电模式;也可以手动进入和退出省电模式。
4)查看/删除闹钟查看闹钟时间为五秒,五秒内按键无动作则自动退出。
器件介绍本次设计主要用到的硬件有:1、51实验板1块2、stm8s105c6开发板1快51实验板:主要用到实验板上的硬件有:1)两个四位一体的共阴LED数码管,电路图如下:2)两个74HC573的锁存芯片:3)8个独立按键,用了其中6个5)一个蜂鸣器:Stm8s105c6开发板:总共有48个引脚,本设计共用引脚20个引脚。
PB0~PB7和PE6~PE7用于数码管显示控制,PD0~PD5用于键盘输入,PD6、PE0、PE3用于LED指示灯控制。
PD7用于蜂鸣器控制。
设计方案本次设计采用51实验板和stm8s105c6开发板来完成,没有做实物。
显示电路采用8个共阳数码管显示;控制按键采用六个独立按键,每一个按键都有复用功能;闹钟提醒采用蜂鸣器;外加四个不同颜色的LED发光二极管,当进入相应功能模式时对应的指示灯就会亮。
1、键盘设计:在键盘电路中,使用的是6个独立键盘。
键盘在源程序中的功能安排如下:1)当扫描到有键盘按下时,设置相应标志位,然后延时一定时间消抖。
2)键盘的设置键盘表面如图:其中各键设置为:待机状态下是“设置闹钟”,在其他模式下是“递增功能”待机状态下是“调整时间”,在其他模式下是“递减功能”。
待机状态下是“秒表功能”,在其他模式下是“左移功能”。
STM8的时钟控制十分强大,用户可独立地管理各个时钟源,并将它们分配到CPU或各个外设。
主时钟和CPU时钟均带有预分频器。
具有安全可靠的无故障时钟切换机制,可在程序运行中将主时钟从一个时钟源切换到另一个时钟源。
本程序是更改内部2M或者外部8M 晶振,让led2闪灯,通过不同初始化,能观察出led的快慢,上代码:#include "stm8s.h"/*========内部高速时钟初始化========*/void init_hsiclk(void){CLK_DeInit(); //寄存器复位CLK_HSICmd(ENABLE); //内部高速时钟使能CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8); //内部8分频2M}/*==========外部高速时钟初始化=======*/void init_hseclk(void){CLK_HSECmd(ENABLE); //外部时钟开8MCLK_ClockSwitchCmd(ENABLE); //切换使能CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO ,CLK_SOURCE_HSE,DISABLE,C LK_CURRENTCLOCKSTATE_DISABLE); //切换配置CLK_ClockSecuritySystemEnable(); //开启时钟安全系统当外部晶振损坏,自动转为内部2M时钟,牛X}/*========GPIO初始化========*/void init_gpio(void){GPIO_DeInit(GPIOD); //PD口复位GPIO_Init(GPIOD , GPIO_PIN_2 , GPIO_MODE_OUT_PP_LOW_SLOW); // LED2初始化推挽输出}/*========延时函数===========*/void delay(u16 n){u16 i=0;while(n--){for(i=0;i<330;i++);}}/*========主函数===========*/void main(void){init_hsiclk(); //更换成init_hseclk();观察led闪灯速度init_gpio();while (1){GPIO_WriteReverse(GPIOD,GPIO_PIN_2);delay(1000);}}。
STM8的C语言编程(11)--切换时钟源
STM8单片机的时钟源非常丰富,芯片内部既有16MHZ的高速RC振荡器,也有128KHZ的低速RC振荡器,外部还可以接一个高速的晶体振荡器。
在系统运行过程中,可以根据需要,自由地切换。
单片机复位后,首先采用的是内部的高速RC振荡器,且分频系数为8,因此CPU的上电运行的时钟频率为2MHZ。
切换时钟源,主要涉及到的寄存器有:主时钟切换寄存器CLK_SWR和切换控制寄存器CLK_SWCR。
主时钟切换寄存器的复位值为0xe1,表示切换到内部的高速RC振荡器上。
当往该寄存器写入0xb4时,表示切换到外部的高速晶体振荡器上。
在实际切换过程中,应该先将切换控制寄存器中的SWEN(第1位)设置成1,然后设置CLK_SWCR的值,最后要判断切换控制寄存器中的SWIF标志是否切换成功。
下面的实验程序首先将主时钟源切换到外部的晶体振荡器上,振荡频率为8MH Z,然后,然后快速闪烁LED指示灯。
接着,将主时钟源又切换到内部的振荡器上,振荡频率为2MHZ,然后再慢速闪烁LED指示灯。
通过观察LED指示灯的闪烁频率,可以看到,同样的循环代码,由于主时钟源的改变的改变,闪烁频率和时间长短都发生了变化。
同样还是利用ST的开发工具,生成一个C语言程序的框架,然后修改其中的m ain.c,修改后的代码如下。
// 程序描述:通过切换CPU的主时钟源,来改变CPU的运行速度
#include "STM8S207C_S.h"
// 函数功能:延时函数
// 输入参数:ms -- 要延时的毫秒数,这里假设CPU的主频为2MHZ
// 输出参数:无
// 返回值:无
// 备注:无
void DelayMS(unsigned int ms)
{
unsigned char i;
while(ms != 0)
{
for(i=0;i<250;i++)
{
}
for(i=0;i<75;i++)
{
}
ms--;
}
}
main()
{
int i;
// 将PD3设置成推挽输出,以便推动LED
PD_DDR = 0x08;
PD_CR1 = 0x08;
PD_CR2 = 0x00;
// 启动外部高速晶体振荡器
CLK_ECKR = 0x01; // 允许外部高速振荡器工作
while((CLK_ECKR & 0x02) == 0x00); // 等待外部高速振荡器准备好
// 注意,复位后CPU的时钟源来自内部的RC振荡器
for(;;) // 进入无限循环
{
// 下面将CPU的时钟源切换到外部的高速晶体振荡器上,在开发板上的频率为8MHZ
// 通过发光二极管,可以看出,程序运行的速度确实明显提高了
CLK_SWCR = CLK_SWCR | 0x02; // SWEN <- 1
CLK_SWR = 0xB4; // 选择芯片外部的高速振荡器为主时钟
while((CLK_SWCR & 0x08) == 0); // 等待切换成功
CLK_SWCR = CLK_SWCR & 0xFD; // 清除切换标志
for(i=0;i<10;i++) // LED高速闪烁10次
{
PD_ODR = 0x08;
DelayMS(100);
PD_ODR = 0x00;
DelayMS(100);
}
// 下面将CPU的时钟源切换到内部的RC振荡器上,由于CLK_CKDIVR的复位值为0x18
// 所以16MHZ的RC振荡器要经过8分频后才作为主时钟,因此频率为2M HZ
// 通过发光二极管,可以看出,程序运行的速度确实明显下降了
CLK_SWCR = CLK_SWCR | 0x02; // SWEN <- 1
CLK_SWR = 0xE1; // 选择HSI为主时钟源
while((CLK_SWCR & 0x08) == 0); // 等待切换成功
CLK_SWCR = CLK_SWCR & 0xFD; // 清除切换标志
for(i=0;i<10;i++) // LED低速闪烁10次
{
PD_ODR = 0x08;
DelayMS(100);
PD_ODR = 0x00;
DelayMS(100);
}
}
}。