实在是没办法了 只有靠大家的力量了 高手一定要帮忙呀!! 单片机上的C程序

zhfxuyg   2009-4-8 15:45 楼主
功能是用单片机测频率,脉冲从P1.1口进去,P1.1和P1.0是连通的。
我连接的计算机的音频输出口,在没有输出的情况下有比较稳定的噪声频率输出,很小的频率。
我定义了一个30个元素的数组arrFreq,存放测的频率,发现里面有异常的数据,突然会冒出100多的值,一般都是三四十;TIME2用做测脉冲间隔时间,用捕获的方式,TIME0定时100ms计算频率一次。
另外:我100ms测频率的话,值有异常;但是200ms测一次的话,置就很正常,没异常数据。我觉得是100ms时间有点短,脉冲本来就少,大概100ms有2,3个的样子,所以误差比较大。
但是总觉得还是有问题,请大家帮帮忙吧!
频率=脉冲个数*1000000/TIME2测的时间





  1. #include
  2. #include

  3. #define unchar unsigned char
  4. #define unint unsigned int
  5. #define unlong unsigned long
  6. #define VALID   1
  7. #define INVALID 0

  8. unint preCounter , curCounter , deltaCounter , curCount ;
  9. unlong preTime , curTime , bufTime , deltaTime ;
  10. unint curFreq ;
  11. unchar t0 , TT2 ;
  12. bit FMFlag ;
  13. unchar ii , tt ;
  14. unchar arrFreq[30];

  15. void T0_Set () ;
  16. void T2_Set () ;
  17. void Init_MCU () ;
  18. void Frequency_Measure () ;
  19. void Time_Compute () ;

  20. void main ( void )
  21. {
  22.         Init_MCU () ;
  23.         T0_Set () ;
  24.         T2_Set () ;
  25.         while ( 1 )
  26.         {
  27.                 if ( FMFlag == 1 )
  28.                 {
  29.                         Frequency_Measure () ;
  30.                 }
  31.         }
  32. }

  33. //计算频率
  34. void Frequency_Measure ()
  35. {
  36.         deltaCounter = curCounter - preCounter ;
  37.         deltaTime = curTime - preTime ;       
  38.         curFreq = deltaCounter * 1000000 / deltaTime ;
  39.        
  40.         ii = tt % 60 ;
  41.         arrFreq[ii]=curFreq;
  42.         tt++;
  43.         preTime = curTime ;
  44.         preCounter = curCounter ;
  45.         FMFlag = 0 ;
  46. }

  47. void Init_MCU ()
  48. {
  49.         EA = VALID ;
  50.         t0 = 0 ;
  51.         curCounter = preCounter = 0 ;
  52.         RCAP2H = 0x00 ;
  53.         RCAP2L = 0x00 ;
  54.         TF2 = 0 ;
  55.         TT2 = 0 ;
  56.         ii=tt=0;
  57.         curFreq = 0 ;
  58.         FMFlag = 0 ;
  59. }
  60. //计时100ms
  61. void time0 () interrupt 1
  62. {       
  63.         t0++ ;
  64.         if ( t0 == 2 )
  65.         {       
  66.                 t0 = 0 ;
  67.                 FMFlag = 1 ;
  68.         }
  69.        
  70.         TH0 = 0x3C ;
  71.             TL0 = 0xB0 ;
  72. }

  73. //TF2溢出,TT2加1;EXF2置位,表示有脉冲,计数加1
  74. void time2 () interrupt 5
  75. {
  76.         if ( TF2 == 1 )
  77.         {       
  78.                 TT2++ ;
  79.                 TF2 = 0 ;
  80.         }
  81.        
  82.         if ( EXF2 == 1 )
  83.         {
  84.                 EXF2 = 0 ;
  85.                 curCounter++ ;       
  86.         }
  87.         Time_Compute () ;
  88. }
  89. //计算当前的时间
  90. void Time_Compute ()
  91. {
  92.         curTime = TT2 ;
  93.         curTime = curTime << 0x10 ;
  94.         bufTime = RCAP2H ;
  95.         bufTime = bufTime << 0x08 ;        
  96.         curTime = curTime + bufTime + RCAP2L ;       
  97. }

  98. //设置定时器T0
  99. void T0_Set ()
  100. {       
  101.         //T0中断 方式1工作
  102.         ET0 = VALID ;
  103.         TMOD = 0x01 ;
  104.         TCON = 0x00 ;
  105.         //初值装载 定时50ms
  106.         TH0=0x3C ;
  107.      TL0=0xB0 ;
  108.            
  109.         //启动定时 T0
  110.         TR0 = VALID ;
  111. }

  112. //设置定时器T2
  113. void T2_Set ()
  114. {
  115.         //T2中断 方式1工作       
  116.         ET2 = VALID ;
  117.         TH2 = 0x00 ;
  118.         TL2 = 0x00 ;
  119.         T2CON = 0x09;
  120.         //T2MOD = 0x00;
  121.        
  122.         //启动定时 T0
  123.         TR2 = VALID;
  124. }

回复评论 (13)

高手哪里
帮帮忙看看
点赞  2009-4-8 17:55
如果100ms只有几个脉冲,误差肯定大,改为测2个脉冲间有多少时间。
点赞  2009-4-8 20:39
可惜是低手……
点赞  2009-4-8 21:57
这么说不是我程序的问题了
现在200ms测一次算了 ,但是间隔就有点大了!
多谢帮忙!

看看还有朋友有什么意见么?
点赞  2009-4-9 14:07
测频率和速度等程序,一般有T法和M法,即一种是测一定时间内(如200ms)有多少脉冲,一种是测2个脉冲内有多少个基准时间(如10us)。
点赞  2009-4-11 09:37
引用: 引用 5 楼 schlafenhamster 的回复:
测频率和速度等程序,一般有T法和M法,即一种是测一定时间内(如200ms)有多少脉冲,一种是测2个脉冲内有多少个基准时间(如10us)。


我是一定时间内统计脉冲数量,然后计算的。像你所说的应该是T法。

但是我的疑问还存在,朋友对我的程序有什么看法么??哪里有不妥的地方,或者整个程序结构上有问题?
谢谢!
点赞  2009-4-11 23:39
ding
ding


点赞  2009-4-14 22:35
既然是要请别人看你的程序,还是把注释写详细一点吧。最好把你的电路图也附上。
点赞  2009-4-15 00:17
你這個頻率測週期求倒數較準確, 你可以試一下.
点赞  2009-4-16 14:33
T 算法和M算法,都是相对于时钟和所测频率来考量其算法的准度。
如果所算的频率与clk接近我建议调节clk的frequence.
点赞  2009-4-30 22:49
为什么不用中断/计数器呢?
点赞  2009-5-1 10:08
距离好远   只能帮顶
点赞  2009-5-11 19:35
楼主的理想状况是认为每个中断发生后,中断程序都会被调用,但实际上不是这样。所以你那些计数器不应该用==,而是>=。
点赞  2009-5-12 08:21
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复