搜索
bottom↓
回复: 6

[原创]利用Compile Time Assert对STM32的一些配置作检查

[复制链接]

出0入0汤圆

发表于 2009-8-28 22:32:18 | 显示全部楼层 |阅读模式
最近做一个东西,要用到好几个Timer的相互Trigger的功能,而Timer的选择又要对Layout作妥协,代码改来改去的
Timer的Trigger关系也是调来调去的,一怒之下准备牺牲代码可阅读来跟上layout的步伐


STM32 的Timer之间可以用一Timer Internal Trigger联系起
各个Timer之间的联系可以用下表表示

(原文件名:ITR.jpg)
如果要用TIM4去触发TIM1,需要将TIM1的Internal Triger配置成ITR3
Timer改来改去容易出错,可以写成一张表,用的时候直接读这张表,由于是宏写的,不会影响运行时的效率,如下:
/*---------------------------------------------------------------------------------------------------------------------------------------*/
/* Just make parameter name shorter */
#define     _GetInternalTrigger(S,M) \
  (S == TIM1 ? (M == TIM5 ? TIM_TS_ITR0 : (M == TIM2 ? TIM_TS_ITR1 : (M == TIM3 ? TIM_TS_ITR2 :(M == TIM4 ? TIM_TS_ITR3 : (u16)-1)))): \
  (S == TIM8 ? (M == TIM1 ? TIM_TS_ITR0 : (M == TIM2 ? TIM_TS_ITR1 : (M == TIM4 ? TIM_TS_ITR2 :(M == TIM5 ? TIM_TS_ITR3 : (u16)-1)))): \
  (S == TIM2 ? (M == TIM1 ? TIM_TS_ITR0 : (M == TIM8 ? TIM_TS_ITR1 : (M == TIM3 ? TIM_TS_ITR2 :(M == TIM4 ? TIM_TS_ITR3 : (u16)-1)))): \
  (S == TIM3 ? (M == TIM1 ? TIM_TS_ITR0 : (M == TIM2 ? TIM_TS_ITR1 : (M == TIM5 ? TIM_TS_ITR2 :(M == TIM4 ? TIM_TS_ITR3 : (u16)-1)))): \
  (S == TIM4 ? (M == TIM1 ? TIM_TS_ITR0 : (M == TIM2 ? TIM_TS_ITR1 : (M == TIM3 ? TIM_TS_ITR2 :(M == TIM8 ? TIM_TS_ITR3 : (u16)-1)))): \
  (S == TIM5 ? (M == TIM2 ? TIM_TS_ITR0 : (M == TIM3 ? TIM_TS_ITR1 : (M == TIM4 ? TIM_TS_ITR2 :(M == TIM8 ? TIM_TS_ITR3 : (u16)-1)))): \
  (u16)-1))))))
    #define     GetInternalTrigger(SlaveTimer,MasterTimer)      _GetInternalTrigger(SlaveTimer,MasterTimer)
/*---------------------------------------------------------------------------------------------------------------------------------------*/

这样在要用的时候这样写就行了
/*-----------------------------------------------------------------------------------------------------*/
    TIM_ITRxExternalClockConfig(TIM1,GetInternalTrigger(TIM1,TIM4)); /* 用TIM4去触发TIM1 */
/*-----------------------------------------------------------------------------------------------------*/

不是每一种Timer的组合都会有这样触发方式,如果写错了需要能够报出这个错误
可以用一种叫做Compile Time Assert的方法
比如:
/*-----------------------------------------------------------------------------------------------------*/
    #define compile_assert(exp)   {extern char lxyppc_at_163_dot_com[(exp) ? 1:-1];}
/*-----------------------------------------------------------------------------------------------------*/

这里是利用了数组下标必需大于零作为compile check的条件,也可以写成别的形式

代码可以这样写
/*-----------------------------------------------------------------------------------------------------*/
    compile_assert((u16)GetInternalTrigger(TIM1,TIM4) != (u16)-1);
    TIM_ITRxExternalClockConfig(TIM1,GetInternalTrigger(TIM1,TIM4)); /* 用TIM4去触发TIM1,正确,编译通过 */
    compile_assert((u16)GetInternalTrigger(TIM2,TIM5) != (u16)-1);
    TIM_ITRxExternalClockConfig(TIM1,GetInternalTrigger(TIM2,TIM5)); /* 用TIM5去触发TIM2,错误,编译报错 */
/*-----------------------------------------------------------------------------------------------------*/

以上代码IAR 4.42 (32K限制版测试通过)
/**
   以上写法不一定能被所有编译器支持,本人对此产生的移植性问题不负任何责任
   P.S. 以上针对layout的牢骚纯属杜撰,只是为了引言一下:)
*/

出0入0汤圆

发表于 2009-8-29 08:13:47 | 显示全部楼层
#define compile_assert(exp)   {extern char lxyppc_at_163_dot_com[(exp) ? 1:-1];}
学到了。


个人稍微变动一点:
#define ve_assert(exp)  do{extern char __assert_data__[(exp) ? 1:-1];  (void)__assert_data__;  } while(0);

出0入0汤圆

发表于 2009-8-29 16:01:53 | 显示全部楼层
学到了,标记马克

出10入95汤圆

发表于 2009-9-23 22:48:59 | 显示全部楼层
楼主功夫不错

出0入0汤圆

发表于 2011-10-11 11:14:43 | 显示全部楼层
mark

出0入0汤圆

发表于 2014-7-19 15:59:08 | 显示全部楼层
大神,你太厉害了 ,我是从你那个步进电机驱动的例子看到你现在这个帖子的  厉害 我用keil编译也能通过,谢谢

出0入0汤圆

发表于 2014-7-20 03:14:31 来自手机 | 显示全部楼层
楼主,有关注过R系列带 timer9/10/11/12/13/14的级联吗?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-3 18:10

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表