您的位置:首页 > 其它

cc2541 红外发送

2015-07-17 13:48 211 查看


红外发送一般基于载波38k,基带信号一般是根据无载波的时间来判断0和1,无论基带信号用什么编码,只要硬件部分能发载波和停止载波就可以。

由于cc2541任务中不能延时太久,用延时来实现红外信号不可行,所以要用硬件来实现。

硬件实现红外信号是基于定时器1和定时器3。定时器3产生38k载波,定时器1的时钟源接定时器3,然后共同输出调制波,当定时器每次比较中断时付值下一位的信号。



#include "IR.h"
#include "hal_mcu.h"
void IR_init()
{

P1DIR|= BV(1);

P1SEL|= BV(1);

PERCFG |= 0x40;

IRCTL |= BV(0);             //开启T1红外模式

T3CTL |= BV(1)| BV(6);      //周期模式 重复0 -》T1CC0
T3CCTL0 |= BV(2);           //channel 0 比较模式
T3CCTL1 |= BV(2)|BV(5);     //changel 1 比较模式 比较置0

T3CC0 = 210;                //38K
T3CC1 = 105;
//T3CTL |= BV(4);

T1CTL = 0x00;
T1CCTL0 |= 0x04;
T1CCTL1 = 0x34;//0x34;

T1CNTL = 0; // Reset timer to 0;

T1CC0L = 0x02;
T1CC0H = 0x02;

T1CC1L = 0x57;
T1CC1H = 0x01;

//T1CTL |= 0x02;
T1IE =1;
//EA=1;

}
uint8 irdat[33];
uint8 ir_i = 0;

void send_dat(void)
{
uint8 dat[4];
dat[0] = 0x00;
dat[1] = 0xff;
dat[2] = 0x09;
dat[3] = 0xf6;
send_irdat(dat);
}

void tran_irdat(uint8 *dat)
{
uint8 i,j,k;
for(i = 0; i < 4; i++)
{
k = dat[i];
for(j = 0; j < 8; j++)
{
if(k&0x01)
{
irdat[i*8+j] = 84;
}
else
{
irdat[i*8+j] = 46;
}
k = k >> 1;
}
}
irdat[32] = 84;
ir_i = 0;
// halIntState_t intState;
// HAL_ENTER_CRITICAL_SECTION( intState );
HAL_DISABLE_INTERRUPTS();
IR_init();
T1CNTH = 0;
T1CNTL = 0;

T3CNT = 0;

T1CC0L = 0x02;
T1CC0H = 0x02;

T1CC1L = 0x57;
T1CC1H = 0x01;
//  T1IE =1;
//  EA=1;
T1CTL |= 0x02;
T3CTL |= BV(4);
HAL_ENABLE_INTERRUPTS();
//HAL_EXIT_CRITICAL_SECTION( intState );

}

//定时器 T1 中断处理函数
#pragma vector = T1_VECTOR
__interrupt void Timer1_ISR(void)
{
//IRCON = 0x00;
HAL_DISABLE_INTERRUPTS();
if(ir_i == 33)
{
T1CTL = 0x00;
T3CTL &= ~BV(4);
HAL_ENABLE_INTERRUPTS();
return;
}
// if(T1STAT&0x01)
{

T1CC0L = irdat[ir_i];
T1CC0H = 0;

T1CC1L = 23;
T1CC1H = 0;
ir_i++;
}
T1STAT = 0;
HAL_ENABLE_INTERRUPTS();
}

uint8 IS_IR_OK(void)
{
if(ir_i == 33)
{
return 1;
}
else
return 0;
}


值得注意的是当开启POWER_SAVING时,当前没有任务时,晶振会给停止从而使时定器停止工作,发送不了信号。所以当发红外信号时,其中一个方法是不断的set_event从而使cc2541不休眠。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: