OpenEdv-开源电子网

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

UCOS系统下,开启串口中断后,触摸屏任务卡死

[复制链接]

1

主题

7

帖子

0

精华

新手上路

积分
36
金钱
36
注册时间
2020-8-5
在线时间
11 小时
发表于 2021-9-7 22:28:14 | 显示全部楼层 |阅读模式
5金钱
在STM32上运行UCOS,其中有一个任务是红外传感器测体温,现在遇到一个问题:传感器是串口2发送接收数据的,当串口2的中断打开,向传感器发送指令后,能读取到传感器返回的数据,但是按触摸屏上的返回按钮时,触摸屏任务卡死,无法返回。如果关闭串口2中断,或者不给传感器发送指令,按 返回 按钮则可以正常返回,找了好几天问题了没找到,求大佬帮忙!!//EMWINDEMO任务
void emwindemo_task(void *p_arg)
{
        OS_ERR err;
        GUI_CURSOR_Show();
       
        //更换皮肤
        BUTTON_SetDefaultSkin(BUTTON_SKIN_FLEX);
        CHECKBOX_SetDefaultSkin(CHECKBOX_SKIN_FLEX);
        DROPDOWN_SetDefaultSkin(DROPDOWN_SKIN_FLEX);
        FRAMEWIN_SetDefaultSkin(FRAMEWIN_SKIN_FLEX);
        HEADER_SetDefaultSkin(HEADER_SKIN_FLEX);
        MENU_SetDefaultSkin(MENU_SKIN_FLEX);
        MULTIPAGE_SetDefaultSkin(MULTIPAGE_SKIN_FLEX);
        PROGBAR_SetDefaultSkin(PROGBAR_SKIN_FLEX);
        RADIO_SetDefaultSkin(RADIO_SKIN_FLEX);
        SCROLLBAR_SetDefaultSkin(SCROLLBAR_SKIN_FLEX);
        SLIDER_SetDefaultSkin(SLIDER_SKIN_FLEX);
        SPINBOX_SetDefaultSkin(SPINBOX_SKIN_FLEX);
        while(1)
        {
                MainDialog_Demo();
                OSTimeDlyHMSM(0,0,0,10,OS_OPT_TIME_PERIODIC,&err);//延时100ms
        }
}

//TOUCH任务
void touch_task(void *p_arg)
{
        static u16 num=0;
        static int xvalue,yvalue;
        OS_ERR err;
        while(1)
        {
                GUI_TOUCH_Exec();       
                OSTimeDlyHMSM(0,0,0,5,OS_OPT_TIME_PERIODIC,&err);//延时5ms
                num++;
                if(num==400)        //2秒
                {
                        num=0;
                        xvalue=GUI_TOUCH_X_MeasureX();
                        yvalue=GUI_TOUCH_X_MeasureY();
                        printf("X坐标:%d\r\nY坐标:%d\r\n",xvalue,yvalue);
                }
        }
}


//体温显示任务
void bt_task(void *p_arg)
{
        OS_ERR err;
       
        u8 t=0;
        u8 sum=0,i=0;
  int16_t data[2]={0};                                                 //??????       
        float TO;
       
        OSTaskSemPend(0,OS_OPT_PEND_BLOCKING,0,&err);                          //请求内嵌任务信号量
        USART_Cmd(USART2, ENABLE);                               //使能串口2
        USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);           //开启相关中断
  POINT_COLOR=BLACK;                                       //设置字体颜色为黑色
        while(1)
        {
                  LED0=!LED0;
                  send_com(0x15);                                      //发送读方位角指令
                        if(Receive_ok)                                       //串口接收完毕
                {
//                        LED1=!LED1;
                        for(sum=0,i=0;i<(TEMP_data[3]+4);i++)                //TEMP_data[3]=4
                        sum+=TEMP_data[i];
                        if(sum==TEMP_data[i])                                //校验和判断
                        {
                                TO=(float)(((TEMP_data[4]<<8)|TEMP_data[5])/100);  //得到真实温度
                                POINT_COLOR=BLUE;                                  //设置字体颜色为蓝色
                                //体温显示
                                data[0]=(TEMP_data[4]<<8)|TEMP_data[5];            //放大100倍的温度
                                if(data[0]<2900)
                                {
                                        // b[0]=data[0];
                                         POINT_COLOR=BLACK;                              //设置字体颜色为黑色
                                          LCD_ShowString(217,213,5,24,24,".");
                                   LCD_ShowxNum(228,213,data[0],2,24,0);           //显示温度的小数值
                                   data[0]/=100;
                                   LCD_ShowxNum(190,213,data[0],2,24,0);           //显示温度的整数值       
                                }
                                else
                                {
                                         data[0]+=200.0;
                                         POINT_COLOR=BLUE;                               //设置字体颜色为蓝色
                                         printf("%f\r\n",(float)(data[0])/100);          //当检测时发送体温值(补偿2℃)
                                         LCD_ShowString(217,213,5,24,24,".");
                                         LCD_ShowxNum(228,213,data[0],2,24,0);           //显示温度的小数值
                                    data[0]/=100;
                                   LCD_ShowxNum(190,213,data[0],2,24,0);           //显示温度的整数值
                                       
                                }
                                //                                send_out(data,2,0x45);                   //上传数据给上位机
                  }
                                Receive_ok=0;//处理数据完毕标志
                }
                OSTimeDlyHMSM(0,0,0,1000,OS_OPT_TIME_HMSM_STRICT,&err);
  }
}


