找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2042|回复: 5
收起左侧

不知道为什么单片机测的频率不对啊 实际测18000 仿真1200左右

[复制链接]
ID:390998 发表于 2018-10-7 16:18 | 显示全部楼层 |阅读模式
各位大佬   小弟做了个测频率的东西  单片机测得的频率严重出错啊  可以告诉我为什么么
  1. //#include"reg52.h"                                                                             /* 调用头文件,单片机内部寄存器都定义在此,用的时候需要先调用 */
  2. #include"LCD1602.H"
  3. #include <NEW_8051.h>

  4. UINT8   CounterCnt;                                         /* 计数器次数 */
  5. UINT8   FreResultFlag;                                      /* 频率计计算结果标志 */

  6. /******************************** 引脚定义 **************************************
  7.                         单片机            NE555
  8.                           P35              OUT
  9. ********************************************************************************/

  10. /*******************************************************************************
  11. * 函  数  名      : Init_Timer
  12. * 描      述      : 初始化定时器T0,计数器T1.
  13. * 输      入      : 无.
  14. * 返      回      : 无.
  15. ********************************************************************************/
  16. void Init_Timer(void)
  17. {
  18.         TMOD |= 0x51;
  19.                                                                                                   /* T0工作在定时器模式1,16位定时器,T1工作在计数器模式 */                     
  20.          TH0 =        ( 65536 -50000 ) / 256;                                                      /* T0定时器初值,定时50ms */
  21.          TL0 =        ( 65536 -50000 ) % 256;

  22.          TH1 =   0;                                              /* T1从0开始计数 */
  23.     TL1 =   0;

  24.     ET0 =        1;                                                               /* 定时器T0中断打开 */
  25. //         ET1 =   1;                                              /* 定时器T1中断打开 */

  26.          EA        =        1;                                                                /* 总中断打开 */

  27. //    PT1 =   1;                                              /* 定义T1为高优先级 */

  28.     TR0 =        1;                                                               /* T0开关打开 */
  29.     TR1 =   1;                                              /* T1开关打开 */
  30. }

  31. /*******************************************************************************
  32. * 函  数  名      : Timer0
  33. * 描      述      : 中断程序,定时时间到后重新赋值开始定时,同时将LED的状态取反.
  34. * 输      入      : 无.
  35. * 返      回      : 无.
  36. ********************************************************************************/
  37. void Timer0(void) interrupt 1
  38. {
  39.         static UINT8 Temp;

  40.     TH0 =        ( 65536 -50000 ) / 256;                                                      /* 重新赋值 */
  41.          TL0 =        ( 65536 -50000 ) % 256;

  42.     Temp++;
  43.     if( Temp == 20 )                                        /* 大概一秒计算一次 */
  44.     {
  45.         Temp = 0;     
  46.                                                       
  47.         TR0  = 0;                                           /* 关闭定时器T0,T1 */
  48.         TR1  = 0;

  49.         FreResultFlag = 1;                                  /* 准备计算频率 */                                          
  50.     }   
  51. }

  52. /*******************************************************************************
  53. * 函  数  名      : Timer1
  54. * 描      述      : 计数器中断程序.
  55. * 输      入      : 无.
  56. * 返      回      : 无.
  57. ********************************************************************************/
  58. void Timer1(void) interrupt 3
  59. {
  60.          CounterCnt++;                                                                        /* 计算脉冲个数 */
  61. }

  62. /*******************************************************************************
  63. * 函  数  名      : DisplayFre
  64. * 描      述      : LCD1602显示频率.
  65. * 输      入      : UINT32 PulseCnt:
  66. *                   脉冲数.
  67. * 返      回      : 无.
  68. ********************************************************************************/
  69. void DisplayFre( UINT32 PulseCnt )
  70. {
  71.     UINT8 i;
  72.     UINT8 DisplayBuf[6];

  73.     for( i = 0; i < 5; i++ )                                /* 计算1-5位的每位数据 */
  74.     {
  75.         DisplayBuf[i] = PulseCnt % 10 + 0x30;               /* 转成成1602可以显示的数值 */
  76.         PulseCnt   =  PulseCnt / 10;
  77.     }
  78.     DisplayBuf[5] = PulseCnt + 0x30;                        /* 计算第6位数据 */

  79.     for( i = 5; i > 0; i-- )                                /* 处理高位为0时候的情况 */
  80.     {
  81.         if( DisplayBuf[ i ] == 0x30 )DisplayBuf[ i ] = 0x20;/* 检测到高位为 0,不显示高位,空格代替 */
  82.         else break;
  83.     }  

  84.     LCD1602_SetDisplayPosition( 7,2 );                      /* 设置显示位置 */

  85.     for( i = 5; i != 0xFF; i-- )
  86.     LCD1602_WriteData(DisplayBuf[i]);                       /* 显示频率计字符 */

  87. }

  88. /*******************************************************************************
  89. * 函  数  名      : main
  90. * 描      述      : 主程序.
  91. * 输      入      : 无.
  92. * 返      回      : 无.
  93. ********************************************************************************/
  94. void main(void)
  95. {
  96.     UINT32 FreNum;                                          /* 计算频率次数 */



  97.     Init_Timer();                                           /* 初始化定时器 */



  98.     LCD1602_Init();                                         /* 初始化LCD1602 */



  99.     LCD1602_SetDisplayPosition(0,1);                        /* 设置第一行显示位置 */
  100.     LCD1602_WriteString("FREQUENCY METER");                 /* 设置频率计字符 */
  101.     LCD1602_SetDisplayPosition(0,2);                        /* 设置第二行显示位置 */
  102.     LCD1602_WriteString("FRE:          Hz");                /* 设置FRE:   HZ字符 */

  103.      while(1)
  104.      {
  105.             if( FreResultFlag )                                 /* 计算频率 */
  106.         {
  107.             FreNum = ( CounterCnt * 65536 + TH1 * 256 + TL1);  /* 计算1秒后的脉冲个数 */

  108.             TH1    = 0;                                     /* 清计数次数 */
  109.             TL1    = 0;

  110.             FreResultFlag = 0;                              /* 清标志 */
  111. //            CounterCnt = 0;
  112.             TR1    = 1;
  113.             TR0    = 1;                                     /* 开定时器 */
  114.         }
  115.         DisplayFre( FreNum );   
  116.       }

  117. }
