中断和定时器使用问题
我用STC8H2K12U做一个遥控灯,用外部中断0口P32做遥控输入,外部中断0来实现遥控解码,用定时器0来作为计算器计数实现LED灯延时翻转,为啥会出现遥控失控,也就是遥控不起作用,
把定时器0改为用定时器1来计数就可以了。是定时器0 和中断0不能同时用?
关于您在使用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的具体配置,包括工作模式、中断使能、优先级设置等,以确保系统稳定运行。
如需进一步调试,可提供具体代码片段,以便进行更详细的分析。
[本文内容由国芯人工智能辅助生成,仅供参考] 其他原因,,INT0和 Timer0 可以同时用,, 单片机型号:STC8H212U
引脚功能:B P54 低电平亮 1- -8P33MOT高电平电机工作
VCC 2- -7P32IR
CAP 3- -6P31G 低电平亮
GND 4- -5P30R 低电平亮
**********************************************************/
#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;
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)
{
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;//红外代码接收缓冲区
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 = byt;
}
irflag = 1;
IE0 = 0;
}
页:
[1]