OpenEdv-开源电子网

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

求大神解决UCOS,寄存器版的按键方式挂起和恢复的问题(与库函数班版功能有点改动)

[复制链接]

34

主题

119

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
275
金钱
275
注册时间
2013-6-15
在线时间
0 小时
发表于 2013-7-24 07:45:36 | 显示全部楼层 |阅读模式

我是用MINI STM32版的开发板,用寄存器版重新完成挂起和恢复任务功能。
出现以下错误现象:
1.当除去LCD和触摸功能,只保留LED0,LDE1,KEY功能时,LED0,LED1能正常显示,但是当按下key0,key1,wk_up当中任一个按键时(哪怕任何返回的按键值没有设置其他功能),LED0,LED1就会停止闪烁,再次按任何按键都没有用,key的延时函数删掉了
2.当添加LCD和触摸功能时(LED0,LED1,key功能都在),LCD显示的画面,触摸屏的画面,LED0,LED1都会出现,但是就是不变化,感觉操作执行完每个任务后直接一直运行空闲任务了,按键也没有。


#include "sys.h"
#include "usart.h"  
#include "delay.h" 
#include "led.h"
#include "key.h"
#include "24cxx.h"
#include "lcd.h"
#include "touch.h"
 
#include "includes.h" 
//Mini STM32开发板扩展实例 8
//ucos 实验
//正点原子@ALIENTEK
//技术支持:www.openedv.com

 
//设置任务堆栈大小
#define LED_STK_SIZE     64
#define LED1_STK_SIZE    64
//#define LCD_STK_SIZE     64
#define KEY_STK_SIZE     64
//#define TOUCH_STK_SIZE   64
#define START_STK_SIZE   512


//设置任务优先级

//注意:在设置优先级时,应该先在os_cfg.h中设置OS_LOWEST_PRIO的值
#define LED_TASK_Prio       6
#define LED1_TASK_Prio      5
//#define LCD_TASK_Prio       4
#define KEY_TASK_Prio       2
//#define TOUCH_TASK_Prio     7

#define START_TASK_Prio     10

//任务堆栈
OS_STK  TASK_LED1_STK[LED_STK_SIZE];
OS_STK  TASK_LED_STK[LED1_STK_SIZE];
//OS_STK  TASK_LCD_STK[LCD_STK_SIZE];
OS_STK  TASK_START_STK[START_STK_SIZE];
OS_STK  TASK_KEY_STK[KEY_STK_SIZE];
//OS_STK  TASK_TOUCH_STK[TOUCH_STK_SIZE];

//任务申明
void TaskStart(void *pdata);
void TaskLed(void *pdata);
void TaskLed1(void *pdata);
//void TaskLCD(void *pdata);
void TaskKey(void *pdata);
//void TaskTouch(void *pdata);

//系统时钟配置函数
void SysTick_Configuration(void);

 


////加载触摸画板函数
// void Load_Drow_Dialog(void)
//{  
// LCD_Fill(0, 180,240,320,WHITE);
//  OINT_COLOR=BLUE;//设置字体为蓝色
// LCD_ShowString(216,304,"RST");//显示清屏区域
// LCD_DrawLine(0, 158, 240, 158);
//   OINT_COLOR=RED;//设置画笔蓝色
//}
////进入触摸屏校准函数
// void Load_Adjust_Panel()
// {
//   LCD_Clear(WHITE);//清屏
// Touch_Adjust();  //屏幕校准
// Save_Adjdata(); 
// Load_Drow_Dialog();
// }

   
int main(void)
{       
 Stm32_Clock_Init(9); //系统时钟设置
 delay_init(72);      //延时初始化
 uart_init(72,9600);  //串口初始化为9600
 LED_Init();      //LED端口初始化
 KEY_Init();    //KEY按键端口初始化
 //LCD_Init();      
 SysTick_Configuration();
                            //删除了SPI_Flash_Init();
 //AT24CXX_Init();  //IIC初始化
 //Touch_Init();
 
 //Load_Drow_Dialog();
  //POINT_COLOR=RED;
 OSInit();
 OSTaskCreate( TaskStart, //task pointer
     (void *)0, //parameter
     (OS_STK *)&TASK_START_STK[START_STK_SIZE-1], //task stack top pointer
     START_TASK_Prio ); //task priority
 
 OSStart();
 return 0;   
}
//开始任务
void TaskStart(void * pdata)
{
 pdata = pdata;
 OS_ENTER_CRITICAL();  
 
 OSTaskCreate(TaskLed, (void * )0, (OS_STK *)&TASK_LED_STK[LED_STK_SIZE-1], LED_TASK_Prio);
 OSTaskCreate(TaskLed1, (void * )0, (OS_STK *)&TASK_LED1_STK[LED1_STK_SIZE-1], LED1_TASK_Prio);
  //OSTaskCreate(TaskLCD, (void * )0, (OS_STK *)&TASK_LCD_STK[LCD_STK_SIZE-1], LCD_TASK_Prio);
   OSTaskCreate(TaskKey, (void * )0, (OS_STK *)&TASK_KEY_STK[KEY_STK_SIZE-1], KEY_TASK_Prio);
  //OSTaskCreate(TaskTouch, (void * )0, (OS_STK *)&TASK_TOUCH_STK[TOUCH_STK_SIZE-1], TOUCH_TASK_Prio);
  OSTaskSuspend(START_TASK_Prio); //挂起自身任务,进入等待状态,暂停但不删除suspend but not delete
 OS_EXIT_CRITICAL();    //注意,当挂起的任务是自身任务时,参数必须是OS_PRIO_SELF
}

