STM8的初始化里面 while (CLK_GetSYSCLKSource() != CLK_SYSCLKSource_HSE)这个什么意思

STM8的初始化里面 while (CLK_GetSYSCLKSource() != CLK_SYSCLKSource_HSE)这个什么意思,第1张

    首先,你要明白STM8的驱动时钟可以采用外部晶振,也可采用STM8内部的RC振荡器,二者只能选其一。 三个语句中的HSI表明是采用内部RC振荡器。

    你先看STM8内部的时钟树结构:

    其中HSI RC 16MHz就是其内部含有的RC振荡器,是ST芯片在出厂前就经过校正的但有一定误差的振荡器。时钟经过HSIDIV[1:0]这个分频器,可以获得16MHz、8MHz、4MHz、2MHz的输出tHsiDIV,该输出经过Master Clock Switch(通过配置来选择外部晶振还是内部晶振)后,再分配到CPU时钟和外围设备时钟。

    因此,STM8可以运行的时钟频率最大可以达到16MHz,你也可以让它低于这个频率运行(有利于低功耗设计)。搞清楚了以上几点,可以知道第一句是配置STM8,让它知道用内部RC振荡器,不要用外部晶振,这样省了一个晶振的钱[成本降低了嘛:)],第二句是让内部振荡器的输出进行8分频,你也可以让它1分频、2分频、4分频,但不能3分频、5分频,因为它内部只设计了这几种分频,况且奇数分频很难实现,你学过数字电路就应该知道。然后第三句话你要看一下库函数的定义

CLK_Source_TypeDef   CLK_GetSYSCLKSource(void)

{

    return((CLK_Source_TypeDef)CLK->CMSR);

}

意思是返回寄存器CMSR的值,这个你就要参考一下《STM8S中文参考手册》了,里面搜索CMSR这个词,我的是在第54页,

看到了吗?它是表明时钟准备好了没有的状态标志,就像你去叫别人办事,别人要经过考虑,这就需要等待,同理,你在STM8S内部配置好了时钟后,内部需要产生一定的延迟,而且受各种状况的影响,比如外部供电电压变化、引脚干扰等,有可能导致配置时钟失败,这就要经过查询这个寄存器的值来看是否配置好时钟没有,如果这个寄存器不等于0,则配置成功,否则失败。第三句的while里的意思就是不断地取CMSR的值,看是否等于宏定义CLK_SOURCE_HSI(OXE1),如果相等了,则跳过循环,继续执行以后的语句。

这个倒没发现过,我现在用过两个型号的STM8,内部和外部晶振都试过,没发现你说的问题STM8用起来还可以,就是可参考的资料较少,官方的函数库很一般,仿真器有点小贵,而且仿真慢的像牛一样,仿真器的USB接口也有点问题,经常板子一重新上电就得重新插拔一下USB但从性价比来说,的确不错,不过似乎没有你说的那么便宜,我买的(零卖)STM8S105要4块多呢。

/

STM8S105 TIM2 TIM3输出PWM PD0 PD3 TIM3输出PWM,/#include "STM8S105Kh"

#include "STM8S105_CLOCKh"

typedef unsigned char u8;

typedef unsigned int u16;u16 value;

/

函数名 : void SystemInit(void)

功能描述: 系统初始化

函数说明: 系统全局初始化

/

void SystemInit(void)

{ SystemClock_Init();

CLK_PCKENR1 |= 0x60; //使能TIM2与TIM3与主频连接

PD_CR2 |= 0x80; //使能PD7口外部中断

}

/

函数名 : void main(void)

功能描述: 主函数

函数说明:

/

void GPIO_init(void)

{

PD_DDR = 0x1F; //配置PD端口的方向寄存器全输出

PD_CR1 = 0x1F; //设置PD为推挽输出

PB_DDR|= 0x04; //PB2输出

PB_CR1|= 0x04; //PB2推挽输出

PB_ODR|= 0x04; //开5V电源

}

void TIM2_init(void) //TIM2 CH1 工作于模式1

{

// TIM2_CCMR2= 0x60; // PWM 模式 1

TIM2_CCMR1= 0x60; // PWM 模式 1,TIM2 CH1

TIM2_CCER1= 0x03; // CC1配置为输出

//TIM2_CCER2= 0x03; // CC3使能

TIM2_ARRH = 0x03; // 配置PWM分辨率为10位,ARR=0x3FF

TIM2_ARRL = 0xFF; // PWM频率=8M/0x03FF=7820Hz

TIM2_CR1 |= 0x01; // 计数器使能,开始计数

}

void TIM3_init(void) //TIM3 CH1 ch2工作于模式2,1

{

TIM3_CCMR1= 0x70; //PWM模式2

TIM3_CCMR2= 0x60; // PWM 模式 1

TIM3_CCER1= 0x33; // CC1 CC2配置为输出,CH1 CH2

TIM3_ARRH = 0x03; // 配置PWM分辨率为10位,ARR=0x3FF

TIM3_ARRL = 0xFF; // PWM频率=8M/0x03FF=7820Hz

TIM3_CR1 = 0x01; // 计数器使能,开始计数

} void Run(void)

{ //TIM2_CCR2H = (unsigned char)(value>>8); // 更新CC2比较寄存器

//TIM2_CCR2L = (unsigned char)(value);

TIM2_CCR1=value;

//TIM2_CCR3=value;

TIM3_CCR2=value;

TIM3_CCR1=value; //注意每个通道都要设CCR

} void init_devices(void)

{

_asm("sim");

SystemInit();

GPIO_init();

TIM2_init();

TIM3_init();

_asm("rim");

} void main( void )

{

init_devices();

while(1)

Run();

} /

函数名 : @near @interrupt void TLI_IRQHandler (void)

功能描述: 中断服务程序

函数说明:

/

@near @interrupt void TLI_IRQHandler (void) {

PD_CR2 &= 0x7F; //关PD7外部中断

value+=50;

while(value>1000)

value=0; PD_CR2 |= 0x80; //使能PD7口外部中断

return;

}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/12188093.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存