void USART2_IRQHandler(void)                                          //串口2中断服务程序
{
          u8 Res;
          OS_ERR err;       
          static uint8_t i=0,rebuf[20]={0};
#if SYSTEM_SUPPORT_OS                                           //ê1ó&#195;UCOS2ù×÷&#207;μí3
          OSIntEnter();   
#endif
        if(USART_GetITStatus(USART2, USART_IT_RXNE)!= RESET)          //判断接收标志
        {
                ////static uint8_t i=0,rebuf[20]={0};
                ////Res =USART_ReceiveData(USART1);//(USART1->DR);                //读取接收到的数据
                USART_ClearITPendingBit(USART2,USART_IT_RXNE);              //清中断标志
                rebuf[i++]=USART_ReceiveData(USART2);                       //读取串口数据,同时清除接收标志
        }
        if(USART_GetFlagStatus(USART2, USART_FLAG_ORE)==SET)          //检查ORE标志
        {
                USART_ClearFlag(USART2,USART_FLAG_ORE);                     //清ORE标志
                rebuf[i++]=USART_ReceiveData(USART2);                       //读取串口数据,同时清除接收标志
        }
                if (rebuf[0]!=0x5a)                                         //帧头不对
                        i=0;       
                if ((i==2)&&(rebuf[1]!=0x5a))                               //帧头不对
                        i=0;
       
                if(i>3)//i等于4时,已经接收到数据量字节rebuf[3]
                {
                        if(i!=(rebuf[3]+5))//判断是否接收一帧数据阶数据结束
                                return;       
                        switch(rebuf[2])//接收完毕后处理
                        {
                                case 0x45:
                                        if(!Receive_ok)//当数据处理完成后才接收新的数据
                                        {
                                                memcpy(TEMP_data,rebuf,9);//拷贝接收到的数据
                                                Receive_ok=1;             //接收完成标志
                                        }
                                        break;
                                case 0x15:break;
                                case 0x35:break;
                        }
                        i=0;//缓存清0
                }
#if SYSTEM_SUPPORT_OS  
        OSIntExit();            //退出中断
#endif
}




向传感器发送指令时能显示温度,但按返回无效

向传感器发送指令时能显示温度,但按返回无效

关闭串口2中断,不向传感器发送指令(注销掉 send_com(0x15);)后,按返回按钮可以返回主页面

关闭串口2中断,不向传感器发送指令(注销掉 send_com(0x15);)后,按返回按钮可以返回主页面
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

890

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1477
金钱
1477
注册时间
2020-8-19
在线时间
335 小时
发表于 2021-9-8 10:00:35 | 显示全部楼层
回复

使用道具 举报

70

主题

6758

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
12991
金钱
12991
注册时间
2012-11-26
在线时间
3789 小时
发表于 2021-9-8 13:20:22 | 显示全部楼层
哪个任务堆栈不够了吧
学无止境
回复

使用道具 举报

1

主题

7

帖子

0

精华

新手上路

积分
36
金钱
36
注册时间
2020-8-5
在线时间
11 小时
 楼主| 发表于 2021-9-8 16:09:32 | 显示全部楼层
jermy_z 发表于 2021-9-8 13:20
哪个任务堆栈不够了吧

应该不是堆栈的问题吧,我把堆栈怎么该都是这个样子
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-26 23:06

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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