STM8的C语言编程(11)-- 切换时钟源

合集下载

STM8教程-第八章 STM8S207时钟编程及其实例

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

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语言中转换时间本文是店铺搜索整理的关于介绍了在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

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语言编程技巧

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 单片机)

闹钟+定时器主程序代码(STM8 单片机)
set_c=1;
}
}
//**********************校时函数****************************//
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语言编程基础与实践

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固件库(时钟部分)

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);。

STM8单片机课程设计报告(闹钟+定时器)

STM8单片机课程设计报告(闹钟+定时器)

课程设计内容与要求课程设计目的: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 CLK

STM8 CLK

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时钟系统详解

STM8时钟系统详解

STM8时钟系统详解就我个⼈看来,研究⼀块单⽚机,分为新⼿和⽼⼿两种模式,新⼈迫切的想先⽤,你得告诉他们怎么样最快的写出⼀个能跑起来的程序,告诉他们每⼀个外设的使⽤⽅式,⽼⼿不同,⽤的单⽚机多了外设对于他们⽽⾔没太多好奇的,中断,⽆⾮配置中断,连接中断,打开中断,中断模式,中断函数,定时器,⽆⾮打开时钟,设置分频率,设置值,等中断到来计数,千篇⼀律,没什么花样但是⽼⼿关注的是不同,这个和那个的差异是什么,这样就能避免惯性思维,不会⽤错,学起来差不多,都是对着⼿册读呗,但是学的⼼态不⼀样,更加的举重若轻闲话少叙,下⾯说说STM8的时钟系统STM8时钟系统看起来是这样的,有⼀个外部输⼊时钟OSC,⼀个外部输出时钟CCO,CCO可选输出内部的时钟五⼤块,CPU时钟,外设时钟,看门狗时钟,CAN总线时钟以及⾃动唤醒时钟CPU时钟的来源包括外部晶振,外部振荡器输⼊,内部⾼速振荡器输⼊,三种输⼊经过主时钟选择,再经过主时钟分频输出CPU以及内部窗⼝看门狗外设时钟和CPU时钟来源⼀样,并不经过主时钟分频,⼆⼗有⼀个外设使能控制,输⼊到各个外设,从这⾥我们可以判断,外设⾥⾯肯定还有分频器⾃动唤醒时钟直接来源于内部低速振荡器或者直接来源于外部始终,经过选项字节选择输⼊独⽴看门狗的时钟只可能来⾃于内部⾼速振荡器⽽CAN总线的时钟也是直接从晶振上获取的,同时内部低速振荡器是可以关掉的接下来我们看看寄存器控制内部低速振荡器和内部⾼速振荡器的开关以及开关状态标识,细节是什么,观察这个复位值,0x01,也就是说,复位的时候内部低速振荡器使能这代表着系统复位的时候肯定是使⽤内部低速振荡器的,不⽤看⽂档的其他部分这⼀点⼏乎就能确定外部时钟使能以及时钟状态⼋个位都是只读,标识当前我们选⽤的系统主时钟是谁,也就是框图中master clock switch的标识让你来选择哪⼀个做主时钟对时钟切换的过程进⾏监控时钟分频,⼀是内部⾼速时钟的分频,⼆是外部⾼速时钟的分频还有⼀个2,⽤来确定各个外设是否连接到时钟上,相当于外设使能,外设没有时钟是跑不起来的时钟安全系统配置时钟输出的配置,也就是刚才说的CCO的来源CAN总线的时钟分频剩下来的⼀个是HIS的始终修正,另⼀个是SWIM时钟的配置,都是不需要我们去关注的初始化时钟的流程包括1. 想要选择的主时钟使能,等待稳定2. 选择主时钟并进⾏切换,等待切换完成3. 选择系统时钟分频数4. 选择相应的外设时钟代码如下Clock.c#include "clock.h"void ClockInit(u8 clockSel){if(clockSel == HSE_CLOCK){//切换到外部始终之前,因为我使⽤的是24M时钟,所以需要修改插⼊flash等待时间 //此处讲解选项字节再补上//注意,下⾯这⼀段只能在使⽤16M⼀下时钟的时候有⽤CLK->ECKR |= 0x01;//使能外部晶振while(!(CLK->ECKR & 0x02));//等待时钟准备就绪CLK->SWCR &= ~((1<<2)|(1<<3));//时钟切换中断禁⽌并清除中断标志CLK->SWR = 0xB4;//时钟选择为HSEwhile(CLK->SWCR & 0x01);//等待时钟切换慢的结束CLK->SWCR |= 0x01;//使能时钟切换while(CLK->CMSR != 0xB4);//等待系统时钟切换到0xb4CLK->CKDIVR = 0x00;//设置时钟预分频,设置为fmaster = fclockCLK->CCOR &= ~(1<<0);//禁⽌CCO输出//此时,应当关闭内部始终CLK->ICKR &= ~0x01;}else if(clockSel == HSI_CLOCK){CLK->ICKR |= 0x01;//使能内部⾼速时钟while(!(CLK->ICKR | 0x02));//等待准备就绪CLK->SWCR &= ~((1<<2)|(1<<3));//时钟切换中断禁⽌并清除中断标志CLK->SWR = 0xE1;//时钟选择为HSIwhile(CLK->SWCR & 0x01);//等待时钟切换慢的结束CLK->SWCR |= 0x01;//使能时钟切换while(CLK->CMSR != 0xE1);//等待系统时钟切换到0xb4CLK->CKDIVR = 0x00;//设置时钟预分频,设置为fmaster = fclockCLK->CCOR &= ~(1<<0);//禁⽌CCO输出//此时,应当关闭外部时钟CLK->ECKR &= ~0x01;//使能外部晶振}}Clock.h#ifndef __CLOCK_H_#define __CLOCK_H_#include "stm8s.h"#define HSE_CLOCK 0#define HSI_CLOCK 1//初始化系统时钟,有两个选择,⼀个hse⼀个是hsivoid ClockInit(u8 clockSel);#endif另外,有⼀个时钟安全系统,这是⼀个什么机构也就是,当系统晶振由于外部⼲扰或者电路故障断开的时候,⾃动切换到内部⾼速时钟,这样能够保证实际的单⽚机电路系统不会失控,防⽌造成不良影响。

