找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 970|回复: 5
打印 上一主题 下一主题
收起左侧

请教使用STC8H1K08单片机芯片测频率问题

[复制链接]
跳转到指定楼层
楼主
使用STC8H1K08芯片,进行频率采集并显示在数码管上,被采集的为霍尔元件产生的方波信号,现在输出的信号无法正常显示在数码管上,各位大佬帮我看看哪里不对。频率范围0-300Hz,用示波器能正常显示方波,霍尔正常产生方波频率



代码
  1. #include <reg52.h>
  2. #include<intrins.h>
  3. sfr  P1M0 = 0x92; //P1口IO模式控制寄存器M0
  4. sfr  P1M1 = 0x91; //P1口IO模式控制寄存器M1
  5. sfr  P3M0 = 0xb2; //P3口IO模式控制寄存器M0
  6. sfr  P3M1 = 0xb1; //P3口IO模式控制寄存器M1
  7. sbit DIG1 = P3^5; //位选1
  8. sbit DIG2 = P3^6; //位选2
  9. sbit DIG3 = P3^7; //位选3

  10. bit flag1s = 0; //1s定时标志
  11. bit Dlflag = 0;        //开始计时标志位
  12. unsigned char T1RH = 0;  //T0重载值的高字节
  13. unsigned char T1RL = 0;  //T0重载值的低字节
  14. void  GetFrequency(); //获取方波脉冲函数
  15. void ConfigTimer1(unsigned int ms); //配置T1定时器中断
  16. unsigned char code LedChar[]={
  17.         0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
  18.         0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
  19.         };
  20. unsigned char LedBuff[3]={
  21.         0xc0, 0xc0, 0xc0
  22.         };
  23. /*500ms延时函数*/
  24. void Delay500ms()                //@24.000MHz
  25. {
  26.         unsigned char i, j, k;

  27.         _nop_();
  28.         _nop_();
  29.         i = 61;
  30.         j = 225;
  31.         k = 62;
  32.         do
  33.         {
  34.                 do
  35.                 {
  36.                         while (--k);
  37.                 } while (--j);
  38.         } while (--i);
  39. }
  40. /** 主函数 **/
  41. void main()
  42. {
  43.     P1M0 = 0x00; //配置P1口为双向IO
  44.         P1M1 = 0x00;
  45.         P3M0 |= 0x00; //配置P3.5 P3.7 P3.7为双向IO,其他为高阻输入
  46.         P3M1 &= 0x1f;

  47.         TMOD &= 0xf0; //清零T0的控制位
  48.     TMOD |= 0x05; //设置T0为计数器  工作模式1 用P3^4/T0进行脉冲计数
  49.     EA = 1;
  50.         ConfigTimer1(2); //2ms定时器1中断

  51.     while (1)
  52.     {
  53.             GetFrequency();
  54.             Delay500ms();
  55.     }
  56.         
  57. }
  58. void  GetFrequency()
  59. {
  60.     unsigned char th1,th2,tl; //用于TH0,TL0值的存放
  61.     unsigned int num,temp2;        //num保存脉冲数,temp2计算显示用
  62.         float temp = 0; //浮点数

  63.     flag1s = 0;
  64.         Dlflag = 1;
  65.         TH0 = 0; //清零TH0准备计数
  66.         TL0 = 0; //清零TL0准备计数
  67.         IT0 = 1; //设置T0低电平计数
  68.         ET0 = 1; //打开T0使能中断
  69.         TF1 = 1; //进入T1中断
  70.     TR0 = 1; //启动T0开始计数
  71.         while(!flag1s)//flag1s标记位
  72.         ET0 = 0; //关闭T0使能中断
  73.     TR0 = 0; //关闭T0
  74.         while(1)
  75.         {
  76.            th1 = TH0;        //读取TH0值
  77.            tl = TL0;        //读取TL0值
  78.            th2 = TH0;        //再次读取TH0值           
  79.            if(th1 == th2) //对比读取的2次TH0值,确保没TL0没进位后退出
  80.            {
  81.                      break;
  82.            }
  83.            
  84.         }
  85.         //关中断防止计算出错
  86.         EA = 0;
  87.         num = th1*256 + tl; //计算脉冲数
  88.         temp = num;

  89.         if(temp<1000)
  90.         {
  91.            temp2 = temp;
  92.            LedBuff[2] = LedChar[temp2%10];
  93.            LedBuff[1] = LedChar[temp2/10%10];
  94.            LedBuff[0] = LedChar[temp2/100%10];
  95.         }
  96.         else
  97.         {
  98.           temp = temp/10;
  99.           if(temp < 1000)
  100.           {
  101.                   temp2 = temp;
  102.                 LedBuff[2] = LedChar[temp2%10];
  103.             LedBuff[1] = LedChar[temp2/10%10];
  104.             LedBuff[0] = LedChar[temp2/100%10];
  105.                 LedBuff[0] &= 0x7f;
  106.           }
  107.           else
  108.           {
  109.                   temp2 = temp/10;
  110.                 LedBuff[2] = LedChar[temp2%10];
  111.             LedBuff[1] = LedChar[temp2/10%10];
  112.             LedBuff[0] = LedChar[temp2/100%10];
  113.                 LedBuff[1] &= 0x7f;
  114.           }
  115.         }
  116.         EA = 1;
  117.         
  118. }
  119. /* 配置并启动T1,ms-T0定时时间 */
  120. void ConfigTimer1(unsigned int ms)
  121. {
  122.     unsigned long tmp;  //临时变量
  123.    
  124.     tmp = 24000000 / 12;      //12T定时器
  125.     tmp = (tmp * ms) / 1000;  //计算所需的计数值
  126.     tmp = 65536 - tmp;        //计算定时器重载值
  127.     tmp = tmp;           //补偿中断响应延时造成的误差
  128.     T1RH = (unsigned char)(tmp>>8);  //定时器重载值拆分为高低字节
  129.     T1RL = (unsigned char)tmp;
  130.     TMOD &= 0x0f;   //清零T1的控制位
  131.     TMOD |= 0x10;   //配置T1为模式1
  132.     TH1 = T1RH;     //加载T0重载值
  133.     TL1 = T1RL;
  134.     ET1 = 1;        //使能T0中断
  135.     TR1 = 1;        //启动T0
  136. }
  137. /*数码管扫描*/
  138. void LedScan()
  139. {
  140.         static unsigned char i = 0;
  141.         
  142.         P1 = 0xff;
  143.         switch(i)
  144.         {
  145.           case 0:  DIG1 = 0; DIG2 = 1; DIG3 = 1; i++; P1 = LedBuff[0]; break;
  146.           case 1:  DIG1 = 1; DIG2 = 0; DIG3 = 1; i++; P1 = LedBuff[1]; break;
  147.           case 2:  DIG1 = 1; DIG2 = 1; DIG3 = 0; i=0; P1 = LedBuff[2]; break;
  148.           default: break;
  149.         }
  150. }
  151. /*定时器1中断*/
  152. void InterruptTimer1() interrupt 3
  153. {   
  154.         static unsigned int tc = 0;
  155.         TH1 = T1RH;
  156.         TL1 = T1RL;
  157.                                                                                                                                                                                                                
  158.         LedScan();
  159.         if(Dlflag)
  160.         {
  161.                    tc++;
  162.                 if(tc >= 500)
  163.                 {
  164.                    tc = 0;
  165.                    Dlflag = 0;
  166.                    flag1s = 1;
  167.                 }
  168.         }
  169. }
