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

求教:STC8H1K08 定时问题 | 提高系统时钟到 30MHz

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2026-06-02 23:40:29
已绑定手机

1

主题

11

回帖

35

积分

新手上路

积分
35
发表于 2026-5-30 12:39:22 | 显示全部楼层
网*** 发表于 2026-5-30 11:37
单片机芯片哪有那么容易仿制的,而且价格本身很低,少量仿制根本不合算,
市场上特别便宜的多半是拆机件或者 ...

不一定是仿制,国内这些51单片机很多都是兼容的,奸商通过修改内部ID和丝印就可以了。好多国产STM32芯片一样能够在ST-Link软件使用是一个道理。至于你说的中断处理里面不要重逻辑,原则上没有问题,但是十M以上的指令时钟,以及单周期的指令执行周期,几十微秒内一两个IO指令和一两个个条件判断语句都处理不过来,实在说不过去。STC-ISP都可以生成微秒级的软件延迟,而且是上百个循环,,说明指令执行还是非常快的,所以只要不是重代码逻辑,MCU是能够执行的。我不通过硬件定时器,直接通过软件延迟,计算值和真实值差了几十倍,说明这个MCU指令执行周期相当长,和宏晶官方给出的数据几乎说是天差地别,就算是旧货或拆机货,都不可能差距如此大吧。
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2026-06-02 23:40:29
已绑定手机

1

主题

11

回帖

35

积分

新手上路

积分
35
发表于 2026-5-30 12:40:38 | 显示全部楼层
宁阳*** 发表于 2026-5-29 23:56
你这个本来就是5us定时 (0xffff-0xffc9)*(1/11059200)≈5us看看是否是不是用示波器测试? ...

就是用示波器观察得出的结论。
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:453
  • 最近打卡:2026-07-03 08:57:36

830

主题

1万

回帖

2万

积分

管理员

积分
23929
发表于 2026-6-1 17:31:09 | 显示全部楼层

系统时钟改用高速时钟频率 30MHz, 中断改成最高优先级

截图202606011729535031.jpg



void Timer0_Isr(void) interrupt 1
{
}

void Timer0_Init(void)                //5微秒@30.000MHz
{
        AUXR |= 0x80;                        //定时器时钟1T模式
        TMOD &= 0xF0;                        //设置定时器模式
        TL0 = 0x6A;                                //设置定时初始值
        TH0 = 0xFF;                                //设置定时初始值
        TF0 = 0;                                //清除TF0标志
        TR0 = 1;                                //定时器0开始计时
        ET0 = 1;                                //使能定时器0中断
}


回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:453
  • 最近打卡:2026-07-03 08:57:36

830

主题

1万

回帖

2万

积分

管理员

积分
23929
发表于 2026-6-1 17:34:44 | 显示全部楼层
将 USB程序去除,系统时钟看程序说明

截图202606011733391691.jpg


#include "stc8h.h"                        //STC8H的通用头文件,头文件不分大小写
#include "ai_usb.h"                        //USB库的头文件,头文件不分大小写
/*
如何获得上面这2个头文件,如已按照前面介绍的方法:
www.STCAI.com 网站,【软件工具 | 工具软件】处,下载安装最新的【AIapp-ISP 软件】,
选择其中的选项卡 【Keil仿真设置 】,
点击【添加型号和头文件到Keil中,并添加仿真器驱动到Keil中】按钮,
则 stc8h 和 AI_usb.h 都会自动复制到Keil 中, 包含进来就可以直接使用,
大家可以打开看下其中的内容,AI_usb.h 和 stc32_stc8_usb.h是相似的,只需用其中的1个头文件,
具体见 Keil_v5\C251\INC\STC 目录,或 Keil_v5\C51\INC\STC 目录。
如将对应的 USB库文件添加到 项目中,后续用户程序中,USB如收到命令字符串 "@STCISP#"
USB库函数就会自动软复位到系统ISP程序区,实现 USB不停电下载,具体见相应部分的说明。
//char *USER_DEVICEDESC = NULL;
//char *USER_PRODUCTDESC = NULL;
//char *USER_STCISPCMD = "@STCISP#";
//使用20250319之前版本的库函数时需要在用户代码中增加上面3行定义。
//使用20250319及以后的版本都不再需要上面的定义
*/

bit         t0_flag = 0;                   //定义1个位变量,T0事件位变量标志,记录定时器0已产生中断
// 供主循环查询到该定时器已产生中断,在主循环中处理定时器0的中断任务,不堵塞其他中断
bit         t1_flag = 0;                   //定义1个位变量,T1事件位变量标志,记录定时器1已产生中断
// 供主循环查询到该定时器已产生中断,在主循环中处理定时器1的中断任务,不堵塞其他中断

void Timer0_Isr(void) interrupt TMR0_VECTOR                //定时器0中断服务程序
{
        P60 = ~P60;                                //P60灯闪烁,中断服务程序中尽量少执行长的任务,防止堵塞其他中断
        t0_flag = 1;                        //置1,记录定时器0已产生中断,供主循环判断要处理定时器0的中断任务
}
//定时器0中断服务程序,TMR0_VECTOR在stc8h头文件中已宏定义为1

void Timer0_Init(void)                //定时器0初始化,2秒@40.000MHz
{
        TM0PS = 0x65;                        //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
        AUXR &= 0x7F;                        //定时器时钟12T模式
        TMOD &= 0xF0;                        //设置定时器模式
        TL0 = 0xB1;                                //设置定时初始值
        TH0 = 0x00;                                //设置定时初始值
        TF0 = 0;                                //清除TF0标志
        TR0 = 1;                                //定时器0开始计时
        ET0 = 1;                                //使能定时器0中断
}