STM8的C语言编程

STM8的C语言编程

第 2 页 共 32 页
STM8 的 C 语言编程(1)--基本程序与启动代码分析
现在几乎所有的单片机都能用 C 语言编程了,采用 C 语言编程确实能带来很多好处,至少可读性比汇 编语言强多了。 在 STM8 的开发环境中,可以通过新建一个工程,自动地建立起一个 C 语言的框架,生成后开发环境 会自动生成 2 个 C 语言的程序,一个是 main.c,另一个是 stm8_interrupt_vector.c。main.c 中就是一 个空的 main()函数,如下所示:
献 给 迷 茫 中 的 STM8 初 学 者
本文内容整理与网络,适用于对单片机有一定的了解和熟悉的人. 希望你们能够快速上手并应用 STM8. 本文所有例程适用于 COSMIC 和 IAR 编译器,更多学习资料可以 登录我们的 官网 和 论坛 查找。 — QIYONG
第 1 页 共 32 页
目 录
第 1 页 共 32 页
{0x82, NonHandledInterrupt}, /* irq1 */ {0x82, NonHandledInterrupt}, /* irq2 */ {0x82, NonHandledInterrupt}, /* irq3 */ {0x82, NonHandledInterrupt}, /* irq4 */ {0x82, NonHandledInterrupt}, /* irq5 */ {0x82, NonHandledInterrupt}, /* irq6 */ {0x82, NonHandledInterrupt}, /* irq7 */ {0x82, NonHandledInterrupt}, /* irq8 */ {0x82, NonHandledInterrupt}, /* irq9 */ {0x82, NonHandledInterrupt}, /* irq10 */ {0x82, NonHandledInterrupt}, /* irq11 */ {0x82, NonHandledInterrupt}, /* irq12 */ {0x82, NonHandledInterrupt}, /* irq13 */ {0x82, NonHandledInterrupt}, /* irq14 */ {0x82, NonHandledInterrupt}, /* irq15 */ {0x82, NonHandledInterrupt}, /* irq16 */ {0x82, NonHandledInterrupt}, /* irq17 */ {0x82, NonHandledInterrupt}, /* irq18 */ {0x82, NonHandledInterrupt}, /* irq19 */ {0x82, NonHandledInterrupt}, /* irq20 */ {0x82, NonHandledInterrupt}, /* irq21 */ {0x82, NonHandledInterrupt}, /* irq22 */ {0x82, NonHandledInterrupt}, /* irq23 */ {0x82, NonHandledInterrupt}, /* irq24 */ {0x82, NonHandledInterrupt}, /* irq25 */ {0x82, NonHandledInterrupt}, /* irq26 */ {0x82, NonHandledInterrupt}, /* irq27 */ {0x82, NonHandledInterrupt}, /* irq28 */ {0x82, NonHandledInterrupt}, /* irq29 */ }; 在 stm8_interrupt_vector.c 中,除了定义了中断向量表外,还定义了空的中断服务程序,用于那些不用 的中断。当然在自动建立时,所有的中断服务都是空的,因此,除了第 1 个复位的向量外,其它都指 向那个空的中断服务函数。 生成框架后,就可以用 Build 菜单下的 Rebuild All 对项目进行编译和连接,生成所需的目标文件,然 后就可以加载到 STM8 的芯片中,这里由于 main()函数是一个空函数,因此没有任何实际的功能。不 过我们可以把这个框架对应的汇编代码反出来,看看 C 语言生成的代码,这样可以更深入地了解 C 语 言编程的特点。 生成的代码包括 4 个部分,如图 1、图 2、图 3、图 4 所示。

stm8s的c语言编程例程

stm8s的c语言编程例程

实例一:控制灯的亮灭(或者蜂鸣器响,只要连接相应端口就可以了):#include ""大24MHz高速外部时钟信号(HSE user-ext)高速内部RC振荡器(HSI)低速内部RC(LSI)各个时钟源可独立打开或者关闭,从而优化功耗。

HSE:高速外部时钟信号,由两个时钟源产生:HSE外部晶体/陶瓷谐振器;HSE用户外部有源时钟。

(为了最大限度的减少输出失真和减少启动失真的稳定时间,谐振器和负载电容应尽可能的靠近谐振器引脚。

负载电容值应根据所选的谐振器进行调整。

)外部1至24MHz的振荡器其优点在于能够产生精确的占空比为50%的主时钟信号。

为使系统快速启动,复位后时钟控制器自动使用HSI的8分频(HSI/8)做为主时钟。

其原因为HSI的稳定时间短,而8分频可保证系统在较差的V DD条件下安全启动。

时钟设置的目的到底是什么时钟设置肯定会出现中断貌似是这样的:运用合适的时钟配置可以使得功耗降低,有时候计数频率很大,需要很大的计数或者怎么样时,需要使用其他的时钟,即非默认的时钟!暂且这样解释!例题四:利用中断按键控制灯的亮灭。

#include ""断产生——在计数器更新时:计数器溢出。

Timer6的主要功能:位向上计数的自动重载计数器位可编程的与分配器(可在运行中修改),提供1,2,4,8,16,32,64,和128这8种分频比例。

3.用于和外部信号相连和定时器级联的同步电路4.中断产生:——在计数器更新时:计数器溢出——在触发信号输入时。

Timer4和timer6中断:该定时器的时钟源是内部时钟(Fmaster)。

该时钟源是直接连接到CK_PSC时钟的,CK_PSC时钟通过预分频器分频后给定时器提供CK_CNT时钟。

预分频器功能如下:1.预分频器是基于由一个3位寄存器(在TIMX_PSCR寄存器中)来控制的一个7位的计数器。

由于该控制寄存器是带缓冲的所以它可以在系统运行中被改变。

stm8C语言例程

stm8C语言例程

