3251|3

7815

帖子

56

TA的资源

裸片初长成(中级)

楼主
 

【PSoC4心得】这是吐槽.....关于温度传感器例程 [复制链接]

这是吐槽,的确,这些话我早就想说,但一直作为工程师似乎不该这样吐槽一些没什么建设性意义的东西,也就一直忍着。
      对我来说,我说过就算,但是还是希望相关人员看到了会有一些重视。因为,作为一种感概真的由来已久。不管是赛普拉斯,还是老牌大牌ST TI这些厂商,他们提供的例程,第三方程序库都好,真的是~~~
      难听点,上不了台面。

      你们用心点,我们会少受很多罪,节省很多时间。
      作为顾客,如果得到一些重视和尊敬,其实,对于卖方应该是很有意义的。

-------------------------------


      根据我要做的 温控箱,我首先选择了两个直接相关的外设来做。
      1.温度传感器;
      2.定时器 ——定时器基本是单片机居家必备。

     在例程里翻出了唯一一个PSoC4的温度传感器例程  ADC_SAR_Seq_DieTemp_PSoC401

      玩了几次以后,现在知道首先去看 cysch文件里的说明了。于是发现,它这个例程真是相当复杂。
      开始我只是以为它只是把 温度传感器 和 LCD 混在一起,就已经够复杂了——
      所谓复杂,就是牵扯了无关的因素。不知道有没人和我一样持一种态度。
   当我们想了解 温度传感器 或者其他任何一种外设时,我们都希望获得一个非常单一的操作例程。
      尽管从厂商针对开发板提供可以马上看到效果的动机来说,这也无可厚非。

      然而对于我们开发的人来说,说真的,其实从LCD上看到结果还是在debug时看到结果,个人真心认为区别不大。反而,对我来说,因为这个LCD,而且因为这个LCD,它还需要用PWM,反而增加了我们去学习单一外设的障碍。

      这个先放下,退一万步来说,即使真的是从厂商为开发板配套的立场出发,我仍然觉得例程里有个地方很别扭。那就是 我的天,Result[]这个数组,从名字和出现的位置来看,都应该是转换后的温度结果,可是见鬼,它居然是int类型!
      哦,刚才跑回去又看了看程序,说明一下,首先result[]数组存的不是我想象的那个 温度值的结果。
      它只是读出寄存器的结果。然后在主函数里放入LCD显示以前转换成温度值。
      然而我发现我果然没有冤枉它......

      在主函数里,它还是很万恶的用了32int去存储转换值。
  1. int32 temperature;
  2. temperature = DieTemp_CountsTo_Celsius(result[TEMP_CH]);
复制代码
我真的没有冤枉它......

      刚开始,我还对它抱有一丝希望,也许它只是略坑爹地把这个转换过程放在LCD显示的函数里。然而我找了半天,还是发现没有。
      也就是说,即使我现在去搞来一个LCD,然后插上底板,我还是不会看到我所期望的带个小数点的温度值,甚至我怀疑那个数值我能不能看懂都是个问题。
