参考官方写了一个计数器 似乎不对
图片是官方例程
/*****中断**********************************/
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
想试试
针对您描述的计数器功能异常问题,结合代码实现和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
[本文内容由国芯人工智能辅助生成,仅供参考]
未配置GPIO,参考此例程测试:
ercircle 发表于 2025-5-12 18:41
未配置GPIO,参考此例程测试:
原开发板原程序下载以后,取反都没有反应 天宁宁 发表于 2025-5-13 10:36
原开发板原程序下载以后,取反都没有反应
哪个开发板测的,我在擎天柱测的是OK的 751
752
用外部中断0 和 1写了一个
速度似乎还可以
擎天柱和我开天斧3芯片一样么
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
按错按键了!
谢谢
一点都没有想这两个3.4 3.5按键
没有显示屏就换了另外一块板
用3.2 3.3外中断下降沿了
下次还能试试计数器{:baoquan:}
页:
[1]