(1);名称:流水灯;描述 : ;先从上至下点亮所有的LED,再逐个点亮单个LED;***********************************************************/#include "stm8s105s4.h"#define uchar unsigned char#define uint unsigned intuchar table[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //存放点亮单个LED的代码void DelayMS(uint s) //延时子函数,约延时1ms{uint i;for(s;s>0;s--)for(i=0;i<500;i++);}void init(void) //stm8初始化函数{PB_DDR = 0xff;PB_CR1 = 0xff; // 将PB设置成推挽输出PB_CR2 = 0x00;CLK_SWR = 0xE1; //选部高速时钟作为主时钟CLK_CKDIVR = 0x08; //将CPU主频设置为2M(STM8默认的就是部高速时钟的八分频,即2MH,这里只是告诉大家设置方法)}void main(){uchar i;init();while (1) //无限循环{PB_ODR = 0xff; //先将所有的LED关闭for(i=0;i<9;i++) //一开始是所有的LED熄灭,再逐点亮所有LED,共九种状态{DelayMS(500); //延时500毫秒PB_ODR<<=1; //将PB_ODR向左移动一位,逐渐点亮所有LED }for(i=0;i<8;i++){PB_ODR=table[i]; //将table中的数依次赋给PB_ODR ,从上至下依次点亮LEDDelayMS(500);}}}中断向量:/* BASIC INTERRUPT VECTOR TABLE FOR STM8 devices* Copyright (c) 2007 STMicroelectronics*/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 */return;}extern void _stext(); /* startup routine */struct interrupt_vector const _vectab[] = {{0x82, (interrupt_handler_t)_stext}, /* reset */{0x82, NonHandledInterrupt}, /* trap */{0x82, NonHandledInterrupt}, /* irq0 */{0x82, NonHandledInterrupt}, /* irq1 */{0x82, NonHandledInterrupt}, /* irq2 */{0x82, NonHandledInterrupt}, /* irq3 */{0x82, NonHandledInterrupt}, /* irq4 */{0x82, NonHandledInterrupt}, /* irq5 */{0x82, NonHandledInterrupt}, /* irq6 */{0x82, NonHandledInterrupt}, /* irq7 */{0x82, NonHandledInterrupt}, /* irq8 */{0x82, NonHandledInterrupt}, /* irq9 */{0x82, NonHandledInterrupt}, /* irq10 */{0x82, NonHandledInterrupt}, /* irq11 */{0x82, NonHandledInterrupt}, /* irq12 */{0x82, NonHandledInterrupt}, /* irq13 */{0x82, NonHandledInterrupt}, /* irq14 */{0x82, NonHandledInterrupt}, /* irq15 */{0x82, NonHandledInterrupt}, /* irq16 */{0x82, NonHandledInterrupt}, /* irq17 */{0x82, NonHandledInterrupt}, /* irq18 */{0x82, NonHandledInterrupt}, /* irq19 */{0x82, NonHandledInterrupt}, /* irq20 */{0x82, NonHandledInterrupt}, /* irq21 */{0x82, NonHandledInterrupt}, /* irq22 */{0x82, NonHandledInterrupt}, /* irq23 */{0x82, NonHandledInterrupt}, /* irq24 */{0x82, NonHandledInterrupt}, /* irq25 */{0x82, NonHandledInterrupt}, /* irq26 */{0x82, NonHandledInterrupt}, /* irq27 */{0x82, NonHandledInterrupt}, /* irq28 */{0x82, NonHandledInterrupt}, /* irq29 */};(2):矩阵键盘、数码管:;描述 : 按下相应按键显示0到F中对应的数;***********************************************************/#include <stm8s105s4.h>#define uint unsigned int#define uchar unsigned charuchartable[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x8 6,0x8e};uchar num;void delay(uchar a){uchar i;for(a;a>0;a--)for(i=0;i<255;i++);}void init(void){PB_DDR=0XFF;PB_CR1=0XFF; // 将PB设置成推挽输出PC_DDR=0X1F;PC_CR1=0XFF; // 将PC设置成推挽输出PE_DDR=0x26;PE_CR1=0XFF; //将PE5,PE2,PE1为推挽输出,其他的设为上拉输入PD_DDR=0X80;PD_CR1=0X80; //将PD7设为推挽输出}/***这里的设置比LED的和数码管的设置要复杂,开始引入输入模式,矩阵键盘列为输出,行为输入,请参考协会开发板原理图及STM8转51PDF资料***//***扫描方式也可为行输出,列输入,读者可以自己尝试着修改***/uchar keys(void) //此子函数看起来很长,实则只有前面一截容,下面的“同理可得”{uchar temp;PE_ODR=0X26; //将列中的PD7置为低电平,列中的其他三个置为高电平PD_ODR=0x00;delay(40); //这里要说明一下,由于矩阵键盘第一列和AD键盘共用一个IO口//AD键盘的RC会影响IO口电平变化的时间,这里需要延时一段时间,让电容C放电完毕if((PE_IDR&0x40)==0) //如果第一列的第四行按键被按下,则进入if语句{delay(5); //延时一段时间,等待IO口电平稳定,即消抖if((PE_IDR&0x40)==0) //再次判断按键是否被按下,避免干扰{num=12; //如果第一列的第四行按键被按下,则令num=12,即数码管显示为Cwhile((PE_IDR&0x40)==0); //如果按键没有松开,则等待}}temp=PC_IDR&0xe0;if(temp!=0xe0){delay(5);temp=PC_IDR&0xe0;if(temp!=0xe0){switch(temp){case 0xc0:num=0; //如果temp的值为0xc0,则说明第1个按键被按下,下面的依次类推break;case 0xa0:num=4;break;case 0x60:num=8;break;}while((PC_IDR&0xe0)!=0xe0);}}PE_ODR=0X24;PD_ODR=0x80;if((PE_IDR&0x40)==0){num=13;delay(5);while((PE_IDR&0x40)==0);}temp=PC_IDR&0xe0;if(temp!=0xe0){delay(5);temp=PC_IDR&0xe0;if(temp!=0xe0){switch(temp){case 0xc0:num=1;break;case 0xa0:num=5;break;case 0x60:num=9;break;}while((PC_IDR&0xe0)!=0xe0);}}PE_ODR=0X22;PD_ODR=0x80;if((PE_IDR&0x40)==0){num=14;delay(5);while((PE_IDR&0x40)==0);}temp=PC_IDR&0xe0;if(temp!=0xe0){delay(5);temp=PC_IDR&0xe0;if(temp!=0xe0){switch(temp){case 0xc0:num=2;break;case 0xa0:num=6;break;case 0x60:num=10;break;}while((PC_IDR&0xe0)!=0xe0);}}PE_ODR=0X06;PD_ODR=0x80;if((PE_IDR&0x40)==0){num=15;delay(5);while((PE_IDR&0x40)==0);}temp=PC_IDR&0xe0;if(temp!=0xe0){delay(5);temp=PC_IDR&0xe0;if(temp!=0xe0){switch(temp){case 0xc0:num=3;break;case 0xa0:num=7;break;case 0x60:num=11;break;}while((PC_IDR&0xe0)!=0xe0);}}return num;}void main(){uchar n;init();while(1){n=keys(); //把函数keys()的返回值num赋给nPB_ODR=table[n];PC_ODR|=0x00; //选择第一个数码管}}中断向量:/* BASIC INTERRUPT VECTOR TABLE FOR STM8 devices* Copyright (c) 2007 STMicroelectronics*/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 */return;}extern void _stext(); /* startup routine */struct interrupt_vector const _vectab[] = {{0x82, (interrupt_handler_t)_stext}, /* reset */{0x82, NonHandledInterrupt}, /* trap */{0x82, NonHandledInterrupt}, /* irq0 */{0x82, NonHandledInterrupt}, /* irq1 */{0x82, NonHandledInterrupt}, /* irq2 */{0x82, NonHandledInterrupt}, /* irq3 */{0x82, NonHandledInterrupt}, /* irq4 */{0x82, NonHandledInterrupt}, /* irq5 */{0x82, NonHandledInterrupt}, /* irq6 */{0x82, NonHandledInterrupt}, /* irq7 */{0x82, NonHandledInterrupt}, /* irq8 */{0x82, NonHandledInterrupt}, /* irq9 */{0x82, NonHandledInterrupt}, /* irq10 */{0x82, NonHandledInterrupt}, /* irq11 */{0x82, NonHandledInterrupt}, /* irq12 */{0x82, NonHandledInterrupt}, /* irq13 */{0x82, NonHandledInterrupt}, /* irq14 */{0x82, NonHandledInterrupt}, /* irq15 */{0x82, NonHandledInterrupt}, /* irq16 */{0x82, NonHandledInterrupt}, /* irq17 */{0x82, NonHandledInterrupt}, /* irq18 */{0x82, NonHandledInterrupt}, /* irq19 */{0x82, NonHandledInterrupt}, /* irq20 */{0x82, NonHandledInterrupt}, /* irq21 */{0x82, NonHandledInterrupt}, /* irq22 */{0x82, NonHandledInterrupt}, /* irq23 */{0x82, NonHandledInterrupt}, /* irq24 */{0x82, NonHandledInterrupt}, /* irq25 */{0x82, NonHandledInterrupt}, /* irq26 */{0x82, NonHandledInterrupt}, /* irq27 */{0x82, NonHandledInterrupt}, /* irq28 */{0x82, NonHandledInterrupt}, /* irq29 */};(3);名称 :定时器的使用;描述 : 数码管显示0~F,利用定时器使得1秒变换一次;***********************************************************/#include <stm8s105s4.h>#define uint unsigned int#define uchar unsigned charuchartable[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x8 6,0x8e};uchar t;void init(void){PB_DDR=0XFF;PB_CR1=0XFF;PB_CR2=0X00;PC_DDR=0XFF;PC_CR1=0XFF;PC_CR2=0X00;TIM2_EGR=0X01; //允许产生更新事件TIM2_PSCR=0X01; //分频,使频率为1MHzTIM2_ARRH=0XC3; //更新后计数器的值TIM2_ARRL=0X50;TIM2_CR1=0X05; //允许定时器工作TIM2_IER=0X01; //允许更新中断_asm("rim"); //汇编语句,启动定时器//注意!使用定时器时要定义中断函数入口,详请打开main.c下面的stm8_interrupt_vector.c,请按照注释进行修改}void main(void){uchar i=0,j;init();while(1){PB_ODR=table[i];PC_ODR=0x02; //选择第二个数码管显示if(t==20) //这里设置50ms进入一次中断,t=20刚好为1秒{t=0; //t清零i++;if(i==16)i=0; //由于数组中只有16个数,所以i最大只能为15,否则显示会出现乱码现象}}}far interrupt void TIM2_UP_IRQHandler (void) //中断函数{TIM2_SR1 = 0x00; //进入中断时TIM2_SR1最低位会被硬件自动置一,进入中断后必须将其清零,否则无法再次产生中断t++; //进入中断后t自加1}/* BASIC INTERRUPT VECTOR TABLE FOR STM8 devices* Copyright (c) 2007 STMicroelectronics*/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*/return;}extern void _stext(); /* startup routine */extern far interrupt void TIM2_UP_IRQHandler (void); //使用定时器要加上这句话struct interrupt_vector const _vectab[] = {{0x82, (interrupt_handler_t)_stext}, /* reset */{0x82, NonHandledInterrupt}, /* trap */{0x82, NonHandledInterrupt}, /* irq0 */{0x82, NonHandledInterrupt}, /* irq1 */{0x82, NonHandledInterrupt}, /* irq2 */{0x82, NonHandledInterrupt}, /* irq3 */{0x82, NonHandledInterrupt}, /* irq4 */{0x82, NonHandledInterrupt}, /* irq5 */{0x82, NonHandledInterrupt}, /* irq6 */{0x82, NonHandledInterrupt}, /* irq7 */{0x82, NonHandledInterrupt}, /* irq8 */{0x82, NonHandledInterrupt}, /* irq9 */{0x82, NonHandledInterrupt}, /* irq10 */{0x82, NonHandledInterrupt}, /* irq11 */{0x82, NonHandledInterrupt}, /* irq12 */{0x82, TIM2_UP_IRQHandler}, /* irq13 */ //使用定时器要把这里的“NonHandledInterrupt”改为“TIM2_UP_IRQHandler”,即中断函数名{0x82, NonHandledInterrupt}, /* irq14 */{0x82, NonHandledInterrupt}, /* irq15 */{0x82, NonHandledInterrupt}, /* irq16 */{0x82, NonHandledInterrupt}, /* irq17 */{0x82, NonHandledInterrupt}, /* irq18 */{0x82, NonHandledInterrupt}, /* irq19 */{0x82, NonHandledInterrupt}, /* irq20 */{0x82, NonHandledInterrupt}, /* irq21 */{0x82, NonHandledInterrupt}, /* irq22 */{0x82, NonHandledInterrupt}, /* irq23 */{0x82, NonHandledInterrupt}, /* irq24 */{0x82, NonHandledInterrupt}, /* irq25 */{0x82, NonHandledInterrupt}, /* irq26 */{0x82, NonHandledInterrupt}, /* irq27 */{0x82, NonHandledInterrupt}, /* irq28 */{0x82, NonHandledInterrupt}, /* irq29 */};(3)(4):蜂鸣器:定时器方式;名称 :蜂鸣器;描述 : 利用定时器产生;***********************************************************/#include <stm8s105s4.h>#define uchar unsigned char_Bool beep PD_ODR:4;uchar t2,t3;void init(void){PD_DDR=0X10;PD_CR1=0X10; //连接蜂鸣器的IO口初始化PD_CR2=0X00;PD_ODR|=0x10;TIM2_EGR=0X01; //允许产生更新事件TIM2_PSCR=0X01; //分频,使频率为1MHzTIM2_ARRH=0XC3; //更新后计数器的值TIM2_ARRL=0X50; //定时50ms,用于控制发声时间TIM2_CR1=0X05; //允许定时器工作TIM2_IER=0X01; //允许更新中断TIM3_EGR=0X01; //允许产生更新事件TIM3_PSCR=0X01; //分频,使频率为1MHzTIM3_ARRH=0X00; //更新后计数器的值TIM3_ARRL=0Xfa; //这里定时0.25ms,用于产生所需的频率TIM3_CR1=0X05; //允许定时器工作TIM3_IER=0X01; //允许更新中断_asm("rim"); //汇编语句,启动定时器}void delay(uchar s){uchar i;for(s;s>0;s--)for(i=0;i<250;i++);}void main(){init();while(1){if(t3%2==0) //前一秒产生2KHz频率的声音beep=1; //定时器3时间0.25ms,一个周期0.5ms,故频率为2Kelsebeep=0;while(t2>=20&&t2<40) //第二秒产生1KHz频率声音 {if(t3%4<2)beep=1;elsebeep=0;}while(t2>=40&&t2<60) //第三秒产生500Hz频率声音 {if(t3%8<4)beep=1;elsebeep=0;}if(t2>=60)t2=0;if(t3==8)t3=0;}}far interrupt void TIM2_UP_IRQHandler (void) //定时器2中断函数{TIM2_SR1 = 0x00; //清零TIM2_SR1 t2++;}far interrupt void TIM3_UP_IRQHandler (void) //定时器三中断函数{TIM3_SR1 = 0x00; //清零TIM2_SR1 t3++;}中断向量:/* BASIC INTERRUPT VECTOR TABLE FOR STM8 devices* Copyright (c) 2007 STMicroelectronics*/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 */return;}extern void _stext(); /* startup routine */extern far interrupt void TIM2_UP_IRQHandler (void);extern far interrupt void TIM3_UP_IRQHandler (void);struct interrupt_vector const _vectab[] = {{0x82, (interrupt_handler_t)_stext}, /* reset */{0x82, NonHandledInterrupt}, /* trap */{0x82, NonHandledInterrupt}, /* irq0 */{0x82, NonHandledInterrupt}, /* irq1 */{0x82, NonHandledInterrupt}, /* irq2 */{0x82, NonHandledInterrupt}, /* irq3 */{0x82, NonHandledInterrupt}, /* irq4 */{0x82, NonHandledInterrupt}, /* irq5 */{0x82, NonHandledInterrupt}, /* irq6 */{0x82, NonHandledInterrupt}, /* irq7 */{0x82, NonHandledInterrupt}, /* irq8 */{0x82, NonHandledInterrupt}, /* irq9 */{0x82, NonHandledInterrupt}, /* irq10 */{0x82, NonHandledInterrupt}, /* irq11 */{0x82, NonHandledInterrupt}, /* irq12 */{0x82, TIM2_UP_IRQHandler}, /* irq13 */{0x82, NonHandledInterrupt}, /* irq14 */{0x82, TIM3_UP_IRQHandler}, /* irq15 */{0x82, NonHandledInterrupt}, /* irq16 */{0x82, NonHandledInterrupt}, /* irq17 */{0x82, NonHandledInterrupt}, /* irq18 */{0x82, NonHandledInterrupt}, /* irq19 */{0x82, NonHandledInterrupt}, /* irq20 */{0x82, NonHandledInterrupt}, /* irq21 */{0x82, NonHandledInterrupt}, /* irq22 */{0x82, NonHandledInterrupt}, /* irq23 */{0x82, NonHandledInterrupt}, /* irq24 */{0x82, NonHandledInterrupt}, /* irq25 */{0x82, NonHandledInterrupt}, /* irq26 */{0x82, NonHandledInterrupt}, /* irq27 */{0x82, NonHandledInterrupt}, /* irq28 */{0x82, NonHandledInterrupt}, /* irq29 */(5)蜂鸣器:stm8BEEP方式;名称:STM8自带蜂鸣器使用;描述 : ;注!此功能需用ST Link辅助设置,协会实验板无常工作,这里仅作参考;***********************************************************/#include <stm8s105s4.h>#define uchar unsigned charuchar t;void init(void) //初始化函数{CLK_ICKR|=0x08; // 打开芯片部的低速振荡器LSIwhile((CLK_ICKR&0x10)==0); // 等待振荡器稳定TIM2_EGR=0X01; //允许产生更新事件TIM2_PSCR=0X01; //分频,使频率为1MHzTIM2_ARRH=0XC3; //更新后计数器的值TIM2_ARRL=0X50;TIM2_CR1=0X05; //允许定时器工作TIM2_IER=0X01; //允许更新中断_asm("rim"); //汇编语句,启动定时器}void main(){uchar i;init();while(1){BEEP_CSR=0x26; //一秒2KHzwhile((t>=20)&&(t<40))BEEP_CSR=0x2e; //一秒1KHzwhile((t>=40)&&(t<60))BEEP_CSR=0x3e; //一秒500Hzwhile((t>=60)&&(t<80))BEEP_CSR&=0xdf; //一秒关闭if(t>=80)t=0;}}far interrupt void TIM2_UP_IRQHandler (void) //中断函数{TIM2_SR1 = 0x00;t++;}中断向量:/* BASIC INTERRUPT VECTOR TABLE FOR STM8 devices* Copyright (c) 2007 STMicroelectronics*/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 */return;}extern void _stext(); /* startup routine */extern far interrupt void TIM2_UP_IRQHandler (void);struct interrupt_vector const _vectab[] = {{0x82, (interrupt_handler_t)_stext}, /* reset */{0x82, NonHandledInterrupt}, /* trap */{0x82, NonHandledInterrupt}, /* irq0 */{0x82, NonHandledInterrupt}, /* irq1 */{0x82, NonHandledInterrupt}, /* irq2 */{0x82, NonHandledInterrupt}, /* irq3 */{0x82, NonHandledInterrupt}, /* irq4 */{0x82, NonHandledInterrupt}, /* irq5 */{0x82, NonHandledInterrupt}, /* irq6 */{0x82, NonHandledInterrupt}, /* irq7 */{0x82, NonHandledInterrupt}, /* irq8 */{0x82, NonHandledInterrupt}, /* irq9 */{0x82, NonHandledInterrupt}, /* irq10 */{0x82, NonHandledInterrupt}, /* irq11 */{0x82, NonHandledInterrupt}, /* irq12 */{0x82, TIM2_UP_IRQHandler}, /* irq13 */{0x82, NonHandledInterrupt}, /* irq14 */{0x82, NonHandledInterrupt}, /* irq15 */{0x82, NonHandledInterrupt}, /* irq16 */{0x82, NonHandledInterrupt}, /* irq17 */{0x82, NonHandledInterrupt}, /* irq18 */{0x82, NonHandledInterrupt}, /* irq19 */{0x82, NonHandledInterrupt}, /* irq20 */{0x82, NonHandledInterrupt}, /* irq21 */{0x82, NonHandledInterrupt}, /* irq22 */{0x82, NonHandledInterrupt}, /* irq23 */{0x82, NonHandledInterrupt}, /* irq24 */{0x82, NonHandledInterrupt}, /* irq25 */{0x82, NonHandledInterrupt}, /* irq26 */{0x82, NonHandledInterrupt}, /* irq27 */{0x82, NonHandledInterrupt}, /* irq28 */{0x82, NonHandledInterrupt}, /* irq29 */};/*Stm8BEEP:*//******************************************************************************** * file stm8s_beep.c* brief This file contains all the functions for the BEEP peripheral.* author STMicroelectronics - MCD Application Team* version V1.1.1* date 06/05/2009****************************************************************************** ** THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.** <h2><center>&copy; COPYRIGHT 2009 STMicroelectronics</center></h2>* image html logo.bmp****************************************************************************** *//* Includes ------------------------------------------------------------------*/ #include "stm8s_beep.h"/* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*//* Private functions ---------------------------------------------------------*//* Public functions ----------------------------------------------------------*//*** addtogroup BEEP_Public_Functions* {*//*** brief Deinitializes the BEEP peripheral registers to their default reset* values.* par Parameters:* None* retval None*/void BEEP_DeInit(void){BEEP->CSR = BEEP_CSR_RESET_VALUE;}/*** brief Initializes the BEEP function according to the specified parameters. * param[in] BEEP_Frequency Frequency selection.* can be one of the values of ref BEEP_Frequency_TypeDef.* retval None* par Required preconditions:* The LS RC calibration must be performed before calling this function.*/void BEEP_Init(BEEP_Frequency_TypeDef BEEP_Frequency){/* Check parameter */assert_param(IS_BEEP_FREQUENCY_OK(BEEP_Frequency));/* Set a default calibration value if no calibration is done */if ((BEEP->CSR & BEEP_CSR_BEEPDIV) == BEEP_CSR_BEEPDIV){BEEP->CSR &= (u8)(~BEEP_CSR_BEEPDIV); /* Clear bits */BEEP->CSR |= BEEP_CALIBRATION_DEFAULT;}/* Select the output frequency */BEEP->CSR &= (u8)(~BEEP_CSR_BEEPSEL);BEEP->CSR |= (u8)(BEEP_Frequency);}/*** brief Enable or disable the BEEP function.* param[in] NewState Indicates the new state of the BEEP function.* retval None* par Required preconditions:* Initialisation of BEEP and LS RC calibration must be done before.*/void BEEP_Cmd(FunctionalState NewState){if (NewState != DISABLE){/* Enable the BEEP peripheral */BEEP->CSR |= BEEP_CSR_BEEPEN;}else{/* Disable the BEEP peripheral */BEEP->CSR &= (u8)(~BEEP_CSR_BEEPEN);}}/*** brief Update CSR register with the measured LSI frequency.* par Note on the APR calculation:* A is the integer part of LSIFreqkHz/4 and x the decimal part.* x <= A/(1+2A) is equivalent to A >= x(1+2A) and also to 4A >= 4x(1+2A) [F1] * but we know that A + x = LSIFreqkHz/4 ==> 4x = LSIFreqkHz-4A* so [F1] can be written :* 4A >= (LSIFreqkHz-4A)(1+2A)* param[in] LSIFreqHz Low Speed RC frequency measured by timer (in Hz).* retval None* par Required preconditions:* - BEEP must be disabled to avoid unwanted interrupts.*/void BEEP_LSICalibrationConfig(u32 LSIFreqHz){u16 lsifreqkhz;u16 A;/* Check parameter */assert_param(IS_LSI_FREQUENCY_OK(LSIFreqHz));lsifreqkhz = (u16)(LSIFreqHz / 1000); /* Converts value in kHz *//* Calculation of BEEPER calibration value */BEEP->CSR &= (u8)(~BEEP_CSR_BEEPDIV); /* Clear bits */A = (u16)(lsifreqkhz >> 3U); /* Division by 8, keep integer part only */if ((8U * A) >= ((lsifreqkhz - (8U * A)) * (1U + (2U * A)))){BEEP->CSR |= (u8)(A - 2U);}else{BEEP->CSR |= (u8)(A - 1U);}/* Set the AWU MR bit to load the new value to the prescalers */AWU->CSR |= AWU_CSR_MR;}/*** }*//******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/ //st visual programmer 把Option Bytes 里//AFR7改为"Port D4 Alternate Function =Beep" ,否则没有声音void main ( void ){CLK_INIT();//设置外部时钟GPIO_INIT();//初始化IOFLASH_INIT();//初始化FLASH//PD4第二功能脚不是beep功能,就强制写成beepif(FLASH_ReadOptionByte(0x4803) != 0x807F){FLASH_ProgramOptionByte(0x4803,0x80);//将PD4的第二功能脚写成beepWWDG->CR = 0x80;//复位stm8}BEEP_LSICalibrationConfig(128000);BEEP_Init(BEEP_FREQUENCY_2KHZ);BEEP_Cmd(ENABLE);while(1){delay(1000);BEEP_Cmd(ENABLE);delay(1000);BEEP_Cmd(DISABLE);}};名称 :点阵;描述 : 循环显示I LOVE(心形) U;说明:由于这里将心形采用动态形式显示,使得显示数组较多,前三个一样的数组是为了延长“I”的显示时间,这样显示时间才协调后三个数组同理,中间的九个数组是使得心形有动态效果的,这里看起来很复杂,实则读者在这里只要掌握595的使用就可以很容易理解了,595的使用涉及到操作时序,需要看懂时序图,这是很重要的;***********************************************************/#include <stm8s105s4.h>#define uchar unsigned char#define uint unsigned int_Bool E PG_ODR:0; //注意这里开始引入位定义,相当于51里的sbit E=PG0;这是stm8的位定义形式_Bool RCLK PD_ODR:4;_Bool SRCLK PD_ODR:5;_Bool SER PD_ODR:6;uchar a,b;uchar table[14][8]={{0xff,0x83,0xef,0xef,0xef,0xef,0x83,0xff},{0xff,0x83,0xef,0xef,0xef,0xef,0x83,0xff},{0xff,0x83,0xef,0xef,0xef,0xef,0x83,0xff},{0xff,0xff,0xef,0xff,0xff,0xff,0xff,0xff},{0xff,0x93,0xef,0xff,0xff,0xff,0xff,0xff},{0xff,0x93,0x6d,0xff,0xff,0xff,0xff,0xff},{0xff,0x93,0x6d,0x7d,0xff,0xff,0xff,0xff},{0xff,0x93,0x6d,0x7d,0xbb,0xff,0xff,0xff},{0xff,0x93,0x6d,0x7d,0xbb,0xd7,0xff,0xff},{0xff,0x93,0x6d,0x7d,0xbb,0xd7,0xef,0xff},{0xff,0x93,0x6d,0x7d,0xbb,0xd7,0xef,0xff},{0xff,0xbb,0xbb,0xbb,0xbb,0xbb,0xc7,0xff},{0xff,0xbb,0xbb,0xbb,0xbb,0xbb,0xc7,0xff},{0xff,0xbb,0xbb,0xbb,0xbb,0xbb,0xc7,0xff}};//存放了显示的代码void delay(uint s){uchar i;for(s;s>0;s--)for(i=0;i<200;i++);}void init(void) //初始化函数,PC是用来控制138以驱动点阵的行{PG_DDR=0x01;PG_CR1=0x01;PG_CR2=0x00;PD_DDR=0x70;PD_CR1=0x70;PD_CR2=0x00;PC_DDR=0x0f;PC_CR1=0x0f;PC_CR2=0x00;}void display(void) //显示子函数{uchar m,n,p,q;E=1; //先关闭595(赋值时会影响显示效果)m=table[a][b]; //将要显示的table[a][b]赋值给mfor(q=0;q<8;q++){p=0;if((m&0x80)==0x80)p=1; //这三句的意思是如果m的最高位是1,则p=1,否则为0,就是把m最高位赋值给pSER=p; //把p输入595输入口SRCLK=0;RCLK=1;if(1);SRCLK=1;RCLK=0; //以上语句涉及 595的操作时序,请参考595芯片资料m=(m<<1);}E=0; //赋值完后打开595}void main(){uint i,j;init();while(1){for(a=0;a<14;a++) //有14个数组要传送{for(i=0;i<10;i++) //每个数组扫描10次,这样才能看清楚{for(b=0;b<8;b++) //每个数组有8个数{display();PC_ODR=b*2; //让138和595同步delay(2); //延时一会,以使显示清楚,延时不能太长,太长会看到闪烁,也不能太短,太短显示不清楚}}}delay(1000); //为了使得看起来是I LOVE U是一个周期,这里循环一次后,延时1秒}}中断向量:/* BASIC INTERRUPT VECTOR TABLE FOR STM8 devices* Copyright (c) 2007 STMicroelectronics*/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*/return;}extern void _stext(); /* startup routine */struct interrupt_vector const _vectab[] = {{0x82, (interrupt_handler_t)_stext}, /* reset */{0x82, NonHandledInterrupt}, /* trap */{0x82, NonHandledInterrupt}, /* irq0 */{0x82, NonHandledInterrupt}, /* irq1 */{0x82, NonHandledInterrupt}, /* irq2 */{0x82, NonHandledInterrupt}, /* irq3 */{0x82, NonHandledInterrupt}, /* irq4 */{0x82, NonHandledInterrupt}, /* irq5 */{0x82, NonHandledInterrupt}, /* irq6 */{0x82, NonHandledInterrupt}, /* irq7 */{0x82, NonHandledInterrupt}, /* irq8 */{0x82, NonHandledInterrupt}, /* irq9 */{0x82, NonHandledInterrupt}, /* irq10 */{0x82, NonHandledInterrupt}, /* irq11 */{0x82, NonHandledInterrupt}, /* irq12 */{0x82, NonHandledInterrupt}, /* irq13 */{0x82, NonHandledInterrupt}, /* irq14 */{0x82, NonHandledInterrupt}, /* irq15 */{0x82, NonHandledInterrupt}, /* irq16 */{0x82, NonHandledInterrupt}, /* irq17 */{0x82, NonHandledInterrupt}, /* irq18 */{0x82, NonHandledInterrupt}, /* irq19 */{0x82, NonHandledInterrupt}, /* irq20 */{0x82, NonHandledInterrupt}, /* irq21 */{0x82, NonHandledInterrupt}, /* irq22 */{0x82, NonHandledInterrupt}, /* irq23 */{0x82, NonHandledInterrupt}, /* irq24 */{0x82, NonHandledInterrupt}, /* irq25 */{0x82, NonHandledInterrupt}, /* irq26 */{0x82, NonHandledInterrupt}, /* irq27 */{0x82, NonHandledInterrupt}, /* irq28 */{0x82, NonHandledInterrupt}, /* irq29 */};(7):1602;名称 :1602液晶屏;描述 : 利用1602显示”today···,I am very happy,以及电协www.gdutelc.,welcome to LCD “;***********************************************************/#include <stm8s105s4.h>#define uchar unsigned char#define uint unsigned intuchar table0[]="today...";uchar table1[]="I am very happy!";uchar table2[]=".gdutelc.";uchar table3[]="Welcome to LCD";_Bool RS PA_ODR:4;_Bool RW PA_ODR:5;_Bool E PA_ODR:6;void write_(uchar );void delay(uint a){uchar i;for(a;a>0;a--)for(i=0;i<250;i++);}void init_stm8(void){PA_DDR=0x70;PA_CR1=0x70;PA_CR2=0x00;PB_DDR=0xff;PB_CR1=0xff;PB_CR2=0x00;}void init_1602(void){write_(0x38); //显示模式设置write_(0x0c); //开显示,不显示光标write_(0x06); //地址指针自动加一write_(0x01); //清屏write_(0x80+0x04); //指针指向第一行第四格RW=0; //因只涉及向1602写数据,不涉及读,写的时候RW引脚都为低电平,故将RW置低}//写指令子函数,涉及1602时序,请参考1602资料void write_(uchar ){RS=0;E=0;PB_ODR=;delay(2);E=1;E=0;}//写数据子函数,写指令和数据区别在RS电平的高低void write_data(uchar data){RS=1;E=0;。

