TI中文支持网
TI专业的中文技术问题搜集分享网站

CC2530: 红外捕获

Part Number:CC2530

CC2530先设置为上升沿捕获,进入上升沿捕获中断后,设置为下降沿捕获,以此来测得高电平的时间。但是在使用的时候发现,只有调试的过程中才能进入上升沿中断当中去,而无法进入下降沿中断。具体代码如下:

/****************************************************************************
* 文 件 名: main.c
* 作 者: Andy
* 修 订: 2013-01-08
* 版 本: 1.0
* 描 述: 定时器T3通过中断方式控制LED1周期性闪烁
****************************************************************************/
#include <ioCC2530.h>

typedef unsigned char uchar;
typedef unsigned int uint;

unsigned char irtime=0;
#define IR P1_0
#define uint32_t unsigned int
#define uint16_t unsigned short
#define uint8_t unsigned char

unsigned char receive_ok=1;
uint32_t upCount=0;
uint16_t valueDown=0;
uint16_t valueUp=0;
uint32_t width=0;
uint32_t isUpCap=1;
uint buffer[200]={0};
char bufferId=0;

//#define leng_23
//#define leng_21

#if defined leng_23
uint8_t leng=23;
uint8_t arr[23]={0x00};
#elif defined leng_21
uint8_t leng=21;
uint8_t arr[21]={0x00};
#else
uint8_t leng=17;
uint8_t arr[17]={0x00};
#endif

void IR_Init(void)
{
P1DIR&=0XFE;//P1.0为输入模式
P1SEL|=0X01;//外设功能

}
void InitUart(void)
{
PERCFG &= 0xF0; //外设控制寄存器 USART 0的IO位置:0为P0口位置1
P0SEL = 0x0c; //P0_2,P0_3用作串口(外设功能)
P2DIR &= ~0XC0; //P0优先作为UART0

U0CSR |= 0x80; //设置为UART方式
U0GCR |= 11;
U0BAUD |= 216; //波特率设为115200
UTX0IF = 0; //UART0 TX中断标志初始置位0
}
void UartSendString(uint *Data, int len)
{
uint i;

for(i=0; i<len; i++)
{
U0DBUF = *Data++;
while(UTX0IF == 0);
UTX0IF = 0;
}
}
void InitT3(void)
{
T3CTL|=0X08;//开启溢出中断
T3IE=1;//开启总中断和T3中断
T3CTL|=0XE0;//128分频

T3CTL&=~0X03;//自动重装载
T3CTL|=0X10;//启动
EA=1;
}

void T1_Init(void)
{
PERCFG|=0X40;//定时器1备用位置2
P2SEL&=0XEF;//定时器1优先
T1CTL=0X0D;//128 自由运行模式
T1CCTL2=0X41;//上升沿捕获,捕获模式,定时器1通道2定时器使能
T1IE=1;
EA=1;
//定时器1溢出中断自动开启,TIMIF的寄存器当中
}

uint ary[3]={1,2,3};

int main()
{

CLKCONCMD &= ~0x40; //设置系统时钟源为32MHZ晶振

while(CLKCONSTA & 0x40); //等待晶振稳定为32M
CLKCONCMD &= ~0x07; //设置系统主时钟频率为32MHZ
IR_Init();
// Time1_Init();
T1_Init();

InitUart();
//UartSendString("usart is ok",11);
UartSendString(ary,3);
while(1)

{

if(receive_ok==0)
{
UartSendString(buffer, sizeof(buffer));
for(int ix=0;ix<200;ix++)
{
buffer[ix]=0x00;
}
receive_ok=1;

}

}

}

uint8_t a=0;

#pragma vector = T1_VECTOR
__interrupt void T1_ISR()
{
T1IF = 0;
T1STAT &= ~0x04;//清除中断标志位
// if(T1STAT&(~0XDF))//定时器 1溢出中断
// {
//
//
// irtime++;
//
// }

if(T1STAT&(~0XFB))//边沿触发中断,定时器1通道2中断
{
if(isUpCap)//判断是否是上升沿触发
{
a=T1CC2H;
uint8_t b=T1CC2L;
valueUp=(a<<8)|b;
isUpCap=0;//下降沿的标志位清除
T1CCTL2|=0X02;//下降沿捕获
irtime=0;//溢出计数值置0
}
else
{

uint8_t c=T1CC2H;
uint8_t d=T1CC2L;
valueDown=(c<<8)|d;
//valueDown=(T1CC2H<<8)|T1CC2L;
isUpCap=1;//上升沿的标志位清除
T1CCTL2|=0X01;//上升沿捕获
width=valueDown-valueUp+65536*irtime;//计算出时间
if(bufferId>=1)
{
buffer[bufferId++]=width;
if(bufferId>184)
{
bufferId=0;
receive_ok=0;
}
}
}

}

}
//#pragma vector = T3_VECTOR
//__interrupt void T3_ISR()//2.1ms
//{
// IRCON=0X00;
// irtime++;
//}

Nick Sun:

您好,

收到您的问题了,我们升级到英文论坛给工程师看下,有答复尽快给到您。

,

Nick Sun:

您好,

您在 T1CCTL2 上使用按位包含 OR 赋值运算符“|=”,因此最终结果将最终变为 0x43来用于所有“边沿捕获”。至于为什么无法进入下降沿的逻辑代码,这可能是由于硬件pin脚弹跳或在处理 ISR 时错过了下降沿。(也可能来自运行定时器时钟变慢或暂停调试器内的操作)。在某些时候,可能会由于 T1CCTL2 的“管理不善”导致这种情况。本质上,在捕获模式(capture mode)和软件标志(software flag)之间的逻辑可能存在混淆。

希望能够帮助到您。

原文:Since the customer is using the bitwise inclusive OR assignment operator "|=" on T1CCTL2 then the end result will eventually become 0x43 for "capture on all edges" instead of their intention.As to why the falling edge logical code is never entered, this could be due to hardware pin bounce or the edge is missed by the time it takes to process the ISR (also from running the timer clock slower or pausing operation inside the debugger).At some point it would be expected to enter this section due to the mismanagement of T1CCTL2, in essence the logic can become confused between the capture mode and software flag.  
 

赞(0)
未经允许不得转载:TI中文支持网 » CC2530: 红外捕获
分享到: 更多 (0)