找回密码
 立即注册
查看: 59|回复: 3

中断和定时器使用问题

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:420
  • 最近打卡:2025-08-11 07:59:54

21

主题

222

回帖

1142

积分

金牌会员

积分
1142
发表于 6 天前 | 显示全部楼层 |阅读模式
  我用STC8H2K12U做一个遥控灯,用外部中断0口P32做遥控输入,外部中断0来实现遥控解码,
用定时器0来作为计算器计数实现LED灯延时翻转,为啥会出现遥控失控,也就是遥控不起作用,
把定时器0改为用定时器1来计数就可以了。是定时器0 和中断0不能同时用?

回复

使用道具 举报 送花

3

主题

2077

回帖

1002

积分

等待验证会员

积分
1002
发表于 6 天前 | 显示全部楼层
关于您在使用STC8H2K12U单片机时遇到的“遥控失控”问题,以下是专业分析与建议:

首先,从硬件和软件层面来看,STC8H2K12U支持多个定时器和中断源,理论上可以同时使用外部中断0(P3.2)和定时器0。但实际应用中,若出现“遥控失控”的现象,可能涉及以下几种原因:

1. 中断优先级冲突  
   STC8系列单片机支持中断优先级设置。如果定时器0中断与外部中断0的优先级配置不当,可能导致外部中断被频繁打断,从而影响遥控解码的稳定性。建议检查中断优先级寄存器(IP)的配置,确保外部中断0的优先级高于或等于定时器0中断。

2. 定时器0的中断频率过高  
   若定时器0配置为高频率计数模式(如方式0或方式1),其中断响应频繁,可能干扰外部中断的处理。特别是在遥控信号解码过程中,若定时器0频繁触发中断,可能导致外部中断未能及时响应,造成遥控信号丢失或误判。

3. 中断服务程序执行时间过长  
   如果定时器0的中断服务程序(ISR)执行时间较长,可能占用较多CPU资源,导致外部中断无法及时响应。建议优化定时器0的中断服务程序,尽量减少其执行时间,避免长时间占用CPU。

4. 定时器0与外部中断0的引脚冲突  
   虽然P3.2是外部中断0的输入引脚,但在某些情况下,若定时器0的输出功能与该引脚发生冲突(例如使用PWM功能),也可能导致外部中断异常。建议检查P3口的配置,确保P3.2未被其他功能占用。

5. 代码逻辑错误或时序问题  
   遥控解码通常依赖于特定的时序判断。若定时器0的计数过程干扰了该时序判断,可能导致解码失败。建议在代码中增加必要的延时或同步机制,确保遥控信号的正确识别。

综上所述,虽然定时器0与外部中断0在硬件上可以共存,但实际应用中需注意中断优先级、中断频率、服务程序效率以及引脚配置等因素。根据您的描述,将定时器0更换为定时器1后问题得到解决,可能是由于定时器1的中断频率较低或优先级设置更合理所致。建议进一步检查定时器0和定时器1的具体配置,包括工作模式、中断使能、优先级设置等,以确保系统稳定运行。

如需进一步调试,可提供具体代码片段,以便进行更详细的分析。

[本文内容由国芯人工智能辅助生成,仅供参考]
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:496
  • 最近打卡:2025-08-11 11:26:29

33

主题

2486

回帖

5401

积分

论坛元老

积分
5401
发表于 6 天前 | 显示全部楼层
其他原因,,INT0和 Timer0 可以同时用,,
参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:420
  • 最近打卡:2025-08-11 07:59:54

21

主题

222

回帖

1142

积分

金牌会员

积分
1142
发表于 6 天前 | 显示全部楼层
单片机型号:STC8H212U
引脚功能:  B P54    低电平亮    1-    -8  P33  MOT  高电平电机工作
            VCC                 2-    -7  P32  IR
            CAP                 3-    -6  P31  G   低电平亮
            GND                 4-    -5  P30  R   低电平亮

**********************************************************/
#include <STC8H.h>
#include <intrins.h>

sbit LEDR = P3^0;       // LEDR接P3.0
sbit LEDG = P3^1;       // LEDG接P3.1
sbit LEDB = P5^4;       // LEDB接P5.4
sbit LEDM = P3^3;       // LEDM接P3.3

unsigned char LEDMODE = 1;      //led模式控制
unsigned char ledState = 0;     //LED状态机状态
unsigned int ledTimer = 0;      //LED定时计数器

extern bit irflag;
extern unsigned char ircode[4];
extern void InitInfrared(void);
void ConfigTimer0(unsigned int ms);
void IrDecode();

void LED_Update(void);          // 新增:LED更新函数

void main()
{
    P3M0 = 0x00;
    P3M1 = 0x00;
    P5M0 &= ~0x10;
    P5M1 &= ~0x10;

    EA = 1;      //开总中断

    InitInfrared();   //初始化红外功能  
   
    // 初始化定时器0,用于LED控制
    TMOD &= 0xF0;     // 清除T0控制位
    TMOD |= 0x01;     // 设置T0为模式1
    TH0 = 0xFC;       // 1ms定时初值 @11.0592MHz
    TL0 = 0x66;
    ET0 = 1;          // 允许T0中断
    TR0 = 1;          // 启动T0

    LEDR = 1;
    LEDG = 1;
    LEDB = 1;
    LEDM = 0;

    while (1)
    {
        IrDecode();  // 处理红外遥控
    }
}