STM8时钟配置笔记

STM8时钟配置笔记
void CLK_ClearITPendingBit(CLK_IT_TypeDef CLK_IT);
//-----------------------------------------------------------------------------------------
void CLK_DeInit(void);
参数:
NewState: 新的状态值
DISABLE 禁用
ENABLE 启用
返回值:无
//-----------------------------------------------------------------------------------------
DISABLE 禁用
ENABLE 启用
返回值:无
如果为了能快速从活跃停机模式中唤醒,进入活跃停机前则调用CLK_SlowActiveHaltWakeUpCmd(ENABLE);但功耗较大。
如果进入活跃停机模式前没有调用CLK_SlowActiveHaltWakeUpCmd(ENABLE);或调用了CLK_SlowActiveHaltWakeUpCmd(DISABLE);即默认的情况下
CLK_PERIPHERAL_UART2
CLK_PERIPHERAL_UART3
CLK_PERIPHERAL_TIMER6
CLK_PERIPHERAL_TIMER4
CLK_PERIPHERAL_TIMER5
CLK_PERIPHERAL_TIMER2
恢复相关的时钟寄存器到默认值
参数:无
返回值:无
注意:
当要复位CCOR寄存器时,如果CCOEN位被置位,则需要先复位CCOEN位,然后再复位CCOSEL位,复位CCOEN位和复位CCOSEL位的操作必须连续。