复制代码
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1130621 发表于 2024-12-10 22:58 | 只看该作者
  1. #include <reg52.h>
  2. #include<intrins.h>
  3. sfr  P1M0 = 0x92; //P1口IO模式控制寄存器M0
  4. sfr  P1M1 = 0x91; //P1口IO模式控制寄存器M1
  5. sfr  P3M0 = 0xb2; //P3口IO模式控制寄存器M0
  6. sfr  P3M1 = 0xb1; //P3口IO模式控制寄存器M1
  7. sbit DIG1 = P3^5; //位选1
  8. sbit DIG2 = P3^6; //位选2
  9. sbit DIG3 = P3^7; //位选3

  10. bit flag1s = 0; //1s定时标志
  11. bit Dlflag = 0;        //开始计时标志位
  12. unsigned char T1RH = 0;  //T0重载值的高字节
  13. unsigned char T1RL = 0;  //T0重载值的低字节
  14. void  GetFrequency(); //获取方波脉冲函数
  15. void ConfigTimer1(unsigned int ms); //配置T1定时器中断
  16. unsigned char code LedChar[]={
  17.         0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
  18.         0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
  19.         };
  20. unsigned char LedBuff[3]={
  21.         0xc0, 0xc0, 0xc0
  22.         };
  23. /*500ms延时函数*/
  24. void Delay500ms()                //@24.000MHz
  25. {
  26.         unsigned char i, j, k;

  27.         _nop_();
  28.         _nop_();
  29.         i = 61;
  30.         j = 225;
  31.         k = 62;
  32.         do
  33.         {
  34.                 do
  35.                 {
  36.                         while (--k);
  37.                 } while (--j);
  38.         } while (--i);
  39. }
  40. /** 主函数 **/
  41. void main()
  42. {
  43.     P1M0 = 0x00; //配置P1口为双向IO
  44.         P1M1 = 0x00;
  45.         P3M0 |= 0x00; //配置P3.5 P3.7 P3.7为双向IO,其他为高阻输入
  46.         P3M1 &= 0x1f;

  47.         TMOD &= 0xf0; //清零T0的控制位
  48.     TMOD |= 0x05; //设置T0为计数器  工作模式1 用P3^4/T0进行脉冲计数
  49.     EA = 1;
  50.         ConfigTimer1(2); //2ms定时器1中断

  51.     while (1)
  52.     {
  53.             GetFrequency();
  54.             Delay500ms();
  55.     }
  56.        
  57. }
  58. void  GetFrequency()
  59. {
  60.     unsigned char th1,th2,tl; //用于TH0,TL0值的存放
  61.     unsigned int num,temp2;        //num保存脉冲数,temp2计算显示用
  62.         float temp = 0; //浮点数

  63.     flag1s = 0;
  64.         Dlflag = 1;
  65.         TH0 = 0; //清零TH0准备计数
  66.         TL0 = 0; //清零TL0准备计数
  67.         IT0 = 1; //设置T0低电平计数
  68.         ET0 = 1; //打开T0使能中断
  69.         TF1 = 1; //进入T1中断
  70.     TR0 = 1; //启动T0开始计数
  71.         while(!flag1s)//flag1s标记位
  72.         ET0 = 0; //关闭T0使能中断
  73.     TR0 = 0; //关闭T0
  74.         while(1)
  75.         {
  76.            th1 = TH0;        //读取TH0值
  77.            tl = TL0;        //读取TL0值
  78.            th2 = TH0;        //再次读取TH0值          
  79.            if(th1 == th2) //对比读取的2次TH0值,确保没TL0没进位后退出
  80.            {
  81.                      break;
  82.            }
  83.           
  84.         }
  85.         //关中断防止计算出错
  86.         EA = 0;
  87.         num = th1*256 + tl; //计算脉冲数
  88.         temp = num;

  89.         if(temp<1000)
  90.         {
  91.            temp2 = temp;
  92.            LedBuff[2] = LedChar[temp2%10];
  93.            LedBuff[1] = LedChar[temp2/10%10];
  94.            LedBuff[0] = LedChar[temp2/100%10];
  95.         }
  96.         else
  97.         {
  98.           temp = temp/10;
  99.           if(temp < 1000)
  100.           {
  101.                   temp2 = temp;
  102.                 LedBuff[2] = LedChar[temp2%10];
  103.             LedBuff[1] = LedChar[temp2/10%10];
  104.             LedBuff[0] = LedChar[temp2/100%10];
  105.                 LedBuff[0] &= 0x7f;
  106.           }
  107.           else
  108.           {
  109.                   temp2 = temp/10;
  110.                 LedBuff[2] = LedChar[temp2%10];
  111.             LedBuff[1] = LedChar[temp2/10%10];
  112.             LedBuff[0] = LedChar[temp2/100%10];
  113.                 LedBuff[1] &= 0x7f;
  114.           }
  115.         }
  116.         EA = 1;
  117.        
  118. }
  119. /* 配置并启动T1,ms-T0定时时间 */
  120. void ConfigTimer1(unsigned int ms)
  121. {
  122.     unsigned long tmp;  //临时变量
  123.    
  124.     tmp = 24000000 / 12;      //12T定时器
  125.     tmp = (tmp * ms) / 1000;  //计算所需的计数值
  126.     tmp = 65536 - tmp;        //计算定时器重载值
  127.     tmp = tmp;           //补偿中断响应延时造成的误差
  128.     T1RH = (unsigned char)(tmp>>8);  //定时器重载值拆分为高低字节
  129.     T1RL = (unsigned char)tmp;
  130.     TMOD &= 0x0f;   //清零T1的控制位
  131.     TMOD |= 0x10;   //配置T1为模式1
  132.     TH1 = T1RH;     //加载T0重载值
  133.     TL1 = T1RL;
  134.     ET1 = 1;        //使能T0中断
  135.     TR1 = 1;        //启动T0
  136. }
  137. /*数码管扫描*/
  138. void LedScan()
  139. {
  140.         static unsigned char i = 0;
  141.        
  142.         P1 = 0xff;
  143.         switch(i)
  144.         {
  145.           case 0:  DIG1 = 0; DIG2 = 1; DIG3 = 1; i++; P1 = LedBuff[0]; break;
  146.           case 1:  DIG1 = 1; DIG2 = 0; DIG3 = 1; i++; P1 = LedBuff[1]; break;
  147.           case 2:  DIG1 = 1; DIG2 = 1; DIG3 = 0; i=0; P1 = LedBuff[2]; break;
  148.           default: break;
  149.         }
  150. }
  151. /*定时器1中断*/
  152. void InterruptTimer1() interrupt 3
  153. {   
  154.         static unsigned int tc = 0;
  155.         TH1 = T1RH;
  156.         TL1 = T1RL;
  157.                                                                                                                                                                                                               
  158.         LedScan();
  159.         if(Dlflag)
  160.         {
  161.                    tc++;
  162.                 if(tc >= 500)
  163.                 {
  164.                    tc = 0;
  165.                    Dlflag = 0;
  166.                    flag1s = 1;
  167.                 }
  168.         }
  169. }
复制代码
回复

使用道具 举报

板凳
ID:1133081 发表于 2024-12-11 11:09 | 只看该作者
给你一个成熟的频率表电路和程序参考,结构简单,也可以用于STC8H1K08-20单片机
数显频率表程序.rar (22.12 KB, 下载次数: 0)





回复

使用道具 举报

地板
ID:161164 发表于 2024-12-12 15:49 | 只看该作者
47行或了个寂
但没关系,P35~P37也配置为推挽模式

什么叫"无法正常显示在数码管上"?
回复

使用道具 举报

5#
ID:1130621 发表于 2024-12-12 22:40 | 只看该作者

就是,显示出来的是正常的频率,是乱跳的数字,
回复

使用道具 举报

6#
ID:161164 发表于 2024-12-13 09:46 | 只看该作者
眼小自然萌 发表于 2024-12-12 22:40
就是,显示出来的是正常的频率,是乱跳的数字,

看代码
定时器1定时1ms
定时器0计数模式
定时器1累计5秒后计算定时器0的计数
你打开了定时器0的中断但又没有中断函数
有没有可能五秒内定时器0溢出了
结果程序跑飞了?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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