OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4957|回复: 3

为什么delay延时的时间内,当外部中断触发时,程序就死了呢?

[复制链接]

5

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
89
金钱
89
注册时间
2017-7-9
在线时间
14 小时
发表于 2017-8-26 04:23:27 | 显示全部楼层 |阅读模式
3金钱
我delay延时了10秒,10秒内触发串口中断没问题,但10秒内触发外部中断,就不行了,无论之后怎么触发外部中断都没反应,但串口接收还可以,请问这是为什么呢?有解决办法吗?不胜感激!

//有人进门发送协议:ff ff 01 fc fc
//设防接受协议:ff 0a 01 fc fc
//取消设防协议:ff 0a 00 fc fc
#define MAIN_Fosc                11059200L        //定义主时钟
#include        "15W4KxxS4.H"

#define  uint unsigned int  
#define  uchar unsigned char

//#define BAUD 9600                            // 波特率
#define BAUD 2400                            // 波特率
//串口初始化相关       
#define S3_S  0x02
//串口中断相关
bit busy;
uchar temp1;      //接收缓冲区
uchar mode[5];      //接收指令存放区
uchar uart3_rflage;               
#define S3RI 0x01
#define S3TI 0x02
//发送指令
uchar youren[5]={0xff,0xff,0x01,0xfc,0xfc};    //有人指令
uchar num=0;     //串口数据长度,数组位
/**********************
引脚别名定义
***********************/
sbit rs485_dr=P3^5;        //使能控制485收发芯片使能引脚
sbit led6=P0^6;   //蓝色LED用IO口P06
sbit led7=P0^7;   //红色LED用IO口P07
sbit beep=P0^3;    //BEEP
sbit red=P0^2;     //red light
sbit green=P0^4;   //green light
bit HW1,HW2;      //红外1和2的标志
bit sf=0;         //1为设防,0为不设防
bit sf_mode;      //接收完一帧指令后的标志
/**************************************
功能描述:外部中断服务程序
入口参数:无
返回值:无
***************************************/
void delay_ms(uint x)
{  
        uint j,i;   
        for(j=0;j<x;j++)   
        {   
                for(i=0;i<1100;i++);   
        }  
}

void WAI_INIT(void)
{
    //外部中断0的初始化配置       
        IE0  = 0;             //将INT0中断请求标志位清"0"
        EX0 = 1;             //使能INT0中断允许位
        IT0 = 1;                   //选择INT0为下降沿触发方式
        EA = 1;                     //允许总中断

//外部中断1的初始化配置
        IE1  = 0;             //将INT1中断请求标志位清"0"
        EX1 = 1;             //使能INT1中断允许位
        IT1 = 1;                   //选择INT1为下降沿触发方式       
        EA = 1;                     //允许总中断
}

void INT0_int (void) interrupt INT0_VECTOR               
{   
    HW1=1;
}

void INT1_int (void) interrupt INT1_VECTOR               
{   
    HW2=1;
}
/***************************************************************************
* 描  述 : 串口3初始化函数
* 入  参 : 无
* 返回值 : 无
**************************************************************************/
void Uart3_Init(void)
{               
    P_SW2|=S3_S;//串口3引脚p00,p01映射到引脚p50,p51        

        S3CON=0x50; //8位UART T3作为波特率发生器  运行串口3接收数据       

        T3H=(65536-(MAIN_Fosc/12/4/BAUD))/256;   //初值
        T3L=(65536-(MAIN_Fosc/12/4/BAUD))%256;
        T4T3M = 0x08;             //允许定时器3运行
        IE2 |= 0x08;              // 串口3中断打开       
        EA=1;                      //总中断打开
}
/***************************************************************************
* 描  述 : 串口3中断服务函数
* 入  参 : 无
* 返回值 : 无
**************************************************************************/
void Uart3() interrupt 17
{         
    IE2 &= 0xF7;                                   // 串口3中断关闭                  
        if(S3CON & S3RI)      //如果接收完
        {
                S3CON &= ~S3RI;          //接收中断标志清0
                temp1 = S3BUF;    //数据缓存
                uart3_rflage = 1;  //串口接收标识符置1

        mode[num]=temp1;     //加上这一条,接收数据后,返回的数据变长了,
        temp1=0;
        if(mode[0]==0xff)    //如果包头为0xff,则继续接收
        {
            if(num==4)
            {           
                led6=~led6;
                sf_mode=1;        //接受完一帧的数据标志
                num=0;            //清楚接收的数组位
            }
            else num++;
        }
        else mode[0]=0;           //如果包头不为0xff,清掉,此时数据变为00 0a 00(或01) fc fc
        }
        if(S3CON & S3TI)        //如果发送完
        {
                T3H=(65536-(MAIN_Fosc/12/4/BAUD))/256;
                T3L=(65536-(MAIN_Fosc/12/4/BAUD))%256;
                S3CON &= ~S3TI;      //发送中断标志清0
                busy=0;             //发送完,就不busy了
        }
    IE2 |= 0x08;                     // 串口3中断打开
}
//串口发送函数
void SendDataByUart3(uchar dat)
{
        while(busy);           //不busy就可以发送下一个了
        ACC=dat;
        busy=1;                //准备要发送了,先告诉别人我在忙
        S3BUF=ACC;
}