IAR for stm8平台 系统时钟设置实验程序

IAR for stm8平台 系统时钟设置实验程序

GPIOF
68 #defineຫໍສະໝຸດ LED2_PORTGPIOF
69 #define LED3_PORT
GPIOF
70
71 void LED_Init(void);
72 void LED1_Open(void);
73 void LED1_Close(void);
74 void LED1_Toggle(void);
102 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
103 *
104 * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
main.c * - Printed on 2020/11/13 12:42:41
1 //"sysclock.h" 头文件
2
3 #ifndef __SYSCLOCK_H
4 #define __SYSCLOCK_H
5
6 /* 包含系统头文件 */
7
8 /* 包含自定义头文件 */
9 #include "stm8.h"
35 #define FlagStatus bool
36 #define u8 uint8_t
37 #define u16 uint16_t
38 #define u32 uint32_t
39 #define EnableInterrupt __enable_interrupt()
40 #endif
41

单片机c 语言编程时钟及闹钟程序

单片机c 语言编程时钟及闹钟程序

一·功能1、计时功能,数码管显示数值从00:00:00--23:59:59循环替换,且周期时间与实际时间吻合。

2、定时闹钟功能,按下“定时”键后,可以设定所需要的任意时间,定时完成后,当到达设定时间后,蜂鸣器发声。

