打印
[应用相关]

进入中断后会一直卡在 while (IRIN)

[复制链接]
287|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
kangzj|  楼主 | 2019-12-19 22:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
按遥控器发射红外信号程序进入中断后会一直卡在 while (IRIN);       //等 IR 变为低电平  是不是单片机检测不到红外接收头发出的低电平啊 还是什么原因 求大神解释
#include <reg52.h>
void LCD_write_com(unsigned char com);
void LCD_write_data(unsigned char data);
void LCD_clear(void);
//void Clock_Init();
void LCD_write_str(unsigned char x,unsigned char y,unsigned char *s);
void LCD_write_char(unsigned char x,unsigned char y,unsigned char data);
void LCD_init(void);
void Port_init();
#define RS_CLR P1OUT &= ~0x01       //RS置低P1.0 = 0
#define RS_SET P1OUT |= 0x01        //RS置高P1.0 = 1
#define RW_CLR P1OUT &= ~0x08     //RW置低
#define RW_SET P1OUT |= 0x08      //RW置高
#define EN_CLR P1OUT &= ~0x04       //E置低
#define EN_SET P1OUT |= 0x04
#define DataPort      P2OUT
typedef unsigned char uchar;
typedef unsigned int uint;
#define CPU_F ((double)1000000)
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))
#define IR_DIR_IN   P1DIR&=~BIT1 //红外接收头P1.1设置为输入,
#define IRIN        (P1IN&BIT1)   //红外接收头输入值
char data[4];                     //保存地址码,地址反码,数据码,数据反码
char m;
void xianshi();
unsigned char num_char_table[]={"0123456789"};
unsigned char temp;
/*****************************************************************************
系统初始化
******************************************************************************/
void InitSys()
{
WDTCTL = WDTPW + WDTHOLD;         //关闭看门狗
DCOCTL=CALDCO_1MHZ;
BCSCTL1=CALBC1_1MHZ;
P1IE|=BIT1;      //P1.1中断功能打开
P1IES|=BIT1;    //P1.1下降沿触发中断
IR_DIR_IN;      //P1.1设置为输入
_EINT();        //打开全局中断控制
}
int main( void )
{
    InitSys(); //初始化
    Port_init();
                          //delay_ms(100);
                          LCD_init();
                          LCD_clear();
    while(1)
    {
            xianshi();
    }
}
void xianshi()
{
        LCD_write_str(0,0,"temperature:");
                                                        LCD_write_char(0,1,num_char_table[temp/100]);
                                                        LCD_write_char(1,1,num_char_table[temp%100/10]);
                                LCD_write_char(2,1,'.');
                                                        LCD_write_char(3,1,num_char_table[temp%10]);
                                                         //LCD_write_char(4,1,num_char_table[0]);
                                                          LCD_write_str(5,1,"'C");

}
/*****************************************************************************
端口1中断函数
******************************************************************************/
#pragma vector=PORT1_VECTOR
__interrupt void Port1()
{
char i,j,k=0,m=1;

if((P1IFG&BIT1) == BIT1)
   {
        P1IFG &= ~BIT1;         //清除P1.1中断标志
        P1IE &=~BIT1;           //关闭P1.1中断功能
       for (i=0;i<8;i++)        //等待9ms引导码,在9ms内出现高电平则退出解码
       {
         delay_ms(1);
         if (IRIN==1) m=0;
       }
       while(!IRIN);        //等 IR 变为高电平
       delay_ms(4);         //等待4.5ms结果码
      if(m==1)
      {
        while (IRIN);       //等 IR 变为低电平  
       for(k=0;k<4;k++)
       {
       for (j=0;j<8;j++)
       {
           delay_us(500);      //等待560us低电平
           while (!IRIN);     //等 IR 变为高电平
           char n=0;
           while (IRIN)       //计算IR高电平时长
           {
             delay_us(140);
             n++;
           }
           data[k]=data[k]>>1;
         if (n<7) {data[k]&=0x7f;}
         else
         if(n>=7&&n<13)
         {data[k]|=0x80;}
         else
           if (n>=13)
         {
           P1IE|=BIT1;
         }
       }
       }
       temp=data[2];
      }
      }
P1IE|=BIT1;
}
void Port_init()
{
    P2SEL = 0x00;
    P2DIR = 0xFF;     //  设置为输出状态
    P1SEL = 0x00;
    //P2DIR |= BIT5 + BIT6 + BIT7;//为什么呢? RS/RW/EN赋值是给P2.0—P2.2的,
    P1DIR |= BIT0 + BIT3 + BIT2;     //P2口德567位设置为输出 01234作为输入
    //控制口设置为输出模式
}
//***********************************************************************
//显示屏命令写入函数
//***********************************************************************
void LCD_write_com(unsigned char com)
{
    RS_CLR;//P2.0 = 0
    RW_CLR;//P2.1 = 0
    EN_SET;//P2.2 = 1                 允许写入数据
    DataPort = com;                 //写入的命令
    delay_ms(5);
    EN_CLR;//写入结束,P2.2 = 0;关闭写入
}

