历史上的今天
今天是:2025年04月13日(星期日)
2018年04月13日 | STM8S---TIM2产生PWM与TIM1定时器周期中断的时钟问题
2018-04-13 来源:eefocus
1 问题
在下面的测试程序中,如果将Init_CLK()函数中的 CLK_CKDIVR |= 0x08;去掉’|‘,则TIM1的功能实现跟预设定相同(10ms中断一次),但是TIM2的PWM频率就变高了;如果加上,则TIM2的功能实现跟预设定相同(产生1Hz的PWM),但是TIM1的周期就变长了;
尝试了很多测试,均无效(买的开发板和另一块gs自画板测试也都一样)。
2 尝试
因为STM8S默认使用内部16M高速RC振荡器,且8分频,则系统启动主时钟为2M。即CLK_CKDIVR = 0X18;,如果再去赋值CLK_CKDIVR |= 0X08; 则主时钟还是不变即0X18,但是如果赋值为CLK_CKDIVR = 0X08;,则主时钟就会改变,变为8M。但是TIM1和TIM2的Fmaster时钟应该是一样的,这样的赋值应该会对TIM1和TIM2都会产生影响,但是两个赋值不同,实现功能的配置正确,而总只有一个能按预设定工作,这到底是怎么回事呢?
发现设置为CLK_CKDIVR = 0X08时(8M),TIM1能按预设定工作,而TIM2的工作频率却明显快了,像是快了一倍,带着这个发现,我就将现在的TIM2的Fmaster时钟频率当做为TIM1的一倍,即16M,再去重新配置TIM2的寄存器,再编译、下载进单片机,居然和TIM1实现的功能相同了。这又到底是怎么回事呢?难道TIM2的Fmaster时钟总是TIM1的Fmaster时钟的一倍吗?又去尝试几种不同的CLK_CKDIVR(当然则TIM1的Fmaster频率不能超过8M)。
接下来测试了 CLK_CKDIVR = 0X10;(4M), CLK_CKDIVR = 0X18;(2M)均是如此。是不是猜想正确了,还是想不明白是怎么回事。看着STM8S的时钟树怎么也想不明白。
3 测试程序
/* MAIN.C file
function : TIM1定时器周期中断实现LED1周期为2S的亮灭;TIM2用PWM波实现同样的功能;
TIM1 10ms定时器周期中断;
TIM2_CH3 PD2 输出周期为1Hz的PWM;
problem :
(1) 在时钟初始化函数Init_CLK()里,|= 与=的问题,加上‘|’
与不加,TIM1和TIM2总有其中一个跟预期实现不一样。
*/
#include
_Bool PD2 @PD_ODR:2;
_Bool PC7 @PC_ODR:7;
#define LED1 PD2
#define LED2 PC7
void Init_CLK(void)
{
//当是'|='时,实际CLK = 2M
//当是' ='时,实际CLK = 8M
CLK_CKDIVR = 0X08;
}
void Init_GPIO(void)
{
/*LED/PWM 配置为推挽输出*/
PD_DDR |= 0X04; //PD2--PWM输出---连接LED1
PD_CR1 |= 0X04;
PD_CR2 &= 0XFD;
PC_DDR |= 0X80; //PC7---LED2;
PC_CR1 |= 0X80;
PC_CR2 &= 0X7F;
}
void Init_TIM1(void)
{
_asm("sim");
TIM1_IER = 0x00;
TIM1_CR1 = 0x00;
TIM1_EGR |= 0x01;
TIM1_PSCRH = 199/256; //2M系统时钟经预分频f=fck/(PSCR+1) TIM1 为16位分频器
TIM1_PSCRL = 199%256; //f=8M/(199+1)=40000Hz,每个计数周期1ms
TIM1_CNTRH = 0x00;
TIM1_CNTRL = 0x00;
TIM1_ARRH = 400/256; // 自动重载寄存器ARR=400
TIM1_ARRL = 400%256; // 每记数400次产生一次中断,即10ms
TIM1_CR1 |= 0x81;
TIM1_IER |= 0x01;
}
/*TIM1---8M TIM2---4M*/
void Init_TIM2(void)
{
//TIM2_IER = 0x00; //禁止各种中断
//TIM2_EGR |= 0X01; //如果要 新的 预分频值生效,必须产生更新事件
TIM2_CCMR3 |= 0X60; //设置定时器2三通道(PD2)输出比较三模式
TIM2_CCMR3 |= 0X08; //输出比较3预装载使能
TIM2_CCER2 |= 0x03; //通道3使能,低电平有效,配置为输出
//初始化时钟分频器为1,即计数器的时钟频率为Fmaster=8M/128=0.0625MHZ
TIM2_PSCR = 0X07;
//初始化自动装载寄存器,决定PWM 方波的频率,Fpwm=0.0625M/62500=1HZ
TIM2_ARRH = 62500/256;
TIM2_ARRL = 62500%256;
//初始化比较寄存器,决定PWM 方波的占空比:50%
TIM2_CCR3H = 31250/256;
TIM2_CCR3L = 31250%256;
//启动计数;更新中断失能
TIM2_CR1 = 0x01;
}
main()
{
Init_CLK();
Init_GPIO();
Init_TIM1();
Init_TIM2();
LED1 = 1;LED2 = 1;
_asm("rim");
while (1);
}
@far @interrupt void TIM1_UPD_OVF_TRG_BRK_IRQHandler(void)
{
static unsigned int i = 0;
TIM1_SR1 &=~(0x01);
++i;
if(100 == i){
LED2 = ~LED2;
i = 0;
}
}
史海拾趣
|
现在我只有vs2005. 我下载的windows embedded ce 6都在线安装的,并且安装不上。不知道什么原因。 我想用VisualStudio和platform builder来开发。 我应该安装哪些东西呢。步骤是什么?… 查看全部问答> |
|
一、课程介绍 嵌入式Linux驱动程序成为进来嵌入式开发的热点,因为驱动程序担负着将嵌入式系统越来越复杂的硬件运转起来的能力。而且Linux内核代码量极大,其中有60%以上代码属于驱动程序,掌握嵌入式Linux驱动程序开发技术,对嵌入式工程师的重 ...… 查看全部问答> |
|
客户要求我们的WinCE设备使用屏保,根据WinCE的帮助,添加了两条注册表项后,屏保可正常运行。 但是,在控制面板的\"密码\"项里设置了屏保密码后(必须先设置开机密码,才能设置屏保密码,二者是关联的,大家可看一下passwd.cpp) 但是,设置开机 ...… 查看全部问答> |
|
单片机是ATmage 128,我试过IAR,编译不了,哪位能帮忙看看这些后缀,是用的什么软件,WinAVR?还是别的什么? 下面是所有编译文件的抓图,… 查看全部问答> |
|
大侠们!!! 好好的帮我看看这个程序好吗? 之前的程序 https://bbs.eeworld.com.cn/forum ... 5521&fromuid=582339 (出处: 电子工程世界-论坛) 下面是我更改之后的程序!之前的闪烁消除了,就是对于定时器中断1里的这段程序 if ...… 查看全部问答> |




