我用Timer的Input Capture功能的时候,发现怎么也测不到方波的周期。
但是独立写一个测试程序是没有问题的,感到很奇怪。
于是看我所用的FWLib版本,是1.0的原始版,2007年的,最新的版本是08年9月份的。
于是备份代码,然后换新的FWLib,问题依然存在。
因为我用Timer2用了2个用途,一个是测频率,一个是测周期。
测频率是外部触发做时钟,测周期用的是Input Capture功能。
后来分析发现是“TIM_InternalClockConfig”的问题,无法从“TIM_ETRClockMode2Config”设置的环境中恢复回来。
而小Demo做测试时候,Reset后寄存器的默认状态就是内部CLK计数的,所以不存在问题。
继续Trace进去,看看到底怎么缺斤短两了?
TIM_InternalClockConfig是负责转换到内部CLK做时钟计数之用:
void TIM_InternalClockConfig(TIM_TypeDef* TIMx)
{
/* Disable slave mode to clock the prescaler directly with the internal clock */
TIMx->SMCR &= SMCR_SMS_Mask;
}
非常Easy,只有一句话,SMCR_SMS_Mask的定义是:
#define SMCR_SMS_Mask ((u16)0xFFF0)
新版本的FWLib是0xFFF8
再看TIM_ETRClockMode2Config中有调用TIM_ETRConfig来设置外部触发,而TIM_ETRConfig对SMCR寄存器的修改如下:
void TIM_ETRConfig(..........)
{
u32 tmpsmcr = 0;
tmpsmcr = TIMx->SMCR;
/* Set the Prescaler, the Filter value and the Polarity */
tmpsmcr &= SMCR_ETR_Mask;
tmpsmcr |= TIM_ExtTRGPrescaler | TIM_ExtTRGPolarity | (u16)((u16)ExtTRGFilter << 8);
TIMx->SMCR = (u16)tmpsmcr;
}
SMCR_ETR_Mask是个非常重点的Mask,找它的define去:
#define SMCR_ETR_Mask ((u16)0x00F7)
问题找到了,就是那个太Easy的函数干活缺斤少两造成的。
正在全面把Lib从1.0移植到2.03
现在编译通过了,功能能否通过,明天先做下简单测试。
移植完成后,再交给测试人员专门做一次全面测试。
这些东东更本用不着库!太"EASY"了。
人家ST公司已经声明了,使用他们的库出的任何问题他们都不负任何责任。
用ST的库,是因为我们想站在巨人肩膀上,而不是其它
总体而言,ST的代码比较严谨
出现一些小的问题,但对FWLib而言是瑕不掩瑜的
比如从1.0到2.0的跳跃,把TIMx和TIM1合并,就是一个很好的进步。
工程师应该用更多的精力在自己的应用,而不是片子的寄存器。
无语了
我所知道的信息是:
1、ST有一个Team在maintain这个Library
2、FWLib有完整的文档(至少我自己的Prj没有做到这样的文档)
3、ST的Library中有很多值得我们学习的方法,基于其他芯片开发时候也用得上
请问LZ,没看懂要怎么改啊。
请问LZ,究竟是哪里错了呢?
#define SMCR_SMS_Mask ((u16)0xFFF0)
是这句要改吗?改成什么呢?请给具体答案。
不修改FWLib也有个解决方案
就是每次修改Timer设置的时候,都调用一次TIM_DeInit()让Timer处于原始状态,则此问题不会出现。
嗯,我的再次明确一点
凡是操作STM32的外设前,强烈要求De_Init()一次。这样可以减少很多奇怪的错误,因为读也可能改变外设寄存器。
st官方论坛的很多老外都这样建议。
有点怀念ATmel,不知道它什么时候出cortex核,现在忙着搞avr32,都不理这个了。
关于“STM32的FWLib潜在问题”与楼主商榷
楼主也认为“TIM_InternalClockConfig是负责转换到内部CLK做时钟计数之用”,那么这个函数除了修改TIMx->SMCR的SMS位之外,不能再做其他事情了,否则就会产生副作用。
例如在希望用外部触发同时使用内部时钟,你如果修改了这个函数,就无法在设置了外部触发后再选择内部时钟了。
寄存器太多也不是好事
就像linux,很灵活,但并不是每个人都玩的好,也并不符合每个人的需求,所以用windows的人更多。STM32傻瓜化才能打败51