天宁宁 发表于 2025-5-12 17:16:11

参考官方写了一个计数器 似乎不对



图片是官方例程
/*****中断**********************************/
            void t0int()interrupt 1
            {
               OutPut0=~OutPut0;
            }

主函数

               AUXR=0X80;
               TMOD=0X04;
               TL0=0XFF;
               TH0=0XFF;
               ET0=1;
               TR0=1;
                EA=1;
               while(1)                        //
                {
               Delay_50ms(20);
               OutPut2=~OutPut2;         //
                }                              //

以上是测试程序


主循环OutPut2不断取反正确

中断3.4取反一次点亮指示灯以后
再触碰3.4口就没有反应了

想用计数器来跟踪PLC发的高速脉冲
做加减计数器

当然P3.2 P3.3也可以
手上刚好一块板有3.4和3.5
想试试



国芯人工智能 发表于 2025-5-12 17:28:00

针对您描述的计数器功能异常问题,结合代码实现和8051架构特性,现提供以下专业分析及解决方案:

一、问题诊断
1. 模式配置矛盾
   c
   TMOD=0x04;// 定时器0配置为模式1(16位计数器),计数器模式
   此处存在两个关键配置问题:
模式1为16位非自动重载模式,但未在中断服务程序中重装初值
计数器初值设置为0xFFFF:
   c
   TL0=0xFF;// 低字节
   TH0=0xFF;// 高字节
   这将导致首次计数脉冲触发立即溢出(0xFFFF+1=0x10000),但后续未重新初始化计数器

2. 中断服务程序缺陷
   c
   void t0int() interrupt 1 {
       OutPut0=~OutPut0; // 仅电平翻转,未重置计数器
   }
   缺少关键操作:
未清除TF0溢出标志(部分型号需手动清除)
未重新装载计数初值
未处理计数器溢出后的状态恢复

