OpenEdv-开源电子网

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

mini板在ucosii里建立的红外键盘任务 获取不到键值,什么原因呢?

[复制链接]

86

主题

417

帖子

0

精华

高级会员

Rank: 4

积分
781
金钱
781
注册时间
2013-2-20
在线时间
0 小时
发表于 2013-6-15 21:11:37 | 显示全部楼层 |阅读模式
void scan_key_task(void *pdata)

    u8 key = 0;
    u8 tmp = 0;
    OS_CPU_SR cpu_sr = 0;
   
    pdata = pdata;
    mqueue_scan_key = OSQCreate(&mqueue_scan_key_tb[0], 5);//创建消息队列(能存5条消息)
     
 while (1)
 {  
        tmp = Remote_Process();
        key = get_infrared_key(tmp);                    
//      key = scan_MatrixKey();//扫描矩阵键盘     
        if (key)
        {
            printf("key=%d\n\n", key);
            OS_ENTER_CRITICAL();//进入临界区(无法被中断打断)
            OSQPost(mqueue_scan_key, &key);//向消息队列发送消息
            OS_EXIT_CRITICAL();  
        }
           
        delay_ms(10);
 }
}
现象:若注销红外键盘(蓝色语句)使用矩阵键盘(红色语句)则一切正常,但反过来如上文所示使用红外键盘则不行。不晓得什么原因啊!
还有使用用红外键盘后,屏幕上的温度值经常会由20几度变成0度~~(对不起,这个现象是由printf函数所致,和红外代码没关系)
u8 get_infrared_key(u8 tmp)
{
    u8 key = 0;    
    if (Remote_Rdy)
 {
  tmp = Remote_Process();  
  switch (tmp)
  {
   //出错
            case 0:              break;
   //电源键
            case 162:          break;
   //上键
            case 98:   key = 15; break;
   //开始键
            case 2:    key = 16; break;
   //外星人键
            case 226:            break;    
   //右键
            case 194:  key = 12; break;                    
   //左键
            case 34:   key = 11; break;                    
   //数字8
            case 56:   key = 9;  break;                    
   //音量减
            case 224:            break;    
   //下键
            case 168:  key = 14; break;                    
   //音量加
            case 144:            break;    
   //数字1
            case 104:  key = 2;  break;                   
   //数字2
            case 152:  key = 3;  break;                    
   //数字3
            case 176: key = 4;   break;                    
      //数字4
         case 48:  key = 5;  break;                   
      //数字5
         case 24:  key = 6; break;                    
      //数字6
         case 122: key = 7; break;                    
      //数字7
         case 16:  key = 8; break;                    
      //数字9
         case 90: key = 10; break;                    
      //数字0
         case 66: key = 1; break;                    
      //删除键
         case 82: key = 13; break;                        
  }
 }
    return key;
}
乐于思考,敢于请教;问人不累,诲人不倦!本人CSDN博客:http://blog.csdn.net/dcx1205 学习嵌入式的同学不要错过啊!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

头像被屏蔽

6168

主题

7036

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
19705
金钱
19705
注册时间
2012-12-27
在线时间
25 小时
发表于 2013-6-15 22:01:08 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

头像被屏蔽

6168

主题

7036

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
19705
金钱
19705
注册时间
2012-12-27
在线时间
25 小时
发表于 2013-6-15 22:03:53 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

9

主题

1385

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
12083
金钱
12083
注册时间
2013-3-8
在线时间
1284 小时
发表于 2013-6-15 23:24:56 | 显示全部楼层
回复【3楼】xouou_53320:
---------------------------------
呵呵,试试吧,也可能是原子程序DELAY函数在用系统与不用系统时延时时间不一样导致。
回复 支持 反对

使用道具 举报

34

主题

805

帖子

4

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1865
金钱
1865
注册时间
2011-3-29
在线时间
140 小时
发表于 2013-6-16 05:30:00 | 显示全部楼层
ucos用哪个版的代码穿上来看看。
业余程序玩家。
回复 支持 反对

使用道具 举报

86

主题

417

帖子

0

精华

高级会员

Rank: 4

积分
781
金钱
781
注册时间
2013-2-20
在线时间
0 小时
 楼主| 发表于 2013-6-16 09:54:38 | 显示全部楼层
回复【4楼】augustedward:
---------------------------------
回复【5楼】ofourme:
---------------------------------
我也怀疑是中断、延时、ucosii这三者的原因 下面是全部的相关代码:

