maxchen 发表于 2013-4-8 16:56
没有看到程序的其他部分,除非其他部分有对startflag赋值,不然,中断里的那个if进不去 ...
多谢提点。
下面是全程序:
/*-----------------------------------------------
名称:遥控器红外解码数码管显示
公司:上海浩豚电子科技有限公司
编写:师访
日期:2009.5
修改:无
内容:按配套遥控器上1-9会在数码管上对应显示
------------------------------------------------*/
#include<AT89X51.h> //<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include<stdio.h>
#include<intrins.h>
//#include<reg51.h> // 包含51单片机寄存器定义的头文件
#define TURE 1
#define FALSE 0
/*-----------------------------------------步进电机控制-----------------------------------------
P0数码管显示 P2.1~3 数码管选位 P1--LED灯,控制步进电机
P3红外遥控器 (独立键盘 P3.0~P3.2不用)
数码管:第一位--模式:1--电跟模式,0--自由模式
第2位--方向:1--逆时针,0--顺时针
第3、4位--目前速度:10为1X地球自转速度,20为2X自转速度。。。
第5、6位--电跟基础速度:50为1X地球自转速度
-----------------------------------------我还是分割线-----------------------------------------*/
/******************************************************************/
/* 变量声明 */
/******************************************************************/
#define uchar unsigned char
#define uint unsigned int
sbit CLK=P1^0; //P1.0引脚为脉冲输出
sbit EN=P1^1; //P1.1引脚为使能
sbit Direct=P1^2; //P1.2引脚为方向,1-反转,0-正转?
uint Speed=101; //设置1X速度定时器1初值:256-(3250/32)=256-101=145 65536-3250=62286
uint Status=1; //启动状态初始为0,停止状态
uint Mode=1; //工作模式。1--单倍电跟状态,0--自由控制状态
//uint Direct=0; //转动方向初值
uchar zx,k,sudu;
int n=0,m,bu,l;
sbit IR=P3^2; //红外接口标志
unsigned char const dofly[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};//数码管显示编码
unsigned char irtime;//红外用全局变量
bit irpro_ok,irok;
unsigned char IRcord[4];
unsigned char irdata[33];
/******************************************************************/
/* 函数声明 */
/******************************************************************/
void Delay(unsigned char mS);//延时子函数
void Ir_work(void);
void Ircordpro(void);
void Ircontrol(void);
/******************************************************************/
/* 定时器0中断服务函数--红外接收 */
/******************************************************************/
void tim0_isr (void) interrupt 1 using 1//定时器0中断服务函数
{
irtime++; //用于计数2个下降沿之间的时间
}
/**************************************************************
函数功能:脉冲输出,定时器T1的中断服务程序
**************************************************************/
void Time1(void) interrupt 3 using 3 //"interrupt"声明函数为中断服务函数
//其后的3为定时器T1的中断编号;3表示使用第2组工作寄存器
{
CLK=~CLK; //按位取反操作,将P1.0引脚输出电平取反
TH1=256-Speed; //(65536-Speed)/256; //定时器T1的高8位重新赋初值
TL1=14; //(65536-Speed)%256; //定时器T1的高8位重新赋初值
}
/******************************************************************/
/* 外部中断0函数 --红外接收,优先级最高 */
/******************************************************************/
void ex0_isr (void) interrupt 0 using 0//外部中断0服务函数
{
static unsigned char i; //接收红外信号处理
static bit startflag; //是否开始处理标志位
if(startflag)
{
if(irtime<63&&irtime>=33)//引导码 TC9012的头码,9ms+4.5ms
{ i=0;
irdata=irtime;//存储每个电平的持续时间,用于以后判断是0还是1
irtime=0;
i++;
if(i==33)
{
irok=1;
i=0;
}
}
else
{irtime=0;startflag=1;}
}
}
/******************************************************************/
/* 定时器初始化 */
/******************************************************************/
void TIMinit(void)//定时器0初始化
{
TMOD=0x02;//定时器0工作方式2,定时器1工作方式0.TH0是重装值,TL0是初值
TH0=0x00; //重载值
TL0=0x00; //初始化值
TH1=256-Speed; //(65536-Speed)/256; //定时器T1的高8位赋初值
TL1=14;// (65536-Speed)%256; //定时器T1的高8位赋初值
ET0=1; //开中断
TR0=1;
ET1=Status; //定时器T1中断允许
TR1=1; //启动定时器T1
}
/******************************************************************/
/* 外部中断初始化 */
/******************************************************************/
void EX0init(void)
{
IT0 = 1; //指定外部中断0下降沿触发,INT0 (P3.2)
EX0 = 1; //使能外部中断
EA = 1; //开总中断
}
/******************************************************************/
/* 红外键值处理 */
/******************************************************************/
void Ir_work(void)//红外键值散转程序
{
switch(IRcord[2])//判断第三个数码值
{
case 0x0c0=dofly[1];break;//1 显示相应的按键值
case 0x180=dofly[2];break;//2
case 0x5e0=dofly[3];break;//3
case 0x080=dofly[4];break;//4
case 0x1c0=dofly[5];break;//5
case 0x5a0=dofly[6];break;//6
case 0x420=dofly[7];break;//7
case 0x520=dofly[8];break;//8
case 0x4a0=dofly[9];break;//9
}
irpro_ok=0;//处理完成标志
}
/******************************************************************/
/* 红外解码函数处理 */
/******************************************************************/
void Ircordpro(void)//红外码值处理函数
{
unsigned char i, j, k;
unsigned char cord,value;
k=1;
for(i=0;i<4;i++) //处理4个字节
{
for(j=1;j<=8;j++) //处理1个字节8位
{
cord=irdata[k];
if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差
{
value=value|0x80;
}
else
{
value=value;
}
if(j<8)
{
value=value>>1;
}
k++;
}
IRcord=value;
value=0;
} irpro_ok=1;//处理完毕标志位置1
}
/******************************************************************/
/* 红外控制处理程序 */
/******************************************************************/
void Ircontrol(void)//红外码值处理函数
{
unsigned char l,m;
if (Mode) //单倍模式
{
// SingleModel: // 单倍电跟状态
if (Direct) //如果处于反转下,先停止,再启动
{
ET1=0; //如处于反转状态,先停
for (l=1;100;l++) //低速启动延时
{
for (m=1;50;m++)
{
}
}
Direct=0;
}
if (IRcord[2]==0x44) //如果按下启动键,则启动定时器1,脉冲输出开始,步进电机运行
{
Direct=0;
Status=~Status; //启动/停止翻转
}
if (IRcord[2]==0x43) //快进按钮按下
{
Direct=0;
Speed=Speed+50;
}
if (IRcord[2]==0x40) //快退按钮按下
{
Direct=1;
Speed=Speed-50;
}
if (IRcord[2]==0x18) //选择自由模式
{
Mode=0;
}
}
else
{
// FreeModel: // 自由状态
if (IRcord[2]==0x44) //如果按下启动键,则启动定时器1,脉冲输出开始,步进电机运行
{
ET1=0; //先停止,关闭定时器1
for (l=1;100;l++) //停止延时
{
for (m=1;100;m++)
{
}
}
Direct=0;
Speed=150; //加速
Status=~Status; //启动/停止翻转
ET1=1;
}
if (IRcord[2]==0x43) //快进按钮按下
{
if (Direct) //如果处于反转下,先停止,再启动
{
ET1=0; //如处于反转状态,先停
for (l=1;100;l++) //低速启动延时
{
for (m=1;50;m++)
{
}
}
Direct=0;
}
Speed=Speed+20;
if (Speed>=220) Speed=220;
if (!ET1) ET1=1; //启动
}
if (IRcord[2]==0x40) //快退按钮按下
{
if (!Direct) //如果处于正转下,先停止,再启动
{
ET1=0; //先停止,关闭定时器1
for (l=1;100;l++) //停止延时
{
for (m=1;100;m++)
{
}
}
}
Direct=1;
Speed=Speed+20;
if (Speed>=220) Speed=220;
if (!ET1) ET1=1;
}
if (IRcord[2]==0x0c) //选择单倍模式
{
Mode=1;
}
} //else对应
}
/////////////////////////////////////////////////////////////////
void main(void)
{
EX0init(); //初始化外部中断
TIMinit();//初始化定时器
P2=0x00;//1位数码管全部显示
Direct=0;
while(1)//主循环
{
if(irok) //如果接收好了进行红外处理
{
Ircordpro();
irok=0;
}
if(irpro_ok) //如果处理好后进行工作处理,如按对应的按键后显示对应的数字等
{
Ircontrol();
Ir_work();
}
}
}
|