3. 端口配置缺失
   未显式配置P3.4(T0引脚)的工作模式:
   ```c
   P3M1 &= ~(1

[本文内容由国芯人工智能辅助生成,仅供参考]

ercircle 发表于 2025-5-12 18:41:49


未配置GPIO,参考此例程测试:

天宁宁 发表于 2025-5-13 10:36:41

ercircle 发表于 2025-5-12 18:41
未配置GPIO,参考此例程测试:

原开发板原程序下载以后,取反都没有反应

ercircle 发表于 2025-5-13 10:42:41

天宁宁 发表于 2025-5-13 10:36
原开发板原程序下载以后,取反都没有反应

哪个开发板测的,我在擎天柱测的是OK的

ercircle 发表于 2025-5-13 10:50:52

751

天宁宁 发表于 2025-5-13 14:00:27

752
用外部中断0 和 1写了一个
速度似乎还可以

擎天柱和我开天斧3芯片一样么


天宁宁 发表于 2025-5-13 14:10:07

753

又试了一下
文件路径
E:\MCU\STCMCU\STC8H\STC8H 开天斧开发板资料\04-利用T0,T1做外部计数器\sample.hex

/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- STC 1T Series MCU Demo Programme -------------------------------*/
/* --- Mobile: (86)13922805190 ----------------------------------------*/
/* --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/
/* --- Tel: 86-0513-55012928,55012929,55012966 ------------------------*/
/* --- Web: www.STCMCU.com --------------------------------------------*/
/* --- Web: www.STCMCUDATA.com---------------------------------------*/
/* --- QQ:800003751 -------------------------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序            */
/*---------------------------------------------------------------------*/

/*************功能说明    **************

本例程基于STC8H8K64U核心实验板(开天斧)进行编写测试。

按一次P3.4(T0)按键,P2.2口翻转一次,对应的LED灯状态改变一次。

按一次P3.5(T1)按键,P2.3口翻转一次,对应的LED灯状态改变一次。

由于按键是机械按键, 按下有抖动, 而本例程没有去抖动处理, 所以按一次有多多次翻转也是正常的.

此外程序演示两种复位进入USB下载模式的方法:
1. 通过每1毫秒执行一次“KeyResetScan”函数,实现长按P3.2口按键触发MCU复位,进入USB下载模式。
   (如果不希望复位进入USB下载模式的话,可在复位代码里将 IAP_CONTR 的bit6清0,选择复位进用户程序区)
2. 通过加载“stc_usb_hid_8h.lib”库函数,实现使用STC-ISP软件发送指令触发MCU复位,进入USB下载模式并自动下载。

下载时, 选择时钟 24MHZ (用户可自行修改频率).

******************************************/

#include "../comm/stc8h.h"   //包含此头文件后,不需要再包含"reg51.h"头文件
#include "../comm/usb.h"   //USB调试及复位所需头文件
#include "stdio.h"
#include "intrins.h"

#define MAIN_Fosc      24000000UL

/*************本地常量声明    **************/

#define T0_CT 0x04
#define T1_CT 0x40

//USB调试及复位所需定义
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";                      //设置自动复位到ISP区的用户接口命令

/*************IO口定义    **************/

/*************本地变量声明    **************/

//P3.2口按键复位所需变量
bit Key_Flag;
u16 Key_cnt;

u8T0_cnt, T1_cnt; //测试用的计数变量

/*************本地函数声明    **************/

void delay_ms(u8 ms);
void KeyResetScan(void);

/****************外部函数声明和外部变量声明 *****************/


//========================================================================
// 函数: void timer0_int (void) interrupt TIMER0_VECTOR
// 描述:timer0中断函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2015-1-12
//========================================================================
void TM0_Isr() interrupt 1
{
    P22 = !P22;//测试端口
    T0_cnt++;    //计数+1
}

//========================================================================
// 函数: void timer1_int (void) interrupt TIMER1_VECTOR
// 描述:timer1中断函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2015-1-12
//========================================================================
void TM1_Isr (void) interrupt 3
{
    P23 = !P23;//测试端口
    T1_cnt++;    //计数+1
}

/******************** 主函数 **************************/
void main(void)
{
    P_SW2 |= 0x80;   //扩展寄存器(XFR)访问使能

    RSTFLAG |= 0x04;   //设置硬件复位后需要检测P3.2的状态选择运行区域,否则硬件复位后进入USB下载模式

    P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口
    P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
    P2M1 = 0x00;   P2M0 = 0x00;   //设置为准双向口
    P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口
    P5M1 = 0x00;   P5M0 = 0x00;   //设置为准双向口
    P6M1 = 0x00;   P6M0 = 0x00;   //设置为准双向口
    P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口
    P3M1 = 0x30;   P3M0 = 0x00;   //P3.4,P3.5设置为输入口

    //USB调试及复位所需代码-----
    P3M0 &= ~0x03;
    P3M1 |= 0x03;
    IRC48MCR = 0x80;
    while (!(IRC48MCR & 0x01));
    usb_init();
    //-------------------------

    P3PU = 0x30;            //P3.4,P3.5使能内部4.1K上拉电阻

    TMOD = 0;
    TMOD |= T0_CT;          //使能T0外部计数模式
    TMOD |= T1_CT;          //使能T1外部计数模式
    TL0 = 0xff;
    TH0 = 0xff;
    TL1 = 0xff;
    TH1 = 0xff;
    TR0 = 1;                //启动定时器T0
    TR1 = 1;                //启动定时器T1
    ET0 = 1;                //使能定时器中断T0
    ET1 = 1;                //使能定时器中断T1

    INTCLKO &= ~0x03;      //T0,T1不输出时钟

    T0_cnt = 0;
    T1_cnt = 0;

    IE2 |= 0x80;   //IE2相关的中断位操作使能后,需要重新设置EUSB
    EA = 1;

    while(1)
    {
      if (bUsbOutReady) //USB调试及复位所需代码
      {
//            memcpy(UsbInBuffer, UsbOutBuffer, 64);      //原路返回, 用于测试HID
//            usb_IN();
            
            usb_OUT_done();
      }

      KeyResetScan();   //P3.2口按键触发软件复位,进入USB下载模式,不需要此功能可删除本行代码
      delay_ms(1);
    }
}

//========================================================================
// 函数: void delay_ms(unsigned char ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 日期: 2013-4-1
// 备注:
//========================================================================
void delay_ms(u8 ms)
{
   u16 i;
   do{
          i = MAIN_Fosc / 10000;
          while(--i);
   }while(--ms);
}

//========================================================================
// 函数: void KeyResetScan(void)
// 描述: P3.2口按键长按1秒触发软件复位,进入USB下载模式。
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2022-6-11
// 备注:
//========================================================================
void KeyResetScan(void)
{
    if(!P32)
    {
      if(!Key_Flag)
      {
            Key_cnt++;
            if(Key_cnt >= 1000)      //连续1000ms有效按键检测
            {
                Key_Flag = 1;      //设置按键状态,防止重复触发

                USBCON = 0x00;      //清除USB设置
                USBCLK = 0x00;
                IRC48MCR = 0x00;
               
                delay_ms(10);
                IAP_CONTR = 0x60;   //触发软件复位,从ISP开始执行
                while (1);
            }
      }
    }
    else
    {
      Key_cnt = 0;
      Key_Flag = 0;
    }
}



ercircle 发表于 2025-5-13 14:49:35

按错按键了!

天宁宁 发表于 2025-5-13 15:01:47

ercircle 发表于 2025-5-13 14:49
按错按键了!

谢谢
一点都没有想这两个3.4 3.5按键
没有显示屏就换了另外一块板
用3.2 3.3外中断下降沿了
下次还能试试计数器{:baoquan:}
页: [1]
查看完整版本: 参考官方写了一个计数器 似乎不对