void scan_key_task(void *pdata)
{
    u8 key = 0;
    u8 tmp = 0;
    OS_CPU_SR cpu_sr = 0; 
    
    pdata = pdata;
    mqueue_scan_key = OSQCreate(&mqueue_scan_key_tb[0], 5);//创建消息队列(能存5条消息)
    
while (1)
{   
        tmp = Remote_Process();
        key = get_infrared_key(tmp);
        printf("key1=%d\n\n", key);                    
//        key = scan_MatrixKey();//扫描矩阵键盘      
        if (key)
        {
            printf("key2=%d\n\n", key);
            OS_ENTER_CRITICAL();//进入临界区(无法被中断打断)
            OSQPost(mqueue_scan_key, &key);//向消息队列发送消息
            OS_EXIT_CRITICAL();   
        } 
            
        delay_ms(10);//10 
}
}


#define REMOTE_ID 0 
u8 IRkey_value = 0;
       
u32 Remote_Odr=0;    //命令暂存处
u8  Remote_Cnt=0;    //按键次数,此次按下键的次数
u8  Remote_Rdy=0;    //红外接收到数据    
//初始化红外接收引脚的设置
//开启中断,并映射 
void Remote_Init(void)
{  
RCC->APB2ENR|=1<<2;    //PA时钟使能   
GPIOA->CRL&=0XFFFFFF0F;
GPIOA->CRL|=0X00000080; //PA1输入  
GPIOA->ODR|=1<<1; //PA.1上拉      
Ex_NVIC_Config(GPIO_A,1,FTIR);//将line1映射到PA.1,下降沿触发.
MY_NVIC_Init(0,0,EXTI1_IRQChannel,2);

  
//检测脉冲宽度
//最长脉宽为5ms
//返回值:x,代表脉宽为x*20us(x=1~250);
u8 ulse_Width_Check(void)
{
    u8 t = 0;  
    while (RDATA)
    {  
t++;
        delay_us(20);  
        if (t == 250)
        {
            return t; //超时溢出
        }       
    }

    return t;
}
   
//处理红外接收  
/*-------------------------协议--------------------------
开始拉低9ms,接着是一个4.5ms的高脉冲,通知器件开始传送数据了
接着是发送4个8位二进制码,第一二个是遥控识别码(REMOTE_ID),第一个为
正码(0),第二个为反码(255),接着两个数据是键值,第一个为正码
第二个为反码.发送完后40ms,遥控再发送一个9ms低,2ms高的脉冲,
表示按键的次数,出现一次则证明只按下了一次,如果出现多次,则可
以认为是持续按下该键.
---------------------------------------------------------*/  

//外部中断服务程序    
void EXTI1_IRQHandler(void)
{       
u8 res = 0;
    u8 OK = 0; 
    u8 RODATA = 0;     
//    u8 tmp = 0;
        
while (1)
    {        
//        printf("EXTI1_IRQHandler\n\n");//ok
        if (RDATA)//有高脉冲出现
        {
            res = ulse_Width_Check();//获得此次高脉冲宽度       
            if (res == 250)
            {
                break;//非有用信号
            }
            else if (res>=200 && res<250)
            {
                OK = 1;//获得前导位(4.5ms)
            }
            else if (res>=85 && res<200)//按键次数加一(2ms)
            {         
                Remote_Rdy = 1;//接受到数据
//                printf("Remote_Rdy1=%d\n\n", Remote_Rdy);//ok
                Remote_Cnt++;//按键次数增加
                break;
            }
            else if (res>=50 && res<85)
            {
                RODATA = 1;//1.5ms
            }
            else if (res>=10 && res<50)
            {
                RODATA = 0;//500us
            }
            if (OK)
            {
                Remote_Odr <<= 1;
                Remote_Odr += RODATA; 
                Remote_Cnt = 0;//按键次数清零
            }   
        }    
    }
//    tmp = Remote_Process();//处理红外键盘,返回相应的键值
//    IRkey_value = get_infrared_key(tmp);
//    printf("tmp=%d\n\n", tmp);
            
EXTI->R = 1<<1;//清除中断标志位        
}  


//处理红外键盘
//返回相应的键值
u8 Remote_Process(void)
{               
    u8 t1,t2;   
    t1 = Remote_Odr >> 24; //得到地址码
    t2 = (Remote_Odr >> 16) & 0xff;//得到地址反码 
    Remote_Rdy = 0;//清除标记        
//    printf("Remote_Process\n\n");
    if (t1==(u8)~t2 && t1==REMOTE_ID)//检验遥控识别码(ID)及地址 
    { 
        t1 = Remote_Odr >> 8;
        t2 = Remote_Odr; 
        if (t1 == (u8)~t2)
        {
            return t1; //处理键值 
        }        
    } 
        
    return 0;
}

u8 get_infrared_key(u8 tmp)
{
    u8 key = 0;    
//    printf("get_infrared_key\n\n"); //ok
    if (Remote_Rdy)
{
// printf("get_infrared_key\n\n");//no
//        printf("Remote_Rdy2=%d\n\n", Remote_Rdy);
        tmp = Remote_Process();           
switch (tmp)
{
//出错
            case 0:              break;
//电源键 
            case 162:          break;
//上键
            case 98:   key = 15;  break;
//开始键
            case 2:    key = 16; break;
//外星人键
            case 226:            break;
//右键
            case 194:  key = 12; break;                
//左键
            case 34:   key = 11; break;                
//数字8
            case 56:   key = 9;  break;                
//音量减
            case 224:            break;
//下键
            case 168:  key = 14; break;                
//音量加
            case 144:            break;
//数字1
            case 104:  key = 2;  break;               
//数字2
            case 152:  key = 3;  break;                
//数字3
            case 176: key = 4;   break;                
    //数字4
         case 48:  key = 5;  break;               
    //数字5
         case 24:  key = 6; break;                
    //数字6
         case 122: key = 7; break;                
    //数字7
         case 16:  key = 8; break;                
    //数字9
         case 90: key = 10; break;                
    //数字0
         case 66: key = 1; break;                
    //删除键
         case 82: key = 13; break;                     
}
}
//    printf("key=%d\n\n", key);
    return key;
}
乐于思考,敢于请教;问人不累,诲人不倦!本人CSDN博客:http://blog.csdn.net/dcx1205 学习嵌入式的同学不要错过啊!
回复 支持 反对

使用道具 举报

34

主题

805

帖子

4

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1865
金钱
1865
注册时间
2011-3-29
在线时间
140 小时
发表于 2013-6-16 10:44:29 | 显示全部楼层

不使用os的话红外中断可用吗?delay_us的原型是什么?看起来你的程序问题多多。

估计是你在中断里面使用延时函数的原因, 在中断里面切换导致程序崩溃?或者是systick中断导致错误?

...所以,在此我要厚颜无耻的推荐我的红外中断程序(在我的小车程序里),虽然只做过初步的测试ok,但是我觉得我的程序写得挺不错滴!!!

如果不想改动太多的话,先替换一下delay_us试一下。我的hw_delay_us函数只是通过查询systick的值来延时。只需启动systick,无需启动中断,也不会影响systick作为他用:
void hw_delay_us(unsigned int us)
{
 unsigned int start ,target,cur;

 while(us > 500) // 保险起见,延时时间不能超过systick中断周期的一般,这里设置为500us,则系统中断频率可以高达1ms,也即1000/s。 
 {
  hw_delay_us(500);
  us -= 500;
 }

 start = SysTick->VAL;
 target = (start-us*9);
 
 if(start<target) 
 {
  target += (9000000 / RT_TICK_PER_SECOND);//RT_TICK_PER_SECOND是系统中断频率
  do
  {
   cur = SysTick->VAL;
  }while(cur<=start || cur>target);  }
 else   // target <= start
 {
  do
  {
   cur = SysTick->VAL;
  }while(target<cur&&cur<=start);  }
}

业余程序玩家。
回复 支持 反对

使用道具 举报

86

主题

417

帖子

0

精华

高级会员

Rank: 4

积分
781
金钱
781
注册时间
2013-2-20
在线时间
0 小时
 楼主| 发表于 2013-6-16 10:53:07 | 显示全部楼层
回复【7楼】ofourme:
---------------------------------
嗯 不用os是可以的呢。好啊,期待你的红外程序啊,我最喜欢写的漂亮的代码了呢。我QQ1982211588,发我邮箱即可。谢了啊。
不过问下 你的红外能在ucosii里用吗?
乐于思考,敢于请教;问人不累,诲人不倦!本人CSDN博客:http://blog.csdn.net/dcx1205 学习嵌入式的同学不要错过啊!
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-6-16 10:56:06 | 显示全部楼层
delay_us,如果是mini板的原版system函数,是不能在ucosii里面用的!!!
用战舰板的,并开通ucosii支持(一个宏定义),就可以了
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

86

主题

417

帖子

0

精华

高级会员

Rank: 4

积分
781
金钱
781
注册时间
2013-2-20
在线时间
0 小时
 楼主| 发表于 2013-6-16 11:05:35 | 显示全部楼层
回复【9楼】正点原子:
---------------------------------
哦,不过我的mini板是跑的战舰的ucosii。现在问题是我移植了mini板的红外键盘程序后 没法用啊,连键值都获取不了,怎么回事呢?
乐于思考,敢于请教;问人不累,诲人不倦!本人CSDN博客:http://blog.csdn.net/dcx1205 学习嵌入式的同学不要错过啊!
回复 支持 反对

使用道具 举报

86

主题

417

帖子

0

精华

高级会员

Rank: 4

积分
781
金钱
781
注册时间
2013-2-20
在线时间
0 小时
 楼主| 发表于 2013-6-16 11:19:39 | 显示全部楼层
回复【7楼】ofourme:
---------------------------------
你看红外代码里只有一次用到延时,就是那个delay_us(20); 我换成你的延时函数后红外还是不行的!
乐于思考,敢于请教;问人不累,诲人不倦!本人CSDN博客:http://blog.csdn.net/dcx1205 学习嵌入式的同学不要错过啊!
回复 支持 反对

使用道具 举报

34

主题

805

帖子

4

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1865
金钱
1865
注册时间
2011-3-29
在线时间
140 小时
发表于 2013-6-16 11:34:01 | 显示全部楼层
你这不行究竟是怎么不行,没说清楚啊。是程序奔溃了还是任务奔溃了还是仅仅没接收到红外?
建议在扫描代码后面再加一段LED灯闪烁程序看看对应的任务运行是否正常。
还是把工程传上来吧,可以的话。
业余程序玩家。
回复 支持 反对

使用道具 举报

86

主题

417

帖子

0

精华

高级会员

Rank: 4

积分
781
金钱
781
注册时间
2013-2-20
在线时间
0 小时
 楼主| 发表于 2013-6-16 13:11:02 | 显示全部楼层
回复【12楼】 ofourme :
---------------------------------
没法接收到红外按键的键值!!

UCOSII+STM32+红外遥控-有问题.rar

154.63 KB, 下载次数: 921

乐于思考,敢于请教;问人不累,诲人不倦!本人CSDN博客:http://blog.csdn.net/dcx1205 学习嵌入式的同学不要错过啊!
回复 支持 反对

使用道具 举报

86

主题

417

帖子

0

精华

高级会员

Rank: 4

积分
781
金钱
781
注册时间
2013-2-20
在线时间
0 小时
 楼主| 发表于 2013-6-16 16:54:49 | 显示全部楼层
楼上各位:
多谢了!!!

问题解决了哦!
乐于思考,敢于请教;问人不累,诲人不倦!本人CSDN博客:http://blog.csdn.net/dcx1205 学习嵌入式的同学不要错过啊!
回复 支持 反对

使用道具 举报

34

主题

805

帖子

4

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1865
金钱
1865
注册时间
2011-3-29
在线时间
140 小时
发表于 2013-6-16 18:17:33 | 显示全部楼层
怎么破?
回复 支持 反对

使用道具 举报

86

主题

417

帖子

0

精华

高级会员

Rank: 4

积分
781
金钱
781
注册时间
2013-2-20
在线时间
0 小时
 楼主| 发表于 2013-6-16 20:36:28 | 显示全部楼层
回复【15楼】ofourme:
---------------------------------
不要用自带的延时函数,自己写个像51里的那种延时就好了哦
乐于思考,敢于请教;问人不累,诲人不倦!本人CSDN博客:http://blog.csdn.net/dcx1205 学习嵌入式的同学不要错过啊!
回复 支持 反对

使用道具 举报

2

主题

8

帖子

0

精华

新手上路

积分
36
金钱
36
注册时间
2013-3-19
在线时间
0 小时
发表于 2013-6-16 22:48:38 | 显示全部楼层
回复【9楼】正点原子:
---------------------------------
原子哥,mini板子的UCOSII的时钟节拍是多少呢?
两个相爱的人同时表白,对我来说那是最幸福的事情了
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-6-17 13:48:22 | 显示全部楼层
5ms.
回复 支持 反对

使用道具 举报

头像被屏蔽

38

主题

382

帖子

0

精华

高级会员

Rank: 4

积分
596
金钱
596
注册时间
2012-12-5
在线时间
19 小时
发表于 2014-12-21 18:46:51 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-27 18:36

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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