void  Timer1_Isr(void)  interrupt  TMR1_VECTOR  
{
        P67 = ~P67;                                //P67灯闪烁,中断服务程序中尽量少执行长的任务,防止堵塞其他中断
        t1_flag = 1;                        //置1,记录定时器1已产生中断,供主循环判断要处理定时器1的中断任务
}
//定时器1中断服务程序,TMR1_VECTOR在stc8h头文件中已宏定义为3

void Timer1_Init(void)                //定时器1初始化,500毫秒@40.000MHz
{
        TM1PS = 0x19;                        //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
        AUXR &= 0xBF;                        //定时器时钟12T模式
        TMOD &= 0x0F;                        //设置定时器模式
        TL1 = 0x99;                                //设置定时初始值
        TH1 = 0x05;                                //设置定时初始值
        TF1 = 0;                                //清除TF1标志
        TR1 = 1;                                //定时器1开始计时
        ET1 = 1;                                //使能定时器1中断
}

void  sys_init(void)                        //系统初始化
{
        P_SW2 |= 0x80;                                //允许访问扩展的特殊寄存器,XFR

                                                                //32位8051需要使用下面3句进行初始化
//        EAXFR = 1;                                        //允许访问扩展的特殊寄存器,XFR
//        WTST = 0;                                        //设置取程序代码等待时间,赋值为0表示不等待,程序以最快速度运行
//        CKCON = 0;                                        //设置访问片内的xdata速度,赋值为0表示用最快速度访问,不增加额外的等待时间

        P0M0 = 0x00; P0M1 = 0x00;         //设置 P0 口为准双向口模式
        P1M0 = 0x00; P1M1 = 0x00;         //设置 P1 口为准双向口模式
        P2M0 = 0x00; P2M1 = 0x00;         //设置 P2 口为准双向口模式
        P3M0 = 0x00; P3M1 = 0x00;         //设置 P3 口为准双向口模式
        P4M0 = 0x00; P4M1 = 0x00;         //设置 P4 口为准双向口模式
        P5M0 = 0x00; P5M1 = 0x00;         //设置 P5 口为准双向口模式
        P6M0 = 0x00; P6M1 = 0x00;         //设置 P6 口为准双向口模式
        P7M0 = 0x00; P7M1 = 0x00;         //设置 P7 口为准双向口模式
}

void  main(void)
{
        sys_init();                                        //调用系统初始化函数
        usb_init();                                        //调用USB初始化函数,不需要立即判断电脑已正确识别到USB从设备
        /*         USB型单片机从设备,如需要主动向电脑发送数据,
                在执行USB_SendData( )函数和printf_usb( )函数时,
                这两个函数已增加了判断电脑是否已正确识别到USB从设备的程序。
                如果电脑要主动发送数据给USB从设备,电脑自己会主动判断与USB从设备是否已正确连接。
        */
        EA = 1;                                                //使能中断

        Timer0_Init();                                //调用定时器0初始化函数
        Timer1_Init();                                //调用定时器1初始化函数

        P40 = 0;                                        //给LED灯供电

        while(1)                                          //主循环中查询需要处理的各种事件,如T0/T1中断事件,并打印输出状态
        {
                if(t0_flag)                                //主循环中查询,定时器0是否已产生中断,是否有需要处理的定时器0事件
                {
                        t0_flag = 0;                //清0,T0事件位变量标志
                        printf_usb("Timer0!\r\n");
                }
                if(t1_flag)                                //主循环中查询,定时器1是否已产生中断,是否有需要处理的定时器1事件
                {
                        t1_flag = 0;                //清0,T1事件位变量标志
                        printf_usb("Timer1!\r\n");
                }
        }
}


回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2026-06-02 23:40:29
已绑定手机

1

主题

11

回帖

35

积分

新手上路

积分
35
发表于 2026-6-2 23:40:29 | 显示全部楼层
神*** 发表于 2026-6-1 17:34
将 USB程序去除,系统时钟看程序说明

谢谢,已经确定MCU芯片是假货,用正品的STC芯片,不管用定时器还是软件延时,定时都非常准群了。
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:120
  • 最近打卡:2026-07-05 08:00:11
已绑定手机

3

主题

180

回帖

857

积分

高级会员

积分
857
发表于 2026-6-4 10:28:48 | 显示全部楼层
cqja*** 发表于 2026-6-2 23:40
谢谢,已经确定MCU芯片是假货,用正品的STC芯片,不管用定时器还是软件延时,定时都非常准群了。 ...

TB假货确实多,曾经买TLP250,换到第三家才买到真货,楼主把截图发上来,以免坛友踩坑。下图是我购买记录。
无标题.jpg



回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:168
  • 最近打卡:2026-07-04 08:09:42
已绑定手机

1

主题

78

回帖

293

积分

中级会员

积分
293
发表于 2026-6-4 17:18:52 | 显示全部楼层
还是的正规渠道采购
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:719
  • 最近打卡:2026-07-05 11:17:37

37

主题

173

回帖

1089

积分

金牌会员

积分
1089
发表于 2026-6-6 14:36:48 | 显示全部楼层
你这个测试的频率是实际频率的一半。因为你取反两次是一个周期。所以你测到的频率是实际频率的一般。当然定时时间也就需要重新计算
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2026-7-5 14:04 , Processed in 0.074540 second(s), 78 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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