这是不是略微有点坑爹呢.......

      然后我决定,试一下读出这个temperature,看看到底是什么值。虽然现在停电,我也不知道现在具体多少度,但从接近蜡烛,数值从25上升到27,我觉得这个应该还是温度值没错,然后看了看转换函数,应该的确是温度值不错。不过,作为温度值居然没有小数点,这的确是略有点坑爹。
      当然再想一下,由于这个片内温度传感器本身就是利用晶体管be结的温度特性,所以本身就只有5度的精度,因此,如此说来,它这么干,似乎也是有点道理的。

      好吧,这个地方我们暂时原谅它。



   如果说上面都只是我这个人太过挑剔的话,那接下来这个就真的是比较坑爹了,因为这属于客观错误。 SAR_ADC的中断里,两个中断触发,我们会发现第二个中断条件始终是进不去的!!

  1. CY_ISR(ADC_SAR_SEQ_ISR_LOC)

  2. {

  3.     uint32 intr_status;

  4.     uint32 range_status;



  5.    

  6.     intr_status = ADC_SAR_SEQ_SAR_INTR_MASKED_REG;

  7.     if((intr_status & ADC_SAR_SEQ_EOS_MASK) != 0u)

  8.     {

  9.         /* Read range detect status */

  10.         range_status = ADC_SAR_SEQ_SAR_RANGE_INTR_MASKED_REG;

  11.         /* Verify that the conversion result met the condition Low_Limit <= Result < High_Limit  */

  12.         if((range_status & (uint32)(1ul << CH0_N)) != 0u)

  13.         {

  14.             /* Read conversion resoult */

  15.             result[CH0_N] = ADC_SAR_SEQ_GetResult16(CH0_N);

  16.             /* Set PWM compare from channel0 */

  17.             PWM_WriteCompare(result[CH0_N]);

  18.         }   

  19.         /* Clear range detect status */

  20.         ADC_SAR_SEQ_SAR_RANGE_INTR_REG = range_status;

  21.         dataReady |= ADC_SAR_SEQ_EOS_MASK;

  22. }   



  23.     /* Check for Injection End of Conversion */

  24.     if((intr_status & ADC_SAR_SEQ_INJ_EOC_MASK) != 0u)

  25.     {

  26.         result[TEMP_CH] = ADC_SAR_SEQ_GetResult16(TEMP_CH);

  27.         dataReady |= ADC_SAR_SEQ_INJ_EOC_MASK;

  28.     }   



  29.     /* Clear handled interrupt */

  30.     ADC_SAR_SEQ_SAR_INTR_REG = intr_status;

  31. }





  32. 这个中断里有两个标志位if检查,第一个是EOS_MASK 意思扫描结束中断;

  33. 第二个是INJ_EOC,是(温度传感器读取温度)转换结束中断;这个地方好像是记反了?
复制代码
      我在这两个条件判断里设置断点,我就发现了,第二个条件从来没有满足过。我还以为需要去理解一下这个外设,这可真是一个很复杂的玩意,pdf里说了一堆东西。但最后发现啥跟这个问题有关的都没有发现。
      还好看了一下寄存器手册,至少知道这些都什么意思。最后我突然猜测,不会是第二个中断根本就没有允许触发吧.......

      于是我在判断以前,读出了中断触发设置位,丫的,果然没有......于是我就在主函数设置完以后,在进入死循环等待以前直接设置这两个位,好家伙,中断终于进去了......


      接下来还要吐槽的地方,就是它的代码了。
      即使是现在我对它自动生成的代码的组织和编写方式还是相当的不爽,但是我仍然认为这是单片机开发环境的一个进步,它就像vc++这些图形界面PC程序一样先进,可以根据图形化的设置方式,自动生成所需代码,这的确是一个可以非常减轻开发者工作负担的事情。

       但是,说实话,它的代码真的是写的相当混乱,看起来很辛苦。当然,和很多半导体厂商,如st ti这些厂商提供的例程或者什么第三方程序库一样。都很混乱,典型的是 “搞单片机的人才会写出的恶心代码”。

       由于编程风格和思路本身是一件极具个人主观意识和习惯的事情,另外,毕竟它要考虑到很多其他我尚且没有意识到的因素。我只是做应用的,而他是提供底层库支持的,这是两种层次的编码。但是我不得不说,至少有几个地方,由于他选择的策略问题,使得这些生成的代码相当难以理解,这在很大程度上足以瓦解它自动生成代码,给上层应用开发者带来的好处。
        首先,比如每个外设的init函数。当我看到它的长度和大量的宏条件编译,就足以吓坏一大堆人。
        我们都很清楚,一个外设可能具有很多功能,需要初始化的地方很多,另外,使用的功能不同,它所操作的寄存器,操作的数值也是不一样的。但是,即使如此,它仍然没有必要把所有这些设置都挤在一个函数里。

      有一个很常见的,并且足以被绝大多数程序员接受的原则是,与其把一堆其实分属不同功能(设置)的代码通过条件编译也好,通过if条件分离也好 地硬挤在一个函数体里,产生一个一堆注释,一堆宏选择的巨无霸,那么情愿写成一个又一个名字明确,功能单一的函数。即使最后你不想在main函数里写那么多个功能很小的子函数,你仍然可以在这个init里一个一个函数调用,都好过这样。