void SendStringByUart3(char *s)
{
    uchar i=5;
//        while(*s)   //指针指向地方有多少个字节发多少个
while(i--)     //只允许发5个字节
        {
                SendDataByUart3(*s++);   //单个字节发送
        }
}

//void jiaoyan()       //接受数据校验
//{
//    uchar i;
//    if((mode[0]!=0xff)&&(mode[4]!=0xfc))
//    {
//        num=0;
//        for(i=0;i<5;i++)
//        {
//            mode[i]=0;
//        }   
//    }   
//}
int setmode()    //设防模式选择
{
    if(sf_mode=1)
    {
        sf_mode=0;
        switch(mode[2])            
        {
            case 0x01:return 1;   //遇到return立即结束当前函数,所以不用break;设防,返回1  
            case 0x00:return 0;   //不设防,返回0
        }   
    }
    else return 0;                //没接收有效指令,返回0
}
/***********************
功能描述:主函数
入口参数:无
返回值:无
************************/
int main()
{
/////////////////////////////////////////////////
//注意: STC15W4K32S4系列的芯片,上电后所有与PWM相关的IO口均为
//      高阻态,需将这些口设置为准双向口或强推挽模式方可正常使用
//相关IO: P0.6/P0.7/P1.6/P1.7/P2.1/P2.2
//        P2.3/P2.7/P3.7/P4.2/P4.4/P4.5
/////////////////////////////////////////////////
//        P0M1 &= 0x3F;        P0M0 &= 0x3F;          //设置P0.6、P07为准双向口(led灯,测试用)
    P0M1 &= 0x23;        P0M0 &= 0x23;          //设置P0.6、P07为准双向口(led灯,测试用),P0.2、P03 、P04为准双向口(继电器用)
    P3M1 = 0;        P3M0 = 0;        //设置P3.0~P3.7为准双向口
        P5M1 = 0;        P5M0 = 0;        //设置P5.0~P5.7为准双向口
    rs485_dr=0;   //控制485接收
    WAI_INIT();       //外部中断初始化
    Uart3_Init();     //串口初始化

  while (1)
        {   
            if(HW1==1&&HW2==0)    //进门
        {      
            delay_ms(180);
            if(HW1==1&&HW2==1)
            {
                HW1=0;       //外部中断标志1清零
                HW2=0;       // 外部中断标志1清零

                rs485_dr=1;   //控制485发送     
                SendStringByUart3(youren);//发送指令
                SendStringByUart3(mode);//发送指令
                delay_ms(5);   //缓冲,延时等485发送完(必须加,因为485发送停止位只发到一半,延时等发完另一半)                 
                rs485_dr=0;   //控制485接收

                led7=~led7;

                if(setmode())          //如果是设防模式,setmode()=1;则开启警报灯蜂鸣器并延时3秒
                {
                    EX0=0;              //关闭外部中断0
                    EX1=0;              //关闭外部中断1
                    red=0;
                    green=0;
                    beep=0;
                    delay_ms(10000);
                    EX0=1;             //打开外部中断0
                    EX1=1;             //打开外部中断0
                    red=1;
                    green=1;
                    beep=1;
                }
            }
        }
        else if(HW1==0&&HW2==1)  //出门
        {
              HW2=0;         //出门,被首先触发的外部中断2清零
              delay_ms(350);//触发外部中断2的路人(出门)必须在该延时内触发外部中断1
              HW1=0;        //若上面延时内被人触发外部中断1,清掉外部中断0内的标志

        }

        }
}


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

13

主题

611

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1929
金钱
1929
注册时间
2014-10-6
在线时间
625 小时
发表于 2017-8-26 07:56:52 | 显示全部楼层
你在延时前都把外部中断关闭了,怎么响应?  if(setmode())          //如果是设防模式,setmode()=1;则开启警报灯蜂鸣器并延时3秒
                {
                    EX0=0;              //关闭外部中断0
                    EX1=0;              //关闭外部中断1
                    red=0;
                    green=0;
                    beep=0;
                    delay_ms(10000);
回复

使用道具 举报

5

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
89
金钱
89
注册时间
2017-7-9
在线时间
14 小时
 楼主| 发表于 2017-8-26 13:14:04 | 显示全部楼层
烟酒不沾 发表于 2017-8-26 07:56
你在延时前都把外部中断关闭了,怎么响应?  if(setmode())          //如果是设防模式,setmode()=1;则 ...

本来是不加关掉中断的,出现同样的问题,我以为是冲突了,就加上去了,而且我在后面不是加了开启中断吗
回复

使用道具 举报

5

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
89
金钱
89
注册时间
2017-7-9
在线时间
14 小时
 楼主| 发表于 2017-8-26 13:19:29 | 显示全部楼层
求原子哥帮帮忙
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-23 21:29

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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