//***********************************************************************
//显示屏数据写入函数
//***********************************************************************
void LCD_write_data(unsigned char data)
{
    RS_SET;//P2.0 = 1;
    RW_CLR;//P2.1 = 0;
    EN_SET;//P2.2 = 1;
    DataPort = data;                //??????
    delay_ms(5);
    EN_CLR;//P2.2 = 0;
}

//***********************************************************************
// 显示屏清空显示
//***********************************************************************
void LCD_clear(void)
{
    LCD_write_com(0x01);            //清屏幕显示
    delay_ms(5);
}
//***********************************************************************
// 显示屏字符串写入函数
//***********************************************************************
void LCD_write_str(unsigned char x,unsigned char y,unsigned char *s)
{
    if (y == 0)
    {
        LCD_write_com(0x80 + x);        //第一行显示
    }
    else
    {
        LCD_write_com(0xC0 + x);        //第二行显示
    }
    while (*s)
    {
        LCD_write_data( *s);
        s++;
    }
}
//***********************************************************************
// 显示屏单字符写入函数
//***********************************************************************
void LCD_write_char(unsigned char x,unsigned char y,unsigned char data)
{
    if (y == 0)
    {
        LCD_write_com(0x80 + x);        //第一行
    }
    else
    {
        LCD_write_com(0xC0 + x);        //第二行
    }
    LCD_write_data( data);
}

//***********************************************************************
// 显示屏初始化函数
//***********************************************************************
void LCD_init(void)
{
    LCD_write_com(0x38);  //显示模式设置
    delay_ms(5);
    LCD_write_com(0x08);  //显示关闭
    delay_ms(5);
    LCD_write_com(0x01);  //显示清屏
    delay_ms(5);
    LCD_write_com(0x06);  //显示光标移动设置
    delay_ms(5);
    LCD_write_com(0x0C);  //显示开机光标设置
    delay_ms(5);
}

使用特权

评论回复
沙发
zhuhuis| | 2019-12-19 22:14 | 只看该作者
建议把中断服务程序里的那么老长的代码,尽量都放到一个普通的函数里

使用特权

评论回复
板凳
songqian17| | 2019-12-19 22:17 | 只看该作者
中断服务程序里只留必须的代码

使用特权

评论回复
地板
songqian17| | 2019-12-19 22:22 | 只看该作者
都是那个1602的显示代码多了点..

使用特权

评论回复
5
juventus9554| | 2019-12-19 22:26 | 只看该作者
while (IRIN)       //计算IR高电平时长
                   {
                     delay_us(140);
                     n++;
                   }

使用特权

评论回复
6
renyaq| | 2019-12-19 22:29 | 只看该作者
中断服务程序里尽量简单,楼主可以设个标志,在主函数处理

使用特权

评论回复
7
yinxiangh| | 2019-12-19 22:36 | 只看该作者
这个地方不能直接放一个while死循环的,一旦硬件出问题了,就一直死在这边了

使用特权

评论回复
8
morrisk| | 2019-12-19 22:39 | 只看该作者
在while循环处添加一个延时处理程序的。

使用特权

评论回复
9
guoyt| | 2019-12-19 22:44 | 只看该作者

建议把while放在中断程序中的。

使用特权

评论回复
10
houcs| | 2019-12-19 22:47 | 只看该作者

看不懂你这咋回事,是不是电路也有问题。

使用特权

评论回复
11
heimaojingzhang| | 2020-1-16 12:59 | 只看该作者
有可能是时序的问题

使用特权

评论回复
12
keaibukelian| | 2020-1-16 13:05 | 只看该作者
最后怎么解决的啊

使用特权

评论回复
13
labasi| | 2020-1-16 13:22 | 只看该作者
是不是通讯有问题啊

使用特权

评论回复
14
paotangsan| | 2020-1-17 11:50 | 只看该作者
看是看起来应该不是中断函数庞大的问题导致的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

672

主题

7007

帖子

2

粉丝