STM8的C语言编程(11)-- 切换时钟源
STM8教程-第八章 STM8S207时钟编程及其实例

第八章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。
STM8 库函学习笔记之CLK

//-----------------------------------------------------------------------------------------
2 void CLK_HSECmd(FunctionalState NewState);
启用或禁用外部高速振荡器(HSE)
启用或禁用内部高速振荡器(HSI 16MHz)
参数: NewState: 新的状态值 DISABLE 禁用 ENABLE 启用
返回值:无
//-----------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------1 void CLK_DeInit(void);
1 / 10
STM8 库函数学习笔记之时钟树解析
2012-12.12
恢复相关的时钟寄存器到默认值
clkflaglsirdy内部低速振荡器就绪标志clkflaghsirdy内部高速振荡器就绪标志clkflaghserdy外部高速振荡器就绪标志clkflagswif时钟切换中断标志clkflagswbsy时钟切换忙标志clkflagcssd系统时钟安全检测标志clkflagaux辅助振荡器的开关状态如果辅助振荡器hsi8开并做为当前的主时钟源clkflagccobsy可配置的时钟输出忙用于指示所选的cco时钟源正处于切换状态clkflagccordy可配置的时钟输出就绪用于指示所选的cco时钟源正处稳定状态返回值
如何在C语言中转换时间

如何在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 返回。
STM8L中文参考手册_2

手动开关手动开关没有自动切换为直接的但它提供给用户的切换事件时间的精确控制。
参照图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晶体时钟源故障时安全作为系统时钟。
STM8单片机C语言编程技巧

如何分配变量到指定的地址举例: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。
闹钟+定时器主程序代码(STM8 单片机)

}
}
//**********************校时函数****************************//
void adjust_times(void)
{
if(ok==0)
{
display(days);
if(lr==0)ud=&A;
unsigned char days[8];//存放当前日期
unsigned char T1=100;//200x10ms=1s秒计算
unsigned char T2=0;//20x10ms=200ms
unsigned char c=0;//用于记录闹钟个数
unsigned char hour=8,minute,second;
unsigned char hour_[5],minute_[5],second_[5]={1,2,3,4,5};
unsigned char sec_time[8];
unsigned char clocks[5][8];//可存5个闹钟信息
unsigned char times[8];//存放当前时间
run=0;
sec1=0;
sec2=0;
esc=0;
}
}
//**********************闹钟设置****************************//
void set_clock(void)
{
unsigned char i,j;
display(times);
if(lr==0)ud=&G;//指针指向G
if(lr==1)ud=&H;
STM8单片机的C语言编程基础与实践

/* MAIN.C file * * Copyright (c) 2002-2005 STMicroelectronics */
main() { while (1); } 而在 stm8_interrupt_vector.c 中,就是声明了对应该芯片的中断向量,如下所示: /* * */ typedef void @far (*interrupt_handler_t)(void); struct interrupt_vector { unsigned char interrupt_instruction; interrupt_handler_t interrupt_handler; }; @far @interrupt void NonHandledInterrupt (void) { /* in order to detect unexpected events during development, it is recommended to set a breakpoint on the following instruction BASIC INTERRUPT VECTOR TABLE FOR STM8 devices Copyright (c) 2007 STMicroelectronics
STM8 的 C 语言编程(2)-- 变量空间的分配
采用 C 这样的高级语言,其实可以不用关心变量在存储器空间中是如何具体分配的。但如果了解如何 分配,对编程还是有好处的,尤其是在调试时。 例如下面的程序定义了全局变量数组 buffer 和一个局部变量 i,在 RAM 中如何分配的呢? /* MAIN.C file * * Copyright (c) 2002-2005 STMicroelectronics */ unsigned char buffer[10]; // 定义全局变量
stm8固件库(时钟部分)

一时钟管理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、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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);
}
}
}。