//任务1
//控制DS0的亮灭.
void TaskLed(void *pdata)
{
 while(1)
 {   
     if(OSTaskDelReq(OS_PRIO_SELF)==OS_TASK_DEL_REQ) //判断是否有删除请求
   OSTaskDel(OS_PRIO_SELF);         //删除任务本身TaskLed
  LED0=!LED0;
  OSTimeDlyHMSM(0,0,0,500); 
 }
}
//任务2       
//控制DS1的亮灭.
void TaskLed1(void *pdata)
{
 while(1)
 {   
  LED1=!LED1;
  OSTimeDlyHMSM(0,0,0,200); 
 }
}

//任务3
//按键检测 
 void TaskKey(void *pdata)
 { u8  key=0;
    while(1){
   key=KEY_Scan();
   key=key;
     

   if(key==1)
   {
      LED1=0;
   LED0=0;
  

  OSTaskSuspend(LED_TASK_Prio);  //Key0挂起任务
  
   }
   else if(key==2)
   {
     OSTaskResume(LED_TASK_Prio);  //Key1恢复任务
   
   }    
   else if(key==3)
   {
     OSTaskDelReq(LED_TASK_Prio);  //请求删除任务
  
   }
   OSTimeDlyHMSM(0,0,0,20);  
 }
 }


////液晶显示
// void TaskLCD(void *pdata){
//  u8  colorIndex=0;
// u16 colorTable[]={BLACK,YELLOW,RED,GREEN};
//    LCD_ShowString(10,4,"LCD Display Panel");
//    while(1)              
//  {
//   if(OSTaskDelReq(OS_PRIO_SELF)==OS_TASK_DEL_REQ)
//      OSTaskDel(OS_PRIO_SELF);
//   if(colorIndex==4)
//         colorIndex=0;
//      LCD_Fill(80,40,160,120,colorTable[colorIndex]);
//      colorIndex++;
//      OSTimeDlyHMSM(0,0,0,400);
//   }     
// } 
//
//
//
//
// //触摸功能
//void TaskTouch(void *pdata)
// {  LCD_ShowString(10,160,"Touch Panel");
//  while(1)
// {   MY_NVIC_Init(2,0,EXTI1_IRQChannel,2); 
//  if(Pen_Point.Key_Sta==Key_Down)//触摸屏被按下
//  {
//   en_Int_Set(0);//关闭中断
//   Convert_Pos();
//   en_Point.Key_Sta=Key_Up;
//   if(Pen_Point.X0>216&&en_Point.Y0>304)Load_Drow_Dialog();//清除
//   else if(Pen_Point.Y0>180)
//   {
//    Draw_Big_Point(Pen_Point.X0,Pen_Point.Y0);//画图    
//    
//   }  
//   en_Int_Set(1);//开启中断 
//  }
//   OSTimeDlyHMSM(0,0,0,2);
// };  
// }
 
 //系统时钟中断服务函数
void SysTick_Handler(void)
{
 OS_ENTER_CRITICAL(); /* Tell uC/OS-II that we are starting an ISR  */
    OSIntNesting++;
    OS_EXIT_CRITICAL();

    OSTimeTick();        /* Call uC/OS-II's OSTimeTick()               */

    OSIntExit();         /* Tell uC/OS-II that we are leaving the ISR  */
}
//系统时钟配置,设计1ms产生一次中断
void SysTick_Configuration(void)
{
  SysTick->CTRL&=~(1<<2);//SYSTICK使用外部时钟源
 SysTick->CTRL|=1<<1;   //开启SYSTICK中断
 SysTick->LOAD=9000;    //产生1ms中断
 //bit2清空,选择外部时钟  HCLK/8
  SysTick->CTRL|=1<<0;   //开启SYSTICK
}

 

 

 

 

 

 