// 定时器0中断服务函数
void Timer0_ISR() interrupt 1
{
    TH0 = 0xFC;      // 重装初值
    TL0 = 0x66;
   
    ledTimer++;
    if(ledTimer >= 1000)  // 约1秒
    {
        ledTimer = 0;
        LED_Update();     // 更新LED状态
    }
}

// LED状态更新函数
void LED_Update(void)
{
    switch(LEDMODE)
    {
        case 0:  // 电机工作模式
            LEDM = 1;
            LEDR = 1; LEDG = 1; LEDB = 1;
            break;
            
        case 1:  // 所有LED关闭
            LEDM = 0;
            LEDR = 1; LEDG = 1; LEDB = 1;
            break;
            
        case 2:  // 红色亮
            LEDR = 0; LEDG = 1; LEDB = 1;
            break;
            
        case 3:  // 绿色亮
            LEDR = 1; LEDG = 0; LEDB = 1;
            break;
            
        case 4:  // 蓝色亮
            LEDR = 1; LEDG = 1; LEDB = 0;
            break;
            
        case 5:  // 三色轮流闪烁
            ledState = (ledState + 1) % 3;
            switch(ledState) {
                case 0: LEDR = 0; LEDG = 1; LEDB = 1; break;
                case 1: LEDR = 1; LEDG = 0; LEDB = 1; break;
                case 2: LEDR = 1; LEDG = 1; LEDB = 0; break;
            }
            break;
            
        case 6:  // 多彩渐变效果
            ledState = (ledState + 1) % 6;
            switch(ledState) {
                case 0: LEDR = 0; LEDG = 1; LEDB = 1; break;
                case 1: LEDR = 0; LEDG = 0; LEDB = 1; break;
                case 2: LEDR = 1; LEDG = 0; LEDB = 1; break;
                case 3: LEDR = 1; LEDG = 0; LEDB = 0; break;
                case 4: LEDR = 1; LEDG = 1; LEDB = 0; break;
                case 5: LEDR = 0; LEDG = 1; LEDB = 0; break;
            }
            break;
            
        default:
            break;
    }
}

// 红外解码函数
void IrDecode()
{
    if (irflag)  //接收到红外数据时刷新显示
    {
        irflag = 0;
        switch(ircode[2])
        {
            case 0x45:
                LEDMODE = 0;
                break;
            case 0x47:
                LEDMODE = 1;
                break;
            case 0x46:
                LEDMODE = 2;
                break;
            case 0x19:
                LEDMODE = 3;
                break;
            case 0xFF:
                LEDMODE = 4;
                break;
            case 0x07:
                LEDMODE = 5;
                break;
            case 0x0D:                                
                LEDMODE = 6;                           
                break;
            default:
                break;
        }
    }
}

红外接收处理程序如下:
#include <STC8H.h>

sbit IR_INPUT = P3^2;  //红外接收引脚

bit irflag = 0;  //红外接收标志,收到一帧正确数据后置1
unsigned char ircode[4];  //红外代码接收缓冲区

void InitInfrared()
{       
        IR_INPUT = 1;
        TMOD &= 0XF0;
        TMOD |= 0x01;
        TR0 = 0;
        ET0 = 0;
        IT0 = 1;
        EX0 = 1;
        PX0 = 1;                    //外部中断0设置为最高优先级
}
unsigned int GetHighTime()
{
        TH0 = 0;
        TL0 = 0;
        TR0 = 1;
        while(IR_INPUT)
        {
                if(TH0 > 0x40)
                {
                        break;
                }
        }
        TR0 = 0;

        return(TH0 * 256 + TL0);
}

unsigned int GetLowTime()
{
        TH0 = 0;
        TL0 = 0;
        TR0 = 1;
        while(!IR_INPUT)
        {
                if(TH0 > 0x40)
                {
                        break;
                }
        }
        TR0 = 0;

        return(TH0 * 256 + TL0);
}
void EXINT0_ISR() interrupt 0
{
        unsigned char i, j;
        unsigned int time;
        unsigned char byt;

        time = GetLowTime();
        if((time <7833) || (time > 8755))          
        {
                IE0 = 0;
                return;       
        }

        time = GetHighTime();
        if((time<3686) || (time > 4608))
        {
                IE0 = 0;
                return;
        }
        for(i=0; i<4; i++)
        {
                for(j=0; j<8; j++)
                {
                        time = GetLowTime();
                        if((time<313) ||(time >718))
                        {
                                IE0 = 0;
                                return;
                        }
                        time = GetHighTime();
                        if((time>313) && (time <718))
                        {
                                byt >>= 1;       
                        }
                        else if((time>1345) && (time<1751))
                        {
                                byt >>= 1;
                                byt |= 0x80;
                        }
                        else
                        {
                                IE0 = 0;
                                return;
                        }
                }
                ircode[i] = byt;
        }
        irflag = 1;
        IE0 = 0;
}





回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-8-11 13:11 , Processed in 0.117945 second(s), 62 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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