3、调整时间功能,根据此项功能可将时钟调至正确的时间。

4、查看定时功能,当设定完成后可以查看上次定时的时间,且能在此基础上进行重新定时。

二·按键说明设定键:按一次开始设定时间,并将设定过程显示在数码管上。

若未按此键,则其他按键无效。

设定过程中,再按一次此键,定时结束,数码管显示返回时钟。

当第一次按下设定键时,显示值为00:00:00,在此基础上调节定时时间。

第一次设定完成后,以后再按设定键,显示初值则为上次定时的时间。

确定键:在定时过程中按下此键,则保留当前设定的时间为定时时间。

若定时过程未按此键,定时无效。

向上键:按下此键,使得当前设定值在现有数值上加一,当加至满位时,当前值变为零。

向下键:按下此键,使得当前设定值在现有数值上减一,当减至零时,当前值变为满位减一。

向左键:按下此键,使得设定值移向左边一位,若已经在最左边,则移至最右边。

向右键:按下此键,使得设定值移向右边一位,若已经在最右边,则移至最左边。

三·具体操作演示(一)·定时及查看定时演示1.仿真开始。

如图:2、按键如图:3、按下设定键,开始设定时间,如图:4、如图所示,当前设定时位。

按向上键,使数值加一。

5、按下向右键,设定位移至分位。

6、按下向下键,使数字减一。

7、按确定键,确定当前设定的时间。

再按设定键,退出定时,开始时钟显示。

8、设定完成后按设定键,显示前次设定值,可在此基础上重新设定,也可直接再按设定键推出。

9、当时钟运行到设定时间时,蜂鸣器发声。

(二)·调整时间演示1、计时开始。

2、按照定时的方法开始设定时间,使其显示20:10:09。

3、调整到正确时间后,按下确定键不放,同时再按一下设定键,将目前设定值送入时钟,使其开始从设定值计时。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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);
}
}
}。

相关文档
最新文档