KEY文件

#include "key.h"
#include "delay.h"
////////////////////////////////////////////////////////////////////////////////// 
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//Mini STM32开发板
//按键输入 驱动代码    
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//修改日期:2010/11/28
//版本:V1.1
//版权所有,盗版必究。
//Copyright(C) 正点原子 2009-2019
//All rights reserved
//********************************************************************************
//V1.1修改说明
//修改按键扫描函数,使整个代码可以支持SWD下载。
//////////////////////////////////////////////////////////////////////////////////   
           
//按键初始化函数
//特别注意:在该函数之后,JTAG将无法使用(SWD也无法使用)
//如果想JTAG仿真,可以屏蔽该函数。
//PA0.13.15 设置成输入
void KEY_Init(void)
{
 RCC->APB2ENR|=1<<2;     //使能PORTA时钟
 GPIOA->CRL&=0XFFFFFFF0;//PA0设置成输入  
 GPIOA->CRL|=0X00000008;  
 GPIOA->CRH&=0X0F0FFFFF;//PA13,15设置成输入  
 GPIOA->CRH|=0X80800000;       
 GPIOA->ODR|=1<<13;    //PA13上拉,PA0默认下拉
 GPIOA->ODR|=1<<15;    //PA15上拉
}
//按键处理函数
//返回按键值
//0,没有任何按键按下
//1,KEY0按下
//2,KEY1按下
//3,KEY2按下 WK_UP
//注意此函数有响应优先级,KEY0>KEY1>KEY2!!
u8 KEY_Scan(void)

 static u8 key_up=1;//按键按松开标志 
 //JTAG_Set(JTAG_SWD_DISABLE);
 if(key_up&&(KEY0==0||KEY1==0||KEY2==1))
 {
  
  key_up=0;
  if(KEY0==0)
  {
   //JTAG_Set(SWD_ENABLE);
   return 1;
  }
  else if(KEY1==0)
  {
   //JTAG_Set(SWD_ENABLE);
   return 2;
  }
  else if(KEY2==1)
  {
   //JTAG_Set(SWD_ENABLE);
   return 3;
  }
 }else if(KEY0==1&&KEY1==1&&KEY2==0)key_up=1;     
 //JTAG_Set(SWD_ENABLE);
 return 0;// 无按键按下
}

 

 

 

 

 

 

 

 


 

自己UCOS-II.rar

1.01 MB, 下载次数: 376

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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165225
金钱
165225
注册时间
2010-12-1
在线时间
2107 小时
发表于 2013-7-24 11:04:12 | 显示全部楼层
拿仿真器跟踪下,看看问题在哪里.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

34

主题

119

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
275
金钱
275
注册时间
2013-6-15
在线时间
0 小时
 楼主| 发表于 2013-7-24 11:18:21 | 显示全部楼层
大体找到问题了,用战舰版的UCOS-II里的SYSTEM文件换一下就行了,MINI版里的UCOS里的DS0,DS1任务调度实验里的SYSTEM文件估计有bug,麻烦原子哥看看里面BUG的位置
回复 支持 反对

使用道具 举报

34

主题

119

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
275
金钱
275
注册时间
2013-6-15
在线时间
0 小时
 楼主| 发表于 2013-7-24 11:18:47 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
大体找到问题了,用战舰版的UCOS-II里的SYSTEM文件换一下就行了,MINI版里的UCOS里的DS0,DS1任务调度实验里的SYSTEM文件估计有bug,麻烦原子哥看看里面BUG的位置
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165225
金钱
165225
注册时间
2010-12-1
在线时间
2107 小时
发表于 2013-7-24 14:58:55 | 显示全部楼层
回复【4楼】ximilenfu:
---------------------------------
mini板的system文件夹的delay函数,不支持ucosii.所以需要修改.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

34

主题

119

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
275
金钱
275
注册时间
2013-6-15
在线时间
0 小时
 楼主| 发表于 2013-7-24 20:32:16 | 显示全部楼层