复制代码
回复

使用道具 举报

ID:401564 发表于 2018-10-7 23:09 | 显示全部楼层
C我不会,但如果你用的是STC的单片机,那你就得好好的看一下它的使用手册了,因为它很多的指令执行时间和传统的8051是不一样的,也就是所谓的1T,但它又不是完全的1T,乱得很!!!!!!!!
定时器也是一样的,有的是1T的有的是12T的

评分

参与人数 1黑币 +40 收起 理由
admin + 40 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:387733 发表于 2018-10-8 06:50 | 显示全部楼层
定时器时间常数计算是否正确?特别是计算定时器常熟的系统主频是否与实际使用的主频一致

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:390998 发表于 2018-10-8 15:21 来自手机 | 显示全部楼层
sxhwdz 发表于 2018-10-8 06:50
定时器时间常数计算是否正确?特别是计算定时器常熟的系统主频是否与实际使用的主频一致

一致啊  主频是指晶振频率么
回复

使用道具 举报

ID:406356 发表于 2018-10-8 20:29 | 显示全部楼层
看定时器计数器初值是否和所使用的晶振相对应,或者这些初值可以通过ISP烧录软件里的定时器生成器生成
回复

使用道具 举报

ID:406764 发表于 2018-10-8 21:55 | 显示全部楼层
定时器的初始值是否计算正确呢?在仿真的时候要把晶振改成你单片机的晶振
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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