找回密码
 立即注册
楼主: jellyfish

Jellyfish从89C51到AI8051学习贴

[复制链接]
  • 打卡等级:常住居民I
  • 打卡总天数:72
  • 最近打卡:2026-03-31 00:08:41

2

主题

16

回帖

260

积分

中级会员

积分
260
发表于 2026-2-17 17:26:21 | 显示全部楼层

image.png

Jellyfish从89C51到AI8051学习贴第十七天!

今天继续学习《8051U深度入门到32位51大型实战教学视频》第十五集 定时器用作计数器

0x01 学习重点

  1. 练习1:CT计数器

    image.png

  2. 配置各种寄存器

0x02 学习心得

  • 定时器4有隐藏寄存器

    定时器 4 有两个隐藏的寄存器 RL_T4H 和 RL_T4L。RL_T4H 与 T4H 共有同一个地址,RL_T4L 与 T4L共有同一个地址。当 T4R=0 即定时器/计数器 4 被禁止工作时,对 T4L 写入的内容会同时写入 RL_T4L,对T4H 写入的内容也会同时写入 RL_T4H。当 T4R=1 即定时器/计数器 4 被允许工作时,对 T4L 写入内容,实际上不是写入当前寄存器 T4L 中,而是写入隐藏的寄存器 RL_T4L 中,对 T4H 写入内容,实际上也不是写入当前寄存器 T4H 中,而是写入隐藏的寄存器 RL_T4H,这样可以巧妙地实现 16 位重装载定时器。当读 T4H和 T4L 的内容时,所读的内容就是 T4H 和 T4L 的内容,而不是 RL_T4H 和 RL_T4L 的内容。

    想要实现初始起点赋值,需要先T4R=0,然后对T4H、T4L进行赋值。

  • 通过双缓存逻辑timesinterval 作为 static 变量来缓存旧值,只有当数据变化时才重新计算 Disp_Buf“变更触发”。极大减轻了 CPU 负担,避免了每 100ms 都在重复执行耗时的除法运算。

  • 32位AI8051U十分强大16位除法比减法还要快!

    测试结果:
    除法 10次 消耗 T3 计数值: 72
    减法 10次 消耗 T3 计数值: 135
    
    // 1. 准备:初始化 T3 为 16 位定时器模式,不分频,不中断
    T3R = 0; T3_CT = 0; 
    T3H = 0; T3L = 0; 
    T3R = 1; // 开始数数
    void Test_Performance(){
        u16 start_count, end_count, i;
        volatile u16 test_val = 12345; // 使用 volatile 防止被编译器优化掉
        u8 cnt;
        // --- 测试 A:除法逻辑 ---
        start_count = (T3H << 8) | T3L;
        for (i = 0; i < 10; i++) { // 跑 1000 次足够看出差异
            Disp_Buf[7] = (u8)(test_val % 10);
            Disp_Buf[6] = (u8)((test_val / 10) % 10);
            Disp_Buf[5] = (u8)((test_val / 100) % 10);
            Disp_Buf[4] = (u8)((test_val / 1000) % 10);
        }
        end_count = (T3H << 8) | T3L;
        printf_usb("除法 10次 消耗 T3 计数值: %u\r\n", end_count - start_count);
    
        // 2. 重置计数器
        T3H = 0; T3L = 0;
    
        // --- 测试 B:循环减法逻辑 ---
        start_count = (T3H << 8) | T3L;
        for (i = 0; i < 10; i++) {
            u16 temp = test_val;
            cnt = 0; while(temp >= 1000) { temp -= 1000; cnt++; } Disp_Buf[4] = cnt;
            cnt = 0; while(temp >= 100)  { temp -= 100;  cnt++; } Disp_Buf[5] = cnt;
            cnt = 0; while(temp >= 10)   { temp -= 10;   cnt++; } Disp_Buf[6] = cnt;
            Disp_Buf[7] = (u8)temp;
        }
        end_count = (T3H << 8) | T3L;
        printf_usb("减法 10次 消耗 T3 计数值: %u\r\n", end_count - start_count);
    }
    
  • 配置启用定时器4用作计数器

    P00=0;		//矩阵键盘配置P00为低电平,这样可以给P06提供下降沿
    T4_CT=1;    //配置定时器3为计数器模式
    T4L=0xff;   //配置底八位
    T4H=0xff;   //配置高八位  默认16位自动重载
    T4R=1;      //配置定时器3开始计数
    ET4=1;      //开启定时器3中断
    T4IF=0;     //清除中断请求标志位
    EA=1;		//开启总中断
    
    //中断函数
    void Timer4_Isr(void) interrupt 20
    {    
      PulseTotal++;
      PulseInterval_Show=PulseInterval_100ms;
      PulseInterval_100ms=0;
    }
    
    //定时器调度结构体
    TASK_COMPONENTS Task_Comps[]=
    {
    //状态  计数  周期  函数
     {0, 1,     1,         Seg_Task},     
     {0, 100,    100,        ClacTimes}, 
    };
    
    //字段定义
    u16 PulseTotal=0;           //累计按下
    u16 PulseInterval_100ms=0;  //间隔数量(单位100ms)
    u16 PulseInterval_Show=0;   //显示的间隔数量
    
    
    // --- 计算当前数量 100ms 调度任务逻辑 ---
    void ClacTimes(){
      static u16 interval=0xffff,times=0xffff;
      u16 val=0;
      //每100ms给计数器加一;
      PulseInterval_100ms++;
    //    printf_usb("PulseInterval_Show=%d",PulseInterval_Show);
    
      if (times!=PulseTotal)
      {
          times=PulseTotal;
          Disp_Buf[3] = (u8)(times%10);
          Disp_Buf[2] = (u8)((times/10)%10);
          Disp_Buf[1] = (u8)((times/100)%10);
          Disp_Buf[0] = (u8)((times/1000)%10);
    
      }
      if (interval != PulseInterval_Show)
      {   
          interval=PulseInterval_Show;
          for ()
          printf_usb("开始PulseInterval_Show=%d",PulseInterval_Show);
    
          Disp_Buf[7] = (u8)(interval%10);
          Disp_Buf[6] = (u8)((interval/10)%10);
          Disp_Buf[5] = (u8)((interval/100)%10);
          Disp_Buf[4] = (u8)((interval/1000)%10);
      }
    }
    
回复

使用道具 举报 送花

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

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-3-31 21:22 , Processed in 0.099862 second(s), 45 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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