[ 本帖最后由 辛昕 于 2013-10-31 00:29 编辑 ]
此帖出自单片机论坛

最新回复

楼主,你好。我经常关注你的评论,首先我对你的观点不完全赞同,但我也不会说你的观点是错的。就好像你评论代码的风格一样,每个人都有自己的风格和思维方式,或者是做事的出发点,你能够发出这个多的感慨证明你把源代码深入去读了,或者读懂了,发现了很多问题,又或者你读出来的味道刚好与作者相反。 ANYWAY,公共的源码是难免有这个问题的,有时候就好像我们读同事的源码一样,也会牢骚多多,但老板总是赞扬同事,关键是老板不看源码只看效果。  详情 回复 发表于 2013-10-31 12:07
点赞 关注
 

回复
举报

7815

帖子

56

TA的资源

裸片初长成(中级)

沙发
 
又看了看这个不很复杂的例程,好像就没什么说了。
上面说的略有点流水帐。
今晚村里经常断电,躲在咖啡厅里写程序,写这个文档。
今天白天收到邮件通知,还剩下16天,已经感觉这个项目很可能又要太监了,真是觉得非常尴尬。
不过今晚写的程序是另一个程序,和单片机无关,当然因为断电,网络不稳定,也没做多少。
而PSOC这个,写了这个文档基本也没时间做别的了,已经零点了,没办法,今晚先这样。

我曾经写过两封英文邮件发给cypress官方一个不知道什么职位的人。
但是收到的回复也只是一些公式化的回复,因此我已经懒得理会了。
之前也没有发这个帖子,因为觉得很像纯粹发牢骚。

但是今天想了想,还是写了这篇东西,也许会有琳子姐说的那个比较靠谱的看到了会比较有用。
即使没用,我也当对这些例程的一个总结。

不过不管如何,接下来——之前各种忙乱,实际上我是大概在一周以前才真正开始做这个东西。
然后前几天因为以上所述种种,老毛病犯了,要求太高,太过愤青,所以停了几天做其他事情。
但是想了想不管如何,在埋怨以前还是首先解决问题再说,不然还有什么资格埋怨呢?

额,又罗嗦了很多,不说了,发出去,回家里洗澡睡觉~~~
此帖出自单片机论坛
 
 

回复

775

帖子

0

TA的资源

纯净的硅(高级)

板凳
 
楼主,你好。我经常关注你的评论,首先我对你的观点不完全赞同,但我也不会说你的观点是错的。就好像你评论代码的风格一样,每个人都有自己的风格和思维方式,或者是做事的出发点,你能够发出这个多的感慨证明你把源代码深入去读了,或者读懂了,发现了很多问题,又或者你读出来的味道刚好与作者相反。

ANYWAY,公共的源码是难免有这个问题的,有时候就好像我们读同事的源码一样,也会牢骚多多,但老板总是赞扬同事,关键是老板不看源码只看效果。
此帖出自单片机论坛
 
 
 

回复

7815

帖子

56

TA的资源

裸片初长成(中级)

4
 

回复 板凳fsyicheng 的帖子

是啊是啊。
所以我现在对这个也没什么兴趣了~~~
现在再一次转移注意力,与其去关注它的长相,还不如关心怎么测试它,看看它的心怎么样......

反正又不是找老婆,只要蕙质兰心,长得丑一点,就丑一点吧.....
反正灯一关,封装到库里头,眼不见为净啊~~~~
此帖出自单片机论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表