打印

用过cortexM0写红外程序的兄弟请进

[复制链接]
2079|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
liwxiong|  楼主 | 2011-6-22 21:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近在做一个红外遥控的程序,遇到一些问题,相信会有一些挑战性,我分析了好久没找到原因:需要两次按键才能够正确地执行完中断,按一次遥控器按钮,只执行到
/*if(irin==0) //(第一次按键,程序执行到此就跳出去了)
  {
   
   LPC_GPIO1->IE |= (0x1<<bitPosi);
   LPC_GPIO1->IC |= (0x1<<bitPosi);
   return;
  }  */  
上面这一句就跳出去了。可以判断出是第一次按键的编码没有被正确地读取。但是奇怪的是第二次却能够正确的读取。因为读到的数据,num1=~num2是对的,并没有错码。我调试了好几天,都没有成功。原来以为是中断优先级会影响,后来又以为irin判断语句不行,结果改过来之后错误仍然依旧。
    希望您能够认真看一下下面的程序,帮忙分析一下可能的原因是什么?不胜感激!
1、发送的码如下:(解码刚好是电平相反的)
file:///C:/Documents%20and%20Settings/corner/Application%20Data/Tencent/Users/605231119/QQ/WinTemp/RichOle/R(3KEI_1FF4SFGN_%7BM%7DH7ZF.jpg

2、程序如下:
#include <lpc11xx.H>
#include "timer32.h"
#define   STATE   0x00000182
#define   LED3    0x00000080
#define   bitPosi    1        
#define   LED5    0x00000002
#define   LED4    0x00000100
#define GPIO_BASE     (0x50000000ul)
#define GPIO1MASKED_ACCESS(bit)  (*(volatile unsigned long *)(GPIO_BASE + 0x10000 + (bit)))
#define PRIO_ONE  1
#define priority 1
#define   irin GPIO1MASKED_ACCESS(0x01 << 3)  
unsigned char addrl,addrh,num1,num2,num3,KeyValue,MaValue,l=0;
void Delay_840us()
{
LPC_TMR32B0->TCR = 0x02;  /* reset timer */
LPC_SYSCON->SYSAHBCLKCTRL  |= (1 << 9);       /*  打开定时器模块    */
LPC_TMR32B0->IR      = 1;
LPC_TMR32B0->PR      = 0;       /* 设置分频系数    */
LPC_TMR32B0->MCR     = 4;        /* 设置MR0 匹配后复位TC不产生中断     */
  LPC_TMR32B0->MR0     = 10080;      /* 设置中断时间    */
  LPC_TMR32B0->TCR     = 0x01;       /* 启动定时器     */
while (LPC_TMR32B0->TCR & 0x01);
}
  void Delay_2400us()
{
LPC_TMR32B0->TCR = 0x02;  /* reset timer */
LPC_SYSCON->SYSAHBCLKCTRL  |= (1 << 9);       /*  打开定时器模块    */
LPC_TMR32B0->IR      = 1;
LPC_TMR32B0->PR      = 0;       /* 设置分频系数    */
LPC_TMR32B0->MCR     = 4;        /* 设置MR0 匹配后复位TC不产生中断     */
  LPC_TMR32B0->MR0     = 28800;      /* 设置中断时间    */
  LPC_TMR32B0->TCR     = 0x01;       /* 启动定时器     */
while (LPC_TMR32B0->TCR & 0x01);
}
  void Delay_240ms()
{
  unsigned int i,n;
  for(i=0;i<100;i++)
  {
  for(n=0;n<1000;n++);
  }
}

unsigned char GetCode()//读码:
  {
    unsigned char n;
   unsigned char temp=0;
    for(n=0;n<8;n++)
    {  while(irin==0);  
       Delay_840us();  
       if(irin != 0)  //  0
       {   temp=(0x80|(temp>>1));   
           while(irin != 0);
       }
        else temp=(0x00|(temp>>1));//   1
    }
    return temp;
  }