回复【5楼】正点原子:
---------------------------------
nimi版的光盘里有UCOS-II的DS0,DS1任务调度实验,你没用delay,你是用OSTimeDlyHMSM()函数的。这个问题解决了,我是用战舰版的UCOS-II的delay函数,但是有一个新问题:当用手“一直”在触摸屏上画画或写字,也会点击“RST”清除,过了一段时间后(这个时间不一定,有时长,有时短),正在写着字或画画时,触摸屏,LED灯都停住保持不变,即触摸屏不变化,LED不闪烁了(要么一直亮,要么一直不亮),触摸功能也不行了,按键功能也不行了(即好像每个任务都没用了)。复位后就有效,但是用手继续一直画画,写字和清除,过了一会儿,还是出现上面问题,当不一直使用触摸功能时,都是好的

//触摸
void TaskTouch(void *pdata)
 {  LCD_ShowString(10,160,"Touch anel");
  while(1)
{   //MY_NVIC_Init(2,0,EXTI1_IRQChannel,2);  
if(Pen_Point.Key_Sta==Key_Down || EN==0)//触摸屏被按下
{
Pen_Int_Set(0);//关闭中断
Convert_Pos();
Pen_Point.Key_Sta=Key_Up;
if(Pen_Point.X0>216&&Pen_Point.Y0>304)Load_Drow_Dialog();//清除
else if(Pen_Point.Y0>180)
{
Draw_Big_Point(Pen_Point.X0,Pen_Point.Y0);//画图     

}  
Pen_Int_Set(1);//开启中断
}
 
     delay_ms(2);
};
 }
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165225
金钱
165225
注册时间
2010-12-1
在线时间
2107 小时
发表于 2013-7-24 20:40:58 | 显示全部楼层
回复【6楼】ximilenfu:
---------------------------------
这要你仿真跟踪看代码才好找问题了.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

34

主题

119

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
275
金钱
275
注册时间
2013-6-15
在线时间
0 小时
 楼主| 发表于 2013-7-24 21:02:34 | 显示全部楼层
回复【7楼】正点原子:
---------------------------------
仿真没用,个任务设断点都无法跟踪,每次出问题时,程序都是在STM32F10x.s中一位置不动
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165225
金钱
165225
注册时间
2010-12-1
在线时间
2107 小时
发表于 2013-7-24 22:52:27 | 显示全部楼层
回复【8楼】ximilenfu:
---------------------------------
那就是死机了...
检查内存.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

34

主题

119

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
275
金钱
275
注册时间
2013-6-15
在线时间
0 小时
 楼主| 发表于 2013-7-25 15:09:08 | 显示全部楼层
回复【9楼】正点原子:
---------------------------------
内存实在是看不懂,全是十六进制,也不知道每个地址是干嘛的
回复 支持 反对

使用道具 举报

34

主题

119

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
275
金钱
275
注册时间
2013-6-15
在线时间
0 小时
 楼主| 发表于 2013-7-25 15:12:38 | 显示全部楼层
回复【9楼】正点原子:
---------------------------------
学的汇编语言不多,求原子哥教一下怎么检查内存
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165225
金钱
165225
注册时间
2010-12-1
在线时间
2107 小时
发表于 2013-7-25 15:13:16 | 显示全部楼层
回复【10楼】ximilenfu:
---------------------------------
1,看函数里面的数组,是不是太大了?这可以导致堆栈溢出死机.
2,看看任务堆栈是不是设置太小了?如果有fatfs读写文件操作的任务,堆栈尽量设置大一点.
3,看是不是指针没分配内存就是用了?这可以导致内存非法访问死机.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

34

主题

119

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
275
金钱
275
注册时间
2013-6-15
在线时间
0 小时
 楼主| 发表于 2013-7-25 15:16:46 | 显示全部楼层
回复【12楼】正点原子:
---------------------------------
呃呃呃谢啦,懂了
回复 支持 反对

使用道具 举报

34

主题

119

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
275
金钱
275
注册时间
2013-6-15
在线时间
0 小时
 楼主| 发表于 2013-7-26 00:29:48 | 显示全部楼层
回复【12楼】正点原子:
---------------------------------
原子哥,我现有块板子,板子上有RS232芯片,有9孔串口,假设有个232转485转换器,将转换器的232口与板子上的9孔连接好后,代码是不是直接用MINISTM32开发板上的实验三串口实验就行了(当然程序中的GPIO口要重新设置其他两个脚了,也将接收的中断函数中的判断回车换行代码也删去了)????????可以吗?不可以的话那是为什么?232转485转换器,我们是应该根据232来编写程序吗?485会自动根据232电平来转换.还有如果都不能的话,能不能用战舰版的实验24   485实验的进行232转485通信?
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-1 14:31

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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