void PIOINT1_IRQHandler(void)
     {   
unsigned char t,n,Count=0;

LPC_GPIO1->IE &= ~(0x1<<bitPosi);
  for(n=0;n<10;n++)       //检测9ms开始码
  {  Delay_840us();  
     if(irin!=0)  
     {   Count++;
          break;  
     }
  }     
  
  if(Count)
  {
     LPC_GPIO1->IE |= (0x1<<bitPosi);
// LPC_GPIO1->IC |= (0x1<<bitPosi);  
     return;
  }   
      
  while(irin==0){};
     l++;
if(irin==0) //第一次按键,程序执行到此就跳出去了。
  {
   
   LPC_GPIO1->IE |= (0x1<<bitPosi);
   LPC_GPIO1->IC |= (0x1<<bitPosi);
   return;
  }  
  Delay_2400us();  
   
  addrl=GetCode();
  
  addrh=GetCode();
  num1=GetCode();
  num2=GetCode();
  num3=~num2;
if(num1!=num3)//错码;
  {   
     LPC_GPIO1->IE |= (0x1<<bitPosi);
  LPC_GPIO1->IC |= (0x1<<bitPosi);  
     return;
  }  
  KeyValue=num2;
  MaValue=addrh;
//led闪烁验证程序是否执行至此
    for(t=0;t<5;t++)
{
LPC_GPIO2 ->DATA=~LED3;
   Delay_240ms();
   LPC_GPIO2 ->DATA|=(0x01<<7);
   Delay_240ms();
}
  LPC_GPIO1->IC |= (0x1<<bitPosi);   
LPC_GPIO1->IE |= (0x1<<bitPosi);   //开中断         
}


void System_init(void)
{


LPC_GPIO2->DIR=STATE ;
LPC_GPIO1->DIR&=~(0x01<<1);

NVIC->IPR[_IP_IDX(30)] = (NVIC->IPR[_IP_IDX(30)] & ~(0xFF << _BIT_SHIFT(30))) |
        (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(30));
  // Enable AHB clock to the GPIO domain.
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);
//zyIsrSet(NVIC_PIOINT1, (unsigned int)PIOINT1_IRQHandler, PRIO_ONE);
//LPC_zyIsrSet(NVIC_PIOINT1, (unsigned long)GPIOIsr, PRIO_ONE);  
// Set up NVIC when I/O pins are configured as external interrupts.
NVIC_EnableIRQ(EINT1_IRQn);
LPC_GPIO1->IS &= ~(0x1<<bitPosi);
// single or double only applies when sense is 0(edge trigger,即边缘触发).
LPC_GPIO1->IBE&= ~(0x1<<bitPosi);  //IS和IBE加起来再加IEV构成下降沿触发
LPC_GPIO1->IEV|= (0x1<<bitPosi);   
LPC_GPIO1->IE |= (0x1<<bitPosi);   //开中断
}



int main(void)
{
   System_init() ;  
   while(1)
   {
   LPC_GPIO2 ->DATA=~LED3;
   Delay_240ms();
   LPC_GPIO2 ->DATA|=(0x01<<8);
   Delay_240ms();
   LPC_GPIO2 ->DATA=~LED4;
   Delay_240ms();
   LPC_GPIO2 ->DATA|=(0x01<<7);
   Delay_240ms();  
   LPC_GPIO2 ->DATA=~LED5;
   Delay_240ms();
   LPC_GPIO2 ->DATA|=(0x01<<7);
   Delay_240ms();  
     
   }  
}

烧入程序,按一次中断,led停止流水灯闪烁,亮着一颗(led3、4、5都有可能)不动,l会加一,即程序执行到l++处了。再按一次,程序继续往下完整地执行完,结尾我用led闪烁几次来提示执行到了末尾。

相关帖子

沙发
liwxiong|  楼主 | 2011-6-22 21:13 | 只看该作者

(添加一份红外编码pdf资料)

提问帖子在上一个。

ir.pdf

1 MB

使用特权

评论回复
板凳
liwxiong|  楼主 | 2011-6-23 08:20 | 只看该作者
自己顶一下,听说21IC高手最多了,希望有人能够指点一下。:)

使用特权

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

本版积分规则

0

主题

13

帖子

1

粉丝